From 647e6ae1c42fade1283a095ac9298919785cb6c6 Mon Sep 17 00:00:00 2001 From: Lei Cao Date: Mon, 24 Nov 2014 23:21:03 +0800 Subject: [PATCH 01/55] Added JWT plugin --- plugins/jwt/jwt.go | 135 +++++++++++++++++++++++++++++++++++ plugins/jwt/jwt_test.go | 88 +++++++++++++++++++++++ plugins/jwt/test/jwt.rsa | 15 ++++ plugins/jwt/test/jwt.rsa.pub | 6 ++ 4 files changed, 244 insertions(+) create mode 100644 plugins/jwt/jwt.go create mode 100644 plugins/jwt/jwt_test.go create mode 100644 plugins/jwt/test/jwt.rsa create mode 100644 plugins/jwt/test/jwt.rsa.pub diff --git a/plugins/jwt/jwt.go b/plugins/jwt/jwt.go new file mode 100644 index 00000000..fd064686 --- /dev/null +++ b/plugins/jwt/jwt.go @@ -0,0 +1,135 @@ +// Copyright 2014 beego Author. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package jwt provides JWT (Json Web Token) authentication +// +// Usage +// In file main.go +// +// import ( +// "github.com/astaxie/beego" +// "github.com/astaxie/beego/plugins/jwt" +// ) +// +// func main() { +// // JWT for Url matching /v1/* +// // PrivateKeyPath: The path for the private RSA key used by JWT +// // PublicKeyPath: The path for the public RSA key used by JWT +// // The list of Urls should be excluded from the JWT Auth +// beego.InsertFilter("/v1/*", beego.BeforeRouter, jwt.AuthRequest(&jwt.Options{ +// PrivateKeyPath: "conf/beeblog.rsa", +// PublicKeyPath: "conf/beeblog.rsa.pub", +// WhiteList: []string{"/v1/jwt/issue-token", "/docs"}, +// })) +// beego.Run() +// } +// +// In file routers/router.go +// +// import ( +// "github.com/astaxie/beego" +// "github.com/astaxie/beego/plugins/jwt" +// ) +// func init() { +// ns := beego.NSNamespace("/jwt", +// beego.NSInclude( +// &jwt.JwtController{}, +// ), +// ) +// beego.AddNamespace(ns) +// } +// + +package jwt + +import ( + "github.com/astaxie/beego" + "github.com/astaxie/beego/context" + "github.com/astaxie/beego/logs" + goJwt "github.com/dgrijalva/jwt-go" + "io/ioutil" + "net/http" + "time" +) + +// Options for the JWT Auth +type Options struct { + PrivateKeyPath string + PublicKeyPath string + WhiteList []string +} + +var RSAKeys struct { + PrivateKey []byte + PublicKey []byte +} + +func AuthRequest(o *Options) beego.FilterFunc { + RSAKeys.PrivateKey, _ = ioutil.ReadFile(o.PrivateKeyPath) + RSAKeys.PublicKey, _ = ioutil.ReadFile(o.PublicKeyPath) + + return func(ctx *context.Context) { + // :TODO the url patterns should be considered here. + // Shouldn't only use the string equal + for _, method := range o.WhiteList { + if method == ctx.Request.URL.Path { + return + } + } + + parsedToken, err := goJwt.ParseFromRequest(ctx.Request, func(t *goJwt.Token) (interface{}, error) { + return RSAKeys.PublicKey, nil + }) + + if err == nil && parsedToken.Valid { + ctx.Output.SetStatus(http.StatusOK) + } else { + ctx.Output.SetStatus(http.StatusUnauthorized) + } + + } +} + +// oprations for Jwt +type JwtController struct { + beego.Controller +} + +func (this *JwtController) URLMapping() { + this.Mapping("IssueToken", this.IssueToken) +} + +// @Title IssueToken +// @Description Issue a Json Web Token +// @Success 200 string +// @Failure 403 no privilege to access +// @Failure 500 server inner error +// @router /issue-token [get] +func (this *JwtController) IssueToken() { + this.Data["json"] = CreateToken() + this.ServeJson() +} + +func CreateToken() map[string]string { + log := logs.NewLogger(10000) + log.SetLogger("console", "") + + token := goJwt.New(goJwt.GetSigningMethod("RS256")) // Create a Token that will be signed with RSA 256. + token.Claims["ID"] = "This is my super fake ID" + token.Claims["exp"] = time.Now().Unix() + 36000 + // The claims object allows you to store information in the actual token. + tokenString, _ := token.SignedString(RSAKeys.PrivateKey) + // tokenString Contains the actual token you should share with your client. + return map[string]string{"token": tokenString} +} diff --git a/plugins/jwt/jwt_test.go b/plugins/jwt/jwt_test.go new file mode 100644 index 00000000..dd8cafe7 --- /dev/null +++ b/plugins/jwt/jwt_test.go @@ -0,0 +1,88 @@ +package jwt + +import ( + "github.com/astaxie/beego" + "net/http" + "net/http/httptest" + "testing" +) + +func testRequest(method, path string) (*httptest.ResponseRecorder, *http.Request) { + request, _ := http.NewRequest(method, path, nil) + recorder := httptest.NewRecorder() + + return recorder, request +} + +func Test_IssueTokenAction(t *testing.T) { + url := "/v1/jwt/issue-token" + + mux := beego.NewControllerRegister() + + mux.InsertFilter("*", beego.BeforeRouter, AuthRequest(&Options{ + PrivateKeyPath: "test/jwt.rsa", + PublicKeyPath: "test/jwt.rsa.pub", + WhiteList: []string{"/v1/jwt/issue-token", "/docs"}, + })) + + mux.Add("/v1/jwt/issue-token", &JwtController{}, "get:IssueToken") + + rw, r := testRequest("GET", url) + mux.ServeHTTP(rw, r) + + if rw.Code != http.StatusOK { + t.Errorf("Shoud return 200") + } +} + +func (tc *JwtController) Foo() { + tc.Ctx.Output.Body([]byte("ok")) +} + +func Test_AuthRequestWithAuthorizationHeader(t *testing.T) { + + url := "/foo" + + mux := beego.NewControllerRegister() + + mux.InsertFilter("*", beego.BeforeRouter, AuthRequest(&Options{ + PrivateKeyPath: "test/jwt.rsa", + PublicKeyPath: "test/jwt.rsa.pub", + WhiteList: []string{"/v1/jwt/issue-token", "/docs"}, + })) + + mux.Add("/foo", &JwtController{}, "get:Foo") + newToken := CreateToken() + + rw, r := testRequest("GET", url) + r.Header.Add("Authorization", "Bearer "+newToken["token"]) + mux.ServeHTTP(rw, r) + + if rw.Code != http.StatusOK { + t.Errorf("Shoud return 200") + } + if rw.Body.String() != "ok" { + t.Errorf("Should output ok") + } +} + +func Test_AuthRequestWithoutAuthorizationHeader(t *testing.T) { + url := "/foo" + + mux := beego.NewControllerRegister() + + mux.InsertFilter("*", beego.BeforeRouter, AuthRequest(&Options{ + PrivateKeyPath: "test/jwt.rsa", + PublicKeyPath: "test/jwt.rsa.pub", + WhiteList: []string{"/v1/jwt/issue-token", "/docs"}, + })) + + mux.Add("/foo", &JwtController{}, "get:Foo") + + rw, r := testRequest("GET", url) + mux.ServeHTTP(rw, r) + + if rw.Code != http.StatusUnauthorized { + t.Errorf("Shoud return 401") + } +} diff --git a/plugins/jwt/test/jwt.rsa b/plugins/jwt/test/jwt.rsa new file mode 100644 index 00000000..8d584fc6 --- /dev/null +++ b/plugins/jwt/test/jwt.rsa @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQCdu+23Y/0J/FTQKnIPnxupoOo9/OYCv90DPXN/KLLRAMjYzgcC +DsBST2xVR5jlimI/gyfCpVB62dwpSzzr0cA3MoDhbaGWuTdQUX9zmiLoQ4I7X6h0 +dwyiihOz+CzOMlAg5+qBhiTGcKvIFlfEc1FUcn/tB3PVRG9j6B1Ibz5CnQIDAQAB +AoGAFGg+/i4ai9MwqeoD7c95Bb5C8BgrLgnir0uhCL+cOvwuABbPw01jRoLuEi58 +Mp5vzaXLXByFSA+ts03/qMbvZkDGac5g5kLli5TjHIONMxVBrdfGQ1+OApnaPayN +N+HYjZKs6xao6J5iFqfA0FqzDR9kQhUoeosdQoo1GlxDckECQQDO/0LJrFiLzYWe +qS/DxfAnFu2BlClKZjxRJ3vIkRRaON6HPl8BeJW901bFKG5+WSfO+OwQ9egWaf3X +fFm/oEHRAkEAwxMor4fOkBZbL4KPW7sen169vwnXuYusqj0t3dIeiIVrCigkOMT4 +OvX/63u4CTdXh1D5u/4Z/1HTYH92VCP7DQJAJPxbNKnE0IYSf/z++d4eQP3JxkNw +9Ug7Msz5QycZGd3bdRLh6uNe7iIa+PN2esD3afX0SDuIEqkxoBUp/CFoYQJAUmi3 +mV+/7bLkFrALK+9iwmTdt+TKk4HkEY8C32CysW3biFDo7GqZix79XFfJqWsNuQaG +WdrA1NGWgH+YV3dTyQJAIWEZGAuUXRkQB20LfjGzpsKgQFbqjTisMS0qe3JjnDwu +0JR8sYXapgeEEEisH+OtkZKIfyeFOwoUyNC83bcvgw== +-----END RSA PRIVATE KEY----- diff --git a/plugins/jwt/test/jwt.rsa.pub b/plugins/jwt/test/jwt.rsa.pub new file mode 100644 index 00000000..3fdd8ce7 --- /dev/null +++ b/plugins/jwt/test/jwt.rsa.pub @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdu+23Y/0J/FTQKnIPnxupoOo9 +/OYCv90DPXN/KLLRAMjYzgcCDsBST2xVR5jlimI/gyfCpVB62dwpSzzr0cA3MoDh +baGWuTdQUX9zmiLoQ4I7X6h0dwyiihOz+CzOMlAg5+qBhiTGcKvIFlfEc1FUcn/t +B3PVRG9j6B1Ibz5CnQIDAQAB +-----END PUBLIC KEY----- From 002302818ddf31ff7e562f07758cf82310d4a9e9 Mon Sep 17 00:00:00 2001 From: Mawueli Kofi Adzoe Date: Wed, 1 Jul 2015 04:17:53 +0000 Subject: [PATCH 02/55] Fix #1237 Package description uses same text as the README. --- beego.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beego.go b/beego.go index cfebfbea..c89ceaf8 100644 --- a/beego.go +++ b/beego.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// beego is an open-source, high-performance, modularity, full-stack web framework +// beego is an open-source, high-performance, modular, full-stack web framework // // package main // From 06b25deab2aa76912289c212d63a68ea86b8fc58 Mon Sep 17 00:00:00 2001 From: SimMan Date: Sat, 4 Jul 2015 17:55:01 +0800 Subject: [PATCH 03/55] Update validators.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support virtual operators paragraph 170! --- validation/validators.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validation/validators.go b/validation/validators.go index 61b0414a..2dcec356 100644 --- a/validation/validators.go +++ b/validation/validators.go @@ -457,7 +457,7 @@ func (b Base64) GetLimitValue() interface{} { } // just for chinese mobile phone number -var mobilePattern = regexp.MustCompile("^((\\+86)|(86))?(1(([35][0-9])|[8][0-9]|[7][67]|[4][579]))\\d{8}$") +var mobilePattern = regexp.MustCompile("^((\\+86)|(86))?(1(([35][0-9])|[8][0-9]|[7][067]|[4][579]))\\d{8}$") type Mobile struct { Match From 079993b9f722f17d0521fe6e2be4850d7b158d22 Mon Sep 17 00:00:00 2001 From: astaxie Date: Mon, 6 Jul 2015 13:54:14 +0800 Subject: [PATCH 04/55] fix #1245 --- context/input.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/context/input.go b/context/input.go index 1985df21..c8a8aaa9 100644 --- a/context/input.go +++ b/context/input.go @@ -353,7 +353,7 @@ func (input *BeegoInput) Bind(dest interface{}, key string) error { } func (input *BeegoInput) bind(key string, typ reflect.Type) reflect.Value { - rv := reflect.Zero(reflect.TypeOf(0)) + rv := reflect.Zero(typ) switch typ.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: val := input.Query(key) @@ -398,7 +398,7 @@ func (input *BeegoInput) bind(key string, typ reflect.Type) reflect.Value { } func (input *BeegoInput) bindValue(val string, typ reflect.Type) reflect.Value { - rv := reflect.Zero(reflect.TypeOf(0)) + rv := reflect.Zero(typ) switch typ.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: rv = input.bindInt(val, typ) From 8c0ad5ef8834c69920a8254403877826d1959c3f Mon Sep 17 00:00:00 2001 From: skycrab Date: Mon, 6 Jul 2015 21:12:03 +0800 Subject: [PATCH 05/55] fix example/chat i/o timeout --- example/chat/controllers/ws.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/example/chat/controllers/ws.go b/example/chat/controllers/ws.go index fc3917b3..9e405513 100644 --- a/example/chat/controllers/ws.go +++ b/example/chat/controllers/ws.go @@ -54,14 +54,13 @@ func (c *connection) readPump() { }() c.ws.SetReadLimit(maxMessageSize) c.ws.SetReadDeadline(time.Now().Add(readWait)) + c.ws.SetPongHandler(func(string) error { c.ws.SetReadDeadline(time.Now().Add(readWait)); return nil }) for { op, r, err := c.ws.NextReader() if err != nil { break } switch op { - case websocket.PongMessage: - c.ws.SetReadDeadline(time.Now().Add(readWait)) case websocket.TextMessage: message, err := ioutil.ReadAll(r) if err != nil { From 59b903d557532abc228860fbf5fb93641fd1f834 Mon Sep 17 00:00:00 2001 From: Hubery Date: Wed, 15 Jul 2015 17:00:48 +0800 Subject: [PATCH 06/55] set DoRotate fname like xx.2013-01-01.2.log fix fname,by extension to identify the file type on mac and windows. --- logs/file.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/logs/file.go b/logs/file.go index 2d3449ce..84a8c4f3 100644 --- a/logs/file.go +++ b/logs/file.go @@ -205,15 +205,20 @@ func (w *FileLogWriter) lines() (int, error) { } // DoRotate means it need to write file in new file. -// new file name like xx.log.2013-01-01.2 +// new file name like xx.2013-01-01.2.log func (w *FileLogWriter) DoRotate() error { _, err := os.Lstat(w.Filename) if err == nil { // file exists // Find the next available number num := 1 fname := "" + suffix := filepath.Ext(w.Filename) + filenameOnly := strings.TrimSuffix(w.Filename, suffix) + if suffix == "" { + suffix = ".log" + } for ; err == nil && num <= 999; num++ { - fname = w.Filename + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), num) + fname = filenameOnly + fmt.Sprintf(".%s.%03d%s", time.Now().Format("2006-01-02"), num, suffix) _, err = os.Lstat(fname) } // return error if the last file checked still existed From 0564956fd6462393ed8d023591b687b4d064da95 Mon Sep 17 00:00:00 2001 From: Mawuli Adzoe Date: Wed, 15 Jul 2015 12:04:18 +0000 Subject: [PATCH 07/55] Fix for #1256. Indent the code sample lines properly. --- beego.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/beego.go b/beego.go index cfebfbea..e4e7f3b0 100644 --- a/beego.go +++ b/beego.go @@ -14,13 +14,13 @@ // beego is an open-source, high-performance, modularity, full-stack web framework // -// package main +// package main // -// import "github.com/astaxie/beego" +// import "github.com/astaxie/beego" // -// func main() { -// beego.Run() -// } +// func main() { +// beego.Run() +// } // // more infomation: http://beego.me package beego From 45d693e6d62c7eef3da6640d0195539c485d31c3 Mon Sep 17 00:00:00 2001 From: Mawueli Kofi Adzoe Date: Thu, 16 Jul 2015 04:32:07 +0000 Subject: [PATCH 08/55] Add quick start example from website to README --- README.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b650887..1eb6e3b3 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,31 @@ beego is an open-source, high-performance, modular, full-stack web framework. More info [beego.me](http://beego.me) -## Installation +##Quick Start +######Download and install go get github.com/astaxie/beego +######Create file `hello.go` +```go +package main + +import "github.com/astaxie/beego" + +func main(){ + beego.Run() +} +``` +######Build and run +```bash + go build hello.go + ./hello +``` +######Congratulations! +You just built your first beego app. +Open your browser and visit `http://localhost:8000`. +Please see [Documentation](http://beego.me/docs) for more. + ## Features * RESTful support From 19d82ab62c3e96a5d7839e89fa7ebd29fd7bbb23 Mon Sep 17 00:00:00 2001 From: Pelle Johnsen Date: Wed, 22 Jul 2015 18:12:57 +0200 Subject: [PATCH 09/55] Fix #1274: Add QuerySeter.Distinct() --- orm/db.go | 6 +++++- orm/orm_queryset.go | 37 ++++++++++++++++++++++--------------- orm/types.go | 1 + 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/orm/db.go b/orm/db.go index 20dc80f2..cefd5dfc 100644 --- a/orm/db.go +++ b/orm/db.go @@ -814,7 +814,11 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi } } - query := fmt.Sprintf("SELECT %s FROM %s%s%s T0 %s%s%s%s", sels, Q, mi.table, Q, join, where, orderBy, limit) + sqlSelect := "SELECT" + if qs.distinct { + sqlSelect += " DISTINCT" + } + query := fmt.Sprintf("%s %s FROM %s%s%s T0 %s%s%s%s", sqlSelect, sels, Q, mi.table, Q, join, where, orderBy, limit) d.ins.ReplaceMarks(&query) diff --git a/orm/orm_queryset.go b/orm/orm_queryset.go index 5cc47617..106b62e5 100644 --- a/orm/orm_queryset.go +++ b/orm/orm_queryset.go @@ -61,6 +61,7 @@ type querySet struct { limit int64 offset int64 orders []string + distinct bool orm *orm } @@ -112,24 +113,30 @@ func (o querySet) OrderBy(exprs ...string) QuerySeter { return &o } +// add DISTINCT to SELECT +func (o querySet) Distinct() QuerySeter { + o.distinct = true + return &o +} + // set relation model to query together. // it will query relation models and assign to parent model. func (o querySet) RelatedSel(params ...interface{}) QuerySeter { - if len(params) == 0 { - o.relDepth = DefaultRelsDepth - } else { - for _, p := range params { - switch val := p.(type) { - case string: - o.related = append(o.related, val) - case int: - o.relDepth = val - default: - panic(fmt.Errorf(" wrong param kind: %v", val)) - } - } - } - return &o + if len(params) == 0 { + o.relDepth = DefaultRelsDepth + } else { + for _, p := range params { + switch val := p.(type) { + case string: + o.related = append(o.related, val) + case int: + o.relDepth = val + default: + panic(fmt.Errorf(" wrong param kind: %v", val)) + } + } + } + return &o } // set condition to QuerySeter. diff --git a/orm/types.go b/orm/types.go index b46be4fc..4347e46f 100644 --- a/orm/types.go +++ b/orm/types.go @@ -67,6 +67,7 @@ type QuerySeter interface { Limit(interface{}, ...interface{}) QuerySeter Offset(interface{}) QuerySeter OrderBy(...string) QuerySeter + Distinct() QuerySeter RelatedSel(...interface{}) QuerySeter Count() (int64, error) Exist() bool From b622d5d369961af4356e4d01dce78deacb0c335a Mon Sep 17 00:00:00 2001 From: Mawuli Adzoe Date: Sat, 18 Jul 2015 10:09:22 +0000 Subject: [PATCH 10/55] Fix #1269 extract documentation Fix #1271 Add description from docs on beego.me to README and also add same description to godoc --- README.md | 3 ++- beego.go | 11 ----------- doc.go | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 12 deletions(-) create mode 100644 doc.go diff --git a/README.md b/README.md index 1eb6e3b3..b1b48e75 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,8 @@ [![Build Status](https://drone.io/github.com/astaxie/beego/status.png)](https://drone.io/github.com/astaxie/beego/latest) [![GoDoc](http://godoc.org/github.com/astaxie/beego?status.svg)](http://godoc.org/github.com/astaxie/beego) -beego is an open-source, high-performance, modular, full-stack web framework. +beego is used for rapid development of RESTful APIs, web apps and backend services in Go. +It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific features such as interfaces and struct embedding. More info [beego.me](http://beego.me) diff --git a/beego.go b/beego.go index 8115a558..60483764 100644 --- a/beego.go +++ b/beego.go @@ -12,17 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -// beego is an open-source, high-performance, modular, full-stack web framework -// -// package main -// -// import "github.com/astaxie/beego" -// -// func main() { -// beego.Run() -// } -// -// more infomation: http://beego.me package beego import ( diff --git a/doc.go b/doc.go new file mode 100644 index 00000000..3a5b5cb8 --- /dev/null +++ b/doc.go @@ -0,0 +1,17 @@ +/* +beego: an open-source, high-performance, modular, full-stack web framework + +It is used for rapid development of RESTful APIs, web apps and backend services in Go. +beego is inspired by Tornado, Sinatra and Flask with the added benefit of some Go-specific features such as interfaces and struct embedding. + + package main + import "github.com/astaxie/beego" + + func main() { + beego.Run() + } + +more infomation: http://beego.me +*/ +package beego + From b26ef5b2e549ea3ba00f9bdb9c2e4c8dbcffb31b Mon Sep 17 00:00:00 2001 From: JessonChan Date: Mon, 27 Jul 2015 08:44:58 +0800 Subject: [PATCH 11/55] typo fixed registor==>register innner ==> inner --- app.go | 2 +- namespace.go | 38 +++++++++++++++++----------------- router.go | 58 ++++++++++++++++++++++++++-------------------------- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/app.go b/app.go index 8fc320ad..eddf7e21 100644 --- a/app.go +++ b/app.go @@ -28,7 +28,7 @@ import ( // App defines beego application with a new PatternServeMux. type App struct { - Handlers *ControllerRegistor + Handlers *ControllerRegister Server *http.Server } diff --git a/namespace.go b/namespace.go index ebb7c14f..86dc2ebd 100644 --- a/namespace.go +++ b/namespace.go @@ -23,16 +23,16 @@ import ( type namespaceCond func(*beecontext.Context) bool -type innnerNamespace func(*Namespace) +type innerNamespace func(*Namespace) // Namespace is store all the info type Namespace struct { prefix string - handlers *ControllerRegistor + handlers *ControllerRegister } // get new Namespace -func NewNamespace(prefix string, params ...innnerNamespace) *Namespace { +func NewNamespace(prefix string, params ...innerNamespace) *Namespace { ns := &Namespace{ prefix: prefix, handlers: NewControllerRegister(), @@ -276,112 +276,112 @@ func addPrefix(t *Tree, prefix string) { } // Namespace Condition -func NSCond(cond namespaceCond) innnerNamespace { +func NSCond(cond namespaceCond) innerNamespace { return func(ns *Namespace) { ns.Cond(cond) } } // Namespace BeforeRouter filter -func NSBefore(filiterList ...FilterFunc) innnerNamespace { +func NSBefore(filiterList ...FilterFunc) innerNamespace { return func(ns *Namespace) { ns.Filter("before", filiterList...) } } // Namespace FinishRouter filter -func NSAfter(filiterList ...FilterFunc) innnerNamespace { +func NSAfter(filiterList ...FilterFunc) innerNamespace { return func(ns *Namespace) { ns.Filter("after", filiterList...) } } // Namespace Include ControllerInterface -func NSInclude(cList ...ControllerInterface) innnerNamespace { +func NSInclude(cList ...ControllerInterface) innerNamespace { return func(ns *Namespace) { ns.Include(cList...) } } // Namespace Router -func NSRouter(rootpath string, c ControllerInterface, mappingMethods ...string) innnerNamespace { +func NSRouter(rootpath string, c ControllerInterface, mappingMethods ...string) innerNamespace { return func(ns *Namespace) { ns.Router(rootpath, c, mappingMethods...) } } // Namespace Get -func NSGet(rootpath string, f FilterFunc) innnerNamespace { +func NSGet(rootpath string, f FilterFunc) innerNamespace { return func(ns *Namespace) { ns.Get(rootpath, f) } } // Namespace Post -func NSPost(rootpath string, f FilterFunc) innnerNamespace { +func NSPost(rootpath string, f FilterFunc) innerNamespace { return func(ns *Namespace) { ns.Post(rootpath, f) } } // Namespace Head -func NSHead(rootpath string, f FilterFunc) innnerNamespace { +func NSHead(rootpath string, f FilterFunc) innerNamespace { return func(ns *Namespace) { ns.Head(rootpath, f) } } // Namespace Put -func NSPut(rootpath string, f FilterFunc) innnerNamespace { +func NSPut(rootpath string, f FilterFunc) innerNamespace { return func(ns *Namespace) { ns.Put(rootpath, f) } } // Namespace Delete -func NSDelete(rootpath string, f FilterFunc) innnerNamespace { +func NSDelete(rootpath string, f FilterFunc) innerNamespace { return func(ns *Namespace) { ns.Delete(rootpath, f) } } // Namespace Any -func NSAny(rootpath string, f FilterFunc) innnerNamespace { +func NSAny(rootpath string, f FilterFunc) innerNamespace { return func(ns *Namespace) { ns.Any(rootpath, f) } } // Namespace Options -func NSOptions(rootpath string, f FilterFunc) innnerNamespace { +func NSOptions(rootpath string, f FilterFunc) innerNamespace { return func(ns *Namespace) { ns.Options(rootpath, f) } } // Namespace Patch -func NSPatch(rootpath string, f FilterFunc) innnerNamespace { +func NSPatch(rootpath string, f FilterFunc) innerNamespace { return func(ns *Namespace) { ns.Patch(rootpath, f) } } //Namespace AutoRouter -func NSAutoRouter(c ControllerInterface) innnerNamespace { +func NSAutoRouter(c ControllerInterface) innerNamespace { return func(ns *Namespace) { ns.AutoRouter(c) } } // Namespace AutoPrefix -func NSAutoPrefix(prefix string, c ControllerInterface) innnerNamespace { +func NSAutoPrefix(prefix string, c ControllerInterface) innerNamespace { return func(ns *Namespace) { ns.AutoPrefix(prefix, c) } } // Namespace add sub Namespace -func NSNamespace(prefix string, params ...innnerNamespace) innnerNamespace { +func NSNamespace(prefix string, params ...innerNamespace) innerNamespace { return func(ns *Namespace) { n := NewNamespace(prefix, params...) ns.Namespace(n) diff --git a/router.go b/router.go index 3e1ebab3..217ad65f 100644 --- a/router.go +++ b/router.go @@ -110,22 +110,22 @@ type controllerInfo struct { routerType int } -// ControllerRegistor containers registered router rules, controller handlers and filters. -type ControllerRegistor struct { +// ControllerRegister containers registered router rules, controller handlers and filters. +type ControllerRegister struct { routers map[string]*Tree enableFilter bool filters map[int][]*FilterRouter } -// NewControllerRegister returns a new ControllerRegistor. -func NewControllerRegister() *ControllerRegistor { - return &ControllerRegistor{ +// NewControllerRegister returns a new ControllerRegister. +func NewControllerRegister() *ControllerRegister { + return &ControllerRegister{ routers: make(map[string]*Tree), filters: make(map[int][]*FilterRouter), } } -// Add controller handler and pattern rules to ControllerRegistor. +// Add controller handler and pattern rules to ControllerRegister. // usage: // default methods is the same name as method // Add("/user",&UserController{}) @@ -135,7 +135,7 @@ func NewControllerRegister() *ControllerRegistor { // 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) { +func (p *ControllerRegister) Add(pattern string, c ControllerInterface, mappingMethods ...string) { reflectVal := reflect.ValueOf(c) t := reflect.Indirect(reflectVal).Type() methods := make(map[string]string) @@ -183,7 +183,7 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM } } -func (p *ControllerRegistor) addToRouter(method, pattern string, r *controllerInfo) { +func (p *ControllerRegister) addToRouter(method, pattern string, r *controllerInfo) { if !RouterCaseSensitive { pattern = strings.ToLower(pattern) } @@ -198,7 +198,7 @@ func (p *ControllerRegistor) addToRouter(method, pattern string, r *controllerIn // only when the Runmode is dev will generate router file in the router/auto.go from the controller // Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{}) -func (p *ControllerRegistor) Include(cList ...ControllerInterface) { +func (p *ControllerRegister) Include(cList ...ControllerInterface) { if RunMode == "dev" { skip := make(map[string]bool, 10) for _, c := range cList { @@ -243,7 +243,7 @@ func (p *ControllerRegistor) Include(cList ...ControllerInterface) { // Get("/", func(ctx *context.Context){ // ctx.Output.Body("hello world") // }) -func (p *ControllerRegistor) Get(pattern string, f FilterFunc) { +func (p *ControllerRegister) Get(pattern string, f FilterFunc) { p.AddMethod("get", pattern, f) } @@ -252,7 +252,7 @@ func (p *ControllerRegistor) Get(pattern string, f FilterFunc) { // Post("/api", func(ctx *context.Context){ // ctx.Output.Body("hello world") // }) -func (p *ControllerRegistor) Post(pattern string, f FilterFunc) { +func (p *ControllerRegister) Post(pattern string, f FilterFunc) { p.AddMethod("post", pattern, f) } @@ -261,7 +261,7 @@ func (p *ControllerRegistor) Post(pattern string, f FilterFunc) { // Put("/api/:id", func(ctx *context.Context){ // ctx.Output.Body("hello world") // }) -func (p *ControllerRegistor) Put(pattern string, f FilterFunc) { +func (p *ControllerRegister) Put(pattern string, f FilterFunc) { p.AddMethod("put", pattern, f) } @@ -270,7 +270,7 @@ func (p *ControllerRegistor) Put(pattern string, f FilterFunc) { // Delete("/api/:id", func(ctx *context.Context){ // ctx.Output.Body("hello world") // }) -func (p *ControllerRegistor) Delete(pattern string, f FilterFunc) { +func (p *ControllerRegister) Delete(pattern string, f FilterFunc) { p.AddMethod("delete", pattern, f) } @@ -279,7 +279,7 @@ func (p *ControllerRegistor) Delete(pattern string, f FilterFunc) { // Head("/api/:id", func(ctx *context.Context){ // ctx.Output.Body("hello world") // }) -func (p *ControllerRegistor) Head(pattern string, f FilterFunc) { +func (p *ControllerRegister) Head(pattern string, f FilterFunc) { p.AddMethod("head", pattern, f) } @@ -288,7 +288,7 @@ func (p *ControllerRegistor) Head(pattern string, f FilterFunc) { // Patch("/api/:id", func(ctx *context.Context){ // ctx.Output.Body("hello world") // }) -func (p *ControllerRegistor) Patch(pattern string, f FilterFunc) { +func (p *ControllerRegister) Patch(pattern string, f FilterFunc) { p.AddMethod("patch", pattern, f) } @@ -297,7 +297,7 @@ func (p *ControllerRegistor) Patch(pattern string, f FilterFunc) { // Options("/api/:id", func(ctx *context.Context){ // ctx.Output.Body("hello world") // }) -func (p *ControllerRegistor) Options(pattern string, f FilterFunc) { +func (p *ControllerRegister) Options(pattern string, f FilterFunc) { p.AddMethod("options", pattern, f) } @@ -306,7 +306,7 @@ func (p *ControllerRegistor) Options(pattern string, f FilterFunc) { // Any("/api/:id", func(ctx *context.Context){ // ctx.Output.Body("hello world") // }) -func (p *ControllerRegistor) Any(pattern string, f FilterFunc) { +func (p *ControllerRegister) Any(pattern string, f FilterFunc) { p.AddMethod("*", pattern, f) } @@ -315,7 +315,7 @@ func (p *ControllerRegistor) Any(pattern string, f FilterFunc) { // AddMethod("get","/api/:id", func(ctx *context.Context){ // ctx.Output.Body("hello world") // }) -func (p *ControllerRegistor) AddMethod(method, pattern string, f FilterFunc) { +func (p *ControllerRegister) AddMethod(method, pattern string, f FilterFunc) { if _, ok := HTTPMETHOD[strings.ToUpper(method)]; method != "*" && !ok { panic("not support http method: " + method) } @@ -344,7 +344,7 @@ func (p *ControllerRegistor) AddMethod(method, pattern string, f FilterFunc) { } // add user defined Handler -func (p *ControllerRegistor) Handler(pattern string, h http.Handler, options ...interface{}) { +func (p *ControllerRegister) Handler(pattern string, h http.Handler, options ...interface{}) { route := &controllerInfo{} route.pattern = pattern route.routerType = routerTypeHandler @@ -359,21 +359,21 @@ func (p *ControllerRegistor) Handler(pattern string, h http.Handler, options ... } } -// Add auto router to ControllerRegistor. +// Add auto router to ControllerRegister. // example beego.AddAuto(&MainContorlller{}), // MainController has method List and Page. // visit the url /main/list to execute List function // /main/page to execute Page function. -func (p *ControllerRegistor) AddAuto(c ControllerInterface) { +func (p *ControllerRegister) AddAuto(c ControllerInterface) { p.AddAutoPrefix("/", c) } -// Add auto router to ControllerRegistor with prefix. +// Add auto router to ControllerRegister with prefix. // example beego.AddAutoPrefix("/admin",&MainContorlller{}), // MainController has method List and Page. // visit the url /admin/main/list to execute List function // /admin/main/page to execute Page function. -func (p *ControllerRegistor) AddAutoPrefix(prefix string, c ControllerInterface) { +func (p *ControllerRegister) AddAutoPrefix(prefix string, c ControllerInterface) { reflectVal := reflect.ValueOf(c) rt := reflectVal.Type() ct := reflect.Indirect(reflectVal).Type() @@ -401,7 +401,7 @@ func (p *ControllerRegistor) AddAutoPrefix(prefix string, c ControllerInterface) // Add a FilterFunc with pattern rule and action constant. // The bool params is for setting the returnOnOutput value (false allows multiple filters to execute) -func (p *ControllerRegistor) InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) error { +func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) error { mr := new(FilterRouter) mr.tree = NewTree() @@ -420,7 +420,7 @@ func (p *ControllerRegistor) InsertFilter(pattern string, pos int, filter Filter } // add Filter into -func (p *ControllerRegistor) insertFilterRouter(pos int, mr *FilterRouter) error { +func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) error { p.filters[pos] = append(p.filters[pos], mr) p.enableFilter = true return nil @@ -428,7 +428,7 @@ func (p *ControllerRegistor) insertFilterRouter(pos int, mr *FilterRouter) error // UrlFor does another controller handler in this request function. // it can access any controller method. -func (p *ControllerRegistor) UrlFor(endpoint string, values ...interface{}) string { +func (p *ControllerRegister) UrlFor(endpoint string, values ...interface{}) string { paths := strings.Split(endpoint, ".") if len(paths) <= 1 { Warn("urlfor endpoint must like path.controller.method") @@ -460,7 +460,7 @@ func (p *ControllerRegistor) UrlFor(endpoint string, values ...interface{}) stri return "" } -func (p *ControllerRegistor) geturl(t *Tree, url, controllName, methodName string, params map[string]string, httpMethod string) (bool, string) { +func (p *ControllerRegister) geturl(t *Tree, url, controllName, methodName string, params map[string]string, httpMethod string) (bool, string) { for k, subtree := range t.fixrouters { u := path.Join(url, k) ok, u := p.geturl(subtree, u, controllName, methodName, params, httpMethod) @@ -575,7 +575,7 @@ func (p *ControllerRegistor) geturl(t *Tree, url, controllName, methodName strin } // Implement http.Handler interface. -func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) { +func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) { starttime := time.Now() var runrouter reflect.Type var findrouter bool @@ -861,7 +861,7 @@ Admin: } } -func (p *ControllerRegistor) recoverPanic(context *beecontext.Context) { +func (p *ControllerRegister) recoverPanic(context *beecontext.Context) { if err := recover(); err != nil { if err == USERSTOPRUN { return From 57fdc308e34e7b656585f1b56fb47078e10963c5 Mon Sep 17 00:00:00 2001 From: wulove Date: Thu, 6 Aug 2015 09:36:43 +0800 Subject: [PATCH 12/55] =?UTF-8?q?AutoRender=E4=B8=BA=E7=A9=BA=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E5=86=8D=E7=BC=96=E8=AF=91=E6=A8=A1=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AutoRender为空,Controller.Render()不再执行,故无需编译模版 --- beego.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/beego.go b/beego.go index 60483764..7bcc0740 100644 --- a/beego.go +++ b/beego.go @@ -306,11 +306,13 @@ func initBeforeHttpRun() { } go GlobalSessions.GC() } - - err := BuildTemplate(ViewsPath) - if err != nil { - if RunMode == "dev" { - Warn(err) + + if AutoRender { + err := BuildTemplate(ViewsPath) + if err != nil { + if RunMode == "dev" { + Warn(err) + } } } From 877b5c233e889046853b17e799fa65e7aee1ee6b Mon Sep 17 00:00:00 2001 From: wulove Date: Thu, 6 Aug 2015 10:09:34 +0800 Subject: [PATCH 13/55] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=A8=A1=E7=89=88=E5=87=BD=E6=95=B0BuildTemplate=E5=8F=AF?= =?UTF-8?q?=E5=8F=98=E5=8F=82=E6=95=B0=EF=BC=8C=E4=BD=BF=E4=B9=8B=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=8D=95=E4=B8=AA=E6=88=96=E5=A4=9A=E4=B8=AA=E6=A8=A1?= =?UTF-8?q?=E7=89=88=E7=9A=84=E7=BC=96=E8=AF=91=EF=BC=8C=E5=90=8C=E6=97=B6?= =?UTF-8?q?=E9=92=88=E5=AF=B9=E5=BC=80=E5=8F=91=E6=A8=A1=E5=BC=8F=EF=BC=8C?= =?UTF-8?q?=E6=AF=8F=E4=B8=AA=E8=AF=B7=E6=B1=82=E5=8F=AA=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E8=AF=B7=E6=B1=82=E7=9B=B8=E5=85=B3=E6=A8=A1?= =?UTF-8?q?=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加编译模版函数BuildTemplate可变参数,使之支持单个或多个模版的编译,同时针对开发模式,每个请求只编译当前请求相关模版,不再每次请求都编译全部模版 --- controller.go | 15 +++++++++++++-- template.go | 14 ++++++++------ template_test.go | 2 +- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/controller.go b/controller.go index a8b9e8d3..65b311b6 100644 --- a/controller.go +++ b/controller.go @@ -200,8 +200,19 @@ func (c *Controller) RenderBytes() ([]byte, error) { if c.TplNames == "" { c.TplNames = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt } + if RunMode == "dev" { - BuildTemplate(ViewsPath) + buildFiles := make([]string, 1) + buildFiles = append(buildFiles, c.TplNames) + if c.LayoutSections != nil { + for _, sectionTpl := range c.LayoutSections { + if sectionTpl == "" { + continue + } + buildFiles = append(buildFiles, sectionTpl) + } + } + BuildTemplate(ViewsPath, buildFiles...) } newbytes := bytes.NewBufferString("") if _, ok := BeeTemplates[c.TplNames]; !ok { @@ -246,7 +257,7 @@ func (c *Controller) RenderBytes() ([]byte, error) { c.TplNames = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt } if RunMode == "dev" { - BuildTemplate(ViewsPath) + BuildTemplate(ViewsPath, c.TplNames) } ibytes := bytes.NewBufferString("") if _, ok := BeeTemplates[c.TplNames]; !ok { diff --git a/template.go b/template.go index 64b1939e..45ecbe52 100644 --- a/template.go +++ b/template.go @@ -127,7 +127,7 @@ func AddTemplateExt(ext string) { // build all template files in a directory. // it makes beego can render any template file in view directory. -func BuildTemplate(dir string) error { +func BuildTemplate(dir string, files... string) error { if _, err := os.Stat(dir); err != nil { if os.IsNotExist(err) { return nil @@ -148,11 +148,13 @@ func BuildTemplate(dir string) error { } for _, v := range self.files { for _, file := range v { - t, err := getTemplate(self.root, file, v...) - if err != nil { - Trace("parse template err:", file, err) - } else { - BeeTemplates[file] = t + if (files == nil || utils.InSlice(file, files)) { + t, err := getTemplate(self.root, file, v...) + if err != nil { + Trace("parse template err:", file, err) + } else { + BeeTemplates[file] = t + } } } } diff --git a/template_test.go b/template_test.go index b35da5ce..79740f2b 100644 --- a/template_test.go +++ b/template_test.go @@ -123,7 +123,7 @@ func TestRelativeTemplate(t *testing.T) { f.Close() } } - if err := BuildTemplate(dir); err != nil { + if err := BuildTemplate(dir, files[1]); err != nil { t.Fatal(err) } if err := BeeTemplates["easyui/rbac/user.tpl"].ExecuteTemplate(os.Stdout, "easyui/rbac/user.tpl", nil); err != nil { From d4e15c0bd0d27c5ed4f49d150e1972af9a58d6bb Mon Sep 17 00:00:00 2001 From: Sergey Shcherbina Date: Mon, 17 Aug 2015 00:08:02 +0500 Subject: [PATCH 14/55] Added MapGet template func --- template.go | 1 + templatefunc.go | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/template.go b/template.go index 64b1939e..905f0bef 100644 --- a/template.go +++ b/template.go @@ -54,6 +54,7 @@ func init() { beegoTplFuncMap["assets_js"] = AssetsJs beegoTplFuncMap["assets_css"] = AssetsCss beegoTplFuncMap["config"] = Config + beegoTplFuncMap["map_get"] = MapGet // go1.2 added template funcs // Comparisons diff --git a/templatefunc.go b/templatefunc.go index 28ed15a3..6092f71e 100644 --- a/templatefunc.go +++ b/templatefunc.go @@ -652,3 +652,76 @@ func ge(arg1, arg2 interface{}) (bool, error) { } // go1.2 added template funcs. end + +// getting value from map by keys +// usage: +// Data["m"] = map[string]interface{} { +// "a": 1, +// "1": map[string]float64{ +// "c": 4, +// }, +// } +// +// {{ map_get m "a" }} // return 1 +// {{ map_get m 1 "c" }} // return 4 +func MapGet(arg1 interface{}, arg2 ...interface{}) (interface{}, error) { + arg1Type := reflect.TypeOf(arg1) + arg1Val := reflect.ValueOf(arg1) + + if arg1Type.Kind() == reflect.Map && len(arg2) > 0 { + // check whether arg2[0] type equals to arg1 key type + // if they are different, make convertion + arg2Val := reflect.ValueOf(arg2[0]) + arg2Type := reflect.TypeOf(arg2[0]) + if arg2Type.Kind() != arg1Type.Key().Kind() { + // convert arg2Value to string + var arg2ConvertedVal interface{} + arg2String := fmt.Sprintf("%v", arg2[0]) + + // convert string representation to any other type + switch arg1Type.Key().Kind() { + case reflect.Bool: + arg2ConvertedVal, _ = strconv.ParseBool(arg2String) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + arg2ConvertedVal, _ = strconv.ParseInt(arg2String, 0, 64) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + arg2ConvertedVal, _ = strconv.ParseUint(arg2String, 0, 64) + case reflect.Float32, reflect.Float64: + arg2ConvertedVal, _ = strconv.ParseFloat(arg2String, 64) + case reflect.String: + arg2ConvertedVal = arg2String + default: + arg2ConvertedVal = arg2Val.Interface() + } + arg2Val = reflect.ValueOf(arg2ConvertedVal) + } + + storedVal := arg1Val.MapIndex(arg2Val) + + var result interface{} + + switch arg1Type.Elem().Kind() { + case reflect.Bool: + result = storedVal.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + result = storedVal.Int() + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + result = storedVal.Uint() + case reflect.Float32, reflect.Float64: + result = storedVal.Float() + case reflect.String: + result = storedVal.String() + default: + result = storedVal.Interface() + } + + // if there is more keys, handle this recursively + if len(arg2) > 1 { + return MapGet(result, arg2[1:]...) + } else { + return result, nil + } + } else { + return nil, nil + } +} From d91840779ac5e82cfea039f1fdd7fa38c7f7d908 Mon Sep 17 00:00:00 2001 From: Hepri Date: Mon, 17 Aug 2015 01:18:29 +0500 Subject: [PATCH 15/55] Update templatefunc.go --- templatefunc.go | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/templatefunc.go b/templatefunc.go index 6092f71e..0bfdd31c 100644 --- a/templatefunc.go +++ b/templatefunc.go @@ -698,29 +698,36 @@ func MapGet(arg1 interface{}, arg2 ...interface{}) (interface{}, error) { storedVal := arg1Val.MapIndex(arg2Val) - var result interface{} + + if storedVal.IsValid() { + var result interface{} - switch arg1Type.Elem().Kind() { - case reflect.Bool: - result = storedVal.Bool() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - result = storedVal.Int() - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - result = storedVal.Uint() - case reflect.Float32, reflect.Float64: - result = storedVal.Float() - case reflect.String: - result = storedVal.String() - default: - result = storedVal.Interface() - } + switch arg1Type.Elem().Kind() { + case reflect.Bool: + result = storedVal.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + result = storedVal.Int() + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + result = storedVal.Uint() + case reflect.Float32, reflect.Float64: + result = storedVal.Float() + case reflect.String: + result = storedVal.String() + default: + result = storedVal.Interface() + } - // if there is more keys, handle this recursively - if len(arg2) > 1 { - return MapGet(result, arg2[1:]...) + // if there is more keys, handle this recursively + if len(arg2) > 1 { + return MapGet(result, arg2[1:]...) + } else { + return result, nil + } } else { - return result, nil + return nil, nil } + + } else { return nil, nil } From 9107fd8898fd98d94a342cc1b251237619f48794 Mon Sep 17 00:00:00 2001 From: astaxie Date: Mon, 17 Aug 2015 22:33:28 +0800 Subject: [PATCH 16/55] remove the default timeout setting --- httplib/httplib.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/httplib/httplib.go b/httplib/httplib.go index 68c22d70..a160bce0 100644 --- a/httplib/httplib.go +++ b/httplib/httplib.go @@ -74,12 +74,6 @@ func SetDefaultSetting(setting BeegoHttpSettings) { settingMutex.Lock() defer settingMutex.Unlock() defaultSetting = setting - if defaultSetting.ConnectTimeout == 0 { - defaultSetting.ConnectTimeout = 60 * time.Second - } - if defaultSetting.ReadWriteTimeout == 0 { - defaultSetting.ReadWriteTimeout = 60 * time.Second - } } // return *BeegoHttpRequest with specific method From 860006bfdae293bd30944a5dd7980b8f964da5b7 Mon Sep 17 00:00:00 2001 From: Shuai Date: Tue, 18 Aug 2015 19:28:17 +0800 Subject: [PATCH 17/55] =?UTF-8?q?httplib=E8=AF=B7=E6=B1=82=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=94=AF=E6=8C=81[]string?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- httplib/httplib.go | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/httplib/httplib.go b/httplib/httplib.go index 68c22d70..c671cc0a 100644 --- a/httplib/httplib.go +++ b/httplib/httplib.go @@ -100,8 +100,8 @@ func NewBeegoRequest(rawurl, method string) *BeegoHttpRequest { return &BeegoHttpRequest{ url: rawurl, req: &req, - params: map[string]string{}, - files: map[string]string{}, + params: map[string]interface{}{}, + files: map[string]string{}, setting: defaultSetting, resp: &resp, } @@ -150,7 +150,7 @@ type BeegoHttpSettings struct { type BeegoHttpRequest struct { url string req *http.Request - params map[string]string + params map[string]interface{} files map[string]string setting BeegoHttpSettings resp *http.Response @@ -272,8 +272,13 @@ func (b *BeegoHttpRequest) SetProxy(proxy func(*http.Request) (*url.URL, error)) // Param adds query param in to request. // params build query string as ?key1=value1&key2=value2... -func (b *BeegoHttpRequest) Param(key, value string) *BeegoHttpRequest { - b.params[key] = value +func (b *BeegoHttpRequest) Param(key, value interface{}) *BeegoHttpRequest { + switch value.(type) { + case string: + b.params[key.(string)] = value.(string) + case []string: + b.params[key.(string)] = value.([]string) + } return b } @@ -348,7 +353,14 @@ func (b *BeegoHttpRequest) buildUrl(paramBody string) { } } for k, v := range b.params { - bodyWriter.WriteField(k, v) + switch v.(type) { + case string: + bodyWriter.WriteField(k, v.(string)) + case []string: + for _, vv := range v.([]string) { + bodyWriter.WriteField(k, vv) + } + } } bodyWriter.Close() pw.Close() @@ -383,10 +395,20 @@ func (b *BeegoHttpRequest) SendOut() (*http.Response, error) { if len(b.params) > 0 { var buf bytes.Buffer for k, v := range b.params { - buf.WriteString(url.QueryEscape(k)) - buf.WriteByte('=') - buf.WriteString(url.QueryEscape(v)) - buf.WriteByte('&') + switch v.(type) { + case string: + buf.WriteString(url.QueryEscape(k)) + buf.WriteByte('=') + buf.WriteString(url.QueryEscape(v.(string))) + buf.WriteByte('&') + case []string: + for _, vv := range v.([]string) { + buf.WriteString(url.QueryEscape(k)) + buf.WriteByte('=') + buf.WriteString(url.QueryEscape(vv)) + buf.WriteByte('&') + } + } } paramBody = buf.String() paramBody = paramBody[0 : len(paramBody)-1] From ff92f22d841a7015958ede181d8c76164c7c84bb Mon Sep 17 00:00:00 2001 From: Shuai Date: Tue, 18 Aug 2015 23:19:24 +0800 Subject: [PATCH 18/55] =?UTF-8?q?=E5=88=A0=E9=99=A4Param=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E6=96=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- httplib/httplib.go | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/httplib/httplib.go b/httplib/httplib.go index c671cc0a..1b7b207d 100644 --- a/httplib/httplib.go +++ b/httplib/httplib.go @@ -272,13 +272,8 @@ func (b *BeegoHttpRequest) SetProxy(proxy func(*http.Request) (*url.URL, error)) // Param adds query param in to request. // params build query string as ?key1=value1&key2=value2... -func (b *BeegoHttpRequest) Param(key, value interface{}) *BeegoHttpRequest { - switch value.(type) { - case string: - b.params[key.(string)] = value.(string) - case []string: - b.params[key.(string)] = value.([]string) - } +func (b *BeegoHttpRequest) Param(key string, value interface{}) *BeegoHttpRequest { + b.params[key] = value return b } From 506f54a080ed4006676af3019d79bdee0507e4bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B0=8F=E7=8E=89?= Date: Wed, 19 Aug 2015 15:23:50 +0800 Subject: [PATCH 19/55] Update router.go, add Flush for responseWriter --- router.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/router.go b/router.go index 217ad65f..7cce86fe 100644 --- a/router.go +++ b/router.go @@ -931,6 +931,13 @@ func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { return hj.Hijack() } +func (w *responseWriter) Flush() { + f, ok := w.writer.(http.Flusher) + if ok { + f.Flush() + } +} + func tourl(params map[string]string) string { if len(params) == 0 { return "" From 0e3fe64c6922bc21f33530a8379b6406b874ba98 Mon Sep 17 00:00:00 2001 From: Sergey Shcherbina Date: Thu, 20 Aug 2015 19:04:43 +0500 Subject: [PATCH 20/55] Added TestMapGet --- templatefunc_test.go | 77 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/templatefunc_test.go b/templatefunc_test.go index 60af5bf5..cc467d95 100644 --- a/templatefunc_test.go +++ b/templatefunc_test.go @@ -244,3 +244,80 @@ func TestParseFormTag(t *testing.T) { t.Errorf("Form Tag that should be ignored was not correctly parsed.") } } + +func TestMapGet(t *testing.T) { + // test one level map + m1 := map[string]int64{ + "a": 1, + "1": 2, + } + + if res, err := MapGet(m1, "a"); err == nil { + if res.(int64) != 1 { + t.Errorf("Should return 1, but return %v", res) + } + } else { + t.Errorf("Error happens %v", err) + } + + if res, err := MapGet(m1, "1"); err == nil { + if res.(int64) != 2 { + t.Errorf("Should return 2, but return %v", res) + } + } else { + t.Errorf("Error happens %v", err) + } + + if res, err := MapGet(m1, 1); err == nil { + if res.(int64) != 2 { + t.Errorf("Should return 2, but return %v", res) + } + } else { + t.Errorf("Error happens %v", err) + } + + // test 2 level map + m2 := map[string]interface{}{ + "1": map[string]float64{ + "2": 3.5, + }, + } + + if res, err := MapGet(m2, 1, 2); err == nil { + if res.(float64) != 3.5 { + t.Errorf("Should return 3.5, but return %v", res) + } + } else { + t.Errorf("Error happens %v", err) + } + + // test 5 level map + m5 := map[string]interface{}{ + "1": map[string]interface{}{ + "2": map[string]interface{}{ + "3": map[string]interface{}{ + "4": map[string]interface{}{ + "5": 1.2, + }, + }, + }, + }, + } + + if res, err := MapGet(m5, 1, 2, 3, 4, 5); err == nil { + if res.(float64) != 1.2 { + t.Errorf("Should return 1.2, but return %v", res) + } + } else { + t.Errorf("Error happens %v", err) + } + + // check whether element not exists in map + if res, err := MapGet(m5, 5, 4, 3, 2, 1); err == nil { + if res != nil { + t.Errorf("Should return nil, but return %v", res) + } + } else { + t.Errorf("Error happens %v", err) + } +} From 38ddb61199f7ab90bfa7265a3b6cd68ecfb81c76 Mon Sep 17 00:00:00 2001 From: wulove Date: Fri, 21 Aug 2015 10:32:53 +0800 Subject: [PATCH 21/55] files is []string, use len(files)==0 --- template.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template.go b/template.go index 45ecbe52..32468d77 100644 --- a/template.go +++ b/template.go @@ -148,7 +148,7 @@ func BuildTemplate(dir string, files... string) error { } for _, v := range self.files { for _, file := range v { - if (files == nil || utils.InSlice(file, files)) { + if (len(files) == 0 || utils.InSlice(file, files)) { t, err := getTemplate(self.root, file, v...) if err != nil { Trace("parse template err:", file, err) From 99b1c5c54b72b0096a6a27b06d670a0738b8f8c2 Mon Sep 17 00:00:00 2001 From: tabalt <245291359@qq.com> Date: Fri, 21 Aug 2015 10:53:59 +0800 Subject: [PATCH 22/55] fixed mux1 to mux --- grace/grace.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grace/grace.go b/grace/grace.go index e5577267..33bf196c 100644 --- a/grace/grace.go +++ b/grace/grace.go @@ -32,7 +32,7 @@ // mux := http.NewServeMux() // mux.HandleFunc("/hello", handler) // -// err := grace.ListenAndServe("localhost:8080", mux1) +// err := grace.ListenAndServe("localhost:8080", mux) // if err != nil { // log.Println(err) // } From 862ea226e5c8b2099c9d3a4e7ed5df90ceae5a56 Mon Sep 17 00:00:00 2001 From: Shuai Date: Mon, 24 Aug 2015 00:16:56 +0800 Subject: [PATCH 23/55] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- httplib/httplib.go | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/httplib/httplib.go b/httplib/httplib.go index 1b7b207d..b10b770a 100644 --- a/httplib/httplib.go +++ b/httplib/httplib.go @@ -100,8 +100,8 @@ func NewBeegoRequest(rawurl, method string) *BeegoHttpRequest { return &BeegoHttpRequest{ url: rawurl, req: &req, - params: map[string]interface{}{}, - files: map[string]string{}, + params: map[string][]string{}, + files: map[string]string{}, setting: defaultSetting, resp: &resp, } @@ -150,7 +150,7 @@ type BeegoHttpSettings struct { type BeegoHttpRequest struct { url string req *http.Request - params map[string]interface{} + params map[string][]string files map[string]string setting BeegoHttpSettings resp *http.Response @@ -272,8 +272,12 @@ func (b *BeegoHttpRequest) SetProxy(proxy func(*http.Request) (*url.URL, error)) // Param adds query param in to request. // params build query string as ?key1=value1&key2=value2... -func (b *BeegoHttpRequest) Param(key string, value interface{}) *BeegoHttpRequest { - b.params[key] = value +func (b *BeegoHttpRequest) Param(key, value string) *BeegoHttpRequest { + if param, ok := b.params[key]; ok { + b.params[key] = append(param, value) + } else { + b.params[key] = []string{value} + } return b } @@ -348,14 +352,9 @@ func (b *BeegoHttpRequest) buildUrl(paramBody string) { } } for k, v := range b.params { - switch v.(type) { - case string: - bodyWriter.WriteField(k, v.(string)) - case []string: - for _, vv := range v.([]string) { - bodyWriter.WriteField(k, vv) - } - } + for _, vv := range v { + bodyWriter.WriteField(k, vv) + } } bodyWriter.Close() pw.Close() @@ -390,20 +389,12 @@ func (b *BeegoHttpRequest) SendOut() (*http.Response, error) { if len(b.params) > 0 { var buf bytes.Buffer for k, v := range b.params { - switch v.(type) { - case string: - buf.WriteString(url.QueryEscape(k)) - buf.WriteByte('=') - buf.WriteString(url.QueryEscape(v.(string))) - buf.WriteByte('&') - case []string: - for _, vv := range v.([]string) { - buf.WriteString(url.QueryEscape(k)) - buf.WriteByte('=') - buf.WriteString(url.QueryEscape(vv)) - buf.WriteByte('&') - } - } + for _, vv := range v { + buf.WriteString(url.QueryEscape(k)) + buf.WriteByte('=') + buf.WriteString(url.QueryEscape(vv)) + buf.WriteByte('&') + } } paramBody = buf.String() paramBody = paramBody[0 : len(paramBody)-1] From 0c33673197f1ecdba5a77418798565db9e68a378 Mon Sep 17 00:00:00 2001 From: Pelle Johnsen Date: Mon, 24 Aug 2015 09:41:10 +0200 Subject: [PATCH 24/55] Revert spaces > tabs change --- orm/orm_queryset.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/orm/orm_queryset.go b/orm/orm_queryset.go index 106b62e5..ea236964 100644 --- a/orm/orm_queryset.go +++ b/orm/orm_queryset.go @@ -122,21 +122,21 @@ func (o querySet) Distinct() QuerySeter { // set relation model to query together. // it will query relation models and assign to parent model. func (o querySet) RelatedSel(params ...interface{}) QuerySeter { - if len(params) == 0 { - o.relDepth = DefaultRelsDepth - } else { - for _, p := range params { - switch val := p.(type) { - case string: - o.related = append(o.related, val) - case int: - o.relDepth = val - default: - panic(fmt.Errorf(" wrong param kind: %v", val)) - } - } - } - return &o + if len(params) == 0 { + o.relDepth = DefaultRelsDepth + } else { + for _, p := range params { + switch val := p.(type) { + case string: + o.related = append(o.related, val) + case int: + o.relDepth = val + default: + panic(fmt.Errorf(" wrong param kind: %v", val)) + } + } + } + return &o } // set condition to QuerySeter. From cbb6591bdb8e14b2b87d6ffed3f79dd75c586eae Mon Sep 17 00:00:00 2001 From: Viet Hung Nguyen Date: Wed, 26 Aug 2015 15:57:28 +0700 Subject: [PATCH 25/55] fix typo --- config/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/config.go b/config/config.go index 8d9261b8..d0eca747 100644 --- a/config/config.go +++ b/config/config.go @@ -88,12 +88,12 @@ func Register(name string, adapter Config) { // adapterName is ini/json/xml/yaml. // filename is the config file path. -func NewConfig(adapterName, fileaname string) (ConfigContainer, error) { +func NewConfig(adapterName, filename string) (ConfigContainer, error) { adapter, ok := adapters[adapterName] if !ok { return nil, fmt.Errorf("config: unknown adaptername %q (forgotten import?)", adapterName) } - return adapter.Parse(fileaname) + return adapter.Parse(filename) } // adapterName is ini/json/xml/yaml. From c516819c56fac85abd82a2991b0b699c196b07ee Mon Sep 17 00:00:00 2001 From: Yongzheng Lai Date: Fri, 28 Aug 2015 16:54:49 +0800 Subject: [PATCH 26/55] Update error.go this caused `http: multiple response.WriteHeader calls` when using method `CustomAbort` or `Abort` when status is already in errMap like 404. --- error.go | 1 - 1 file changed, 1 deletion(-) diff --git a/error.go b/error.go index 99a1fcf3..21768cdb 100644 --- a/error.go +++ b/error.go @@ -453,7 +453,6 @@ func exception(errcode string, ctx *context.Context) { func executeError(err *errorInfo, ctx *context.Context, code int) { if err.errorType == errorTypeHandler { - ctx.ResponseWriter.WriteHeader(code) err.handler(ctx.ResponseWriter, ctx.Request) return } From ad6547936e038759488f5a24823fba4baba9a077 Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 28 Aug 2015 23:08:00 +0800 Subject: [PATCH 27/55] fix the http: multiple response.WriteHeader calls --- plugins/apiauth/apiauth.go | 14 +++++++------- plugins/cors/cors.go | 5 +---- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/plugins/apiauth/apiauth.go b/plugins/apiauth/apiauth.go index bbae7def..56a92d25 100644 --- a/plugins/apiauth/apiauth.go +++ b/plugins/apiauth/apiauth.go @@ -83,41 +83,41 @@ func APIBaiscAuth(appid, appkey string) beego.FilterFunc { func APIAuthWithFunc(f AppIdToAppSecret, timeout int) beego.FilterFunc { return func(ctx *context.Context) { if ctx.Input.Query("appid") == "" { - ctx.Output.SetStatus(403) + ctx.ResponseWriter.WriteHeader(403) ctx.WriteString("miss query param: appid") return } appsecret := f(ctx.Input.Query("appid")) if appsecret == "" { - ctx.Output.SetStatus(403) + ctx.ResponseWriter.WriteHeader(403) ctx.WriteString("not exist this appid") return } if ctx.Input.Query("signature") == "" { - ctx.Output.SetStatus(403) + ctx.ResponseWriter.WriteHeader(403) ctx.WriteString("miss query param: signature") return } if ctx.Input.Query("timestamp") == "" { - ctx.Output.SetStatus(403) + ctx.ResponseWriter.WriteHeader(403) ctx.WriteString("miss query param: timestamp") return } u, err := time.Parse("2006-01-02 15:04:05", ctx.Input.Query("timestamp")) if err != nil { - ctx.Output.SetStatus(403) + ctx.ResponseWriter.WriteHeader(403) ctx.WriteString("timestamp format is error, should 2006-01-02 15:04:05") return } t := time.Now() if t.Sub(u).Seconds() > float64(timeout) { - ctx.Output.SetStatus(403) + ctx.ResponseWriter.WriteHeader(403) ctx.WriteString("timeout! the request time is long ago, please try again") return } if ctx.Input.Query("signature") != Signature(appsecret, ctx.Input.Method(), ctx.Request.Form, ctx.Input.Uri()) { - ctx.Output.SetStatus(403) + ctx.ResponseWriter.WriteHeader(403) ctx.WriteString("auth failed") } } diff --git a/plugins/cors/cors.go b/plugins/cors/cors.go index 052d3bc6..1e973a40 100644 --- a/plugins/cors/cors.go +++ b/plugins/cors/cors.go @@ -24,7 +24,7 @@ // // - PUT and PATCH methods // // - Origin header // // - Credentials share -// beego.InsertFilter("*", beego.BeforeRouter,cors.Allow(&cors.Options{ +// beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{ // AllowOrigins: []string{"https://*.foo.com"}, // AllowMethods: []string{"PUT", "PATCH"}, // AllowHeaders: []string{"Origin"}, @@ -36,7 +36,6 @@ package cors import ( - "net/http" "regexp" "strconv" "strings" @@ -216,8 +215,6 @@ func Allow(opts *Options) beego.FilterFunc { for key, value := range headers { ctx.Output.Header(key, value) } - ctx.Output.SetStatus(http.StatusOK) - ctx.WriteString("") return } headers = opts.Header(origin) From dd4cbdda66af752f229fb0a6bf8ac9900df5e482 Mon Sep 17 00:00:00 2001 From: astaxie Date: Mon, 31 Aug 2015 11:58:11 +0800 Subject: [PATCH 28/55] update the gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 39ae5706..9806457b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .DS_Store *.swp *.swo +beego.iml From 9fd571830d62fce13a06743512b00c8582ebb2da Mon Sep 17 00:00:00 2001 From: Yongzheng Lai Date: Tue, 1 Sep 2015 17:52:44 +0800 Subject: [PATCH 29/55] Update beego.go Maybe the `Hard Coding` should have a higher priority --- beego.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/beego.go b/beego.go index cfebfbea..516e3116 100644 --- a/beego.go +++ b/beego.go @@ -259,6 +259,8 @@ func AddAPPStartHook(hf hookfunc) { // beego.Run(":8089") // beego.Run("127.0.0.1:8089") func Run(params ...string) { + initBeforeHttpRun() + if len(params) > 0 && params[0] != "" { strs := strings.Split(params[0], ":") if len(strs) > 0 && strs[0] != "" { @@ -268,7 +270,6 @@ func Run(params ...string) { HttpPort, _ = strconv.Atoi(strs[1]) } } - initBeforeHttpRun() if EnableAdmin { go beeAdminApp.Run() From adca4558044e9eb5bc64492021f2128773930826 Mon Sep 17 00:00:00 2001 From: onealtang Date: Wed, 2 Sep 2015 15:50:40 +0800 Subject: [PATCH 30/55] always use server's locale to parse date When parsing the date without time, it's always using UTC date, which is unexpected. If we want to use UTC date, it's recommend to set the server's timezone as UTC, and keep the code flexible. --- templatefunc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templatefunc.go b/templatefunc.go index 28ed15a3..39ada253 100644 --- a/templatefunc.go +++ b/templatefunc.go @@ -352,7 +352,7 @@ func ParseForm(form url.Values, obj interface{}) error { if len(tags) > 1 { format = tags[1] } - t, err := time.Parse(format, value) + t, err := time.ParseInLocation(format, value, time.Local) if err != nil { return err } From a074df9c2e9d25ffdb0050b68488b2484497cee4 Mon Sep 17 00:00:00 2001 From: f0r Date: Thu, 3 Sep 2015 00:45:09 +0800 Subject: [PATCH 31/55] =?UTF-8?q?=E4=B8=BAquerySeter=E6=B7=BB=E5=8A=A0Grou?= =?UTF-8?q?pBy=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- orm/db.go | 6 ++++-- orm/db_tables.go | 24 ++++++++++++++++++++++++ orm/orm_queryset.go | 7 +++++++ orm/types.go | 1 + 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/orm/db.go b/orm/db.go index cefd5dfc..1803db4f 100644 --- a/orm/db.go +++ b/orm/db.go @@ -802,6 +802,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi tables.parseRelated(qs.related, qs.relDepth) where, args := tables.getCondSql(cond, false, tz) + groupBy := tables.getGroupSql(qs.groups) orderBy := tables.getOrderSql(qs.orders) limit := tables.getLimitSql(mi, offset, rlimit) join := tables.getJoinSql() @@ -818,7 +819,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi if qs.distinct { sqlSelect += " DISTINCT" } - query := fmt.Sprintf("%s %s FROM %s%s%s T0 %s%s%s%s", sqlSelect, sels, Q, mi.table, Q, join, where, orderBy, limit) + query := fmt.Sprintf("%s %s FROM %s%s%s T0 %s%s%s%s%s", sqlSelect, sels, Q, mi.table, Q, join, where, groupBy, orderBy, limit) d.ins.ReplaceMarks(&query) @@ -1448,13 +1449,14 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond } where, args := tables.getCondSql(cond, false, tz) + groupBy := tables.getGroupSql(qs.groups) orderBy := tables.getOrderSql(qs.orders) limit := tables.getLimitSql(mi, qs.offset, qs.limit) join := tables.getJoinSql() sels := strings.Join(cols, ", ") - query := fmt.Sprintf("SELECT %s FROM %s%s%s T0 %s%s%s%s", sels, Q, mi.table, Q, join, where, orderBy, limit) + query := fmt.Sprintf("SELECT %s FROM %s%s%s T0 %s%s%s%s%s", sels, Q, mi.table, Q, join, where, groupBy,orderBy, limit) d.ins.ReplaceMarks(&query) diff --git a/orm/db_tables.go b/orm/db_tables.go index a9aa10ab..245be891 100644 --- a/orm/db_tables.go +++ b/orm/db_tables.go @@ -390,6 +390,30 @@ func (t *dbTables) getCondSql(cond *Condition, sub bool, tz *time.Location) (whe return } +// generate group sql. +func (t *dbTables) getGroupSql(groups []string) (groupSql string) { + if len(groups) == 0 { + return + } + + Q := t.base.TableQuote() + + groupSqls := make([]string, 0, len(groups)) + for _, group := range groups { + exprs := strings.Split(group, ExprSep) + + index, _, fi, suc := t.parseExprs(t.mi, exprs) + if suc == false { + panic(fmt.Errorf("unknown field/column name `%s`", strings.Join(exprs, ExprSep))) + } + + groupSqls = append(groupSqls, fmt.Sprintf("%s.%s%s%s", index, Q, fi.column, Q)) + } + + groupSql = fmt.Sprintf("GROUP BY %s ", strings.Join(groupSqls, ", ")) + return +} + // generate order sql. func (t *dbTables) getOrderSql(orders []string) (orderSql string) { if len(orders) == 0 { diff --git a/orm/orm_queryset.go b/orm/orm_queryset.go index ea236964..af16b694 100644 --- a/orm/orm_queryset.go +++ b/orm/orm_queryset.go @@ -60,6 +60,7 @@ type querySet struct { relDepth int limit int64 offset int64 + groups []string orders []string distinct bool orm *orm @@ -106,6 +107,12 @@ func (o querySet) Offset(offset interface{}) QuerySeter { return &o } +// add GROUP expression +func (o querySet) GroupBy(exprs ...string) QuerySeter { + o.groups = exprs + return &o +} + // add ORDER expression. // "column" means ASC, "-column" means DESC. func (o querySet) OrderBy(exprs ...string) QuerySeter { diff --git a/orm/types.go b/orm/types.go index 4347e46f..95a3fee3 100644 --- a/orm/types.go +++ b/orm/types.go @@ -66,6 +66,7 @@ type QuerySeter interface { SetCond(*Condition) QuerySeter Limit(interface{}, ...interface{}) QuerySeter Offset(interface{}) QuerySeter + GroupBy(...string) QuerySeter OrderBy(...string) QuerySeter Distinct() QuerySeter RelatedSel(...interface{}) QuerySeter From 9ab7466d5c36ad08a5173cb91e885d4c02c32157 Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 4 Sep 2015 22:20:55 +0800 Subject: [PATCH 32/55] fix the cappital --- logs/smtp.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/logs/smtp.go b/logs/smtp.go index 95123ebf..f9b292b7 100644 --- a/logs/smtp.go +++ b/logs/smtp.go @@ -31,9 +31,9 @@ const ( // smtpWriter implements LoggerInterface and is used to send emails via given SMTP-server. type SmtpWriter struct { - Username string `json:"Username"` + Username string `json:"username"` Password string `json:"password"` - Host string `json:"Host"` + Host string `json:"host"` Subject string `json:"subject"` FromAddress string `json:"fromAddress"` RecipientAddresses []string `json:"sendTos"` From f9fe89fff0e6044468d27fb14febbc7ee38ae336 Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 4 Sep 2015 22:33:03 +0800 Subject: [PATCH 33/55] fix the file rotate test case issues --- logs/file_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logs/file_test.go b/logs/file_test.go index c71e9bb4..97260f12 100644 --- a/logs/file_test.go +++ b/logs/file_test.go @@ -103,7 +103,7 @@ func TestFileRotate(t *testing.T) { log.Critical("critical") log.Emergency("emergency") time.Sleep(time.Second * 4) - rotatename := "test3.log" + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), 1) + rotatename := "test3" + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), 1) + ".log" b, err := exists(rotatename) if !b || err != nil { t.Fatal("rotate not generated") From 34aa9002bba92457bafdace3ecb2773caeed7503 Mon Sep 17 00:00:00 2001 From: astaxie Date: Fri, 4 Sep 2015 23:03:10 +0800 Subject: [PATCH 34/55] fix the httplib test case timeout --- httplib/httplib_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/httplib/httplib_test.go b/httplib/httplib_test.go index 0b551c53..0b6b5779 100644 --- a/httplib/httplib_test.go +++ b/httplib/httplib_test.go @@ -19,6 +19,7 @@ import ( "os" "strings" "testing" + "time" ) func TestResponse(t *testing.T) { @@ -153,6 +154,7 @@ func TestWithSetting(t *testing.T) { setting.EnableCookie = true setting.UserAgent = v setting.Transport = nil + setting.ReadWriteTimeout = 5 * time.Second SetDefaultSetting(setting) str, err := Get("http://httpbin.org/get").String() From f55bbbdff41b43402fe8f4767ed0ebfcc35da46b Mon Sep 17 00:00:00 2001 From: sidbusy Date: Sat, 5 Sep 2015 10:31:31 +0800 Subject: [PATCH 35/55] allows custom the TableName of Session --- session/mysql/sess_mysql.go | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/session/mysql/sess_mysql.go b/session/mysql/sess_mysql.go index 76a13932..26237e95 100644 --- a/session/mysql/sess_mysql.go +++ b/session/mysql/sess_mysql.go @@ -51,7 +51,10 @@ import ( _ "github.com/go-sql-driver/mysql" ) -var mysqlpder = &MysqlProvider{} +var ( + TableName = "session" + mysqlpder = &MysqlProvider{} +) // mysql session store type MysqlSessionStore struct { @@ -110,7 +113,7 @@ func (st *MysqlSessionStore) SessionRelease(w http.ResponseWriter) { if err != nil { return } - st.c.Exec("UPDATE session set `session_data`=?, `session_expiry`=? where session_key=?", + st.c.Exec("UPDATE "+TableName+" set `session_data`=?, `session_expiry`=? where session_key=?", b, time.Now().Unix(), st.sid) } @@ -141,11 +144,11 @@ func (mp *MysqlProvider) SessionInit(maxlifetime int64, savePath string) error { // get mysql session by sid func (mp *MysqlProvider) SessionRead(sid string) (session.SessionStore, error) { c := mp.connectInit() - row := c.QueryRow("select session_data from session where session_key=?", sid) + row := c.QueryRow("select session_data from "+TableName+" where session_key=?", sid) var sessiondata []byte err := row.Scan(&sessiondata) if err == sql.ErrNoRows { - c.Exec("insert into session(`session_key`,`session_data`,`session_expiry`) values(?,?,?)", + c.Exec("insert into "+TableName+"(`session_key`,`session_data`,`session_expiry`) values(?,?,?)", sid, "", time.Now().Unix()) } var kv map[interface{}]interface{} @@ -165,7 +168,7 @@ func (mp *MysqlProvider) SessionRead(sid string) (session.SessionStore, error) { func (mp *MysqlProvider) SessionExist(sid string) bool { c := mp.connectInit() defer c.Close() - row := c.QueryRow("select session_data from session where session_key=?", sid) + row := c.QueryRow("select session_data from "+TableName+" where session_key=?", sid) var sessiondata []byte err := row.Scan(&sessiondata) if err == sql.ErrNoRows { @@ -178,13 +181,13 @@ func (mp *MysqlProvider) SessionExist(sid string) bool { // generate new sid for mysql session func (mp *MysqlProvider) SessionRegenerate(oldsid, sid string) (session.SessionStore, error) { c := mp.connectInit() - row := c.QueryRow("select session_data from session where session_key=?", oldsid) + row := c.QueryRow("select session_data from "+TableName+" where session_key=?", oldsid) var sessiondata []byte err := row.Scan(&sessiondata) if err == sql.ErrNoRows { - c.Exec("insert into session(`session_key`,`session_data`,`session_expiry`) values(?,?,?)", oldsid, "", time.Now().Unix()) + c.Exec("insert into "+TableName+"(`session_key`,`session_data`,`session_expiry`) values(?,?,?)", oldsid, "", time.Now().Unix()) } - c.Exec("update session set `session_key`=? where session_key=?", sid, oldsid) + c.Exec("update "+TableName+" set `session_key`=? where session_key=?", sid, oldsid) var kv map[interface{}]interface{} if len(sessiondata) == 0 { kv = make(map[interface{}]interface{}) @@ -201,7 +204,7 @@ func (mp *MysqlProvider) SessionRegenerate(oldsid, sid string) (session.SessionS // delete mysql session by sid func (mp *MysqlProvider) SessionDestroy(sid string) error { c := mp.connectInit() - c.Exec("DELETE FROM session where session_key=?", sid) + c.Exec("DELETE FROM "+TableName+" where session_key=?", sid) c.Close() return nil } @@ -209,7 +212,7 @@ func (mp *MysqlProvider) SessionDestroy(sid string) error { // delete expired values in mysql session func (mp *MysqlProvider) SessionGC() { c := mp.connectInit() - c.Exec("DELETE from session where session_expiry < ?", time.Now().Unix()-mp.maxlifetime) + c.Exec("DELETE from "+TableName+" where session_expiry < ?", time.Now().Unix()-mp.maxlifetime) c.Close() return } @@ -219,7 +222,7 @@ func (mp *MysqlProvider) SessionAll() int { c := mp.connectInit() defer c.Close() var total int - err := c.QueryRow("SELECT count(*) as num from session").Scan(&total) + err := c.QueryRow("SELECT count(*) as num from " + TableName).Scan(&total) if err != nil { return 0 } From 06ec3a931ddb0f19681520d798cdc5d260050df6 Mon Sep 17 00:00:00 2001 From: Kyoung-chan Lee Date: Sun, 6 Sep 2015 17:13:55 +0900 Subject: [PATCH 36/55] Fix a wrong test name. --- cache/memcache/memcache_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cache/memcache/memcache_test.go b/cache/memcache/memcache_test.go index 0523ae85..27b085e6 100644 --- a/cache/memcache/memcache_test.go +++ b/cache/memcache/memcache_test.go @@ -23,7 +23,7 @@ import ( "time" ) -func TestRedisCache(t *testing.T) { +func TestMemcacheCache(t *testing.T) { bm, err := cache.NewCache("memcache", `{"conn": "127.0.0.1:11211"}`) if err != nil { t.Error("init err") From 4ad743fc8b5fcbd2037cfe2a4da14d1b46c4cc27 Mon Sep 17 00:00:00 2001 From: Kyoung-chan Lee Date: Sun, 6 Sep 2015 17:20:18 +0900 Subject: [PATCH 37/55] Update a outdated information in README. --- cache/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cache/README.md b/cache/README.md index 72d0d1c5..893b213f 100644 --- a/cache/README.md +++ b/cache/README.md @@ -43,7 +43,7 @@ interval means the gc time. The cache will check at each time interval, whether ## Memcache adapter -Memcache adapter use the vitess's [Memcache](http://code.google.com/p/vitess/go/memcache) client. +Memcache adapter use the [gomemcache](http://github.com/bradfitz/gomemcache) client. Configure like this: From fe1ec1675f7b29f340e5f3e387a72eec64bf75ad Mon Sep 17 00:00:00 2001 From: Kyoung-chan Lee Date: Sun, 6 Sep 2015 17:22:33 +0900 Subject: [PATCH 38/55] Fix a wrong url (http 404). --- cache/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cache/README.md b/cache/README.md index 893b213f..4152c57e 100644 --- a/cache/README.md +++ b/cache/README.md @@ -52,7 +52,7 @@ Configure like this: ## Redis adapter -Redis adapter use the [redigo](http://github.com/garyburd/redigo/redis) client. +Redis adapter use the [redigo](http://github.com/garyburd/redigo) client. Configure like this: From eb3479b753986929aeaba194905b4a044283137f Mon Sep 17 00:00:00 2001 From: astaxie Date: Sun, 6 Sep 2015 23:00:42 +0800 Subject: [PATCH 39/55] optimize the app structure --- app.go | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++ beego.go | 201 +++--------------------------------------------------- config.go | 4 -- 3 files changed, 198 insertions(+), 196 deletions(-) diff --git a/app.go b/app.go index eddf7e21..96e2ad2c 100644 --- a/app.go +++ b/app.go @@ -20,12 +20,22 @@ import ( "net/http" "net/http/fcgi" "os" + "path" "time" "github.com/astaxie/beego/grace" "github.com/astaxie/beego/utils" ) +var ( + BeeApp *App +) + +func init() { + // create beego application + BeeApp = NewApp() +} + // App defines beego application with a new PatternServeMux. type App struct { Handlers *ControllerRegister @@ -170,3 +180,182 @@ func (app *App) Run() { } <-endRunning } + +// Router adds a patterned controller handler to BeeApp. +// it's an alias method of App.Router. +// usage: +// simple router +// beego.Router("/admin", &admin.UserController{}) +// beego.Router("/admin/index", &admin.ArticleController{}) +// +// regex router +// +// 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") +func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *App { + BeeApp.Handlers.Add(rootpath, c, mappingMethods...) + return BeeApp +} + +// Router add list from +// usage: +// beego.Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{}) +// type BankAccount struct{ +// beego.Controller +// } +// +// register the function +// func (b *BankAccount)Mapping(){ +// b.Mapping("ShowAccount" , b.ShowAccount) +// b.Mapping("ModifyAccount", b.ModifyAccount) +//} +// +// //@router /account/:id [get] +// func (b *BankAccount) ShowAccount(){ +// //logic +// } +// +// +// //@router /account/:id [post] +// func (b *BankAccount) ModifyAccount(){ +// //logic +// } +// +// the comments @router url methodlist +// url support all the function Router's pattern +// methodlist [get post head put delete options *] +func Include(cList ...ControllerInterface) *App { + BeeApp.Handlers.Include(cList...) + return BeeApp +} + +// RESTRouter adds a restful controller handler to BeeApp. +// its' controller implements beego.ControllerInterface and +// defines a param "pattern/:objectId" to visit each resource. +func RESTRouter(rootpath string, c ControllerInterface) *App { + Router(rootpath, c) + Router(path.Join(rootpath, ":objectId"), c) + return BeeApp +} + +// AutoRouter adds defined controller handler to BeeApp. +// it's same to App.AutoRouter. +// if beego.AddAuto(&MainContorlller{}) and MainController has methods List and Page, +// visit the url /main/list to exec List function or /main/page to exec Page function. +func AutoRouter(c ControllerInterface) *App { + BeeApp.Handlers.AddAuto(c) + return BeeApp +} + +// AutoPrefix adds controller handler to BeeApp with prefix. +// it's same to App.AutoRouterWithPrefix. +// if beego.AutoPrefix("/admin",&MainContorlller{}) and MainController has methods List and Page, +// visit the url /admin/main/list to exec List function or /admin/main/page to exec Page function. +func AutoPrefix(prefix string, c ControllerInterface) *App { + BeeApp.Handlers.AddAutoPrefix(prefix, c) + return BeeApp +} + +// register router for Get method +// usage: +// beego.Get("/", func(ctx *context.Context){ +// ctx.Output.Body("hello world") +// }) +func Get(rootpath string, f FilterFunc) *App { + BeeApp.Handlers.Get(rootpath, f) + return BeeApp +} + +// register router for Post method +// usage: +// beego.Post("/api", func(ctx *context.Context){ +// ctx.Output.Body("hello world") +// }) +func Post(rootpath string, f FilterFunc) *App { + BeeApp.Handlers.Post(rootpath, f) + return BeeApp +} + +// register router for Delete method +// usage: +// beego.Delete("/api", func(ctx *context.Context){ +// ctx.Output.Body("hello world") +// }) +func Delete(rootpath string, f FilterFunc) *App { + BeeApp.Handlers.Delete(rootpath, f) + return BeeApp +} + +// register router for Put method +// usage: +// beego.Put("/api", func(ctx *context.Context){ +// ctx.Output.Body("hello world") +// }) +func Put(rootpath string, f FilterFunc) *App { + BeeApp.Handlers.Put(rootpath, f) + return BeeApp +} + +// register router for Head method +// usage: +// beego.Head("/api", func(ctx *context.Context){ +// ctx.Output.Body("hello world") +// }) +func Head(rootpath string, f FilterFunc) *App { + BeeApp.Handlers.Head(rootpath, f) + return BeeApp +} + +// register router for Options method +// usage: +// beego.Options("/api", func(ctx *context.Context){ +// ctx.Output.Body("hello world") +// }) +func Options(rootpath string, f FilterFunc) *App { + BeeApp.Handlers.Options(rootpath, f) + return BeeApp +} + +// register router for Patch method +// usage: +// beego.Patch("/api", func(ctx *context.Context){ +// ctx.Output.Body("hello world") +// }) +func Patch(rootpath string, f FilterFunc) *App { + BeeApp.Handlers.Patch(rootpath, f) + return BeeApp +} + +// register router for all method +// usage: +// beego.Any("/api", func(ctx *context.Context){ +// ctx.Output.Body("hello world") +// }) +func Any(rootpath string, f FilterFunc) *App { + BeeApp.Handlers.Any(rootpath, f) + return BeeApp +} + +// register router for own Handler +// usage: +// beego.Handler("/api", func(ctx *context.Context){ +// ctx.Output.Body("hello world") +// }) +func Handler(rootpath string, h http.Handler, options ...interface{}) *App { + BeeApp.Handlers.Handler(rootpath, h, options...) + return BeeApp +} + +// InsertFilter adds a FilterFunc with pattern condition and action constant. +// The pos means action constant including +// beego.BeforeStatic, beego.BeforeRouter, beego.BeforeExec, beego.AfterExec and beego.FinishRouter. +// The bool params is for setting the returnOnOutput value (false allows multiple filters to execute) +func InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) *App { + BeeApp.Handlers.InsertFilter(pattern, pos, filter, params...) + return BeeApp +} diff --git a/beego.go b/beego.go index 43f98755..ead5a6d4 100644 --- a/beego.go +++ b/beego.go @@ -15,9 +15,7 @@ package beego import ( - "net/http" "os" - "path" "path/filepath" "strconv" "strings" @@ -28,178 +26,12 @@ import ( // beego web framework version. const VERSION = "1.5.0" -type hookfunc func() error //hook function to run -var hooks []hookfunc //hook function slice to store the hookfunc +//hook function to run +type hookfunc func() error -// Router adds a patterned controller handler to BeeApp. -// it's an alias method of App.Router. -// usage: -// simple router -// beego.Router("/admin", &admin.UserController{}) -// beego.Router("/admin/index", &admin.ArticleController{}) -// -// regex router -// -// 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") -func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *App { - BeeApp.Handlers.Add(rootpath, c, mappingMethods...) - return BeeApp -} - -// Router add list from -// usage: -// beego.Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{}) -// type BankAccount struct{ -// beego.Controller -// } -// -// register the function -// func (b *BankAccount)Mapping(){ -// b.Mapping("ShowAccount" , b.ShowAccount) -// b.Mapping("ModifyAccount", b.ModifyAccount) -//} -// -// //@router /account/:id [get] -// func (b *BankAccount) ShowAccount(){ -// //logic -// } -// -// -// //@router /account/:id [post] -// func (b *BankAccount) ModifyAccount(){ -// //logic -// } -// -// the comments @router url methodlist -// url support all the function Router's pattern -// methodlist [get post head put delete options *] -func Include(cList ...ControllerInterface) *App { - BeeApp.Handlers.Include(cList...) - return BeeApp -} - -// RESTRouter adds a restful controller handler to BeeApp. -// its' controller implements beego.ControllerInterface and -// defines a param "pattern/:objectId" to visit each resource. -func RESTRouter(rootpath string, c ControllerInterface) *App { - Router(rootpath, c) - Router(path.Join(rootpath, ":objectId"), c) - return BeeApp -} - -// AutoRouter adds defined controller handler to BeeApp. -// it's same to App.AutoRouter. -// if beego.AddAuto(&MainContorlller{}) and MainController has methods List and Page, -// visit the url /main/list to exec List function or /main/page to exec Page function. -func AutoRouter(c ControllerInterface) *App { - BeeApp.Handlers.AddAuto(c) - return BeeApp -} - -// AutoPrefix adds controller handler to BeeApp with prefix. -// it's same to App.AutoRouterWithPrefix. -// if beego.AutoPrefix("/admin",&MainContorlller{}) and MainController has methods List and Page, -// visit the url /admin/main/list to exec List function or /admin/main/page to exec Page function. -func AutoPrefix(prefix string, c ControllerInterface) *App { - BeeApp.Handlers.AddAutoPrefix(prefix, c) - return BeeApp -} - -// register router for Get method -// usage: -// beego.Get("/", func(ctx *context.Context){ -// ctx.Output.Body("hello world") -// }) -func Get(rootpath string, f FilterFunc) *App { - BeeApp.Handlers.Get(rootpath, f) - return BeeApp -} - -// register router for Post method -// usage: -// beego.Post("/api", func(ctx *context.Context){ -// ctx.Output.Body("hello world") -// }) -func Post(rootpath string, f FilterFunc) *App { - BeeApp.Handlers.Post(rootpath, f) - return BeeApp -} - -// register router for Delete method -// usage: -// beego.Delete("/api", func(ctx *context.Context){ -// ctx.Output.Body("hello world") -// }) -func Delete(rootpath string, f FilterFunc) *App { - BeeApp.Handlers.Delete(rootpath, f) - return BeeApp -} - -// register router for Put method -// usage: -// beego.Put("/api", func(ctx *context.Context){ -// ctx.Output.Body("hello world") -// }) -func Put(rootpath string, f FilterFunc) *App { - BeeApp.Handlers.Put(rootpath, f) - return BeeApp -} - -// register router for Head method -// usage: -// beego.Head("/api", func(ctx *context.Context){ -// ctx.Output.Body("hello world") -// }) -func Head(rootpath string, f FilterFunc) *App { - BeeApp.Handlers.Head(rootpath, f) - return BeeApp -} - -// register router for Options method -// usage: -// beego.Options("/api", func(ctx *context.Context){ -// ctx.Output.Body("hello world") -// }) -func Options(rootpath string, f FilterFunc) *App { - BeeApp.Handlers.Options(rootpath, f) - return BeeApp -} - -// register router for Patch method -// usage: -// beego.Patch("/api", func(ctx *context.Context){ -// ctx.Output.Body("hello world") -// }) -func Patch(rootpath string, f FilterFunc) *App { - BeeApp.Handlers.Patch(rootpath, f) - return BeeApp -} - -// register router for all method -// usage: -// beego.Any("/api", func(ctx *context.Context){ -// ctx.Output.Body("hello world") -// }) -func Any(rootpath string, f FilterFunc) *App { - BeeApp.Handlers.Any(rootpath, f) - return BeeApp -} - -// register router for own Handler -// usage: -// beego.Handler("/api", func(ctx *context.Context){ -// ctx.Output.Body("hello world") -// }) -func Handler(rootpath string, h http.Handler, options ...interface{}) *App { - BeeApp.Handlers.Handler(rootpath, h, options...) - return BeeApp -} +var ( + hooks = make([]hookfunc, 0) //hook function slice to store the hookfunc +) // SetViewsPath sets view directory path in beego application. func SetViewsPath(path string) *App { @@ -228,15 +60,6 @@ func DelStaticPath(url string) *App { return BeeApp } -// InsertFilter adds a FilterFunc with pattern condition and action constant. -// The pos means action constant including -// beego.BeforeStatic, beego.BeforeRouter, beego.BeforeExec, beego.AfterExec and beego.FinishRouter. -// The bool params is for setting the returnOnOutput value (false allows multiple filters to execute) -func InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) *App { - BeeApp.Handlers.InsertFilter(pattern, pos, filter, params...) - return BeeApp -} - // The hookfunc will run in beego.Run() // such as sessionInit, middlerware start, buildtemplate, admin start func AddAPPStartHook(hf hookfunc) { @@ -249,7 +72,7 @@ func AddAPPStartHook(hf hookfunc) { // beego.Run("127.0.0.1:8089") func Run(params ...string) { initBeforeHttpRun() - + if len(params) > 0 && params[0] != "" { strs := strings.Split(params[0], ":") if len(strs) > 0 && strs[0] != "" { @@ -307,13 +130,11 @@ func initBeforeHttpRun() { } go GlobalSessions.GC() } - + if AutoRender { err := BuildTemplate(ViewsPath) - if err != nil { - if RunMode == "dev" { - Warn(err) - } + if err != nil && RunMode == "dev" { + Warn(err) } } @@ -338,7 +159,3 @@ func TestBeegoInit(apppath string) { os.Chdir(AppPath) initBeforeHttpRun() } - -func init() { - hooks = make([]hookfunc, 0) -} diff --git a/config.go b/config.go index 09d0df24..2bbd14f6 100644 --- a/config.go +++ b/config.go @@ -29,7 +29,6 @@ import ( ) var ( - BeeApp *App // beego application AppName string AppPath string workPath string @@ -215,9 +214,6 @@ func (b *beegoAppConfig) SaveConfigFile(filename string) error { } func init() { - // create beego application - BeeApp = NewApp() - workPath, _ = os.Getwd() workPath, _ = filepath.Abs(workPath) // initialize default configurations From 85d8ec5ca65a1615289cdd6e80645e885556a0e6 Mon Sep 17 00:00:00 2001 From: astaxie Date: Mon, 7 Sep 2015 19:18:04 +0800 Subject: [PATCH 40/55] optimize the beego structure --- beego.go | 138 +++++++++++++++++++++---------------------------------- error.go | 41 ----------------- hooks.go | 100 ++++++++++++++++++++++++++++++++++++++++ mime.go | 11 ----- 4 files changed, 153 insertions(+), 137 deletions(-) create mode 100644 hooks.go diff --git a/beego.go b/beego.go index ead5a6d4..042a4270 100644 --- a/beego.go +++ b/beego.go @@ -19,8 +19,6 @@ import ( "path/filepath" "strconv" "strings" - - "github.com/astaxie/beego/session" ) // beego web framework version. @@ -33,33 +31,6 @@ var ( hooks = make([]hookfunc, 0) //hook function slice to store the hookfunc ) -// SetViewsPath sets view directory path in beego application. -func SetViewsPath(path string) *App { - ViewsPath = path - return BeeApp -} - -// SetStaticPath sets static directory path and proper url pattern in beego application. -// if beego.SetStaticPath("static","public"), visit /static/* to load static file in folder "public". -func SetStaticPath(url string, path string) *App { - if !strings.HasPrefix(url, "/") { - url = "/" + url - } - url = strings.TrimRight(url, "/") - StaticDir[url] = path - return BeeApp -} - -// DelStaticPath removes the static folder setting in this url pattern in beego application. -func DelStaticPath(url string) *App { - if !strings.HasPrefix(url, "/") { - url = "/" + url - } - url = strings.TrimRight(url, "/") - delete(StaticDir, url) - return BeeApp -} - // The hookfunc will run in beego.Run() // such as sessionInit, middlerware start, buildtemplate, admin start func AddAPPStartHook(hf hookfunc) { @@ -90,62 +61,6 @@ func Run(params ...string) { BeeApp.Run() } -func initBeforeHttpRun() { - // if AppConfigPath not In the conf/app.conf reParse config - if AppConfigPath != filepath.Join(AppPath, "conf", "app.conf") { - err := ParseConfig() - if err != nil && AppConfigPath != filepath.Join(workPath, "conf", "app.conf") { - // configuration is critical to app, panic here if parse failed - panic(err) - } - } - - //init mime - AddAPPStartHook(initMime) - - // do hooks function - for _, hk := range hooks { - err := hk() - if err != nil { - panic(err) - } - } - - if SessionOn { - var err error - sessionConfig := AppConfig.String("sessionConfig") - if sessionConfig == "" { - sessionConfig = `{"cookieName":"` + SessionName + `",` + - `"gclifetime":` + strconv.FormatInt(SessionGCMaxLifetime, 10) + `,` + - `"providerConfig":"` + filepath.ToSlash(SessionSavePath) + `",` + - `"secure":` + strconv.FormatBool(EnableHttpTLS) + `,` + - `"enableSetCookie":` + strconv.FormatBool(SessionAutoSetCookie) + `,` + - `"domain":"` + SessionDomain + `",` + - `"cookieLifeTime":` + strconv.Itoa(SessionCookieLifeTime) + `}` - } - GlobalSessions, err = session.NewManager(SessionProvider, - sessionConfig) - if err != nil { - panic(err) - } - go GlobalSessions.GC() - } - - if AutoRender { - err := BuildTemplate(ViewsPath) - if err != nil && RunMode == "dev" { - Warn(err) - } - } - - registerDefaultErrorHandler() - - if EnableDocs { - Get("/docs", serverDocs) - Get("/docs/*", serverDocs) - } -} - // this function is for test package init func TestBeegoInit(apppath string) { AppPath = apppath @@ -159,3 +74,56 @@ func TestBeegoInit(apppath string) { os.Chdir(AppPath) initBeforeHttpRun() } + +func initBeforeHttpRun() { + // if AppConfigPath not In the conf/app.conf reParse config + if AppConfigPath != filepath.Join(AppPath, "conf", "app.conf") { + err := ParseConfig() + if err != nil && AppConfigPath != filepath.Join(workPath, "conf", "app.conf") { + // configuration is critical to app, panic here if parse failed + panic(err) + } + } + + //init mime + AddAPPStartHook(registerMime) + AddAPPStartHook(registerDefaultErrorHandler) + AddAPPStartHook(registerSession) + AddAPPStartHook(registerDocs) + AddAPPStartHook(registerTemplate) + + // do hooks function + for _, hk := range hooks { + err := hk() + if err != nil { + panic(err) + } + } +} + +// SetViewsPath sets view directory path in beego application. +func SetViewsPath(path string) *App { + ViewsPath = path + return BeeApp +} + +// SetStaticPath sets static directory path and proper url pattern in beego application. +// if beego.SetStaticPath("static","public"), visit /static/* to load static file in folder "public". +func SetStaticPath(url string, path string) *App { + if !strings.HasPrefix(url, "/") { + url = "/" + url + } + url = strings.TrimRight(url, "/") + StaticDir[url] = path + return BeeApp +} + +// DelStaticPath removes the static folder setting in this url pattern in beego application. +func DelStaticPath(url string) *App { + if !strings.HasPrefix(url, "/") { + url = "/" + url + } + url = strings.TrimRight(url, "/") + delete(StaticDir, url) + return BeeApp +} diff --git a/error.go b/error.go index 21768cdb..f5c0c80b 100644 --- a/error.go +++ b/error.go @@ -358,47 +358,6 @@ func gatewayTimeout(rw http.ResponseWriter, r *http.Request) { t.Execute(rw, data) } -// register default error http handlers, 404,401,403,500 and 503. -func registerDefaultErrorHandler() { - if _, ok := ErrorMaps["401"]; !ok { - Errorhandler("401", unauthorized) - } - - if _, ok := ErrorMaps["402"]; !ok { - Errorhandler("402", paymentRequired) - } - - if _, ok := ErrorMaps["403"]; !ok { - Errorhandler("403", forbidden) - } - - if _, ok := ErrorMaps["404"]; !ok { - Errorhandler("404", notFound) - } - - if _, ok := ErrorMaps["405"]; !ok { - Errorhandler("405", methodNotAllowed) - } - - if _, ok := ErrorMaps["500"]; !ok { - Errorhandler("500", internalServerError) - } - if _, ok := ErrorMaps["501"]; !ok { - Errorhandler("501", notImplemented) - } - if _, ok := ErrorMaps["502"]; !ok { - Errorhandler("502", badGateway) - } - - if _, ok := ErrorMaps["503"]; !ok { - Errorhandler("503", serviceUnavailable) - } - - if _, ok := ErrorMaps["504"]; !ok { - Errorhandler("504", gatewayTimeout) - } -} - // ErrorHandler registers http.HandlerFunc to each http err code string. // usage: // beego.ErrorHandler("404",NotFound) diff --git a/hooks.go b/hooks.go new file mode 100644 index 00000000..ded0d794 --- /dev/null +++ b/hooks.go @@ -0,0 +1,100 @@ +package beego + +import ( + "mime" + "path/filepath" + "strconv" + + "github.com/astaxie/beego/session" +) + +// +func registerMime() error { + for k, v := range mimemaps { + mime.AddExtensionType(k, v) + } + return nil +} + +// register default error http handlers, 404,401,403,500 and 503. +func registerDefaultErrorHandler() error { + if _, ok := ErrorMaps["401"]; !ok { + Errorhandler("401", unauthorized) + } + + if _, ok := ErrorMaps["402"]; !ok { + Errorhandler("402", paymentRequired) + } + + if _, ok := ErrorMaps["403"]; !ok { + Errorhandler("403", forbidden) + } + + if _, ok := ErrorMaps["404"]; !ok { + Errorhandler("404", notFound) + } + + if _, ok := ErrorMaps["405"]; !ok { + Errorhandler("405", methodNotAllowed) + } + + if _, ok := ErrorMaps["500"]; !ok { + Errorhandler("500", internalServerError) + } + if _, ok := ErrorMaps["501"]; !ok { + Errorhandler("501", notImplemented) + } + if _, ok := ErrorMaps["502"]; !ok { + Errorhandler("502", badGateway) + } + + if _, ok := ErrorMaps["503"]; !ok { + Errorhandler("503", serviceUnavailable) + } + + if _, ok := ErrorMaps["504"]; !ok { + Errorhandler("504", gatewayTimeout) + } + return nil +} + +func registerSession() error { + if SessionOn { + var err error + sessionConfig := AppConfig.String("sessionConfig") + if sessionConfig == "" { + sessionConfig = `{"cookieName":"` + SessionName + `",` + + `"gclifetime":` + strconv.FormatInt(SessionGCMaxLifetime, 10) + `,` + + `"providerConfig":"` + filepath.ToSlash(SessionSavePath) + `",` + + `"secure":` + strconv.FormatBool(EnableHttpTLS) + `,` + + `"enableSetCookie":` + strconv.FormatBool(SessionAutoSetCookie) + `,` + + `"domain":"` + SessionDomain + `",` + + `"cookieLifeTime":` + strconv.Itoa(SessionCookieLifeTime) + `}` + } + GlobalSessions, err = session.NewManager(SessionProvider, + sessionConfig) + if err != nil { + return err + } + go GlobalSessions.GC() + } + return nil +} + +func registerTemplate() error { + if AutoRender { + err := BuildTemplate(ViewsPath) + if err != nil && RunMode == "dev" { + Warn(err) + } + } + return nil +} + +func registerDocs() error { + if EnableDocs { + Get("/docs", serverDocs) + Get("/docs/*", serverDocs) + } + return nil +} diff --git a/mime.go b/mime.go index 20246c21..0034976e 100644 --- a/mime.go +++ b/mime.go @@ -14,10 +14,6 @@ package beego -import ( - "mime" -) - var mimemaps map[string]string = map[string]string{ ".3dm": "x-world/x-3dmf", ".3dmf": "x-world/x-3dmf", @@ -558,10 +554,3 @@ var mimemaps map[string]string = map[string]string{ ".oex": "application/x-opera-extension", ".mustache": "text/html", } - -func initMime() error { - for k, v := range mimemaps { - mime.AddExtensionType(k, v) - } - return nil -} From 284dfc08438819c57800f9998234684ccc8aa47b Mon Sep 17 00:00:00 2001 From: astaxie Date: Mon, 7 Sep 2015 19:21:55 +0800 Subject: [PATCH 41/55] move the template related fun to template.go --- beego.go | 27 --------------------------- template.go | 31 +++++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/beego.go b/beego.go index 042a4270..b79e0e3f 100644 --- a/beego.go +++ b/beego.go @@ -100,30 +100,3 @@ func initBeforeHttpRun() { } } } - -// SetViewsPath sets view directory path in beego application. -func SetViewsPath(path string) *App { - ViewsPath = path - return BeeApp -} - -// SetStaticPath sets static directory path and proper url pattern in beego application. -// if beego.SetStaticPath("static","public"), visit /static/* to load static file in folder "public". -func SetStaticPath(url string, path string) *App { - if !strings.HasPrefix(url, "/") { - url = "/" + url - } - url = strings.TrimRight(url, "/") - StaticDir[url] = path - return BeeApp -} - -// DelStaticPath removes the static folder setting in this url pattern in beego application. -func DelStaticPath(url string) *App { - if !strings.HasPrefix(url, "/") { - url = "/" + url - } - url = strings.TrimRight(url, "/") - delete(StaticDir, url) - return BeeApp -} diff --git a/template.go b/template.go index fdd9dc37..e976886a 100644 --- a/template.go +++ b/template.go @@ -128,7 +128,7 @@ func AddTemplateExt(ext string) { // build all template files in a directory. // it makes beego can render any template file in view directory. -func BuildTemplate(dir string, files... string) error { +func BuildTemplate(dir string, files ...string) error { if _, err := os.Stat(dir); err != nil { if os.IsNotExist(err) { return nil @@ -149,7 +149,7 @@ func BuildTemplate(dir string, files... string) error { } for _, v := range self.files { for _, file := range v { - if (len(files) == 0 || utils.InSlice(file, files)) { + if len(files) == 0 || utils.InSlice(file, files) { t, err := getTemplate(self.root, file, v...) if err != nil { Trace("parse template err:", file, err) @@ -263,3 +263,30 @@ func _getTemplate(t0 *template.Template, root string, submods [][]string, others } return } + +// SetViewsPath sets view directory path in beego application. +func SetViewsPath(path string) *App { + ViewsPath = path + return BeeApp +} + +// SetStaticPath sets static directory path and proper url pattern in beego application. +// if beego.SetStaticPath("static","public"), visit /static/* to load static file in folder "public". +func SetStaticPath(url string, path string) *App { + if !strings.HasPrefix(url, "/") { + url = "/" + url + } + url = strings.TrimRight(url, "/") + StaticDir[url] = path + return BeeApp +} + +// DelStaticPath removes the static folder setting in this url pattern in beego application. +func DelStaticPath(url string) *App { + if !strings.HasPrefix(url, "/") { + url = "/" + url + } + url = strings.TrimRight(url, "/") + delete(StaticDir, url) + return BeeApp +} From fe9c52fb69b226b177c6ae1732038497cc60c120 Mon Sep 17 00:00:00 2001 From: astaxie Date: Mon, 7 Sep 2015 19:27:53 +0800 Subject: [PATCH 42/55] optimize init admin --- beego.go | 36 ++++++++++++++++-------------------- hooks.go | 7 +++++++ 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/beego.go b/beego.go index b79e0e3f..81df5752 100644 --- a/beego.go +++ b/beego.go @@ -54,27 +54,9 @@ func Run(params ...string) { } } - if EnableAdmin { - go beeAdminApp.Run() - } - BeeApp.Run() } -// this function is for test package init -func TestBeegoInit(apppath string) { - AppPath = apppath - os.Setenv("BEEGO_RUNMODE", "test") - AppConfigPath = filepath.Join(AppPath, "conf", "app.conf") - err := ParseConfig() - if err != nil && !os.IsNotExist(err) { - // for init if doesn't have app.conf will not panic - Info(err) - } - os.Chdir(AppPath) - initBeforeHttpRun() -} - func initBeforeHttpRun() { // if AppConfigPath not In the conf/app.conf reParse config if AppConfigPath != filepath.Join(AppPath, "conf", "app.conf") { @@ -91,12 +73,26 @@ func initBeforeHttpRun() { AddAPPStartHook(registerSession) AddAPPStartHook(registerDocs) AddAPPStartHook(registerTemplate) + AddAPPStartHook(registerAdmin) // do hooks function for _, hk := range hooks { - err := hk() - if err != nil { + if err := hk(); err != nil { panic(err) } } } + +// this function is for test package init +func TestBeegoInit(apppath string) { + AppPath = apppath + os.Setenv("BEEGO_RUNMODE", "test") + AppConfigPath = filepath.Join(AppPath, "conf", "app.conf") + err := ParseConfig() + if err != nil && !os.IsNotExist(err) { + // for init if doesn't have app.conf will not panic + Info(err) + } + os.Chdir(AppPath) + initBeforeHttpRun() +} diff --git a/hooks.go b/hooks.go index ded0d794..78aec636 100644 --- a/hooks.go +++ b/hooks.go @@ -98,3 +98,10 @@ func registerDocs() error { } return nil } + +func registerAdmin() error { + if EnableAdmin { + go beeAdminApp.Run() + } + return nil +} From 919675e7935293772a593a3bb6e37eeceb09157c Mon Sep 17 00:00:00 2001 From: astaxie Date: Mon, 7 Sep 2015 19:29:52 +0800 Subject: [PATCH 43/55] update the comments --- beego.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/beego.go b/beego.go index 81df5752..d5d66c13 100644 --- a/beego.go +++ b/beego.go @@ -67,7 +67,7 @@ func initBeforeHttpRun() { } } - //init mime + //init hooks AddAPPStartHook(registerMime) AddAPPStartHook(registerDefaultErrorHandler) AddAPPStartHook(registerSession) @@ -75,7 +75,6 @@ func initBeforeHttpRun() { AddAPPStartHook(registerTemplate) AddAPPStartHook(registerAdmin) - // do hooks function for _, hk := range hooks { if err := hk(); err != nil { panic(err) From 152127c2af9f56f376b0e1931f14721031e7dc2d Mon Sep 17 00:00:00 2001 From: astaxie Date: Mon, 7 Sep 2015 21:38:53 +0800 Subject: [PATCH 44/55] make golint happy --- admin.go | 4 ++-- app.go | 21 +++++++++++---------- beego.go | 11 ++++++----- hooks.go | 3 +-- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/admin.go b/admin.go index 64d7fe34..583eadfc 100644 --- a/admin.go +++ b/admin.go @@ -314,14 +314,14 @@ func profIndex(rw http.ResponseWriter, r *http.Request) { data["Content"] = result.String() if format == "json" && command == "gc summary" { - dataJson, err := json.Marshal(data) + dataJSON, err := json.Marshal(data) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } rw.Header().Set("Content-Type", "application/json") - rw.Write(dataJson) + rw.Write(dataJSON) return } diff --git a/app.go b/app.go index 96e2ad2c..c340bcbe 100644 --- a/app.go +++ b/app.go @@ -28,6 +28,7 @@ import ( ) var ( + // BeeApp is an application instance BeeApp *App ) @@ -202,7 +203,7 @@ func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *A return BeeApp } -// Router add list from +// Include will generate router file in the router/xxx.go from the controller's comments // usage: // beego.Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{}) // type BankAccount struct{ @@ -261,7 +262,7 @@ func AutoPrefix(prefix string, c ControllerInterface) *App { return BeeApp } -// register router for Get method +// Get used to register router for Get method // usage: // beego.Get("/", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -271,7 +272,7 @@ func Get(rootpath string, f FilterFunc) *App { return BeeApp } -// register router for Post method +// Post used to register router for Post method // usage: // beego.Post("/api", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -281,7 +282,7 @@ func Post(rootpath string, f FilterFunc) *App { return BeeApp } -// register router for Delete method +// Delete used to register router for Delete method // usage: // beego.Delete("/api", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -291,7 +292,7 @@ func Delete(rootpath string, f FilterFunc) *App { return BeeApp } -// register router for Put method +// Put used to register router for Put method // usage: // beego.Put("/api", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -301,7 +302,7 @@ func Put(rootpath string, f FilterFunc) *App { return BeeApp } -// register router for Head method +// Head used to register router for Head method // usage: // beego.Head("/api", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -311,7 +312,7 @@ func Head(rootpath string, f FilterFunc) *App { return BeeApp } -// register router for Options method +// Options used to register router for Options method // usage: // beego.Options("/api", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -321,7 +322,7 @@ func Options(rootpath string, f FilterFunc) *App { return BeeApp } -// register router for Patch method +// Patch used to register router for Patch method // usage: // beego.Patch("/api", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -331,7 +332,7 @@ func Patch(rootpath string, f FilterFunc) *App { return BeeApp } -// register router for all method +// Any used to register router for all methods // usage: // beego.Any("/api", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -341,7 +342,7 @@ func Any(rootpath string, f FilterFunc) *App { return BeeApp } -// register router for own Handler +// Handler used to register a Handler router // usage: // beego.Handler("/api", func(ctx *context.Context){ // ctx.Output.Body("hello world") diff --git a/beego.go b/beego.go index d5d66c13..06d53750 100644 --- a/beego.go +++ b/beego.go @@ -31,7 +31,8 @@ var ( hooks = make([]hookfunc, 0) //hook function slice to store the hookfunc ) -// The hookfunc will run in beego.Run() +// AddAPPStartHook is used to register the hookfunc +// The hookfuncs will run in beego.Run() // such as sessionInit, middlerware start, buildtemplate, admin start func AddAPPStartHook(hf hookfunc) { hooks = append(hooks, hf) @@ -42,7 +43,7 @@ func AddAPPStartHook(hf hookfunc) { // beego.Run(":8089") // beego.Run("127.0.0.1:8089") func Run(params ...string) { - initBeforeHttpRun() + initBeforeHTTPRun() if len(params) > 0 && params[0] != "" { strs := strings.Split(params[0], ":") @@ -57,7 +58,7 @@ func Run(params ...string) { BeeApp.Run() } -func initBeforeHttpRun() { +func initBeforeHTTPRun() { // if AppConfigPath not In the conf/app.conf reParse config if AppConfigPath != filepath.Join(AppPath, "conf", "app.conf") { err := ParseConfig() @@ -82,7 +83,7 @@ func initBeforeHttpRun() { } } -// this function is for test package init +// TestBeegoInit is for test package init func TestBeegoInit(apppath string) { AppPath = apppath os.Setenv("BEEGO_RUNMODE", "test") @@ -93,5 +94,5 @@ func TestBeegoInit(apppath string) { Info(err) } os.Chdir(AppPath) - initBeforeHttpRun() + initBeforeHTTPRun() } diff --git a/hooks.go b/hooks.go index 78aec636..526913c3 100644 --- a/hooks.go +++ b/hooks.go @@ -71,8 +71,7 @@ func registerSession() error { `"domain":"` + SessionDomain + `",` + `"cookieLifeTime":` + strconv.Itoa(SessionCookieLifeTime) + `}` } - GlobalSessions, err = session.NewManager(SessionProvider, - sessionConfig) + GlobalSessions, err = session.NewManager(SessionProvider, sessionConfig) if err != nil { return err } From f28a941e267d4c416eae6aaca032a1dc05a3f401 Mon Sep 17 00:00:00 2001 From: astaxie Date: Mon, 7 Sep 2015 23:19:42 +0800 Subject: [PATCH 45/55] make golint happy and also make the config readable --- admin.go | 28 +++---- app.go | 44 +++++----- beego.go | 4 +- config.go | 235 +++++++++++++++++++++++++++++++++--------------------- hooks.go | 4 +- router.go | 4 +- 6 files changed, 185 insertions(+), 134 deletions(-) diff --git a/admin.go b/admin.go index 583eadfc..93087e12 100644 --- a/admin.go +++ b/admin.go @@ -101,11 +101,11 @@ func listConf(rw http.ResponseWriter, r *http.Request) { m["AppConfigPath"] = AppConfigPath m["StaticDir"] = StaticDir m["StaticExtensionsToGzip"] = StaticExtensionsToGzip - m["HttpAddr"] = HttpAddr - m["HttpPort"] = HttpPort - m["HttpTLS"] = EnableHttpTLS - m["HttpCertFile"] = HttpCertFile - m["HttpKeyFile"] = HttpKeyFile + m["HTTPAddr"] = HTTPAddr + m["HTTPPort"] = HTTPPort + m["HTTPTLS"] = EnableHTTPTLS + m["HTTPCertFile"] = HTTPCertFile + m["HTTPKeyFile"] = HTTPKeyFile m["RecoverPanic"] = RecoverPanic m["AutoRender"] = AutoRender m["ViewsPath"] = ViewsPath @@ -114,14 +114,14 @@ func listConf(rw http.ResponseWriter, r *http.Request) { m["SessionProvider"] = SessionProvider m["SessionName"] = SessionName m["SessionGCMaxLifetime"] = SessionGCMaxLifetime - m["SessionSavePath"] = SessionSavePath + m["SessionProviderConfig"] = SessionProviderConfig m["SessionCookieLifeTime"] = SessionCookieLifeTime - m["UseFcgi"] = UseFcgi + m["EnabelFcgi"] = EnabelFcgi m["MaxMemory"] = MaxMemory m["EnableGzip"] = EnableGzip m["DirectoryIndex"] = DirectoryIndex - m["HttpServerTimeOut"] = HttpServerTimeOut - m["ErrorsShow"] = ErrorsShow + m["HTTPServerTimeOut"] = HTTPServerTimeOut + m["EnableErrorsShow"] = EnableErrorsShow m["XSRFKEY"] = XSRFKEY m["EnableXSRF"] = EnableXSRF m["XSRFExpire"] = XSRFExpire @@ -130,8 +130,8 @@ func listConf(rw http.ResponseWriter, r *http.Request) { m["TemplateRight"] = TemplateRight m["BeegoServerName"] = BeegoServerName m["EnableAdmin"] = EnableAdmin - m["AdminHttpAddr"] = AdminHttpAddr - m["AdminHttpPort"] = AdminHttpPort + m["AdminHTTPAddr"] = AdminHTTPAddr + m["AdminHTTPPort"] = AdminHTTPPort tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl)) tmpl = template.Must(tmpl.Parse(configTpl)) @@ -451,10 +451,10 @@ func (admin *adminApp) Run() { if len(toolbox.AdminTaskList) > 0 { toolbox.StartTask() } - addr := AdminHttpAddr + addr := AdminHTTPAddr - if AdminHttpPort != 0 { - addr = fmt.Sprintf("%s:%d", AdminHttpAddr, AdminHttpPort) + if AdminHTTPPort != 0 { + addr = fmt.Sprintf("%s:%d", AdminHTTPAddr, AdminHTTPPort) } for p, f := range admin.routers { http.Handle(p, f) diff --git a/app.go b/app.go index c340bcbe..d10d436c 100644 --- a/app.go +++ b/app.go @@ -52,10 +52,10 @@ func NewApp() *App { // Run beego application. func (app *App) Run() { - addr := HttpAddr + addr := HTTPAddr - if HttpPort != 0 { - addr = fmt.Sprintf("%s:%d", HttpAddr, HttpPort) + if HTTPPort != 0 { + addr = fmt.Sprintf("%s:%d", HTTPAddr, HTTPPort) } var ( @@ -64,8 +64,8 @@ func (app *App) Run() { ) endRunning := make(chan bool, 1) - if UseFcgi { - if UseStdIo { + if EnabelFcgi { + if EnableStdIo { err = fcgi.Serve(nil, app.Handlers) // standard I/O if err == nil { BeeLogger.Info("Use FCGI via standard I/O") @@ -73,7 +73,7 @@ func (app *App) Run() { BeeLogger.Info("Cannot use FCGI via standard I/O", err) } } else { - if HttpPort == 0 { + if HTTPPort == 0 { // remove the Socket file before start if utils.FileExists(addr) { os.Remove(addr) @@ -91,18 +91,18 @@ func (app *App) Run() { if Graceful { app.Server.Addr = addr app.Server.Handler = app.Handlers - app.Server.ReadTimeout = time.Duration(HttpServerTimeOut) * time.Second - app.Server.WriteTimeout = time.Duration(HttpServerTimeOut) * time.Second - if EnableHttpTLS { + app.Server.ReadTimeout = time.Duration(HTTPServerTimeOut) * time.Second + app.Server.WriteTimeout = time.Duration(HTTPServerTimeOut) * time.Second + if EnableHTTPTLS { go func() { time.Sleep(20 * time.Microsecond) - if HttpsPort != 0 { - addr = fmt.Sprintf("%s:%d", HttpAddr, HttpsPort) + if HTTPSPort != 0 { + addr = fmt.Sprintf("%s:%d", HTTPAddr, HTTPSPort) app.Server.Addr = addr } server := grace.NewServer(addr, app.Handlers) server.Server = app.Server - err := server.ListenAndServeTLS(HttpCertFile, HttpKeyFile) + err := server.ListenAndServeTLS(HTTPCertFile, HTTPKeyFile) if err != nil { BeeLogger.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid())) time.Sleep(100 * time.Microsecond) @@ -110,11 +110,11 @@ func (app *App) Run() { } }() } - if EnableHttpListen { + if EnableHTTPListen { go func() { server := grace.NewServer(addr, app.Handlers) server.Server = app.Server - if ListenTCP4 && HttpAddr == "" { + if ListenTCP4 && HTTPAddr == "" { server.Network = "tcp4" } err := server.ListenAndServe() @@ -128,17 +128,17 @@ func (app *App) Run() { } else { app.Server.Addr = addr app.Server.Handler = app.Handlers - app.Server.ReadTimeout = time.Duration(HttpServerTimeOut) * time.Second - app.Server.WriteTimeout = time.Duration(HttpServerTimeOut) * time.Second + app.Server.ReadTimeout = time.Duration(HTTPServerTimeOut) * time.Second + app.Server.WriteTimeout = time.Duration(HTTPServerTimeOut) * time.Second - if EnableHttpTLS { + if EnableHTTPTLS { go func() { time.Sleep(20 * time.Microsecond) - if HttpsPort != 0 { - app.Server.Addr = fmt.Sprintf("%s:%d", HttpAddr, HttpsPort) + if HTTPSPort != 0 { + app.Server.Addr = fmt.Sprintf("%s:%d", HTTPAddr, HTTPSPort) } BeeLogger.Info("https server Running on %s", app.Server.Addr) - err := app.Server.ListenAndServeTLS(HttpCertFile, HttpKeyFile) + err := app.Server.ListenAndServeTLS(HTTPCertFile, HTTPKeyFile) if err != nil { BeeLogger.Critical("ListenAndServeTLS: ", err) time.Sleep(100 * time.Microsecond) @@ -147,11 +147,11 @@ func (app *App) Run() { }() } - if EnableHttpListen { + if EnableHTTPListen { go func() { app.Server.Addr = addr BeeLogger.Info("http server Running on %s", app.Server.Addr) - if ListenTCP4 && HttpAddr == "" { + if ListenTCP4 && HTTPAddr == "" { ln, err := net.Listen("tcp4", app.Server.Addr) if err != nil { BeeLogger.Critical("ListenAndServe: ", err) diff --git a/beego.go b/beego.go index 06d53750..329e0713 100644 --- a/beego.go +++ b/beego.go @@ -48,10 +48,10 @@ func Run(params ...string) { if len(params) > 0 && params[0] != "" { strs := strings.Split(params[0], ":") if len(strs) > 0 && strs[0] != "" { - HttpAddr = strs[0] + HTTPAddr = strs[0] } if len(strs) > 1 && strs[1] != "" { - HttpPort, _ = strconv.Atoi(strs[1]) + HTTPPort, _ = strconv.Atoi(strs[1]) } } diff --git a/config.go b/config.go index 2bbd14f6..ae334cd7 100644 --- a/config.go +++ b/config.go @@ -29,59 +29,115 @@ import ( ) var ( - AppName string - AppPath string - workPath string - AppConfigPath string - StaticDir map[string]string - TemplateCache map[string]*template.Template // template caching map - StaticExtensionsToGzip []string // files with should be compressed with gzip (.js,.css,etc) - EnableHttpListen bool - HttpAddr string - HttpPort int - ListenTCP4 bool - EnableHttpTLS bool - HttpsPort int - HttpCertFile string - HttpKeyFile string - RecoverPanic bool // flag of auto recover panic - AutoRender bool // flag of render template automatically - ViewsPath string - AppConfig *beegoAppConfig - RunMode string // run mode, "dev" or "prod" - GlobalSessions *session.Manager // global session mananger - SessionOn bool // flag of starting session auto. default is false. - SessionProvider string // default session provider, memory, mysql , redis ,etc. - SessionName string // the cookie name when saving session id into cookie. - SessionGCMaxLifetime int64 // session gc time for auto cleaning expired session. - SessionSavePath string // if use mysql/redis/file provider, define save path to connection info. - SessionCookieLifeTime int // the life time of session id in cookie. - SessionAutoSetCookie bool // auto setcookie - SessionDomain string // the cookie domain default is empty - UseFcgi bool - UseStdIo bool - MaxMemory int64 - EnableGzip bool // flag of enable gzip - DirectoryIndex bool // flag of display directory index. default is false. - HttpServerTimeOut int64 - ErrorsShow bool // flag of show errors in page. if true, show error and trace info in page rendered with error template. - XSRFKEY string // xsrf hash salt string. - EnableXSRF bool // flag of enable xsrf. - XSRFExpire int // the expiry of xsrf value. - CopyRequestBody bool // flag of copy raw request body in context. - TemplateLeft string - TemplateRight string - BeegoServerName string // beego server name exported in response header. - EnableAdmin bool // flag of enable admin module to log every request info. - AdminHttpAddr string // http server configurations for admin module. - AdminHttpPort int - FlashName string // name of the flash variable found in response header and cookie - FlashSeperator string // used to seperate flash key:value - AppConfigProvider string // config provider - EnableDocs bool // enable generate docs & server docs API Swagger - RouterCaseSensitive bool // router case sensitive default is true - AccessLogs bool // print access logs, default is false - Graceful bool // use graceful start the server + // AccessLogs represent whether output the access logs, default is false + AccessLogs bool + // AdminHTTPAddr is address for admin + AdminHTTPAddr string + // AdminHTTPPort is listens port for admin + AdminHTTPPort int + // AppConfig is the instance of Config, store the config information from file + AppConfig *beegoAppConfig + // AppName represent Application name, always the project folder name + AppName string + // AppPath is the path to the application + AppPath string + // AppConfigPath is the path to the config files + AppConfigPath string + // AppConfigProvider is the provider for the config, default is ini + AppConfigProvider string + // AutoRender is a flag of render template automatically. It's always turn off in API application + // default is true + AutoRender bool + // BeegoServerName exported in response header. + BeegoServerName string + // CopyRequestBody is just useful for raw request body in context. default is false + CopyRequestBody bool + // DirectoryIndex wheather display directory index. default is false. + DirectoryIndex bool + // EnableAdmin means turn on admin module to log every request info. + EnableAdmin bool + // EnableDocs enable generate docs & server docs API Swagger + EnableDocs bool + // EnableErrorsShow wheather show errors in page. if true, show error and trace info in page rendered with error template. + EnableErrorsShow bool + // EnabelFcgi turn on the fcgi Listen, default is false + EnabelFcgi bool + // EnableGzip means gzip the response + EnableGzip bool + // EnableHTTPListen represent whether turn on the HTTP, default is true + EnableHTTPListen bool + // EnableHTTPTLS represent whether turn on the HTTPS, default is true + EnableHTTPTLS bool + // EnableStdIo works with EnabelFcgi Use FCGI via standard I/O + EnableStdIo bool + // EnableXSRF whether turn on xsrf. default is false + EnableXSRF bool + // FlashName is the name of the flash variable found in response header and cookie + FlashName string + // FlashSeperator used to seperate flash key:value, default is BEEGOFLASH + FlashSeperator string + // GlobalSessions is the instance for the session manager + GlobalSessions *session.Manager + // Graceful means use graceful module to start the server + Graceful bool + // workPath is always the same as AppPath, but sometime when it started with other + // program, like supervisor + workPath string + // ListenTCP4 represent only Listen in TCP4, default is false + ListenTCP4 bool + // MaxMemory The whole request body is parsed and up to a total of maxMemory + // bytes of its file parts are stored in memory, with the remainder stored on disk in temporary files + MaxMemory int64 + // HTTPAddr is the TCP network address addr for HTTP + HTTPAddr string + // HTTPPort is listens port for HTTP + HTTPPort int + // HTTPSPort is listens port for HTTPS + HTTPSPort int + // HTTPCertFile is the path to certificate file + HTTPCertFile string + // HTTPKeyFile is the path to private key file + HTTPKeyFile string + // HTTPServerTimeOut HTTP server timeout. default is 0, no timeout + HTTPServerTimeOut int64 + // RecoverPanic is a flag for auto recover panic, default is true + RecoverPanic bool + // RouterCaseSensitive means whether router case sensitive, default is true + RouterCaseSensitive bool + // RunMode represent the staging, "dev" or "prod" + RunMode string + // SessionOn means whether turn on the session auto when application started. default is false. + SessionOn bool + // SessionProvider means session provider, e.q memory, mysql, redis,etc. + SessionProvider string + // SessionName is the cookie name when saving session id into cookie. + SessionName string + // SessionGCMaxLifetime for auto cleaning expired session. + SessionGCMaxLifetime int64 + // SessionProviderConfig is for the provider config, define save path or connection info. + SessionProviderConfig string + // SessionCookieLifeTime means the life time of session id in cookie. + SessionCookieLifeTime int + // SessionAutoSetCookie auto setcookie + SessionAutoSetCookie bool + // SessionDomain means the cookie domain default is empty + SessionDomain string + // StaticDir store the static path, key is path, value is the folder + StaticDir map[string]string + // StaticExtensionsToGzip stores the extensions which need to gzip(.js,.css,etc) + StaticExtensionsToGzip []string + // TemplateCache store the caching template + TemplateCache map[string]*template.Template + // TemplateLeft left delimiter + TemplateLeft string + // TemplateRight right delimiter + TemplateRight string + // ViewsPath means the template folder + ViewsPath string + // XSRFKEY xsrf hash salt string. + XSRFKEY string + // XSRFExpire is the expiry of xsrf value. + XSRFExpire int ) type beegoAppConfig struct { @@ -239,12 +295,12 @@ func init() { TemplateCache = make(map[string]*template.Template) // set this to 0.0.0.0 to make this app available to externally - EnableHttpListen = true //default enable http Listen + EnableHTTPListen = true //default enable http Listen - HttpAddr = "" - HttpPort = 8080 + HTTPAddr = "" + HTTPPort = 8080 - HttpsPort = 10443 + HTTPSPort = 10443 AppName = "beego" @@ -260,20 +316,15 @@ func init() { SessionProvider = "memory" SessionName = "beegosessionID" SessionGCMaxLifetime = 3600 - SessionSavePath = "" + SessionProviderConfig = "" SessionCookieLifeTime = 0 //set cookie default is the brower life SessionAutoSetCookie = true - UseFcgi = false - UseStdIo = false - MaxMemory = 1 << 26 //64MB - EnableGzip = false + HTTPServerTimeOut = 0 - HttpServerTimeOut = 0 - - ErrorsShow = true + EnableErrorsShow = true XSRFKEY = "beegoxsrf" XSRFExpire = 0 @@ -284,8 +335,8 @@ func init() { BeegoServerName = "beegoServer:" + VERSION EnableAdmin = false - AdminHttpAddr = "127.0.0.1" - AdminHttpPort = 8088 + AdminHTTPAddr = "127.0.0.1" + AdminHTTPPort = 8088 FlashName = "BEEGO_FLASH" FlashSeperator = "BEEGOFLASH" @@ -326,18 +377,18 @@ func ParseConfig() (err error) { RunMode = runmode } - HttpAddr = AppConfig.String("HttpAddr") + HTTPAddr = AppConfig.String("HTTPAddr") - if v, err := AppConfig.Int("HttpPort"); err == nil { - HttpPort = v + if v, err := AppConfig.Int("HTTPPort"); err == nil { + HTTPPort = v } if v, err := AppConfig.Bool("ListenTCP4"); err == nil { ListenTCP4 = v } - if v, err := AppConfig.Bool("EnableHttpListen"); err == nil { - EnableHttpListen = v + if v, err := AppConfig.Bool("EnableHTTPListen"); err == nil { + EnableHTTPListen = v } if maxmemory, err := AppConfig.Int64("MaxMemory"); err == nil { @@ -372,8 +423,8 @@ func ParseConfig() (err error) { SessionName = sessName } - if sesssavepath := AppConfig.String("SessionSavePath"); sesssavepath != "" { - SessionSavePath = sesssavepath + if sessProvConfig := AppConfig.String("SessionProviderConfig"); sessProvConfig != "" { + SessionProviderConfig = sessProvConfig } if sessMaxLifeTime, err := AppConfig.Int64("SessionGCMaxLifetime"); err == nil && sessMaxLifeTime != 0 { @@ -384,8 +435,8 @@ func ParseConfig() (err error) { SessionCookieLifeTime = sesscookielifetime } - if usefcgi, err := AppConfig.Bool("UseFcgi"); err == nil { - UseFcgi = usefcgi + if enabelFcgi, err := AppConfig.Bool("EnabelFcgi"); err == nil { + EnabelFcgi = enabelFcgi } if enablegzip, err := AppConfig.Bool("EnableGzip"); err == nil { @@ -396,12 +447,12 @@ func ParseConfig() (err error) { DirectoryIndex = directoryindex } - if timeout, err := AppConfig.Int64("HttpServerTimeOut"); err == nil { - HttpServerTimeOut = timeout + if timeout, err := AppConfig.Int64("HTTPServerTimeOut"); err == nil { + HTTPServerTimeOut = timeout } - if errorsshow, err := AppConfig.Bool("ErrorsShow"); err == nil { - ErrorsShow = errorsshow + if errorsshow, err := AppConfig.Bool("EnableErrorsShow"); err == nil { + EnableErrorsShow = errorsshow } if copyrequestbody, err := AppConfig.Bool("CopyRequestBody"); err == nil { @@ -428,20 +479,20 @@ func ParseConfig() (err error) { TemplateRight = tplright } - if httptls, err := AppConfig.Bool("EnableHttpTLS"); err == nil { - EnableHttpTLS = httptls + if httptls, err := AppConfig.Bool("EnableHTTPTLS"); err == nil { + EnableHTTPTLS = httptls } - if httpsport, err := AppConfig.Int("HttpsPort"); err == nil { - HttpsPort = httpsport + if httpsport, err := AppConfig.Int("HTTPSPort"); err == nil { + HTTPSPort = httpsport } - if certfile := AppConfig.String("HttpCertFile"); certfile != "" { - HttpCertFile = certfile + if certfile := AppConfig.String("HTTPCertFile"); certfile != "" { + HTTPCertFile = certfile } - if keyfile := AppConfig.String("HttpKeyFile"); keyfile != "" { - HttpKeyFile = keyfile + if keyfile := AppConfig.String("HTTPKeyFile"); keyfile != "" { + HTTPKeyFile = keyfile } if serverName := AppConfig.String("BeegoServerName"); serverName != "" { @@ -491,12 +542,12 @@ func ParseConfig() (err error) { EnableAdmin = enableadmin } - if adminhttpaddr := AppConfig.String("AdminHttpAddr"); adminhttpaddr != "" { - AdminHttpAddr = adminhttpaddr + if adminhttpaddr := AppConfig.String("AdminHTTPAddr"); adminhttpaddr != "" { + AdminHTTPAddr = adminhttpaddr } - if adminhttpport, err := AppConfig.Int("AdminHttpPort"); err == nil { - AdminHttpPort = adminhttpport + if adminhttpport, err := AppConfig.Int("AdminHTTPPort"); err == nil { + AdminHTTPPort = adminhttpport } if enabledocs, err := AppConfig.Bool("EnableDocs"); err == nil { diff --git a/hooks.go b/hooks.go index 526913c3..3691a800 100644 --- a/hooks.go +++ b/hooks.go @@ -65,8 +65,8 @@ func registerSession() error { if sessionConfig == "" { sessionConfig = `{"cookieName":"` + SessionName + `",` + `"gclifetime":` + strconv.FormatInt(SessionGCMaxLifetime, 10) + `,` + - `"providerConfig":"` + filepath.ToSlash(SessionSavePath) + `",` + - `"secure":` + strconv.FormatBool(EnableHttpTLS) + `,` + + `"providerConfig":"` + filepath.ToSlash(SessionProviderConfig) + `",` + + `"secure":` + strconv.FormatBool(EnableHTTPTLS) + `,` + `"enableSetCookie":` + strconv.FormatBool(SessionAutoSetCookie) + `,` + `"domain":"` + SessionDomain + `",` + `"cookieLifeTime":` + strconv.Itoa(SessionCookieLifeTime) + `}` diff --git a/router.go b/router.go index 7cce86fe..4ac6cb5b 100644 --- a/router.go +++ b/router.go @@ -617,7 +617,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) if ok, params := filterR.ValidRouter(urlPath); ok { for k, v := range params { if context.Input.Params == nil { - context.Input.Params = make(map[string]string) + context.Input.Params = make(map[string]string) } context.Input.Params[k] = v } @@ -869,7 +869,7 @@ func (p *ControllerRegister) recoverPanic(context *beecontext.Context) { if !RecoverPanic { panic(err) } else { - if ErrorsShow { + if EnableErrorsShow { if _, ok := ErrorMaps[fmt.Sprint(err)]; ok { exception(fmt.Sprint(err), context) return From 61570ac2f7b429220a9b2603bec299bb560aa8ab Mon Sep 17 00:00:00 2001 From: astaxie Date: Tue, 8 Sep 2015 10:43:42 +0800 Subject: [PATCH 46/55] make golint happy with controller.go --- controller.go | 132 +++++++++++++++++++++++------------------------- router.go | 2 +- template.go | 2 +- templatefunc.go | 30 +++++------ 4 files changed, 80 insertions(+), 86 deletions(-) diff --git a/controller.go b/controller.go index 65b311b6..cad2b5ac 100644 --- a/controller.go +++ b/controller.go @@ -34,18 +34,19 @@ import ( //commonly used mime-types const ( - applicationJson = "application/json" - applicationXml = "application/xml" - textXml = "text/xml" + applicationJSON = "application/json" + applicationXML = "application/xml" + textXML = "text/xml" ) var ( - // custom error when user stop request handler manually. - USERSTOPRUN = errors.New("User stop run") - GlobalControllerRouter map[string][]ControllerComments = make(map[string][]ControllerComments) //pkgpath+controller:comments + // ErrAbort custom error when user stop request handler manually. + ErrAbort = errors.New("User stop run") + // GlobalControllerRouter store comments with controller. pkgpath+controller:comments + GlobalControllerRouter = make(map[string][]ControllerComments) ) -// store the comment for the controller method +// ControllerComments store the comment for the controller method type ControllerComments struct { Method string Router string @@ -64,7 +65,7 @@ type Controller struct { Layout string LayoutSections map[string]string // the key is the section name and the value is the template name TplExt string - _xsrf_token string + _xsrfToken string gotofunc string CruSession session.SessionStore XSRFExpire int @@ -153,20 +154,20 @@ func (c *Controller) Options() { http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) } -// call function fn +// HandlerFunc call function with the name func (c *Controller) HandlerFunc(fnname string) bool { if v, ok := c.methodMapping[fnname]; ok { v() return true - } else { - return false } + return false } // URLMapping register the internal Controller router. func (c *Controller) URLMapping() { } +// Mapping the method to function func (c *Controller) Mapping(method string, fn func()) { c.methodMapping[method] = fn } @@ -177,13 +178,11 @@ func (c *Controller) Render() error { return nil } rb, err := c.RenderBytes() - if err != nil { return err - } else { - c.Ctx.Output.Header("Content-Type", "text/html; charset=utf-8") - c.Ctx.Output.Body(rb) } + c.Ctx.Output.Header("Content-Type", "text/html; charset=utf-8") + c.Ctx.Output.Body(rb) return nil } @@ -200,7 +199,7 @@ func (c *Controller) RenderBytes() ([]byte, error) { if c.TplNames == "" { c.TplNames = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt } - + if RunMode == "dev" { buildFiles := make([]string, 1) buildFiles = append(buildFiles, c.TplNames) @@ -252,25 +251,25 @@ func (c *Controller) RenderBytes() ([]byte, error) { } icontent, _ := ioutil.ReadAll(ibytes) return icontent, nil - } else { - if c.TplNames == "" { - c.TplNames = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt - } - if RunMode == "dev" { - BuildTemplate(ViewsPath, c.TplNames) - } - ibytes := bytes.NewBufferString("") - if _, ok := BeeTemplates[c.TplNames]; !ok { - panic("can't find templatefile in the path:" + c.TplNames) - } - err := BeeTemplates[c.TplNames].ExecuteTemplate(ibytes, c.TplNames, c.Data) - if err != nil { - Trace("template Execute err:", err) - return nil, err - } - icontent, _ := ioutil.ReadAll(ibytes) - return icontent, nil } + + if c.TplNames == "" { + c.TplNames = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt + } + if RunMode == "dev" { + BuildTemplate(ViewsPath, c.TplNames) + } + ibytes := bytes.NewBufferString("") + if _, ok := BeeTemplates[c.TplNames]; !ok { + panic("can't find templatefile in the path:" + c.TplNames) + } + err := BeeTemplates[c.TplNames].ExecuteTemplate(ibytes, c.TplNames, c.Data) + if err != nil { + Trace("template Execute err:", err) + return nil, err + } + icontent, _ := ioutil.ReadAll(ibytes) + return icontent, nil } // Redirect sends the redirection response to url with status code. @@ -278,7 +277,7 @@ func (c *Controller) Redirect(url string, code int) { c.Ctx.Redirect(code, url) } -// Aborts stops controller handler and show the error data if code is defined in ErrorMap or code string. +// Abort stops controller handler and show the error data if code is defined in ErrorMap or code string. func (c *Controller) Abort(code string) { status, err := strconv.Atoi(code) if err != nil { @@ -296,29 +295,28 @@ func (c *Controller) CustomAbort(status int, body string) { } // last panic user string c.Ctx.ResponseWriter.Write([]byte(body)) - panic(USERSTOPRUN) + panic(ErrAbort) } // StopRun makes panic of USERSTOPRUN error and go to recover function if defined. func (c *Controller) StopRun() { - panic(USERSTOPRUN) + panic(ErrAbort) } -// UrlFor does another controller handler in this request function. +// URLFor does another controller handler in this request function. // it goes to this controller method if endpoint is not clear. -func (c *Controller) UrlFor(endpoint string, values ...interface{}) string { +func (c *Controller) URLFor(endpoint string, values ...interface{}) string { if len(endpoint) <= 0 { return "" } if endpoint[0] == '.' { - return UrlFor(reflect.Indirect(reflect.ValueOf(c.AppController)).Type().Name()+endpoint, values...) - } else { - return UrlFor(endpoint, values...) + return URLFor(reflect.Indirect(reflect.ValueOf(c.AppController)).Type().Name()+endpoint, values...) } + return URLFor(endpoint, values...) } -// ServeJson sends a json response with encoding charset. -func (c *Controller) ServeJson(encoding ...bool) { +// ServeJSON sends a json response with encoding charset. +func (c *Controller) ServeJSON(encoding ...bool) { var hasIndent bool var hasencoding bool if RunMode == "prod" { @@ -332,8 +330,8 @@ func (c *Controller) ServeJson(encoding ...bool) { c.Ctx.Output.Json(c.Data["json"], hasIndent, hasencoding) } -// ServeJsonp sends a jsonp response. -func (c *Controller) ServeJsonp() { +// ServeJSONP sends a jsonp response. +func (c *Controller) ServeJSONP() { var hasIndent bool if RunMode == "prod" { hasIndent = false @@ -343,8 +341,8 @@ func (c *Controller) ServeJsonp() { c.Ctx.Output.Jsonp(c.Data["jsonp"], hasIndent) } -// ServeXml sends xml response. -func (c *Controller) ServeXml() { +// ServeXML sends xml response. +func (c *Controller) ServeXML() { var hasIndent bool if RunMode == "prod" { hasIndent = false @@ -358,12 +356,12 @@ func (c *Controller) ServeXml() { func (c *Controller) ServeFormatted() { accept := c.Ctx.Input.Header("Accept") switch accept { - case applicationJson: - c.ServeJson() - case applicationXml, textXml: - c.ServeXml() + case applicationJSON: + c.ServeJSON() + case applicationXML, textXML: + c.ServeXML() default: - c.ServeJson() + c.ServeJSON() } } @@ -389,9 +387,8 @@ func (c *Controller) GetString(key string, def ...string) string { if v := c.Ctx.Input.Query(key); v != "" { return v - } else { - return defv } + return defv } // GetStrings returns the input string slice by key string or the default value while it's present and input is blank @@ -410,9 +407,8 @@ func (c *Controller) GetStrings(key string, def ...[]string) []string { vs := f[key] if len(vs) > 0 { return vs - } else { - return defv } + return defv } // GetInt returns input as an int or the default value while it's present and input is blank @@ -586,7 +582,7 @@ func (c *Controller) GetSession(name interface{}) interface{} { return c.CruSession.Get(name) } -// SetSession removes value from session. +// DelSession removes value from session. func (c *Controller) DelSession(name interface{}) { if c.CruSession == nil { c.StartSession() @@ -625,34 +621,34 @@ func (c *Controller) SetSecureCookie(Secret, name, value string, others ...inter c.Ctx.SetSecureCookie(Secret, name, value, others...) } -// XsrfToken creates a xsrf token string and returns. -func (c *Controller) XsrfToken() string { - if c._xsrf_token == "" { +// XSRFToken creates a CSRF token string and returns. +func (c *Controller) XSRFToken() string { + if c._xsrfToken == "" { var expire int64 if c.XSRFExpire > 0 { expire = int64(c.XSRFExpire) } else { expire = int64(XSRFExpire) } - c._xsrf_token = c.Ctx.XsrfToken(XSRFKEY, expire) + c._xsrfToken = c.Ctx.XsrfToken(XSRFKEY, expire) } - return c._xsrf_token + return c._xsrfToken } -// CheckXsrfCookie checks xsrf token in this request is valid or not. +// CheckXSRFCookie checks xsrf token in this request is valid or not. // the token can provided in request header "X-Xsrftoken" and "X-CsrfToken" // or in form field value named as "_xsrf". -func (c *Controller) CheckXsrfCookie() bool { +func (c *Controller) CheckXSRFCookie() bool { if !c.EnableXSRF { return true } return c.Ctx.CheckXsrfCookie() } -// XsrfFormHtml writes an input field contains xsrf token value. -func (c *Controller) XsrfFormHtml() string { +// XSRFFormHTML writes an input field contains xsrf token value. +func (c *Controller) XSRFFormHTML() string { return "" + c._xsrfToken + "\"/>" } // GetControllerAndAction gets the executing controller name and action name. diff --git a/router.go b/router.go index 4ac6cb5b..6fbf90ea 100644 --- a/router.go +++ b/router.go @@ -863,7 +863,7 @@ Admin: func (p *ControllerRegister) recoverPanic(context *beecontext.Context) { if err := recover(); err != nil { - if err == USERSTOPRUN { + if err == ErrAbort { return } if !RecoverPanic { diff --git a/template.go b/template.go index e976886a..9403c71f 100644 --- a/template.go +++ b/template.go @@ -65,7 +65,7 @@ func init() { beegoTplFuncMap["lt"] = lt // < beegoTplFuncMap["ne"] = ne // != - beegoTplFuncMap["urlfor"] = UrlFor // != + beegoTplFuncMap["urlfor"] = URLFor // != } // AddFuncMap let user to register a func in the template. diff --git a/templatefunc.go b/templatefunc.go index d1f64f8a..1106e4d0 100644 --- a/templatefunc.go +++ b/templatefunc.go @@ -140,11 +140,11 @@ func Compare(a, b interface{}) (equal bool) { } func CompareNot(a, b interface{}) (equal bool) { - return ! Compare(a, b) + return !Compare(a, b) } func NotNil(a interface{}) (is_nil bool) { - return CompareNot(a, nil) + return CompareNot(a, nil) } func Config(returnType, key string, defaultVal interface{}) (value interface{}, err error) { @@ -237,14 +237,14 @@ func Htmlunquote(src string) string { return strings.TrimSpace(text) } -// UrlFor returns url string with another registered controller handler with params. +// URLFor returns url string with another registered controller handler with params. // usage: // -// UrlFor(".index") -// print UrlFor("index") +// URLFor(".index") +// print URLFor("index") // router /login -// print UrlFor("login") -// print UrlFor("login", "next","/"") +// print URLFor("login") +// print URLFor("login", "next","/"") // router /profile/:username // print UrlFor("profile", ":username","John Doe") // result: @@ -254,7 +254,7 @@ func Htmlunquote(src string) string { // /user/John%20Doe // // more detail http://beego.me/docs/mvc/controller/urlbuilding.md -func UrlFor(endpoint string, values ...interface{}) string { +func URLFor(endpoint string, values ...interface{}) string { return BeeApp.Handlers.UrlFor(endpoint, values...) } @@ -698,22 +698,21 @@ func MapGet(arg1 interface{}, arg2 ...interface{}) (interface{}, error) { storedVal := arg1Val.MapIndex(arg2Val) - if storedVal.IsValid() { var result interface{} switch arg1Type.Elem().Kind() { - case reflect.Bool: + case reflect.Bool: result = storedVal.Bool() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: result = storedVal.Int() - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: result = storedVal.Uint() - case reflect.Float32, reflect.Float64: + case reflect.Float32, reflect.Float64: result = storedVal.Float() - case reflect.String: + case reflect.String: result = storedVal.String() - default: + default: result = storedVal.Interface() } @@ -727,7 +726,6 @@ func MapGet(arg1 interface{}, arg2 ...interface{}) (interface{}, error) { return nil, nil } - } else { return nil, nil } From 67b36d7c487a163ce2496a9f7d38d6dc12090f36 Mon Sep 17 00:00:00 2001 From: astaxie Date: Tue, 8 Sep 2015 21:41:38 +0800 Subject: [PATCH 47/55] make golint happy --- controller.go | 4 +- doc.go | 2 +- docs.go | 9 +++-- error.go | 6 +-- filter.go | 3 +- flash_test.go | 2 +- hooks.go | 20 +++++----- log.go | 15 ++++--- memzipfile.go | 6 ++- mime.go | 2 +- namespace.go | 105 +++++++++++++++++++++++++------------------------ router.go | 4 +- router_test.go | 4 +- 13 files changed, 94 insertions(+), 88 deletions(-) diff --git a/controller.go b/controller.go index cad2b5ac..b225df03 100644 --- a/controller.go +++ b/controller.go @@ -88,8 +88,8 @@ type ControllerInterface interface { Options() Finish() Render() error - XsrfToken() string - CheckXsrfCookie() bool + XSRFToken() string + CheckXSRFCookie() bool HandlerFunc(fn string) bool URLMapping() } diff --git a/doc.go b/doc.go index 3a5b5cb8..4be305b3 100644 --- a/doc.go +++ b/doc.go @@ -1,4 +1,5 @@ /* +Package beego provide a MVC framework beego: an open-source, high-performance, modular, full-stack web framework It is used for rapid development of RESTful APIs, web apps and backend services in Go. @@ -14,4 +15,3 @@ beego is inspired by Tornado, Sinatra and Flask with the added benefit of some G more infomation: http://beego.me */ package beego - diff --git a/docs.go b/docs.go index aaad205e..1dbed6cc 100644 --- a/docs.go +++ b/docs.go @@ -20,20 +20,21 @@ import ( "github.com/astaxie/beego/context" ) -var GlobalDocApi map[string]interface{} +// GlobalDocAPI store the swagger api documents +var GlobalDocAPI map[string]interface{} func init() { if EnableDocs { - GlobalDocApi = make(map[string]interface{}) + GlobalDocAPI = make(map[string]interface{}) } } func serverDocs(ctx *context.Context) { var obj interface{} if splat := ctx.Input.Param(":splat"); splat == "" { - obj = GlobalDocApi["Root"] + obj = GlobalDocAPI["Root"] } else { - if v, ok := GlobalDocApi[splat]; ok { + if v, ok := GlobalDocAPI[splat]; ok { obj = v } } diff --git a/error.go b/error.go index f5c0c80b..b4708b30 100644 --- a/error.go +++ b/error.go @@ -362,7 +362,7 @@ func gatewayTimeout(rw http.ResponseWriter, r *http.Request) { // usage: // beego.ErrorHandler("404",NotFound) // beego.ErrorHandler("500",InternalServerError) -func Errorhandler(code string, h http.HandlerFunc) *App { +func ErrorHandler(code string, h http.HandlerFunc) *App { errinfo := &errorInfo{} errinfo.errorType = errorTypeHandler errinfo.handler = h @@ -373,7 +373,7 @@ func Errorhandler(code string, h http.HandlerFunc) *App { // ErrorController registers ControllerInterface to each http err code string. // usage: -// beego.ErrorHandler(&controllers.ErrorController{}) +// beego.ErrorController(&controllers.ErrorController{}) func ErrorController(c ControllerInterface) *App { reflectVal := reflect.ValueOf(c) rt := reflectVal.Type() @@ -431,7 +431,7 @@ func executeError(err *errorInfo, ctx *context.Context, code int) { execController.URLMapping() - in := make([]reflect.Value, 0) + var in []reflect.Value method := vc.MethodByName(err.method) method.Call(in) diff --git a/filter.go b/filter.go index f673ab66..7dbc7028 100644 --- a/filter.go +++ b/filter.go @@ -39,7 +39,6 @@ func (f *FilterRouter) ValidRouter(url string) (bool, map[string]string) { } if isok, ok := isok.(bool); ok { return isok, params - } else { - return false, nil } + return false, nil } diff --git a/flash_test.go b/flash_test.go index b655f552..640d54de 100644 --- a/flash_test.go +++ b/flash_test.go @@ -30,7 +30,7 @@ func (t *TestFlashController) TestWriteFlash() { flash.Notice("TestFlashString") flash.Store(&t.Controller) // we choose to serve json because we don't want to load a template html file - t.ServeJson(true) + t.ServeJSON(true) } func TestFlashHeader(t *testing.T) { diff --git a/hooks.go b/hooks.go index 3691a800..178d8dc4 100644 --- a/hooks.go +++ b/hooks.go @@ -19,41 +19,41 @@ func registerMime() error { // register default error http handlers, 404,401,403,500 and 503. func registerDefaultErrorHandler() error { if _, ok := ErrorMaps["401"]; !ok { - Errorhandler("401", unauthorized) + ErrorHandler("401", unauthorized) } if _, ok := ErrorMaps["402"]; !ok { - Errorhandler("402", paymentRequired) + ErrorHandler("402", paymentRequired) } if _, ok := ErrorMaps["403"]; !ok { - Errorhandler("403", forbidden) + ErrorHandler("403", forbidden) } if _, ok := ErrorMaps["404"]; !ok { - Errorhandler("404", notFound) + ErrorHandler("404", notFound) } if _, ok := ErrorMaps["405"]; !ok { - Errorhandler("405", methodNotAllowed) + ErrorHandler("405", methodNotAllowed) } if _, ok := ErrorMaps["500"]; !ok { - Errorhandler("500", internalServerError) + ErrorHandler("500", internalServerError) } if _, ok := ErrorMaps["501"]; !ok { - Errorhandler("501", notImplemented) + ErrorHandler("501", notImplemented) } if _, ok := ErrorMaps["502"]; !ok { - Errorhandler("502", badGateway) + ErrorHandler("502", badGateway) } if _, ok := ErrorMaps["503"]; !ok { - Errorhandler("503", serviceUnavailable) + ErrorHandler("503", serviceUnavailable) } if _, ok := ErrorMaps["504"]; !ok { - Errorhandler("504", gatewayTimeout) + ErrorHandler("504", gatewayTimeout) } return nil } diff --git a/log.go b/log.go index 7949ed96..68252236 100644 --- a/log.go +++ b/log.go @@ -32,18 +32,18 @@ const ( LevelDebug ) -// SetLogLevel sets the global log level used by the simple -// logger. +// SetLevel sets the global log level used by the simple logger. func SetLevel(l int) { BeeLogger.SetLevel(l) } +// SetLogFuncCall set the CallDepth, default is 3 func SetLogFuncCall(b bool) { BeeLogger.EnableFuncCallDepth(b) BeeLogger.SetLogFuncCallDepth(3) } -// logger references the used application logger. +// BeeLogger references the used application logger. var BeeLogger *logs.BeeLogger // SetLogger sets a new logger. @@ -55,10 +55,12 @@ func SetLogger(adaptername string, config string) error { return nil } +// Emergency logs a message at emergency level. func Emergency(v ...interface{}) { BeeLogger.Emergency(generateFmtStr(len(v)), v...) } +// Alert logs a message at alert level. func Alert(v ...interface{}) { BeeLogger.Alert(generateFmtStr(len(v)), v...) } @@ -78,21 +80,22 @@ func Warning(v ...interface{}) { BeeLogger.Warning(generateFmtStr(len(v)), v...) } -// compatibility alias for Warning() +// Warn compatibility alias for Warning() func Warn(v ...interface{}) { BeeLogger.Warn(generateFmtStr(len(v)), v...) } +// Notice logs a message at notice level. func Notice(v ...interface{}) { BeeLogger.Notice(generateFmtStr(len(v)), v...) } -// Info logs a message at info level. +// Informational logs a message at info level. func Informational(v ...interface{}) { BeeLogger.Informational(generateFmtStr(len(v)), v...) } -// compatibility alias for Warning() +// Info compatibility alias for Warning() func Info(v ...interface{}) { BeeLogger.Info(generateFmtStr(len(v)), v...) } diff --git a/memzipfile.go b/memzipfile.go index cc5e3851..0fff44b6 100644 --- a/memzipfile.go +++ b/memzipfile.go @@ -28,8 +28,10 @@ import ( "time" ) -var gmfim map[string]*memFileInfo = make(map[string]*memFileInfo) -var lock sync.RWMutex +var ( + gmfim = make(map[string]*memFileInfo) + lock sync.RWMutex +) // OpenMemZipFile returns MemFile object with a compressed static file. // it's used for serve static file if gzip enable. diff --git a/mime.go b/mime.go index 0034976e..e85fcb2a 100644 --- a/mime.go +++ b/mime.go @@ -14,7 +14,7 @@ package beego -var mimemaps map[string]string = map[string]string{ +var mimemaps = map[string]string{ ".3dm": "x-world/x-3dmf", ".3dmf": "x-world/x-3dmf", ".7z": "application/x-7z-compressed", diff --git a/namespace.go b/namespace.go index 86dc2ebd..0dfdd7af 100644 --- a/namespace.go +++ b/namespace.go @@ -23,7 +23,8 @@ import ( type namespaceCond func(*beecontext.Context) bool -type innerNamespace func(*Namespace) +// LinkNamespace used as link action +type LinkNamespace func(*Namespace) // Namespace is store all the info type Namespace struct { @@ -31,8 +32,8 @@ type Namespace struct { handlers *ControllerRegister } -// get new Namespace -func NewNamespace(prefix string, params ...innerNamespace) *Namespace { +// NewNamespace get new Namespace +func NewNamespace(prefix string, params ...LinkNamespace) *Namespace { ns := &Namespace{ prefix: prefix, handlers: NewControllerRegister(), @@ -43,7 +44,7 @@ func NewNamespace(prefix string, params ...innerNamespace) *Namespace { return ns } -// set condtion function +// Cond set condtion function // if cond return true can run this namespace, else can't // usage: // ns.Cond(func (ctx *context.Context) bool{ @@ -72,7 +73,7 @@ func (n *Namespace) Cond(cond namespaceCond) *Namespace { return n } -// add filter in the Namespace +// Filter add filter in the Namespace // action has before & after // FilterFunc // usage: @@ -95,98 +96,98 @@ func (n *Namespace) Filter(action string, filter ...FilterFunc) *Namespace { return n } -// same as beego.Rourer +// Router same as beego.Rourer // refer: https://godoc.org/github.com/astaxie/beego#Router func (n *Namespace) Router(rootpath string, c ControllerInterface, mappingMethods ...string) *Namespace { n.handlers.Add(rootpath, c, mappingMethods...) return n } -// same as beego.AutoRouter +// AutoRouter same as beego.AutoRouter // refer: https://godoc.org/github.com/astaxie/beego#AutoRouter func (n *Namespace) AutoRouter(c ControllerInterface) *Namespace { n.handlers.AddAuto(c) return n } -// same as beego.AutoPrefix +// AutoPrefix same as beego.AutoPrefix // refer: https://godoc.org/github.com/astaxie/beego#AutoPrefix func (n *Namespace) AutoPrefix(prefix string, c ControllerInterface) *Namespace { n.handlers.AddAutoPrefix(prefix, c) return n } -// same as beego.Get +// Get same as beego.Get // refer: https://godoc.org/github.com/astaxie/beego#Get func (n *Namespace) Get(rootpath string, f FilterFunc) *Namespace { n.handlers.Get(rootpath, f) return n } -// same as beego.Post +// Post same as beego.Post // refer: https://godoc.org/github.com/astaxie/beego#Post func (n *Namespace) Post(rootpath string, f FilterFunc) *Namespace { n.handlers.Post(rootpath, f) return n } -// same as beego.Delete +// Delete same as beego.Delete // refer: https://godoc.org/github.com/astaxie/beego#Delete func (n *Namespace) Delete(rootpath string, f FilterFunc) *Namespace { n.handlers.Delete(rootpath, f) return n } -// same as beego.Put +// Put same as beego.Put // refer: https://godoc.org/github.com/astaxie/beego#Put func (n *Namespace) Put(rootpath string, f FilterFunc) *Namespace { n.handlers.Put(rootpath, f) return n } -// same as beego.Head +// Head same as beego.Head // refer: https://godoc.org/github.com/astaxie/beego#Head func (n *Namespace) Head(rootpath string, f FilterFunc) *Namespace { n.handlers.Head(rootpath, f) return n } -// same as beego.Options +// Options same as beego.Options // refer: https://godoc.org/github.com/astaxie/beego#Options func (n *Namespace) Options(rootpath string, f FilterFunc) *Namespace { n.handlers.Options(rootpath, f) return n } -// same as beego.Patch +// Patch same as beego.Patch // refer: https://godoc.org/github.com/astaxie/beego#Patch func (n *Namespace) Patch(rootpath string, f FilterFunc) *Namespace { n.handlers.Patch(rootpath, f) return n } -// same as beego.Any +// Any same as beego.Any // refer: https://godoc.org/github.com/astaxie/beego#Any func (n *Namespace) Any(rootpath string, f FilterFunc) *Namespace { n.handlers.Any(rootpath, f) return n } -// same as beego.Handler +// Handler same as beego.Handler // refer: https://godoc.org/github.com/astaxie/beego#Handler func (n *Namespace) Handler(rootpath string, h http.Handler) *Namespace { n.handlers.Handler(rootpath, h) return n } -// add include class +// Include add include class // refer: https://godoc.org/github.com/astaxie/beego#Include func (n *Namespace) Include(cList ...ControllerInterface) *Namespace { n.handlers.Include(cList...) return n } -// nest Namespace +// Namespace add nest Namespace // usage: //ns := beego.NewNamespace(“/v1”). //Namespace( @@ -230,7 +231,7 @@ func (n *Namespace) Namespace(ns ...*Namespace) *Namespace { return n } -// register Namespace into beego.Handler +// AddNamespace register Namespace into beego.Handler // support multi Namespace func AddNamespace(nl ...*Namespace) { for _, n := range nl { @@ -275,113 +276,113 @@ func addPrefix(t *Tree, prefix string) { } -// Namespace Condition -func NSCond(cond namespaceCond) innerNamespace { +// NSCond is Namespace Condition +func NSCond(cond namespaceCond) LinkNamespace { return func(ns *Namespace) { ns.Cond(cond) } } -// Namespace BeforeRouter filter -func NSBefore(filiterList ...FilterFunc) innerNamespace { +// NSBefore Namespace BeforeRouter filter +func NSBefore(filiterList ...FilterFunc) LinkNamespace { return func(ns *Namespace) { ns.Filter("before", filiterList...) } } -// Namespace FinishRouter filter -func NSAfter(filiterList ...FilterFunc) innerNamespace { +// NSAfter add Namespace FinishRouter filter +func NSAfter(filiterList ...FilterFunc) LinkNamespace { return func(ns *Namespace) { ns.Filter("after", filiterList...) } } -// Namespace Include ControllerInterface -func NSInclude(cList ...ControllerInterface) innerNamespace { +// NSInclude Namespace Include ControllerInterface +func NSInclude(cList ...ControllerInterface) LinkNamespace { return func(ns *Namespace) { ns.Include(cList...) } } -// Namespace Router -func NSRouter(rootpath string, c ControllerInterface, mappingMethods ...string) innerNamespace { +// NSRouter call Namespace Router +func NSRouter(rootpath string, c ControllerInterface, mappingMethods ...string) LinkNamespace { return func(ns *Namespace) { ns.Router(rootpath, c, mappingMethods...) } } -// Namespace Get -func NSGet(rootpath string, f FilterFunc) innerNamespace { +// NSGet call Namespace Get +func NSGet(rootpath string, f FilterFunc) LinkNamespace { return func(ns *Namespace) { ns.Get(rootpath, f) } } -// Namespace Post -func NSPost(rootpath string, f FilterFunc) innerNamespace { +// NSPost call Namespace Post +func NSPost(rootpath string, f FilterFunc) LinkNamespace { return func(ns *Namespace) { ns.Post(rootpath, f) } } -// Namespace Head -func NSHead(rootpath string, f FilterFunc) innerNamespace { +// NSHead call Namespace Head +func NSHead(rootpath string, f FilterFunc) LinkNamespace { return func(ns *Namespace) { ns.Head(rootpath, f) } } -// Namespace Put -func NSPut(rootpath string, f FilterFunc) innerNamespace { +// NSPut call Namespace Put +func NSPut(rootpath string, f FilterFunc) LinkNamespace { return func(ns *Namespace) { ns.Put(rootpath, f) } } -// Namespace Delete -func NSDelete(rootpath string, f FilterFunc) innerNamespace { +// NSDelete call Namespace Delete +func NSDelete(rootpath string, f FilterFunc) LinkNamespace { return func(ns *Namespace) { ns.Delete(rootpath, f) } } -// Namespace Any -func NSAny(rootpath string, f FilterFunc) innerNamespace { +// NSAny call Namespace Any +func NSAny(rootpath string, f FilterFunc) LinkNamespace { return func(ns *Namespace) { ns.Any(rootpath, f) } } -// Namespace Options -func NSOptions(rootpath string, f FilterFunc) innerNamespace { +// NSOptions call Namespace Options +func NSOptions(rootpath string, f FilterFunc) LinkNamespace { return func(ns *Namespace) { ns.Options(rootpath, f) } } -// Namespace Patch -func NSPatch(rootpath string, f FilterFunc) innerNamespace { +// NSPatch call Namespace Patch +func NSPatch(rootpath string, f FilterFunc) LinkNamespace { return func(ns *Namespace) { ns.Patch(rootpath, f) } } -//Namespace AutoRouter -func NSAutoRouter(c ControllerInterface) innerNamespace { +// NSAutoRouter call Namespace AutoRouter +func NSAutoRouter(c ControllerInterface) LinkNamespace { return func(ns *Namespace) { ns.AutoRouter(c) } } -// Namespace AutoPrefix -func NSAutoPrefix(prefix string, c ControllerInterface) innerNamespace { +// NSAutoPrefix call Namespace AutoPrefix +func NSAutoPrefix(prefix string, c ControllerInterface) LinkNamespace { return func(ns *Namespace) { ns.AutoPrefix(prefix, c) } } -// Namespace add sub Namespace -func NSNamespace(prefix string, params ...innerNamespace) innerNamespace { +// NSNamespace add sub Namespace +func NSNamespace(prefix string, params ...LinkNamespace) LinkNamespace { return func(ns *Namespace) { n := NewNamespace(prefix, params...) ns.Namespace(n) diff --git a/router.go b/router.go index 6fbf90ea..dc4ddb0f 100644 --- a/router.go +++ b/router.go @@ -770,10 +770,10 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) //if XSRF is Enable then check cookie where there has any cookie in the request's cookie _csrf if EnableXSRF { - execController.XsrfToken() + execController.XSRFToken() if r.Method == "POST" || r.Method == "DELETE" || r.Method == "PUT" || (r.Method == "POST" && (context.Input.Query("_method") == "DELETE" || context.Input.Query("_method") == "PUT")) { - execController.CheckXsrfCookie() + execController.CheckXSRFCookie() } } diff --git a/router_test.go b/router_test.go index 005f32d6..093a1fad 100644 --- a/router_test.go +++ b/router_test.go @@ -53,7 +53,7 @@ func (tc *TestController) Myext() { } func (tc *TestController) GetUrl() { - tc.Ctx.Output.Body([]byte(tc.UrlFor(".Myext"))) + tc.Ctx.Output.Body([]byte(tc.URLFor(".Myext"))) } func (t *TestController) GetParams() { @@ -76,7 +76,7 @@ type JsonController struct { func (this *JsonController) Prepare() { this.Data["json"] = "prepare" - this.ServeJson(true) + this.ServeJSON(true) } func (this *JsonController) Get() { From 21fffc446b4f45e87c724e63afa0f05a36ff87cf Mon Sep 17 00:00:00 2001 From: astaxie Date: Tue, 8 Sep 2015 21:45:45 +0800 Subject: [PATCH 48/55] make golint happy parser.go --- parser.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/parser.go b/parser.go index cf8dee22..dd468c1c 100644 --- a/parser.go +++ b/parser.go @@ -42,13 +42,13 @@ func init() { ` var ( - lastupdateFilename string = "lastupdate.tmp" + lastupdateFilename = "lastupdate.tmp" commentFilename string pkgLastupdate map[string]int64 genInfoList map[string][]ControllerComments ) -const COMMENTFL = "commentsRouter_" +const coomentPrefix = "commentsRouter_" func init() { pkgLastupdate = make(map[string]int64) @@ -56,7 +56,7 @@ func init() { func parserPkg(pkgRealpath, pkgpath string) error { rep := strings.NewReplacer("/", "_", ".", "_") - commentFilename = COMMENTFL + rep.Replace(pkgpath) + ".go" + commentFilename = coomentPrefix + rep.Replace(pkgpath) + ".go" if !compareFile(pkgRealpath) { Info(pkgRealpath + " has not changed, not reloading") return nil @@ -129,9 +129,11 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat func genRouterCode() { os.Mkdir(path.Join(workPath, "routers"), 0755) Info("generate router from comments") - var globalinfo string - sortKey := make([]string, 0) - for k, _ := range genInfoList { + var ( + globalinfo string + sortKey []string + ) + for k := range genInfoList { sortKey = append(sortKey, k) } sort.Strings(sortKey) From c11740b647e765499470a21c7baefcf20ab0fb7a Mon Sep 17 00:00:00 2001 From: astaxie Date: Tue, 8 Sep 2015 22:01:13 +0800 Subject: [PATCH 49/55] make golint happy router.go --- router.go | 137 ++++++++++++++++++++++++------------------------ templatefunc.go | 2 +- 2 files changed, 69 insertions(+), 70 deletions(-) diff --git a/router.go b/router.go index dc4ddb0f..12b5f6ae 100644 --- a/router.go +++ b/router.go @@ -34,8 +34,8 @@ import ( "github.com/astaxie/beego/utils" ) +// default filter execution points const ( - // default filter execution points BeforeStatic = iota BeforeRouter BeforeExec @@ -50,7 +50,7 @@ const ( ) var ( - // supported http methods. + // HTTPMETHOD list the supported http methods. HTTPMETHOD = map[string]string{ "GET": "GET", "POST": "POST", @@ -71,10 +71,12 @@ var ( "SetSecureCookie", "XsrfToken", "CheckXsrfCookie", "XsrfFormHtml", "GetControllerAndAction"} - url_placeholder = "{{placeholder}}" - DefaultLogFilter FilterHandler = &logFilter{} + urlPlaceholder = "{{placeholder}}" + // DefaultAccessLogFilter will skip the accesslog if return true + DefaultAccessLogFilter FilterHandler = &logFilter{} ) +// FilterHandler is an interface for type FilterHandler interface { Filter(*beecontext.Context) bool } @@ -96,7 +98,7 @@ func (l *logFilter) Filter(ctx *beecontext.Context) bool { return false } -// To append a slice's value into "exceptMethod", for controller's methods shouldn't reflect to AutoRouter +// ExceptMethodAppend to append a slice's value into "exceptMethod", for controller's methods shouldn't reflect to AutoRouter func ExceptMethodAppend(action string) { exceptMethod = append(exceptMethod, action) } @@ -196,7 +198,7 @@ func (p *ControllerRegister) addToRouter(method, pattern string, r *controllerIn } } -// only when the Runmode is dev will generate router file in the router/auto.go from the controller +// Include only when the Runmode is dev will generate router file in the router/auto.go from the controller // Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{}) func (p *ControllerRegister) Include(cList ...ControllerInterface) { if RunMode == "dev" { @@ -238,7 +240,7 @@ func (p *ControllerRegister) Include(cList ...ControllerInterface) { } } -// add get method +// Get add get method // usage: // Get("/", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -247,7 +249,7 @@ func (p *ControllerRegister) Get(pattern string, f FilterFunc) { p.AddMethod("get", pattern, f) } -// add post method +// Post add post method // usage: // Post("/api", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -256,7 +258,7 @@ func (p *ControllerRegister) Post(pattern string, f FilterFunc) { p.AddMethod("post", pattern, f) } -// add put method +// Put add put method // usage: // Put("/api/:id", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -265,7 +267,7 @@ func (p *ControllerRegister) Put(pattern string, f FilterFunc) { p.AddMethod("put", pattern, f) } -// add delete method +// Delete add delete method // usage: // Delete("/api/:id", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -274,7 +276,7 @@ func (p *ControllerRegister) Delete(pattern string, f FilterFunc) { p.AddMethod("delete", pattern, f) } -// add head method +// Head add head method // usage: // Head("/api/:id", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -283,7 +285,7 @@ func (p *ControllerRegister) Head(pattern string, f FilterFunc) { p.AddMethod("head", pattern, f) } -// add patch method +// Patch add patch method // usage: // Patch("/api/:id", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -292,7 +294,7 @@ func (p *ControllerRegister) Patch(pattern string, f FilterFunc) { p.AddMethod("patch", pattern, f) } -// add options method +// Options add options method // usage: // Options("/api/:id", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -301,7 +303,7 @@ func (p *ControllerRegister) Options(pattern string, f FilterFunc) { p.AddMethod("options", pattern, f) } -// add all method +// Any add all method // usage: // Any("/api/:id", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -310,7 +312,7 @@ func (p *ControllerRegister) Any(pattern string, f FilterFunc) { p.AddMethod("*", pattern, f) } -// add http method router +// AddMethod add http method router // usage: // AddMethod("get","/api/:id", func(ctx *context.Context){ // ctx.Output.Body("hello world") @@ -343,7 +345,7 @@ func (p *ControllerRegister) AddMethod(method, pattern string, f FilterFunc) { } } -// add user defined Handler +// Handler add user defined Handler func (p *ControllerRegister) Handler(pattern string, h http.Handler, options ...interface{}) { route := &controllerInfo{} route.pattern = pattern @@ -359,7 +361,7 @@ func (p *ControllerRegister) Handler(pattern string, h http.Handler, options ... } } -// Add auto router to ControllerRegister. +// AddAuto router to ControllerRegister. // example beego.AddAuto(&MainContorlller{}), // MainController has method List and Page. // visit the url /main/list to execute List function @@ -368,7 +370,7 @@ func (p *ControllerRegister) AddAuto(c ControllerInterface) { p.AddAutoPrefix("/", c) } -// Add auto router to ControllerRegister with prefix. +// AddAutoPrefix Add auto router to ControllerRegister with prefix. // example beego.AddAutoPrefix("/admin",&MainContorlller{}), // MainController has method List and Page. // visit the url /admin/main/list to execute List function @@ -399,7 +401,7 @@ func (p *ControllerRegister) AddAutoPrefix(prefix string, c ControllerInterface) } } -// Add a FilterFunc with pattern rule and action constant. +// InsertFilter Add a FilterFunc with pattern rule and action constant. // The bool params is for setting the returnOnOutput value (false allows multiple filters to execute) func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) error { @@ -426,9 +428,9 @@ func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) error return nil } -// UrlFor does another controller handler in this request function. +// URLFor does another controller handler in this request function. // it can access any controller method. -func (p *ControllerRegister) UrlFor(endpoint string, values ...interface{}) string { +func (p *ControllerRegister) URLFor(endpoint string, values ...interface{}) string { paths := strings.Split(endpoint, ".") if len(paths) <= 1 { Warn("urlfor endpoint must like path.controller.method") @@ -469,7 +471,7 @@ func (p *ControllerRegister) geturl(t *Tree, url, controllName, methodName strin } } if t.wildcard != nil { - u := path.Join(url, url_placeholder) + u := path.Join(url, urlPlaceholder) ok, u := p.geturl(t.wildcard, u, controllName, methodName, params, httpMethod) if ok { return ok, u @@ -499,22 +501,21 @@ func (p *ControllerRegister) geturl(t *Tree, url, controllName, methodName strin if find { if l.regexps == nil { if len(l.wildcards) == 0 { - return true, strings.Replace(url, "/"+url_placeholder, "", 1) + tourl(params) + return true, strings.Replace(url, "/"+urlPlaceholder, "", 1) + tourl(params) } if len(l.wildcards) == 1 { if v, ok := params[l.wildcards[0]]; ok { delete(params, l.wildcards[0]) - return true, strings.Replace(url, url_placeholder, v, 1) + tourl(params) - } else { - return false, "" + return true, strings.Replace(url, urlPlaceholder, v, 1) + tourl(params) } + return false, "" } if len(l.wildcards) == 3 && l.wildcards[0] == "." { if p, ok := params[":path"]; ok { if e, isok := params[":ext"]; isok { delete(params, ":path") delete(params, ":ext") - return true, strings.Replace(url, url_placeholder, p+"."+e, -1) + tourl(params) + return true, strings.Replace(url, urlPlaceholder, p+"."+e, -1) + tourl(params) } } } @@ -526,45 +527,43 @@ func (p *ControllerRegister) geturl(t *Tree, url, controllName, methodName strin } if u, ok := params[v]; ok { delete(params, v) - url = strings.Replace(url, url_placeholder, u, 1) + url = strings.Replace(url, urlPlaceholder, u, 1) } else { if canskip { canskip = false continue - } else { - return false, "" } + return false, "" } } return true, url + tourl(params) - } else { - var i int - var startreg bool - regurl := "" - for _, v := range strings.Trim(l.regexps.String(), "^$") { - if v == '(' { - startreg = true - continue - } else if v == ')' { - startreg = false - if v, ok := params[l.wildcards[i]]; ok { - delete(params, l.wildcards[i]) - regurl = regurl + v - i++ - } else { - break - } - } else if !startreg { - regurl = string(append([]rune(regurl), v)) + } + var i int + var startreg bool + regurl := "" + for _, v := range strings.Trim(l.regexps.String(), "^$") { + if v == '(' { + startreg = true + continue + } else if v == ')' { + startreg = false + if v, ok := params[l.wildcards[i]]; ok { + delete(params, l.wildcards[i]) + regurl = regurl + v + i++ + } else { + break } + } else if !startreg { + regurl = string(append([]rune(regurl), v)) } - if l.regexps.MatchString(regurl) { - ps := strings.Split(regurl, "/") - for _, p := range ps { - url = strings.Replace(url, url_placeholder, p, 1) - } - return true, url + tourl(params) + } + if l.regexps.MatchString(regurl) { + ps := strings.Split(regurl, "/") + for _, p := range ps { + url = strings.Replace(url, urlPlaceholder, p, 1) } + return true, url + tourl(params) } } } @@ -607,7 +606,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) urlPath = r.URL.Path } // defined filter function - do_filter := func(pos int) (started bool) { + doFilter := func(pos int) (started bool) { if p.enableFilter { if l, ok := p.filters[pos]; ok { for _, filterR := range l { @@ -639,7 +638,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) } // filter for static file - if do_filter(BeforeStatic) { + if doFilter(BeforeStatic) { goto Admin } @@ -670,7 +669,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) context.Input.ParseFormOrMulitForm(MaxMemory) } - if do_filter(BeforeRouter) { + if doFilter(BeforeRouter) { goto Admin } @@ -681,17 +680,17 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) } if !findrouter { - http_method := r.Method + httpMethod := r.Method - if http_method == "POST" && context.Input.Query("_method") == "PUT" { - http_method = "PUT" + if httpMethod == "POST" && context.Input.Query("_method") == "PUT" { + httpMethod = "PUT" } - if http_method == "POST" && context.Input.Query("_method") == "DELETE" { - http_method = "DELETE" + if httpMethod == "POST" && context.Input.Query("_method") == "DELETE" { + httpMethod = "DELETE" } - if t, ok := p.routers[http_method]; ok { + if t, ok := p.routers[httpMethod]; ok { runObject, p := t.Match(urlPath) if r, ok := runObject.(*controllerInfo); ok { routerInfo = r @@ -718,7 +717,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) if findrouter { //execute middleware filters - if do_filter(BeforeExec) { + if doFilter(BeforeExec) { goto Admin } isRunable := false @@ -798,7 +797,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) execController.Options() default: if !execController.HandlerFunc(runMethod) { - in := make([]reflect.Value, 0) + var in []reflect.Value method := vc.MethodByName(runMethod) method.Call(in) } @@ -819,12 +818,12 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) } //execute middleware filters - if do_filter(AfterExec) { + if doFilter(AfterExec) { goto Admin } } - do_filter(FinishRouter) + doFilter(FinishRouter) Admin: timeend := time.Since(starttime) @@ -850,7 +849,7 @@ Admin: } else { devinfo = fmt.Sprintf("| % -10s | % -40s | % -16s | % -10s |", r.Method, r.URL.Path, timeend.String(), "notmatch") } - if DefaultLogFilter == nil || !DefaultLogFilter.Filter(context) { + if DefaultAccessLogFilter == nil || !DefaultAccessLogFilter.Filter(context) { Debug(devinfo) } } diff --git a/templatefunc.go b/templatefunc.go index 1106e4d0..6b77fda3 100644 --- a/templatefunc.go +++ b/templatefunc.go @@ -255,7 +255,7 @@ func Htmlunquote(src string) string { // // more detail http://beego.me/docs/mvc/controller/urlbuilding.md func URLFor(endpoint string, values ...interface{}) string { - return BeeApp.Handlers.UrlFor(endpoint, values...) + return BeeApp.Handlers.URLFor(endpoint, values...) } // returns script tag with src string. From b2048e8653545d5b9c0650e0723b95b49847986c Mon Sep 17 00:00:00 2001 From: astaxie Date: Tue, 8 Sep 2015 22:05:38 +0800 Subject: [PATCH 50/55] make router test passed --- router_test.go | 56 +++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/router_test.go b/router_test.go index 093a1fad..c6ec9c92 100644 --- a/router_test.go +++ b/router_test.go @@ -52,17 +52,17 @@ func (tc *TestController) Myext() { tc.Ctx.Output.Body([]byte(tc.Ctx.Input.Param(":ext"))) } -func (tc *TestController) GetUrl() { +func (tc *TestController) GetURL() { tc.Ctx.Output.Body([]byte(tc.URLFor(".Myext"))) } -func (t *TestController) GetParams() { - t.Ctx.WriteString(t.Ctx.Input.Query(":last") + "+" + - t.Ctx.Input.Query(":first") + "+" + t.Ctx.Input.Query("learn")) +func (tc *TestController) GetParams() { + tc.Ctx.WriteString(tc.Ctx.Input.Query(":last") + "+" + + tc.Ctx.Input.Query(":first") + "+" + tc.Ctx.Input.Query("learn")) } -func (t *TestController) GetManyRouter() { - t.Ctx.WriteString(t.Ctx.Input.Query(":id") + t.Ctx.Input.Query(":page")) +func (tc *TestController) GetManyRouter() { + tc.Ctx.WriteString(tc.Ctx.Input.Query(":id") + tc.Ctx.Input.Query(":page")) } type ResStatus struct { @@ -70,29 +70,29 @@ type ResStatus struct { Msg string } -type JsonController struct { +type JSONController struct { Controller } -func (this *JsonController) Prepare() { - this.Data["json"] = "prepare" - this.ServeJSON(true) +func (jc *JSONController) Prepare() { + jc.Data["json"] = "prepare" + jc.ServeJSON(true) } -func (this *JsonController) Get() { - this.Data["Username"] = "astaxie" - this.Ctx.Output.Body([]byte("ok")) +func (jc *JSONController) Get() { + jc.Data["Username"] = "astaxie" + jc.Ctx.Output.Body([]byte("ok")) } func TestUrlFor(t *testing.T) { handler := NewControllerRegister() handler.Add("/api/list", &TestController{}, "*:List") handler.Add("/person/:last/:first", &TestController{}, "*:Param") - if a := handler.UrlFor("TestController.List"); a != "/api/list" { + if a := handler.URLFor("TestController.List"); a != "/api/list" { Info(a) t.Errorf("TestController.List must equal to /api/list") } - if a := handler.UrlFor("TestController.Param", ":last", "xie", ":first", "asta"); a != "/person/xie/asta" { + if a := handler.URLFor("TestController.Param", ":last", "xie", ":first", "asta"); a != "/person/xie/asta" { t.Errorf("TestController.Param must equal to /person/xie/asta, but get " + a) } } @@ -100,39 +100,39 @@ func TestUrlFor(t *testing.T) { func TestUrlFor3(t *testing.T) { handler := NewControllerRegister() handler.AddAuto(&TestController{}) - if a := handler.UrlFor("TestController.Myext"); a != "/test/myext" && a != "/Test/Myext" { + if a := handler.URLFor("TestController.Myext"); a != "/test/myext" && a != "/Test/Myext" { t.Errorf("TestController.Myext must equal to /test/myext, but get " + a) } - if a := handler.UrlFor("TestController.GetUrl"); a != "/test/geturl" && a != "/Test/GetUrl" { - t.Errorf("TestController.GetUrl must equal to /test/geturl, but get " + a) + if a := handler.URLFor("TestController.GetURL"); a != "/test/geturl" && a != "/Test/GetURL" { + t.Errorf("TestController.GetURL must equal to /test/geturl, but get " + a) } } func TestUrlFor2(t *testing.T) { handler := NewControllerRegister() handler.Add("/v1/:v/cms_:id(.+)_:page(.+).html", &TestController{}, "*:List") - handler.Add("/v1/:username/edit", &TestController{}, "get:GetUrl") + handler.Add("/v1/:username/edit", &TestController{}, "get:GetURL") handler.Add("/v1/:v(.+)_cms/ttt_:id(.+)_:page(.+).html", &TestController{}, "*:Param") handler.Add("/:year:int/:month:int/:title/:entid", &TestController{}) - if handler.UrlFor("TestController.GetUrl", ":username", "astaxie") != "/v1/astaxie/edit" { - Info(handler.UrlFor("TestController.GetUrl")) + if handler.URLFor("TestController.GetURL", ":username", "astaxie") != "/v1/astaxie/edit" { + Info(handler.URLFor("TestController.GetURL")) t.Errorf("TestController.List must equal to /v1/astaxie/edit") } - if handler.UrlFor("TestController.List", ":v", "za", ":id", "12", ":page", "123") != + if handler.URLFor("TestController.List", ":v", "za", ":id", "12", ":page", "123") != "/v1/za/cms_12_123.html" { - Info(handler.UrlFor("TestController.List")) + Info(handler.URLFor("TestController.List")) t.Errorf("TestController.List must equal to /v1/za/cms_12_123.html") } - if handler.UrlFor("TestController.Param", ":v", "za", ":id", "12", ":page", "123") != + if handler.URLFor("TestController.Param", ":v", "za", ":id", "12", ":page", "123") != "/v1/za_cms/ttt_12_123.html" { - Info(handler.UrlFor("TestController.Param")) + Info(handler.URLFor("TestController.Param")) t.Errorf("TestController.List must equal to /v1/za_cms/ttt_12_123.html") } - if handler.UrlFor("TestController.Get", ":year", "1111", ":month", "11", + if handler.URLFor("TestController.Get", ":year", "1111", ":month", "11", ":title", "aaaa", ":entid", "aaaa") != "/1111/11/aaaa/aaaa" { - Info(handler.UrlFor("TestController.Get")) + Info(handler.URLFor("TestController.Get")) t.Errorf("TestController.Get must equal to /1111/11/aaaa/aaaa") } } @@ -270,7 +270,7 @@ func TestPrepare(t *testing.T) { w := httptest.NewRecorder() handler := NewControllerRegister() - handler.Add("/json/list", &JsonController{}) + handler.Add("/json/list", &JSONController{}) handler.ServeHTTP(w, r) if w.Body.String() != `"prepare"` { t.Errorf(w.Body.String() + "user define func can't run") From 8615f875f82a40a66baf5cbcef3efcd8b5403a60 Mon Sep 17 00:00:00 2001 From: astaxie Date: Tue, 8 Sep 2015 22:07:44 +0800 Subject: [PATCH 51/55] make golint happy staticfile.go --- staticfile.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/staticfile.go b/staticfile.go index 7c1ed98c..c85f17e0 100644 --- a/staticfile.go +++ b/staticfile.go @@ -40,15 +40,13 @@ func serverStaticRouter(ctx *context.Context) { if utils.FileExists(file) { http.ServeFile(ctx.ResponseWriter, ctx.Request, file) return - } else { - i++ - if i == len(StaticDir) { - http.NotFound(ctx.ResponseWriter, ctx.Request) - return - } else { - continue - } } + i++ + if i == len(StaticDir) { + http.NotFound(ctx.ResponseWriter, ctx.Request) + return + } + continue } if strings.HasPrefix(requestPath, prefix) { if len(requestPath) > len(prefix) && requestPath[len(prefix)] != '/' { From 44bd3beb5ed3eb270b7d832ac7a3411d3a8980e7 Mon Sep 17 00:00:00 2001 From: astaxie Date: Tue, 8 Sep 2015 23:29:58 +0800 Subject: [PATCH 52/55] golint happy with template --- template.go | 32 ++++++++++++++------------------ template_test.go | 10 +++++----- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/template.go b/template.go index 9403c71f..6e196c0a 100644 --- a/template.go +++ b/template.go @@ -28,17 +28,14 @@ import ( ) var ( - beegoTplFuncMap template.FuncMap - // beego template caching map and supported template file extensions. - BeeTemplates map[string]*template.Template - BeeTemplateExt []string + beegoTplFuncMap = make(template.FuncMap) + // BeeTemplates caching map and supported template file extensions. + BeeTemplates = make(map[string]*template.Template) + // BeeTemplateExt stores the template extention which will build + BeeTemplateExt = []string{"tpl", "html"} ) func init() { - BeeTemplates = make(map[string]*template.Template) - beegoTplFuncMap = make(template.FuncMap) - BeeTemplateExt = make([]string, 0) - BeeTemplateExt = append(BeeTemplateExt, "tpl", "html") beegoTplFuncMap["dateformat"] = DateFormat beegoTplFuncMap["date"] = Date beegoTplFuncMap["compare"] = Compare @@ -79,7 +76,7 @@ type templatefile struct { files map[string][]string } -func (self *templatefile) visit(paths string, f os.FileInfo, err error) error { +func (tf *templatefile) visit(paths string, f os.FileInfo, err error) error { if f == nil { return err } @@ -92,21 +89,21 @@ func (self *templatefile) visit(paths string, f os.FileInfo, err error) error { replace := strings.NewReplacer("\\", "/") a := []byte(paths) - a = a[len([]byte(self.root)):] + a = a[len([]byte(tf.root)):] file := strings.TrimLeft(replace.Replace(string(a)), "/") subdir := filepath.Dir(file) - if _, ok := self.files[subdir]; ok { - self.files[subdir] = append(self.files[subdir], file) + if _, ok := tf.files[subdir]; ok { + tf.files[subdir] = append(tf.files[subdir], file) } else { m := make([]string, 1) m[0] = file - self.files[subdir] = m + tf.files[subdir] = m } return nil } -// return this path contains supported template extension of beego or not. +// HasTemplateExt return this path contains supported template extension of beego or not. func HasTemplateExt(paths string) bool { for _, v := range BeeTemplateExt { if strings.HasSuffix(paths, "."+v) { @@ -116,7 +113,7 @@ func HasTemplateExt(paths string) bool { return false } -// add new extension for template. +// AddTemplateExt add new extension for template. func AddTemplateExt(ext string) { for _, v := range BeeTemplateExt { if v == ext { @@ -126,15 +123,14 @@ func AddTemplateExt(ext string) { BeeTemplateExt = append(BeeTemplateExt, ext) } -// build all template files in a directory. +// BuildTemplate will build all template files in a directory. // it makes beego can render any template file in view directory. func BuildTemplate(dir string, files ...string) error { if _, err := os.Stat(dir); err != nil { if os.IsNotExist(err) { return nil - } else { - return errors.New("dir open err") } + return errors.New("dir open err") } self := &templatefile{ root: dir, diff --git a/template_test.go b/template_test.go index 79740f2b..2e222efc 100644 --- a/template_test.go +++ b/template_test.go @@ -20,11 +20,11 @@ import ( "testing" ) -var header string = `{{define "header"}} +var header = `{{define "header"}}

Hello, astaxie!

{{end}}` -var index string = ` +var index = ` beego welcome template @@ -37,7 +37,7 @@ var index string = ` ` -var block string = `{{define "block"}} +var block = `{{define "block"}}

Hello, blocks!

{{end}}` @@ -82,7 +82,7 @@ func TestTemplate(t *testing.T) { os.RemoveAll(dir) } -var menu string = `