From ff18ae2562b55bcce70690c3faa937136c5bb4d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=82=85=E5=B0=8F=E9=BB=91?= Date: Sat, 21 Dec 2013 13:19:24 +0800 Subject: [PATCH] add api comments in file memzipfile.go,reload.go,router.go,template.go and templatefunc.go, fix spelling error GetInitListner as GetInitListener. --- app.go | 22 ++++++++++---------- memzipfile.go | 26 +++++++++++++++++++++--- reload.go | 9 ++++++++- router.go | 53 +++++++++++++++++++++++++++++++------------------ template.go | 11 +++++++--- templatefunc.go | 36 +++++++++++++++++++-------------- 6 files changed, 105 insertions(+), 52 deletions(-) diff --git a/app.go b/app.go index c8d91d78..da18718e 100644 --- a/app.go +++ b/app.go @@ -61,7 +61,7 @@ func (app *App) Run() { if nil != err { BeeLogger.Critical("ResolveTCPAddr:", err) } - l, err = GetInitListner(laddr) + l, err = GetInitListener(laddr) theStoppable = newStoppable(l) err = server.Serve(theStoppable) theStoppable.wg.Wait() @@ -92,19 +92,19 @@ func (app *App) Run() { // The c argument needs a controller handler implemented beego.ControllerInterface. // The mapping methods argument only need one string to define custom router rules. // usage: -// simple router -// beego.Router("/admin", &admin.UserController{}) -// beego.Router("/admin/index", &admin.ArticleController{}) +// simple router +// beego.Router("/admin", &admin.UserController{}) +// beego.Router("/admin/index", &admin.ArticleController{}) // -// regex router +// regex router // -// beego.Router(“/api/:id([0-9]+)“, &controllers.RController{}) +// beego.Router(“/api/:id([0-9]+)“, &controllers.RController{}) // // custom rules -// beego.Router("/api/list",&RestController{},"*:ListFood") -// beego.Router("/api/create",&RestController{},"post:CreateFood") -// beego.Router("/api/update",&RestController{},"put:UpdateFood") -// beego.Router("/api/delete",&RestController{},"delete:DeleteFood") +// beego.Router("/api/list",&RestController{},"*:ListFood") +// beego.Router("/api/create",&RestController{},"post:CreateFood") +// beego.Router("/api/update",&RestController{},"put:UpdateFood") +// beego.Router("/api/delete",&RestController{},"delete:DeleteFood") func (app *App) Router(path string, c ControllerInterface, mappingMethods ...string) *App { app.Handlers.Add(path, c, mappingMethods...) return app @@ -118,7 +118,7 @@ func (app *App) AutoRouter(c ControllerInterface) *App { return app } -// UrlFor does another controller handler with params in current context. +// UrlFor creates a url with another registered controller handler with params. // The endpoint is formed as path.controller.name to defined the controller method which will run. // The values need key-pair data to assign into controller method. func (app *App) UrlFor(endpoint string, values ...string) string { diff --git a/memzipfile.go b/memzipfile.go index 593c876b..43a82a30 100644 --- a/memzipfile.go +++ b/memzipfile.go @@ -16,7 +16,8 @@ import ( var gmfim map[string]*MemFileInfo = make(map[string]*MemFileInfo) -//TODO: 加锁保证数据完整性 +// OpenMemZipFile returns MemFile object with a compressed static file. +// it's used for serve static file if gzip enable. func OpenMemZipFile(path string, zip string) (*MemFile, error) { osfile, e := os.Open(path) if e != nil { @@ -86,6 +87,8 @@ func OpenMemZipFile(path string, zip string) (*MemFile, error) { return &MemFile{fi: cfi, offset: 0}, nil } +// MemFileInfo contains a compressed file bytes and file information. +// it implements os.FileInfo interface. type MemFileInfo struct { os.FileInfo modTime time.Time @@ -94,49 +97,62 @@ type MemFileInfo struct { fileSize int64 } +// Name returns the compressed filename. func (fi *MemFileInfo) Name() string { return fi.Name() } +// Size returns the raw file content size, not compressed size. func (fi *MemFileInfo) Size() int64 { return fi.contentSize } +// Mode returns file mode. func (fi *MemFileInfo) Mode() os.FileMode { return fi.Mode() } +// ModTime returns the last modified time of raw file. func (fi *MemFileInfo) ModTime() time.Time { return fi.modTime } +// IsDir returns the compressing file is a directory or not. func (fi *MemFileInfo) IsDir() bool { return fi.IsDir() } +// return nil. implement the os.FileInfo interface method. func (fi *MemFileInfo) Sys() interface{} { return nil } +// MemFile contains MemFileInfo and bytes offset when reading. +// it implements io.Reader,io.ReadCloser and io.Seeker. type MemFile struct { fi *MemFileInfo offset int64 } +// Close memfile. func (f *MemFile) Close() error { return nil } +// Get os.FileInfo of memfile. func (f *MemFile) Stat() (os.FileInfo, error) { return f.fi, nil } +// read os.FileInfo of files in directory of memfile. +// it returns empty slice. func (f *MemFile) Readdir(count int) ([]os.FileInfo, error) { infos := []os.FileInfo{} return infos, nil } +// Read bytes from the compressed file bytes. func (f *MemFile) Read(p []byte) (n int, err error) { if len(f.fi.content)-int(f.offset) >= len(p) { n = len(p) @@ -152,6 +168,7 @@ func (f *MemFile) Read(p []byte) (n int, err error) { var errWhence = errors.New("Seek: invalid whence") var errOffset = errors.New("Seek: invalid offset") +// Read bytes from the compressed file bytes by seeker. func (f *MemFile) Seek(offset int64, whence int) (ret int64, err error) { switch whence { default: @@ -169,8 +186,9 @@ func (f *MemFile) Seek(offset int64, whence int) (ret int64, err error) { return f.offset, nil } -//返回: gzip, deflate, 优先gzip -//返回空, 表示不zip +// GetAcceptEncodingZip returns accept encoding format in http header. +// zip is first, then deflate if both accepted. +// If no accepted, return empty string. func GetAcceptEncodingZip(r *http.Request) string { ss := r.Header.Get("Accept-Encoding") ss = strings.ToLower(ss) @@ -181,8 +199,10 @@ func GetAcceptEncodingZip(r *http.Request) string { } else { return "" } + return "" } +// CloseZWriter closes the io.Writer after compressing static file. func CloseZWriter(zwriter io.Writer) { if zwriter == nil { return diff --git a/reload.go b/reload.go index 0087765d..ad8ad8e7 100644 --- a/reload.go +++ b/reload.go @@ -16,6 +16,7 @@ import ( ) const ( + // An environment variable when restarting application http listener. FDKey = "BEEGO_HOT_FD" ) @@ -32,6 +33,7 @@ type conn struct { lock sync.Mutex } +// Close current processing connection. func (c conn) Close() error { c.lock.Lock() defer c.lock.Unlock() @@ -67,6 +69,8 @@ func newStoppable(l net.Listener) (sl *stoppableListener) { return } +// Set stopped Listener to accept requests again. +// it returns the accepted and closable connection or error. func (sl *stoppableListener) Accept() (c net.Conn, err error) { c, err = sl.Listener.Accept() if err != nil { @@ -80,6 +84,7 @@ func (sl *stoppableListener) Accept() (c net.Conn, err error) { return } +// Listener waits signal to kill or interrupt then restart. func WaitSignal(l net.Listener) error { ch := make(chan os.Signal, 1) signal.Notify(ch, os.Interrupt, os.Kill) @@ -101,6 +106,7 @@ func WaitSignal(l net.Listener) error { return nil // It'll never get here. } +// Kill current running os process. func CloseSelf() error { ppid := os.Getpid() if ppid == 1 { // init provided sockets, for example systemd @@ -140,7 +146,8 @@ func Restart(l net.Listener) error { return nil } -func GetInitListner(tcpaddr *net.TCPAddr) (l net.Listener, err error) { +// Get current net.Listen in running process. +func GetInitListener(tcpaddr *net.TCPAddr) (l net.Listener, err error) { countStr := os.Getenv(FDKey) if countStr == "" { return net.ListenTCP("tcp", tcpaddr) diff --git a/router.go b/router.go index ea307404..dd2567c0 100644 --- a/router.go +++ b/router.go @@ -19,6 +19,7 @@ import ( ) const ( + // default filter execution points BeforeRouter = iota AfterStatic BeforeExec @@ -27,6 +28,7 @@ const ( ) var ( + // supported http methods. HTTPMETHOD = []string{"get", "post", "put", "delete", "patch", "options", "head"} ) @@ -39,6 +41,7 @@ type controllerInfo struct { hasMethod bool } +// ControllerRegistor containers registered router rules, controller handlers and filters. type ControllerRegistor struct { routers []*controllerInfo // regexp router storage fixrouters []*controllerInfo // fixed router storage @@ -48,6 +51,7 @@ type ControllerRegistor struct { autoRouter map[string]map[string]reflect.Type //key:controller key:method value:reflect.type } +// NewControllerRegistor returns a new ControllerRegistor. func NewControllerRegistor() *ControllerRegistor { return &ControllerRegistor{ routers: make([]*controllerInfo, 0), @@ -56,15 +60,16 @@ func NewControllerRegistor() *ControllerRegistor { } } -//methods support like this: -//default methods is the same name as method -//Add("/user",&UserController{}) -//Add("/api/list",&RestController{},"*:ListFood") -//Add("/api/create",&RestController{},"post:CreateFood") -//Add("/api/update",&RestController{},"put:UpdateFood") -//Add("/api/delete",&RestController{},"delete:DeleteFood") -//Add("/api",&RestController{},"get,post:ApiFunc") -//Add("/simple",&SimpleController{},"get:GetFunc;post:PostFunc") +// Add controller handler and pattern rules to ControllerRegistor. +// usage: +// default methods is the same name as method +// Add("/user",&UserController{}) +// Add("/api/list",&RestController{},"*:ListFood") +// Add("/api/create",&RestController{},"post:CreateFood") +// Add("/api/update",&RestController{},"put:UpdateFood") +// Add("/api/delete",&RestController{},"delete:DeleteFood") +// Add("/api",&RestController{},"get,post:ApiFunc") +// Add("/simple",&SimpleController{},"get:GetFunc;post:PostFunc") func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingMethods ...string) { parts := strings.Split(pattern, "/") @@ -210,11 +215,11 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM } } -// add auto router to controller -// example beego.AddAuto(&MainContorlller{}) -// MainController has method List and Page -// you can visit the url /main/list to exec List function -// /main/page to exec Page function +// Add auto router to ControllerRegistor. +// example beego.AddAuto(&MainContorlller{}), +// MainController has method List and Page. +// visit the url /main/list to exec List function +// /main/page to exec Page function. func (p *ControllerRegistor) AddAuto(c ControllerInterface) { p.enableAuto = true reflectVal := reflect.ValueOf(c) @@ -231,6 +236,8 @@ func (p *ControllerRegistor) AddAuto(c ControllerInterface) { } } +// [Deprecated] use InsertFilter. +// Add FilterFunc with pattern for action. func (p *ControllerRegistor) AddFilter(pattern, action string, filter FilterFunc) { mr := buildFilter(pattern, filter) switch action { @@ -248,12 +255,15 @@ func (p *ControllerRegistor) AddFilter(pattern, action string, filter FilterFunc p.enableFilter = true } +// Add a FilterFunc with pattern rule and action constant. func (p *ControllerRegistor) InsertFilter(pattern string, pos int, filter FilterFunc) { mr := buildFilter(pattern, filter) p.filters[pos] = append(p.filters[pos], mr) p.enableFilter = true } +// UrlFor does another controller handler in this request function. +// it can access any controller method. func (p *ControllerRegistor) UrlFor(endpoint string, values ...string) string { paths := strings.Split(endpoint, ".") if len(paths) <= 1 { @@ -369,7 +379,7 @@ func (p *ControllerRegistor) UrlFor(endpoint string, values ...string) string { return "" } -// main function to serveHTTP +// Implement http.Handler interface. func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) { defer func() { if err := recover(); err != nil { @@ -753,8 +763,8 @@ Admin: } } -// there always should be error handler that sets error code accordingly for all unhandled errors -// in order to have custom UI for error page it's necessary to override "500" error +// there always should be error handler that sets error code accordingly for all unhandled errors. +// in order to have custom UI for error page it's necessary to override "500" error. func (p *ControllerRegistor) getErrorHandler(errorCode string) func(rw http.ResponseWriter, r *http.Request) { handler := middleware.SimpleServerError ok := true @@ -771,6 +781,9 @@ func (p *ControllerRegistor) getErrorHandler(errorCode string) func(rw http.Resp return handler } +// returns method name from request header or form field. +// sometimes browsers can't create PUT and DELETE request. +// set a form field "_method" instead. func (p *ControllerRegistor) getRunMethod(method string, context *beecontext.Context, router *controllerInfo) string { method = strings.ToLower(method) if method == "post" && strings.ToLower(context.Input.Query("_method")) == "put" { @@ -806,6 +819,7 @@ func (w *responseWriter) Header() http.Header { return w.writer.Header() } +// Init content-length header. func (w *responseWriter) InitHeadContent(contentlength int64) { if w.contentEncoding == "gzip" { w.Header().Set("Content-Encoding", "gzip") @@ -817,14 +831,15 @@ func (w *responseWriter) InitHeadContent(contentlength int64) { } // Write writes the data to the connection as part of an HTTP reply, -// and sets `started` to true +// and sets `started` to true. +// started means the response has sent out. func (w *responseWriter) Write(p []byte) (int, error) { w.started = true return w.writer.Write(p) } // WriteHeader sends an HTTP response header with status code, -// and sets `started` to true +// and sets `started` to true. func (w *responseWriter) WriteHeader(code int) { w.status = code w.started = true diff --git a/template.go b/template.go index 1985c9a4..e604fcff 100644 --- a/template.go +++ b/template.go @@ -17,8 +17,9 @@ import ( var ( beegoTplFuncMap template.FuncMap - BeeTemplates map[string]*template.Template - BeeTemplateExt []string + // beego template caching map ans supported template file extensions. + BeeTemplates map[string]*template.Template + BeeTemplateExt []string ) func init() { @@ -50,7 +51,7 @@ func init() { beegoTplFuncMap["urlfor"] = UrlFor // != } -// AddFuncMap let user to register a func in the template +// AddFuncMap let user to register a func in the template. func AddFuncMap(key string, funname interface{}) error { beegoTplFuncMap[key] = funname return nil @@ -88,6 +89,7 @@ func (self *templatefile) visit(paths string, f os.FileInfo, err error) error { return nil } +// return this path has supported template extension of beego or not. func HasTemplateExt(paths string) bool { for _, v := range BeeTemplateExt { if strings.HasSuffix(paths, "."+v) { @@ -97,6 +99,7 @@ func HasTemplateExt(paths string) bool { return false } +// add new extension for template. func AddTemplateExt(ext string) { for _, v := range BeeTemplateExt { if v == ext { @@ -106,6 +109,8 @@ func AddTemplateExt(ext string) { BeeTemplateExt = append(BeeTemplateExt, ext) } +// build all template files in a directory. +// it makes beego can render any template file in view directory. func BuildTemplate(dir string) error { if _, err := os.Stat(dir); err != nil { if os.IsNotExist(err) { diff --git a/templatefunc.go b/templatefunc.go index 88acbb3f..278e0e9b 100644 --- a/templatefunc.go +++ b/templatefunc.go @@ -12,7 +12,7 @@ import ( "time" ) -// Substr() return the substr from start to length +// Substr returns the substr from start to length. func Substr(s string, start, length int) string { bt := []rune(s) if start < 0 { @@ -27,7 +27,7 @@ func Substr(s string, start, length int) string { return string(bt[start:end]) } -// Html2str() returns escaping text convert from html +// Html2str returns escaping text convert from html. func Html2str(html string) string { src := string(html) @@ -60,6 +60,7 @@ func DateFormat(t time.Time, layout string) (datestring string) { return } +// DateFormat pattern rules. var DatePatterns = []string{ // year "Y", "2006", // A full numeric representation of a year, 4 digits Examples: 1999 or 2003 @@ -100,14 +101,14 @@ var DatePatterns = []string{ "r", time.RFC1123Z, } -// Parse Date use PHP time format +// Parse Date use PHP time format. func DateParse(dateString, format string) (time.Time, error) { replacer := strings.NewReplacer(DatePatterns...) format = replacer.Replace(format) return time.ParseInLocation(format, dateString, time.Local) } -// Date takes a PHP like date func to Go's time format +// Date takes a PHP like date func to Go's time format. func Date(t time.Time, format string) string { replacer := strings.NewReplacer(DatePatterns...) format = replacer.Replace(format) @@ -115,7 +116,7 @@ func Date(t time.Time, format string) string { } // Compare is a quick and dirty comparison function. It will convert whatever you give it to strings and see if the two values are equal. -// Whitespace is trimmed. Used by the template parser as "eq" +// Whitespace is trimmed. Used by the template parser as "eq". func Compare(a, b interface{}) (equal bool) { equal = false if strings.TrimSpace(fmt.Sprintf("%v", a)) == strings.TrimSpace(fmt.Sprintf("%v", b)) { @@ -124,10 +125,12 @@ func Compare(a, b interface{}) (equal bool) { return } +// Convert string to template.HTML type. func Str2html(raw string) template.HTML { return template.HTML(raw) } +// Htmlquote returns quoted html string. func Htmlquote(src string) string { //HTML编码为实体符号 /* @@ -150,6 +153,7 @@ func Htmlquote(src string) string { return strings.TrimSpace(text) } +// Htmlunquote returns unquoted html string. func Htmlunquote(src string) string { //实体符号解释为HTML /* @@ -174,13 +178,14 @@ func Htmlunquote(src string) string { return strings.TrimSpace(text) } -// This will reference the index function local to the current blueprint: +// UrlFor returns url string with another registered controller handler with params. +// usage: // UrlFor(".index") -// ... print UrlFor("index") -// ... print UrlFor("login") -// ... print UrlFor("login", "next","/"") -// ... print UrlFor("profile", "username","John Doe") -// ... +// print UrlFor("index") +// print UrlFor("login") +// print UrlFor("login", "next","/"") +// print UrlFor("profile", "username","John Doe") +// result: // / // /login // /login?next=/ @@ -189,7 +194,7 @@ func UrlFor(endpoint string, values ...string) string { return BeeApp.UrlFor(endpoint, values...) } -//This can be changed to a better name +// returns script tag with src string. func AssetsJs(src string) template.HTML { text := string(src) @@ -198,7 +203,7 @@ func AssetsJs(src string) template.HTML { return template.HTML(text) } -//This can be changed to a better name +// returns stylesheet link tag with str string. func AssetsCss(src string) template.HTML { text := string(src) @@ -207,7 +212,7 @@ func AssetsCss(src string) template.HTML { return template.HTML(text) } -// parse form values to struct via tag +// parse form values to struct via tag. func ParseForm(form url.Values, obj interface{}) error { objT := reflect.TypeOf(obj) objV := reflect.ValueOf(obj) @@ -295,7 +300,8 @@ var unKind = map[reflect.Kind]bool{ reflect.UnsafePointer: true, } -// obj must be a struct pointer +// render object to form html. +// obj must be a struct pointer. func RenderForm(obj interface{}) template.HTML { objT := reflect.TypeOf(obj) objV := reflect.ValueOf(obj)