Commit ff18ae25 authored by 傅小黑's avatar 傅小黑

add api comments in file memzipfile.go,reload.go,router.go,template.go and…

add api comments in file memzipfile.go,reload.go,router.go,template.go and templatefunc.go, fix spelling error GetInitListner as GetInitListener.
parent 57781d10
......@@ -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 {
......
......@@ -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
......
......@@ -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)
......
......@@ -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
......
......@@ -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) {
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment