Merge pull request #2596 from astaxie/develop

beego 1.8.1
This commit is contained in:
astaxie 2017-04-25 22:51:23 +08:00 committed by GitHub
commit 522b3a4a70
72 changed files with 556 additions and 442 deletions

4
.gosimpleignore Normal file
View File

@ -0,0 +1,4 @@
github.com/astaxie/beego/*/*:S1012
github.com/astaxie/beego/*:S1012
github.com/astaxie/beego/*/*:S1007
github.com/astaxie/beego/*:S1007

View File

@ -1,9 +1,9 @@
language: go
go:
- 1.6
- 1.5.3
- 1.4.3
- 1.6.4
- 1.7.5
- 1.8.1
services:
- redis-server
- mysql
@ -33,6 +33,8 @@ install:
- go get github.com/ssdb/gossdb/ssdb
- go get github.com/cloudflare/golz4
- go get github.com/gogo/protobuf/proto
- go get -u honnef.co/go/tools/cmd/gosimple
- go get -u github.com/mdempsky/unconvert
before_script:
- psql --version
- sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi"
@ -47,5 +49,7 @@ after_script:
- rm -rf ./res/var/*
script:
- go test -v ./...
- gosimple -ignore "$(cat .gosimpleignore)" $(go list ./... | grep -v /vendor/)
- unconvert $(go list ./... | grep -v /vendor/)
addons:
postgresql: "9.4"

View File

@ -1,20 +1,17 @@
## Beego
[![Build Status](https://travis-ci.org/astaxie/beego.svg?branch=master)](https://travis-ci.org/astaxie/beego)
[![GoDoc](http://godoc.org/github.com/astaxie/beego?status.svg)](http://godoc.org/github.com/astaxie/beego)
[![Foundation](https://img.shields.io/badge/Golang-Foundation-green.svg)](http://golangfoundation.org)
# Beego [![Build Status](https://travis-ci.org/astaxie/beego.svg?branch=master)](https://travis-ci.org/astaxie/beego) [![GoDoc](http://godoc.org/github.com/astaxie/beego?status.svg)](http://godoc.org/github.com/astaxie/beego) [![Foundation](https://img.shields.io/badge/Golang-Foundation-green.svg)](http://golangfoundation.org)
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)
###### More info at [beego.me](http://beego.me).
##Quick Start
######Download and install
## Quick Start
#### Download and install
go get github.com/astaxie/beego
######Create file `hello.go`
#### Create file `hello.go`
```go
package main
@ -24,15 +21,16 @@ func main(){
beego.Run()
}
```
######Build and run
```bash
#### Build and run
go build hello.go
./hello
```
######Congratulations!
You just built your first beego app.
Open your browser and visit `http://localhost:8080`.
Please see [Documentation](http://beego.me/docs) for more.
#### Go to [http://localhost:8080](http://localhost:8080)
Congratulations! You've just built your first **beego** app.
###### Please see [Documentation](http://beego.me/docs) for more.
## Features
@ -56,7 +54,7 @@ Please see [Documentation](http://beego.me/docs) for more.
* [http://beego.me/community](http://beego.me/community)
* Welcome to join us in Slack: [https://beego.slack.com](https://beego.slack.com), you can get invited from [here](https://github.com/beego/beedoc/issues/232)
## LICENSE
## License
beego source code is licensed under the Apache Licence, Version 2.0
(http://www.apache.org/licenses/LICENSE-2.0.html).

View File

@ -157,8 +157,8 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
resultList := new([][]string)
for _, f := range bf {
var result = []string{
fmt.Sprintf("%s", f.pattern),
fmt.Sprintf("%s", utils.GetFuncName(f.filterFunc)),
f.pattern,
utils.GetFuncName(f.filterFunc),
}
*resultList = append(*resultList, result)
}
@ -208,12 +208,12 @@ func printTree(resultList *[][]string, t *Tree) {
printTree(resultList, t.wildcard)
}
for _, l := range t.leaves {
if v, ok := l.runObject.(*controllerInfo); ok {
if v, ok := l.runObject.(*ControllerInfo); ok {
if v.routerType == routerTypeBeego {
var result = []string{
v.pattern,
fmt.Sprintf("%s", v.methods),
fmt.Sprintf("%s", v.controllerType),
v.controllerType.String(),
}
*resultList = append(*resultList, result)
} else if v.routerType == routerTypeRESTFul {
@ -276,8 +276,8 @@ func profIndex(rw http.ResponseWriter, r *http.Request) {
// it's in "/healthcheck" pattern in admin module.
func healthcheck(rw http.ResponseWriter, req *http.Request) {
var (
result []string
data = make(map[interface{}]interface{})
result = []string{}
resultList = new([][]string)
content = map[string]interface{}{
"Fields": []string{"Name", "Message", "Status"},
@ -287,21 +287,20 @@ func healthcheck(rw http.ResponseWriter, req *http.Request) {
for name, h := range toolbox.AdminCheckList {
if err := h.Check(); err != nil {
result = []string{
fmt.Sprintf("error"),
fmt.Sprintf("%s", name),
fmt.Sprintf("%s", err.Error()),
"error",
name,
err.Error(),
}
} else {
result = []string{
fmt.Sprintf("success"),
fmt.Sprintf("%s", name),
fmt.Sprintf("OK"),
"success",
name,
"OK",
}
}
*resultList = append(*resultList, result)
}
content["Data"] = resultList
data["Content"] = content
data["Title"] = "Health Check"
@ -330,7 +329,6 @@ func taskStatus(rw http.ResponseWriter, req *http.Request) {
// List Tasks
content := make(map[string]interface{})
resultList := new([][]string)
var result = []string{}
var fields = []string{
"Task Name",
"Task Spec",
@ -339,10 +337,10 @@ func taskStatus(rw http.ResponseWriter, req *http.Request) {
"",
}
for tname, tk := range toolbox.AdminTaskList {
result = []string{
result := []string{
tname,
fmt.Sprintf("%s", tk.GetSpec()),
fmt.Sprintf("%s", tk.GetStatus()),
tk.GetSpec(),
tk.GetStatus(),
tk.GetPrev().String(),
}
*resultList = append(*resultList, result)

6
app.go
View File

@ -348,9 +348,9 @@ func Any(rootpath string, f FilterFunc) *App {
// Handler used to register a Handler router
// usage:
// beego.Handler("/api", func(ctx *context.Context){
// ctx.Output.Body("hello world")
// })
// beego.Handler("/api", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
// fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
// }))
func Handler(rootpath string, h http.Handler, options ...interface{}) *App {
BeeApp.Handlers.Handler(rootpath, h, options...)
return BeeApp

View File

@ -23,7 +23,7 @@ import (
const (
// VERSION represent beego web framework version.
VERSION = "1.8.0"
VERSION = "1.8.1"
// DEV is for develop
DEV = "dev"

6
cache/conv_test.go vendored
View File

@ -118,14 +118,14 @@ func TestGetFloat64(t *testing.T) {
func TestGetBool(t *testing.T) {
var t1 = true
if true != GetBool(t1) {
if !GetBool(t1) {
t.Error("get bool from bool error")
}
var t2 = "true"
if true != GetBool(t2) {
if !GetBool(t2) {
t.Error("get bool from string error")
}
if false != GetBool(nil) {
if GetBool(nil) {
t.Error("get bool from nil error")
}
}

View File

@ -146,10 +146,7 @@ func (rc *Cache) IsExist(key string) bool {
}
}
_, err := rc.conn.Get(key)
if err != nil {
return false
}
return true
return !(err != nil)
}
// ClearAll clear all cached in memcache.

View File

@ -137,7 +137,7 @@ func (rc *Cache) IsExist(key string) bool {
if err != nil {
return false
}
if v == false {
if !v {
if _, err = rc.do("HDEL", rc.key, key); err != nil {
return false
}

19
cache/ssdb/ssdb.go vendored
View File

@ -53,7 +53,7 @@ func (rc *Cache) GetMulti(keys []string) []interface{} {
resSize := len(res)
if err == nil {
for i := 1; i < resSize; i += 2 {
values = append(values, string(res[i+1]))
values = append(values, res[i+1])
}
return values
}
@ -71,10 +71,7 @@ func (rc *Cache) DelMulti(keys []string) error {
}
}
_, err := rc.conn.Do("multi_del", keys)
if err != nil {
return err
}
return nil
return err
}
// Put put value to memcache. only support string.
@ -113,10 +110,7 @@ func (rc *Cache) Delete(key string) error {
}
}
_, err := rc.conn.Del(key)
if err != nil {
return err
}
return nil
return err
}
// Incr increase counter.
@ -175,7 +169,7 @@ func (rc *Cache) ClearAll() error {
}
keys := []string{}
for i := 1; i < size; i += 2 {
keys = append(keys, string(resp[i]))
keys = append(keys, resp[i])
}
_, e := rc.conn.Do("multi_del", keys)
if e != nil {
@ -229,10 +223,7 @@ func (rc *Cache) connectInit() error {
}
var err error
rc.conn, err = ssdb.Connect(host, port)
if err != nil {
return err
}
return nil
return err
}
func init() {

View File

@ -345,7 +345,7 @@ func assignSingleConfig(p interface{}, ac config.Configer) {
case reflect.String:
pf.SetString(ac.DefaultString(name, pf.String()))
case reflect.Int, reflect.Int64:
pf.SetInt(int64(ac.DefaultInt64(name, pf.Int())))
pf.SetInt(ac.DefaultInt64(name, pf.Int()))
case reflect.Bool:
pf.SetBool(ac.DefaultBool(name, pf.Bool()))
case reflect.Struct:

View File

@ -21,6 +21,7 @@ import (
"io"
"io/ioutil"
"os"
"os/user"
"path/filepath"
"strconv"
"strings"
@ -184,10 +185,17 @@ func (ini *IniConfig) parseData(dir string, data []byte) (*IniConfigContainer, e
// ParseData parse ini the data
// When include other.conf,other.conf is either absolute directory
// or under beego in default temporary directory(/tmp/beego).
// or under beego in default temporary directory(/tmp/beego[-username]).
func (ini *IniConfig) ParseData(data []byte) (Configer, error) {
dir := filepath.Join(os.TempDir(), "beego")
os.MkdirAll(dir, os.ModePerm)
dir := "beego"
currentUser, err := user.Current()
if err == nil {
dir = "beego-" + currentUser.Username
}
dir = filepath.Join(os.TempDir(), dir)
if err = os.MkdirAll(dir, os.ModePerm); err != nil {
return nil, err
}
return ini.parseData(dir, data)
}
@ -397,11 +405,8 @@ func (c *IniConfigContainer) SaveConfigFile(filename string) (err error) {
}
}
}
if _, err = buf.WriteTo(f); err != nil {
return err
}
return nil
_, err = buf.WriteTo(f)
return err
}
// Set writes a new value for key.
@ -416,7 +421,7 @@ func (c *IniConfigContainer) Set(key, value string) error {
var (
section, k string
sectionKey = strings.Split(key, "::")
sectionKey = strings.Split(strings.ToLower(key), "::")
)
if len(sectionKey) >= 2 {

View File

@ -181,7 +181,7 @@ name=mysql
cfgData := string(data)
datas := strings.Split(saveResult, "\n")
for _, line := range datas {
if strings.Contains(cfgData, line+"\n") == false {
if !strings.Contains(cfgData, line+"\n") {
t.Fatalf("different after save ini config file. need contains %q", line)
}
}

View File

@ -73,8 +73,8 @@ func TestBind(t *testing.T) {
{"/?human.ID=888&human.Nick=astaxie&human.Ms=true&human[Pwd]=pass", []testItem{{"human", Human{}, Human{ID: 888, Nick: "astaxie", Ms: true, Pwd: "pass"}}}},
{"/?human[0].ID=888&human[0].Nick=astaxie&human[0].Ms=true&human[0][Pwd]=pass01&human[1].ID=999&human[1].Nick=ysqi&human[1].Ms=On&human[1].Pwd=pass02",
[]testItem{{"human", []Human{}, []Human{
Human{ID: 888, Nick: "astaxie", Ms: true, Pwd: "pass01"},
Human{ID: 999, Nick: "ysqi", Ms: true, Pwd: "pass02"},
{ID: 888, Nick: "astaxie", Ms: true, Pwd: "pass01"},
{ID: 999, Nick: "ysqi", Ms: true, Pwd: "pass02"},
}}}},
{

View File

@ -105,7 +105,7 @@ func (output *BeegoOutput) Cookie(name string, value string, others ...interface
switch {
case maxAge > 0:
fmt.Fprintf(&b, "; Expires=%s; Max-Age=%d", time.Now().Add(time.Duration(maxAge)*time.Second).UTC().Format(time.RFC1123), maxAge)
case maxAge < 0:
case maxAge <= 0:
fmt.Fprintf(&b, "; Max-Age=0")
}
}

View File

@ -223,7 +223,7 @@ func (c *Controller) RenderBytes() ([]byte, error) {
}
buf.Reset()
ExecuteViewPathTemplate(&buf, c.Layout, c.viewPath() ,c.Data)
ExecuteViewPathTemplate(&buf, c.Layout, c.viewPath(), c.Data)
}
return buf.Bytes(), err
}
@ -249,7 +249,7 @@ func (c *Controller) renderTemplate() (bytes.Buffer, error) {
}
}
}
BuildTemplate(c.viewPath() , buildFiles...)
BuildTemplate(c.viewPath(), buildFiles...)
}
return buf, ExecuteViewPathTemplate(&buf, c.TplName, c.viewPath(), c.Data)
}
@ -314,7 +314,7 @@ func (c *Controller) ServeJSON(encoding ...bool) {
if BConfig.RunMode == PROD {
hasIndent = false
}
if len(encoding) > 0 && encoding[0] == true {
if len(encoding) > 0 && encoding[0] {
hasEncoding = true
}
c.Ctx.Output.JSON(c.Data["json"], hasIndent, hasEncoding)

View File

@ -172,10 +172,10 @@ func TestAdditionalViewPaths(t *testing.T) {
t.Fatal("TestAdditionalViewPaths expected error")
}
}()
ctrl.RenderString();
ctrl.RenderString()
}()
ctrl.TplName = "file2.tpl"
ctrl.ViewPath = dir2
ctrl.RenderString();
ctrl.RenderString()
}

View File

@ -48,7 +48,7 @@ func TestFlashHeader(t *testing.T) {
// match for the expected header
res := strings.Contains(sc, "BEEGO_FLASH=%00notice%23BEEGOFLASH%23TestFlashString%00")
// validate the assertion
if res != true {
if !res {
t.Errorf("TestFlashHeader() unable to validate flash message")
}
}

View File

@ -21,7 +21,7 @@ func newGraceListener(l net.Listener, srv *Server) (el *graceListener) {
server: srv,
}
go func() {
_ = <-el.stop
<-el.stop
el.stopped = true
el.stop <- el.Listener.Close()
}()

View File

@ -196,7 +196,6 @@ func (srv *Server) signalHooks(ppFlag int, sig os.Signal) {
for _, f := range srv.SignalHooks[ppFlag][sig] {
f()
}
return
}
// shutdown closes the listener so that no new connections are accepted. it also

View File

@ -335,7 +335,7 @@ func (b *BeegoHTTPRequest) JSONBody(obj interface{}) (*BeegoHTTPRequest, error)
func (b *BeegoHTTPRequest) buildURL(paramBody string) {
// build GET url with query string
if b.req.Method == "GET" && len(paramBody) > 0 {
if strings.Index(b.url, "?") != -1 {
if strings.Contains(b.url, "?") {
b.url += "&" + paramBody
} else {
b.url = b.url + "?" + paramBody
@ -344,7 +344,7 @@ func (b *BeegoHTTPRequest) buildURL(paramBody string) {
}
// build POST/PUT/PATCH url and body
if (b.req.Method == "POST" || b.req.Method == "PUT" || b.req.Method == "PATCH") && b.req.Body == nil {
if (b.req.Method == "POST" || b.req.Method == "PUT" || b.req.Method == "PATCH" || b.req.Method == "DELETE") && b.req.Body == nil {
// with files
if len(b.files) > 0 {
pr, pw := io.Pipe()

View File

@ -102,6 +102,14 @@ func TestSimpleDelete(t *testing.T) {
t.Log(str)
}
func TestSimpleDeleteParam(t *testing.T) {
str, err := Delete("http://httpbin.org/delete").Param("key", "val").String()
if err != nil {
t.Fatal(err)
}
t.Log(str)
}
func TestWithCookie(t *testing.T) {
v := "smallfish"
str, err := Get("http://httpbin.org/cookies/set?k1=" + v).SetEnableCookie(true).String()

View File

@ -395,7 +395,7 @@ func sovLog(x uint64) (n int) {
return n
}
func sozLog(x uint64) (n int) {
return sovLog(uint64((x << 1) ^ uint64((int64(x) >> 63))))
return sovLog((x << 1) ^ (x >> 63))
}
func (m *Log) Unmarshal(data []byte) error {
var hasFields [1]uint64

View File

@ -76,7 +76,7 @@ func signature(project *LogProject, method, uri string,
var keys sort.StringSlice
vals := u.Query()
for k, _ := range vals {
for k := range vals {
keys = append(keys, k)
}
@ -109,4 +109,3 @@ func signature(project *LogProject, method, uri string,
digest = base64.StdEncoding.EncodeToString(mac.Sum(nil))
return
}

View File

@ -41,7 +41,7 @@ var colors = []brush{
newBrush("1;33"), // Warning yellow
newBrush("1;32"), // Notice green
newBrush("1;34"), // Informational blue
newBrush("1;34"), // Debug blue
newBrush("1;44"), // Debug Background blue
}
// consoleWriter implements LoggerInterface and writes messages to terminal.

View File

@ -193,16 +193,14 @@ func (w *fileLogWriter) dailyRotate(openTime time.Time) {
y, m, d := openTime.Add(24 * time.Hour).Date()
nextDay := time.Date(y, m, d, 0, 0, 0, 0, openTime.Location())
tm := time.NewTimer(time.Duration(nextDay.UnixNano() - openTime.UnixNano() + 100))
select {
case <-tm.C:
w.Lock()
if w.needRotate(0, time.Now().Day()) {
if err := w.doRotate(time.Now()); err != nil {
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
}
<-tm.C
w.Lock()
if w.needRotate(0, time.Now().Day()) {
if err := w.doRotate(time.Now()); err != nil {
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
}
w.Unlock()
}
w.Unlock()
}
func (w *fileLogWriter) lines() (int, error) {
@ -270,7 +268,7 @@ func (w *fileLogWriter) doRotate(logTime time.Time) error {
// Rename the file to its new found name
// even if occurs error,we MUST guarantee to restart new logger
err = os.Rename(w.Filename, fName)
err = os.Chmod(fName, os.FileMode(440))
err = os.Chmod(fName, os.FileMode(0440))
// re-start logger
RESTART_LOGGER:

View File

@ -162,7 +162,27 @@ func TestFileRotate_05(t *testing.T) {
testFileDailyRotate(t, fn1, fn2)
os.Remove(fn)
}
func TestFileRotate_06(t *testing.T) { //test file mode
log := NewLogger(10000)
log.SetLogger("file", `{"filename":"test3.log","maxlines":4}`)
log.Debug("debug")
log.Info("info")
log.Notice("notice")
log.Warning("warning")
log.Error("error")
log.Alert("alert")
log.Critical("critical")
log.Emergency("emergency")
rotateName := "test3" + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), 1) + ".log"
s, _ := os.Lstat(rotateName)
if s.Mode() != 0440 {
os.Remove(rotateName)
os.Remove("test3.log")
t.Fatal("rotate file mode error")
}
os.Remove(rotateName)
os.Remove("test3.log")
}
func testFileRotate(t *testing.T, fn1, fn2 string) {
fw := &fileLogWriter{
Daily: true,

View File

@ -25,11 +25,7 @@ func newJLWriter() Logger {
// Init JLWriter with json config string
func (s *JLWriter) Init(jsonconfig string) error {
err := json.Unmarshal([]byte(jsonconfig), s)
if err != nil {
return err
}
return nil
return json.Unmarshal([]byte(jsonconfig), s)
}
// WriteMsg write message in smtp writer.
@ -65,12 +61,10 @@ func (s *JLWriter) WriteMsg(when time.Time, msg string, level int) error {
// Flush implementing method. empty.
func (s *JLWriter) Flush() {
return
}
// Destroy implementing method. empty.
func (s *JLWriter) Destroy() {
return
}
func init() {

View File

@ -275,7 +275,7 @@ func (bl *BeeLogger) writeMsg(logLevel int, msg string, v ...interface{}) error
line = 0
}
_, filename := path.Split(file)
msg = "[" + filename + ":" + strconv.FormatInt(int64(line), 10) + "] " + msg
msg = "[" + filename + ":" + strconv.Itoa(line) + "] " + msg
}
//set level info in front of filename info
@ -561,11 +561,7 @@ func SetLogFuncCallDepth(d int) {
// SetLogger sets a new logger.
func SetLogger(adapter string, config ...string) error {
err := beeLogger.SetLogger(adapter, config...)
if err != nil {
return err
}
return nil
return beeLogger.SetLogger(adapter, config...)
}
// Emergency logs a message at emergency level.

View File

@ -21,11 +21,7 @@ func newSLACKWriter() Logger {
// Init SLACKWriter with json config string
func (s *SLACKWriter) Init(jsonconfig string) error {
err := json.Unmarshal([]byte(jsonconfig), s)
if err != nil {
return err
}
return nil
return json.Unmarshal([]byte(jsonconfig), s)
}
// WriteMsg write message in smtp writer.
@ -53,12 +49,10 @@ func (s *SLACKWriter) WriteMsg(when time.Time, msg string, level int) error {
// Flush implementing method. empty.
func (s *SLACKWriter) Flush() {
return
}
// Destroy implementing method. empty.
func (s *SLACKWriter) Destroy() {
return
}
func init() {

View File

@ -52,11 +52,7 @@ func newSMTPWriter() Logger {
// "level":LevelError
// }
func (s *SMTPWriter) Init(jsonconfig string) error {
err := json.Unmarshal([]byte(jsonconfig), s)
if err != nil {
return err
}
return nil
return json.Unmarshal([]byte(jsonconfig), s)
}
func (s *SMTPWriter) getSMTPAuth(host string) smtp.Auth {
@ -106,7 +102,7 @@ func (s *SMTPWriter) sendMail(hostAddressWithPort string, auth smtp.Auth, fromAd
if err != nil {
return err
}
_, err = w.Write([]byte(msgContent))
_, err = w.Write(msgContent)
if err != nil {
return err
}
@ -116,12 +112,7 @@ func (s *SMTPWriter) sendMail(hostAddressWithPort string, auth smtp.Auth, fromAd
return err
}
err = client.Quit()
if err != nil {
return err
}
return nil
return client.Quit()
}
// WriteMsg write message in smtp writer.
@ -147,12 +138,10 @@ func (s *SMTPWriter) WriteMsg(when time.Time, msg string, level int) error {
// Flush implementing method. empty.
func (s *SMTPWriter) Flush() {
return
}
// Destroy implementing method. empty.
func (s *SMTPWriter) Destroy() {
return
}
func init() {

View File

@ -267,13 +267,12 @@ func addPrefix(t *Tree, prefix string) {
addPrefix(t.wildcard, prefix)
}
for _, l := range t.leaves {
if c, ok := l.runObject.(*controllerInfo); ok {
if c, ok := l.runObject.(*ControllerInfo); ok {
if !strings.HasPrefix(c.pattern, prefix) {
c.pattern = prefix + c.pattern
}
}
}
}
// NSCond is Namespace Condition
@ -284,16 +283,16 @@ func NSCond(cond namespaceCond) LinkNamespace {
}
// NSBefore Namespace BeforeRouter filter
func NSBefore(filiterList ...FilterFunc) LinkNamespace {
func NSBefore(filterList ...FilterFunc) LinkNamespace {
return func(ns *Namespace) {
ns.Filter("before", filiterList...)
ns.Filter("before", filterList...)
}
}
// NSAfter add Namespace FinishRouter filter
func NSAfter(filiterList ...FilterFunc) LinkNamespace {
func NSAfter(filterList ...FilterFunc) LinkNamespace {
return func(ns *Namespace) {
ns.Filter("after", filiterList...)
ns.Filter("after", filterList...)
}
}

View File

@ -139,10 +139,7 @@ func TestNamespaceCond(t *testing.T) {
ns := NewNamespace("/v2")
ns.Cond(func(ctx *context.Context) bool {
if ctx.Input.Domain() == "beego.me" {
return true
}
return false
return ctx.Input.Domain() == "beego.me"
}).
AutoRouter(&TestController{})
AddNamespace(ns)

View File

@ -150,7 +150,7 @@ func (d *commandSyncDb) Run() error {
}
for _, fi := range mi.fields.fieldsDB {
if _, ok := columns[fi.column]; ok == false {
if _, ok := columns[fi.column]; !ok {
fields = append(fields, fi)
}
}
@ -175,7 +175,7 @@ func (d *commandSyncDb) Run() error {
}
for _, idx := range indexes[mi.table] {
if d.al.DbBaser.IndexExists(db, idx.Table, idx.Name) == false {
if !d.al.DbBaser.IndexExists(db, idx.Table, idx.Name) {
if !d.noInfo {
fmt.Printf("create index `%s` for table `%s`\n", idx.Name, idx.Table)
}

View File

@ -89,7 +89,7 @@ checkColumn:
col = T["float64"]
case TypeDecimalField:
s := T["float64-decimal"]
if strings.Index(s, "%d") == -1 {
if !strings.Contains(s, "%d") {
col = s
} else {
col = fmt.Sprintf(s, fi.digits, fi.decimals)
@ -120,7 +120,7 @@ func getColumnAddQuery(al *alias, fi *fieldInfo) string {
Q := al.DbBaser.TableQuote()
typ := getColumnTyp(al, fi)
if fi.null == false {
if !fi.null {
typ += " " + "NOT NULL"
}
@ -172,7 +172,7 @@ func getDbCreateSQL(al *alias) (sqls []string, tableIndexes map[string][]dbIndex
} else {
column += col
if fi.null == false {
if !fi.null {
column += " " + "NOT NULL"
}
@ -192,7 +192,7 @@ func getDbCreateSQL(al *alias) (sqls []string, tableIndexes map[string][]dbIndex
}
}
if strings.Index(column, "%COL%") != -1 {
if strings.Contains(column, "%COL%") {
column = strings.Replace(column, "%COL%", fi.column, -1)
}

View File

@ -48,7 +48,7 @@ var (
"lte": true,
"eq": true,
"nq": true,
"ne": true,
"ne": true,
"startswith": true,
"endswith": true,
"istartswith": true,
@ -87,7 +87,7 @@ func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, cols []string,
} else {
panic(fmt.Errorf("wrong db field/column name `%s` for model `%s`", column, mi.fullName))
}
if fi.dbcol == false || fi.auto && skipAuto {
if !fi.dbcol || fi.auto && skipAuto {
continue
}
value, err := d.collectFieldValue(mi, fi, ind, insert, tz)
@ -224,7 +224,7 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val
value = nil
}
}
if fi.null == false && value == nil {
if !fi.null && value == nil {
return nil, fmt.Errorf("field `%s` cannot be NULL", fi.fullName)
}
}
@ -271,7 +271,7 @@ func (d *dbBase) PrepareInsert(q dbQuerier, mi *modelInfo) (stmtQuerier, string,
dbcols := make([]string, 0, len(mi.fields.dbcols))
marks := make([]string, 0, len(mi.fields.dbcols))
for _, fi := range mi.fields.fieldsDB {
if fi.auto == false {
if !fi.auto {
dbcols = append(dbcols, fi.column)
marks = append(marks, "?")
}
@ -326,7 +326,7 @@ func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Lo
} else {
// default use pk value as where condtion.
pkColumn, pkValue, ok := getExistPk(mi, ind)
if ok == false {
if !ok {
return ErrMissPK
}
whereCols = []string{pkColumn}
@ -592,7 +592,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
row := q.QueryRow(query, values...)
var id int64
err = row.Scan(&id)
if err.Error() == `pq: syntax error at or near "ON"` {
if err != nil && err.Error() == `pq: syntax error at or near "ON"` {
err = fmt.Errorf("postgres version must 9.5 or higher")
}
return id, err
@ -601,7 +601,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
// execute update sql dbQuerier with given struct reflect.Value.
func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string) (int64, error) {
pkName, pkValue, ok := getExistPk(mi, ind)
if ok == false {
if !ok {
return 0, ErrMissPK
}
@ -654,7 +654,7 @@ func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.
} else {
// default use pk value as where condtion.
pkColumn, pkValue, ok := getExistPk(mi, ind)
if ok == false {
if !ok {
return 0, ErrMissPK
}
whereCols = []string{pkColumn}
@ -699,7 +699,7 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
columns := make([]string, 0, len(params))
values := make([]interface{}, 0, len(params))
for col, val := range params {
if fi, ok := mi.fields.GetByAny(col); ok == false || fi.dbcol == false {
if fi, ok := mi.fields.GetByAny(col); !ok || !fi.dbcol {
panic(fmt.Errorf("wrong field/column name `%s`", col))
} else {
columns = append(columns, fi.column)
@ -929,7 +929,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
if hasRel {
for _, fi := range mi.fields.fieldsDB {
if fi.fieldType&IsRelField > 0 {
if maps[fi.column] == false {
if !maps[fi.column] {
tCols = append(tCols, fi.column)
}
}
@ -987,7 +987,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
var cnt int64
for rs.Next() {
if one && cnt == 0 || one == false {
if one && cnt == 0 || !one {
if err := rs.Scan(refs...); err != nil {
return 0, err
}
@ -1067,7 +1067,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
cnt++
}
if one == false {
if !one {
if cnt > 0 {
ind.Set(slice)
} else {
@ -1357,7 +1357,7 @@ end:
func (d *dbBase) setFieldValue(fi *fieldInfo, value interface{}, field reflect.Value) (interface{}, error) {
fieldType := fi.fieldType
isNative := fi.isFielder == false
isNative := !fi.isFielder
setValue:
switch {
@ -1533,7 +1533,7 @@ setValue:
}
}
if isNative == false {
if !isNative {
fd := field.Addr().Interface().(Fielder)
err := fd.SetRaw(value)
if err != nil {
@ -1594,7 +1594,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
infos = make([]*fieldInfo, 0, len(exprs))
for _, ex := range exprs {
index, name, fi, suc := tables.parseExprs(mi, strings.Split(ex, ExprSep))
if suc == false {
if !suc {
panic(fmt.Errorf("unknown field/column name `%s`", ex))
}
cols = append(cols, fmt.Sprintf("%s.%s%s%s %s%s%s", index, Q, fi.column, Q, Q, name, Q))

View File

@ -60,6 +60,8 @@ var (
"sqlite3": DRSqlite,
"tidb": DRTiDB,
"oracle": DROracle,
"oci8": DROracle, // github.com/mattn/go-oci8
"ora": DROracle, //https://github.com/rana/ora
}
dbBasers = map[DriverType]dbBaser{
DRMySQL: newdbBaseMysql(),
@ -186,7 +188,7 @@ func addAliasWthDB(aliasName, driverName string, db *sql.DB) (*alias, error) {
return nil, fmt.Errorf("register db Ping `%s`, %s", aliasName, err.Error())
}
if dataBaseCache.add(aliasName, al) == false {
if !dataBaseCache.add(aliasName, al) {
return nil, fmt.Errorf("DataBase alias name `%s` already registered, cannot reuse", aliasName)
}
@ -244,7 +246,7 @@ end:
// RegisterDriver Register a database driver use specify driver name, this can be definition the driver is which database type.
func RegisterDriver(driverName string, typ DriverType) error {
if t, ok := drivers[driverName]; ok == false {
if t, ok := drivers[driverName]; !ok {
drivers[driverName] = typ
} else {
if t != typ {

View File

@ -134,7 +134,7 @@ func (d *dbBaseSqlite) IndexExists(db dbQuerier, table string, name string) bool
defer rows.Close()
for rows.Next() {
var tmp, index sql.NullString
rows.Scan(&tmp, &index, &tmp)
rows.Scan(&tmp, &index, &tmp, &tmp, &tmp)
if name == index.String {
return true
}

View File

@ -63,7 +63,7 @@ func (t *dbTables) set(names []string, mi *modelInfo, fi *fieldInfo, inner bool)
// add table info to collection.
func (t *dbTables) add(names []string, mi *modelInfo, fi *fieldInfo, inner bool) (*dbTable, bool) {
name := strings.Join(names, ExprSep)
if _, ok := t.tablesM[name]; ok == false {
if _, ok := t.tablesM[name]; !ok {
i := len(t.tables) + 1
jt := &dbTable{i, fmt.Sprintf("T%d", i), name, names, false, inner, mi, fi, nil}
t.tablesM[name] = jt
@ -261,7 +261,7 @@ loopFor:
fiN, okN = mmi.fields.GetByAny(exprs[i+1])
}
if isRel && (fi.mi.isThrough == false || num != i) {
if isRel && (!fi.mi.isThrough || num != i) {
if fi.null || t.skipEnd {
inner = false
}
@ -364,7 +364,7 @@ func (t *dbTables) getCondSQL(cond *Condition, sub bool, tz *time.Location) (whe
}
index, _, fi, suc := t.parseExprs(mi, exprs)
if suc == false {
if !suc {
panic(fmt.Errorf("unknown field/column name `%s`", strings.Join(p.exprs, ExprSep)))
}
@ -383,7 +383,7 @@ func (t *dbTables) getCondSQL(cond *Condition, sub bool, tz *time.Location) (whe
}
}
if sub == false && where != "" {
if !sub && where != "" {
where = "WHERE " + where
}
@ -403,7 +403,7 @@ func (t *dbTables) getGroupSQL(groups []string) (groupSQL string) {
exprs := strings.Split(group, ExprSep)
index, _, fi, suc := t.parseExprs(t.mi, exprs)
if suc == false {
if !suc {
panic(fmt.Errorf("unknown field/column name `%s`", strings.Join(exprs, ExprSep)))
}
@ -432,7 +432,7 @@ func (t *dbTables) getOrderSQL(orders []string) (orderSQL string) {
exprs := strings.Split(order, ExprSep)
index, _, fi, suc := t.parseExprs(t.mi, exprs)
if suc == false {
if !suc {
panic(fmt.Errorf("unknown field/column name `%s`", strings.Join(exprs, ExprSep)))
}

View File

@ -128,7 +128,7 @@ func bootStrap() {
if i := strings.LastIndex(fi.relThrough, "."); i != -1 && len(fi.relThrough) > (i+1) {
pn := fi.relThrough[:i]
rmi, ok := modelCache.getByFullName(fi.relThrough)
if ok == false || pn != rmi.pkg {
if !ok || pn != rmi.pkg {
err = fmt.Errorf("field `%s` wrong rel_through value `%s` cannot find table", fi.fullName, fi.relThrough)
goto end
}
@ -171,7 +171,7 @@ func bootStrap() {
break
}
}
if inModel == false {
if !inModel {
rmi := fi.relModelInfo
ffi := new(fieldInfo)
ffi.name = mi.name
@ -185,7 +185,7 @@ func bootStrap() {
} else {
ffi.fieldType = RelReverseMany
}
if rmi.fields.Add(ffi) == false {
if !rmi.fields.Add(ffi) {
added := false
for cnt := 0; cnt < 5; cnt++ {
ffi.name = fmt.Sprintf("%s%d", mi.name, cnt)
@ -195,7 +195,7 @@ func bootStrap() {
break
}
}
if added == false {
if !added {
panic(fmt.Errorf("cannot generate auto reverse field info `%s` to `%s`", fi.fullName, ffi.fullName))
}
}
@ -248,7 +248,7 @@ func bootStrap() {
break mForA
}
}
if found == false {
if !found {
err = fmt.Errorf("reverse field `%s` not found in model `%s`", fi.fullName, fi.relModelInfo.fullName)
goto end
}
@ -267,7 +267,7 @@ func bootStrap() {
break mForB
}
}
if found == false {
if !found {
mForC:
for _, ffi := range fi.relModelInfo.fields.fieldsByType[RelManyToMany] {
conditions := fi.relThrough != "" && fi.relThrough == ffi.relThrough ||
@ -287,7 +287,7 @@ func bootStrap() {
}
}
}
if found == false {
if !found {
err = fmt.Errorf("reverse field for `%s` not found in model `%s`", fi.fullName, fi.relModelInfo.fullName)
goto end
}

View File

@ -47,7 +47,7 @@ func (f *fields) Add(fi *fieldInfo) (added bool) {
} else {
return
}
if _, ok := f.fieldsByType[fi.fieldType]; ok == false {
if _, ok := f.fieldsByType[fi.fieldType]; !ok {
f.fieldsByType[fi.fieldType] = make([]*fieldInfo, 0)
}
f.fieldsByType[fi.fieldType] = append(f.fieldsByType[fi.fieldType], fi)
@ -334,12 +334,12 @@ checkType:
switch onDelete {
case odCascade, odDoNothing:
case odSetDefault:
if initial.Exist() == false {
if !initial.Exist() {
err = errors.New("on_delete: set_default need set field a default value")
goto end
}
case odSetNULL:
if fi.null == false {
if !fi.null {
err = errors.New("on_delete: set_null need set field null")
goto end
}

View File

@ -78,7 +78,7 @@ func addModelFields(mi *modelInfo, ind reflect.Value, mName string, index []int)
fi.fieldIndex = append(index, i)
fi.mi = mi
fi.inModel = true
if mi.fields.Add(fi) == false {
if !mi.fields.Add(fi) {
err = fmt.Errorf("duplicate column name: %s", fi.column)
break
}

View File

@ -122,21 +122,13 @@ func (o *orm) getFieldInfo(mi *modelInfo, name string) *fieldInfo {
// read data to model
func (o *orm) Read(md interface{}, cols ...string) error {
mi, ind := o.getMiInd(md, true)
err := o.alias.DbBaser.Read(o.db, mi, ind, o.alias.TZ, cols, false)
if err != nil {
return err
}
return nil
return o.alias.DbBaser.Read(o.db, mi, ind, o.alias.TZ, cols, false)
}
// read data to model, like Read(), but use "SELECT FOR UPDATE" form
func (o *orm) ReadForUpdate(md interface{}, cols ...string) error {
mi, ind := o.getMiInd(md, true)
err := o.alias.DbBaser.Read(o.db, mi, ind, o.alias.TZ, cols, true)
if err != nil {
return err
}
return nil
return o.alias.DbBaser.Read(o.db, mi, ind, o.alias.TZ, cols, true)
}
// Try to read a row from the database, or insert one if it doesn't exist
@ -238,15 +230,11 @@ func (o *orm) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64
// cols set the columns those want to update.
func (o *orm) Update(md interface{}, cols ...string) (int64, error) {
mi, ind := o.getMiInd(md, true)
num, err := o.alias.DbBaser.Update(o.db, mi, ind, o.alias.TZ, cols)
if err != nil {
return num, err
}
return num, nil
return o.alias.DbBaser.Update(o.db, mi, ind, o.alias.TZ, cols)
}
// delete model in database
// cols shows the delete conditions values read from. deafult is pk
// cols shows the delete conditions values read from. default is pk
func (o *orm) Delete(md interface{}, cols ...string) (int64, error) {
mi, ind := o.getMiInd(md, true)
num, err := o.alias.DbBaser.Delete(o.db, mi, ind, o.alias.TZ, cols)
@ -361,7 +349,7 @@ func (o *orm) queryRelated(md interface{}, name string) (*modelInfo, *fieldInfo,
fi := o.getFieldInfo(mi, name)
_, _, exist := getExistPk(mi, ind)
if exist == false {
if !exist {
panic(ErrMissPK)
}
@ -489,7 +477,7 @@ func (o *orm) Begin() error {
// commit transaction
func (o *orm) Commit() error {
if o.isTx == false {
if !o.isTx {
return ErrTxDone
}
err := o.db.(txEnder).Commit()
@ -504,7 +492,7 @@ func (o *orm) Commit() error {
// rollback transaction
func (o *orm) Rollback() error {
if o.isTx == false {
if !o.isTx {
return ErrTxDone
}
err := o.db.(txEnder).Rollback()

View File

@ -72,7 +72,7 @@ func (o *queryM2M) Add(mds ...interface{}) (int64, error) {
}
_, v1, exist := getExistPk(o.mi, o.ind)
if exist == false {
if !exist {
panic(ErrMissPK)
}
@ -87,7 +87,7 @@ func (o *queryM2M) Add(mds ...interface{}) (int64, error) {
v2 = ind.Interface()
} else {
_, v2, exist = getExistPk(fi.relModelInfo, ind)
if exist == false {
if !exist {
panic(ErrMissPK)
}
}
@ -104,11 +104,7 @@ func (o *queryM2M) Remove(mds ...interface{}) (int64, error) {
fi := o.fi
qs := o.qs.Filter(fi.reverseFieldInfo.name, o.md)
nums, err := qs.Filter(fi.reverseFieldInfoTwo.name+ExprSep+"in", mds).Delete()
if err != nil {
return nums, err
}
return nums, nil
return qs.Filter(fi.reverseFieldInfoTwo.name+ExprSep+"in", mds).Delete()
}
// check model is existed in relationship of origin model

View File

@ -93,14 +93,14 @@ wrongArg:
}
func AssertIs(a interface{}, args ...interface{}) error {
if ok, err := ValuesCompare(true, a, args...); ok == false {
if ok, err := ValuesCompare(true, a, args...); !ok {
return err
}
return nil
}
func AssertNot(a interface{}, args ...interface{}) error {
if ok, err := ValuesCompare(false, a, args...); ok == false {
if ok, err := ValuesCompare(false, a, args...); !ok {
return err
}
return nil

View File

@ -92,11 +92,11 @@ func (f StrTo) Int64() (int64, error) {
i := new(big.Int)
ni, ok := i.SetString(f.String(), 10) // octal
if !ok {
return int64(v), err
return v, err
}
return ni.Int64(), nil
}
return int64(v), err
return v, err
}
// Uint string to uint
@ -130,11 +130,11 @@ func (f StrTo) Uint64() (uint64, error) {
i := new(big.Int)
ni, ok := i.SetString(f.String(), 10)
if !ok {
return uint64(v), err
return v, err
}
return ni.Uint64(), nil
}
return uint64(v), err
return v, err
}
// String string to string
@ -225,7 +225,7 @@ func camelString(s string) string {
if d == '_' {
flag = true
continue
} else if flag == true {
} else if flag {
if d >= 'a' && d <= 'z' {
d = d - 32
}

View File

@ -17,7 +17,6 @@ package beego
import (
"fmt"
"net/http"
"os"
"path"
"path/filepath"
"reflect"
@ -109,7 +108,8 @@ func ExceptMethodAppend(action string) {
exceptMethod = append(exceptMethod, action)
}
type controllerInfo struct {
// ControllerInfo holds information about the controller.
type ControllerInfo struct {
pattern string
controllerType reflect.Type
methods map[string]string
@ -176,7 +176,7 @@ func (p *ControllerRegister) Add(pattern string, c ControllerInterface, mappingM
}
}
route := &controllerInfo{}
route := &ControllerInfo{}
route.pattern = pattern
route.methods = methods
route.routerType = routerTypeBeego
@ -198,7 +198,7 @@ func (p *ControllerRegister) Add(pattern string, c ControllerInterface, mappingM
}
}
func (p *ControllerRegister) addToRouter(method, pattern string, r *controllerInfo) {
func (p *ControllerRegister) addToRouter(method, pattern string, r *ControllerInfo) {
if !BConfig.RouterCaseSensitive {
pattern = strings.ToLower(pattern)
}
@ -219,13 +219,11 @@ func (p *ControllerRegister) Include(cList ...ControllerInterface) {
for _, c := range cList {
reflectVal := reflect.ValueOf(c)
t := reflect.Indirect(reflectVal).Type()
gopath := os.Getenv("GOPATH")
if gopath == "" {
wgopath := utils.GetGOPATHs()
if len(wgopath) == 0 {
panic("you are in dev mode. So please set gopath")
}
pkgpath := ""
wgopath := filepath.SplitList(gopath)
for _, wg := range wgopath {
wg, _ = filepath.EvalSymlinks(filepath.Join(wg, "src", t.PkgPath()))
if utils.FileExists(wg) {
@ -335,7 +333,7 @@ func (p *ControllerRegister) AddMethod(method, pattern string, f FilterFunc) {
if _, ok := HTTPMETHOD[method]; method != "*" && !ok {
panic("not support http method: " + method)
}
route := &controllerInfo{}
route := &ControllerInfo{}
route.pattern = pattern
route.routerType = routerTypeRESTFul
route.runFunction = f
@ -361,7 +359,7 @@ func (p *ControllerRegister) AddMethod(method, pattern string, f FilterFunc) {
// Handler add user defined Handler
func (p *ControllerRegister) Handler(pattern string, h http.Handler, options ...interface{}) {
route := &controllerInfo{}
route := &ControllerInfo{}
route.pattern = pattern
route.routerType = routerTypeHandler
route.handler = h
@ -396,7 +394,7 @@ func (p *ControllerRegister) AddAutoPrefix(prefix string, c ControllerInterface)
controllerName := strings.TrimSuffix(ct.Name(), "Controller")
for i := 0; i < rt.NumMethod(); i++ {
if !utils.InSlice(rt.Method(i).Name, exceptMethod) {
route := &controllerInfo{}
route := &ControllerInfo{}
route.routerType = routerTypeBeego
route.methods = map[string]string{"*": rt.Method(i).Name}
route.controllerType = ct
@ -502,7 +500,7 @@ func (p *ControllerRegister) geturl(t *Tree, url, controllName, methodName strin
}
}
for _, l := range t.leaves {
if c, ok := l.runObject.(*controllerInfo); ok {
if c, ok := l.runObject.(*ControllerInfo); ok {
if c.routerType == routerTypeBeego &&
strings.HasSuffix(path.Join(c.controllerType.PkgPath(), c.controllerType.Name()), controllName) {
find := false
@ -629,7 +627,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
runRouter reflect.Type
findRouter bool
runMethod string
routerInfo *controllerInfo
routerInfo *ControllerInfo
isRunnable bool
)
context := p.pool.Get().(*beecontext.Context)
@ -670,7 +668,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
goto Admin
}
if r.Method != "GET" && r.Method != "HEAD" {
if r.Method != http.MethodGet && r.Method != http.MethodHead {
if BConfig.CopyRequestBody && !context.Input.IsUpload() {
context.Input.CopyBody(BConfig.MaxMemory)
}
@ -743,11 +741,11 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
} else {
runRouter = routerInfo.controllerType
method := r.Method
if r.Method == "POST" && context.Input.Query("_method") == "PUT" {
method = "PUT"
if r.Method == http.MethodPost && context.Input.Query("_method") == http.MethodPost {
method = http.MethodPut
}
if r.Method == "POST" && context.Input.Query("_method") == "DELETE" {
method = "DELETE"
if r.Method == http.MethodPost && context.Input.Query("_method") == http.MethodDelete {
method = http.MethodDelete
}
if m, ok := routerInfo.methods[method]; ok {
runMethod = m
@ -777,8 +775,8 @@ 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 BConfig.WebConfig.EnableXSRF {
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")) {
if r.Method == http.MethodPost || r.Method == http.MethodDelete || r.Method == http.MethodPut ||
(r.Method == http.MethodPost && (context.Input.Query("_method") == http.MethodDelete || context.Input.Query("_method") == http.MethodPut)) {
execController.CheckXSRFCookie()
}
}
@ -788,19 +786,19 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
if !context.ResponseWriter.Started {
//exec main logic
switch runMethod {
case "GET":
case http.MethodGet:
execController.Get()
case "POST":
case http.MethodPost:
execController.Post()
case "DELETE":
case http.MethodDelete:
execController.Delete()
case "PUT":
case http.MethodPut:
execController.Put()
case "HEAD":
case http.MethodHead:
execController.Head()
case "PATCH":
case http.MethodPatch:
execController.Patch()
case "OPTIONS":
case http.MethodOptions:
execController.Options()
default:
if !execController.HandlerFunc(runMethod) {
@ -887,7 +885,7 @@ Admin:
}
// FindRouter Find Router info for URL
func (p *ControllerRegister) FindRouter(context *beecontext.Context) (routerInfo *controllerInfo, isFind bool) {
func (p *ControllerRegister) FindRouter(context *beecontext.Context) (routerInfo *ControllerInfo, isFind bool) {
var urlPath = context.Input.URL()
if !BConfig.RouterCaseSensitive {
urlPath = strings.ToLower(urlPath)
@ -895,7 +893,7 @@ func (p *ControllerRegister) FindRouter(context *beecontext.Context) (routerInfo
httpMethod := context.Input.Method()
if t, ok := p.routers[httpMethod]; ok {
runObject := t.Match(urlPath, context)
if r, ok := runObject.(*controllerInfo); ok {
if r, ok := runObject.(*ControllerInfo); ok {
return r, true
}
}

View File

@ -502,10 +502,10 @@ func TestFilterBeforeRouter(t *testing.T) {
rw, r := testRequest("GET", url)
mux.ServeHTTP(rw, r)
if strings.Contains(rw.Body.String(), "BeforeRouter1") == false {
if !strings.Contains(rw.Body.String(), "BeforeRouter1") {
t.Errorf(testName + " BeforeRouter did not run")
}
if strings.Contains(rw.Body.String(), "hello") == true {
if strings.Contains(rw.Body.String(), "hello") {
t.Errorf(testName + " BeforeRouter did not return properly")
}
}
@ -525,13 +525,13 @@ func TestFilterBeforeExec(t *testing.T) {
rw, r := testRequest("GET", url)
mux.ServeHTTP(rw, r)
if strings.Contains(rw.Body.String(), "BeforeExec1") == false {
if !strings.Contains(rw.Body.String(), "BeforeExec1") {
t.Errorf(testName + " BeforeExec did not run")
}
if strings.Contains(rw.Body.String(), "hello") == true {
if strings.Contains(rw.Body.String(), "hello") {
t.Errorf(testName + " BeforeExec did not return properly")
}
if strings.Contains(rw.Body.String(), "BeforeRouter") == true {
if strings.Contains(rw.Body.String(), "BeforeRouter") {
t.Errorf(testName + " BeforeRouter ran in error")
}
}
@ -552,16 +552,16 @@ func TestFilterAfterExec(t *testing.T) {
rw, r := testRequest("GET", url)
mux.ServeHTTP(rw, r)
if strings.Contains(rw.Body.String(), "AfterExec1") == false {
if !strings.Contains(rw.Body.String(), "AfterExec1") {
t.Errorf(testName + " AfterExec did not run")
}
if strings.Contains(rw.Body.String(), "hello") == false {
if !strings.Contains(rw.Body.String(), "hello") {
t.Errorf(testName + " handler did not run properly")
}
if strings.Contains(rw.Body.String(), "BeforeRouter") == true {
if strings.Contains(rw.Body.String(), "BeforeRouter") {
t.Errorf(testName + " BeforeRouter ran in error")
}
if strings.Contains(rw.Body.String(), "BeforeExec") == true {
if strings.Contains(rw.Body.String(), "BeforeExec") {
t.Errorf(testName + " BeforeExec ran in error")
}
}
@ -583,19 +583,19 @@ func TestFilterFinishRouter(t *testing.T) {
rw, r := testRequest("GET", url)
mux.ServeHTTP(rw, r)
if strings.Contains(rw.Body.String(), "FinishRouter1") == true {
if strings.Contains(rw.Body.String(), "FinishRouter1") {
t.Errorf(testName + " FinishRouter did not run")
}
if strings.Contains(rw.Body.String(), "hello") == false {
if !strings.Contains(rw.Body.String(), "hello") {
t.Errorf(testName + " handler did not run properly")
}
if strings.Contains(rw.Body.String(), "AfterExec1") == true {
if strings.Contains(rw.Body.String(), "AfterExec1") {
t.Errorf(testName + " AfterExec ran in error")
}
if strings.Contains(rw.Body.String(), "BeforeRouter") == true {
if strings.Contains(rw.Body.String(), "BeforeRouter") {
t.Errorf(testName + " BeforeRouter ran in error")
}
if strings.Contains(rw.Body.String(), "BeforeExec") == true {
if strings.Contains(rw.Body.String(), "BeforeExec") {
t.Errorf(testName + " BeforeExec ran in error")
}
}
@ -615,14 +615,14 @@ func TestFilterFinishRouterMultiFirstOnly(t *testing.T) {
rw, r := testRequest("GET", url)
mux.ServeHTTP(rw, r)
if strings.Contains(rw.Body.String(), "FinishRouter1") == false {
if !strings.Contains(rw.Body.String(), "FinishRouter1") {
t.Errorf(testName + " FinishRouter1 did not run")
}
if strings.Contains(rw.Body.String(), "hello") == false {
if !strings.Contains(rw.Body.String(), "hello") {
t.Errorf(testName + " handler did not run properly")
}
// not expected in body
if strings.Contains(rw.Body.String(), "FinishRouter2") == true {
if strings.Contains(rw.Body.String(), "FinishRouter2") {
t.Errorf(testName + " FinishRouter2 did run")
}
}
@ -642,44 +642,52 @@ func TestFilterFinishRouterMulti(t *testing.T) {
rw, r := testRequest("GET", url)
mux.ServeHTTP(rw, r)
if strings.Contains(rw.Body.String(), "FinishRouter1") == false {
if !strings.Contains(rw.Body.String(), "FinishRouter1") {
t.Errorf(testName + " FinishRouter1 did not run")
}
if strings.Contains(rw.Body.String(), "hello") == false {
if !strings.Contains(rw.Body.String(), "hello") {
t.Errorf(testName + " handler did not run properly")
}
if strings.Contains(rw.Body.String(), "FinishRouter2") == false {
if !strings.Contains(rw.Body.String(), "FinishRouter2") {
t.Errorf(testName + " FinishRouter2 did not run properly")
}
}
func beegoFilterNoOutput(ctx *context.Context) {
return
}
func beegoBeforeRouter1(ctx *context.Context) {
ctx.WriteString("|BeforeRouter1")
}
func beegoBeforeRouter2(ctx *context.Context) {
ctx.WriteString("|BeforeRouter2")
}
func beegoBeforeExec1(ctx *context.Context) {
ctx.WriteString("|BeforeExec1")
}
func beegoBeforeExec2(ctx *context.Context) {
ctx.WriteString("|BeforeExec2")
}
func beegoAfterExec1(ctx *context.Context) {
ctx.WriteString("|AfterExec1")
}
func beegoAfterExec2(ctx *context.Context) {
ctx.WriteString("|AfterExec2")
}
func beegoFinishRouter1(ctx *context.Context) {
ctx.WriteString("|FinishRouter1")
}
func beegoFinishRouter2(ctx *context.Context) {
ctx.WriteString("|FinishRouter2")
}
func beegoResetParams(ctx *context.Context) {
ctx.ResponseWriter.Header().Set("splat", ctx.Input.Param(":splat"))
}

View File

@ -155,10 +155,13 @@ func (cp *Provider) SessionInit(maxlifetime int64, savePath string) error {
func (cp *Provider) SessionRead(sid string) (session.Store, error) {
cp.b = cp.getBucket()
var doc []byte
var (
kv map[interface{}]interface{}
err error
doc []byte
)
err := cp.b.Get(sid, &doc)
var kv map[interface{}]interface{}
err = cp.b.Get(sid, &doc)
if doc == nil {
kv = make(map[interface{}]interface{})
} else {
@ -230,7 +233,6 @@ func (cp *Provider) SessionDestroy(sid string) error {
// SessionGC Recycle
func (cp *Provider) SessionGC() {
return
}
// SessionAll return all active session

View File

@ -12,8 +12,10 @@ import (
"github.com/siddontang/ledisdb/ledis"
)
var ledispder = &Provider{}
var c *ledis.DB
var (
ledispder = &Provider{}
c *ledis.DB
)
// SessionStore ledis session store
type SessionStore struct {
@ -97,27 +99,36 @@ func (lp *Provider) SessionInit(maxlifetime int64, savePath string) error {
}
cfg := new(config.Config)
cfg.DataDir = lp.savePath
nowLedis, err := ledis.Open(cfg)
c, err = nowLedis.Select(lp.db)
var ledisInstance *ledis.Ledis
ledisInstance, err = ledis.Open(cfg)
if err != nil {
println(err)
return nil
return err
}
return nil
c, err = ledisInstance.Select(lp.db)
return err
}
// SessionRead read ledis session by sid
func (lp *Provider) SessionRead(sid string) (session.Store, error) {
kvs, err := c.Get([]byte(sid))
var kv map[interface{}]interface{}
var (
kv map[interface{}]interface{}
kvs []byte
err error
)
if kvs, err = c.Get([]byte(sid)); err != nil {
return nil, err
}
if len(kvs) == 0 {
kv = make(map[interface{}]interface{})
} else {
kv, err = session.DecodeGob(kvs)
if err != nil {
if kv, err = session.DecodeGob(kvs); err != nil {
return nil, err
}
}
ls := &SessionStore{sid: sid, values: kv, maxlifetime: lp.maxlifetime}
return ls, nil
}
@ -125,10 +136,7 @@ func (lp *Provider) SessionRead(sid string) (session.Store, error) {
// SessionExist check ledis session exist by sid
func (lp *Provider) SessionExist(sid string) bool {
count, _ := c.Exists([]byte(sid))
if count == 0 {
return false
}
return true
return !(count == 0)
}
// SessionRegenerate generate new sid for ledis session
@ -145,18 +153,7 @@ func (lp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error)
c.Set([]byte(sid), data)
c.Expire([]byte(sid), lp.maxlifetime)
}
kvs, err := c.Get([]byte(sid))
var kv map[interface{}]interface{}
if len(kvs) == 0 {
kv = make(map[interface{}]interface{})
} else {
kv, err = session.DecodeGob([]byte(kvs))
if err != nil {
return nil, err
}
}
ls := &SessionStore{sid: sid, values: kv, maxlifetime: lp.maxlifetime}
return ls, nil
return lp.SessionRead(sid)
}
// SessionDestroy delete ledis session by id
@ -167,7 +164,6 @@ func (lp *Provider) SessionDestroy(sid string) error {
// SessionGC Impelment method, no used.
func (lp *Provider) SessionGC() {
return
}
// SessionAll return all active session

View File

@ -205,11 +205,7 @@ func (rp *MemProvider) SessionDestroy(sid string) error {
}
}
err := client.Delete(sid)
if err != nil {
return err
}
return nil
return client.Delete(sid)
}
func (rp *MemProvider) connectInit() error {
@ -219,7 +215,6 @@ func (rp *MemProvider) connectInit() error {
// SessionGC Impelment method, no used.
func (rp *MemProvider) SessionGC() {
return
}
// SessionAll return all activeSession

View File

@ -143,7 +143,6 @@ func (mp *Provider) SessionInit(maxlifetime int64, savePath string) error {
// SessionRead get mysql session by sid
func (mp *Provider) SessionRead(sid string) (session.Store, error) {
c := mp.connectInit()
defer c.Close()
row := c.QueryRow("select session_data from "+TableName+" where session_key=?", sid)
var sessiondata []byte
err := row.Scan(&sessiondata)
@ -171,16 +170,12 @@ func (mp *Provider) SessionExist(sid string) bool {
row := c.QueryRow("select session_data from "+TableName+" where session_key=?", sid)
var sessiondata []byte
err := row.Scan(&sessiondata)
if err == sql.ErrNoRows {
return false
}
return true
return !(err == sql.ErrNoRows)
}
// SessionRegenerate generate new sid for mysql session
func (mp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
c := mp.connectInit()
defer c.Close()
row := c.QueryRow("select session_data from "+TableName+" where session_key=?", oldsid)
var sessiondata []byte
err := row.Scan(&sessiondata)
@ -214,7 +209,6 @@ func (mp *Provider) SessionGC() {
c := mp.connectInit()
c.Exec("DELETE from "+TableName+" where session_expiry < ?", time.Now().Unix()-mp.maxlifetime)
c.Close()
return
}
// SessionAll count values in mysql session

View File

@ -184,11 +184,7 @@ func (mp *Provider) SessionExist(sid string) bool {
row := c.QueryRow("select session_data from session where session_key=$1", sid)
var sessiondata []byte
err := row.Scan(&sessiondata)
if err == sql.ErrNoRows {
return false
}
return true
return !(err == sql.ErrNoRows)
}
// SessionRegenerate generate new sid for postgresql session
@ -228,7 +224,6 @@ func (mp *Provider) SessionGC() {
c := mp.connectInit()
c.Exec("DELETE from session where EXTRACT(EPOCH FROM (current_timestamp - session_expiry)) > $1", mp.maxlifetime)
c.Close()
return
}
// SessionAll count values in postgresql session

View File

@ -128,7 +128,7 @@ func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error {
}
if len(configs) > 1 {
poolsize, err := strconv.Atoi(configs[1])
if err != nil || poolsize <= 0 {
if err != nil || poolsize < 0 {
rp.poolsize = MaxPoolSize
} else {
rp.poolsize = poolsize
@ -155,7 +155,7 @@ func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error {
return nil, err
}
if rp.password != "" {
if _, err := c.Do("AUTH", rp.password); err != nil {
if _, err = c.Do("AUTH", rp.password); err != nil {
c.Close()
return nil, err
}
@ -176,13 +176,20 @@ func (rp *Provider) SessionRead(sid string) (session.Store, error) {
c := rp.poollist.Get()
defer c.Close()
kvs, err := redis.String(c.Do("GET", sid))
var kv map[interface{}]interface{}
var (
kv map[interface{}]interface{}
kvs string
err error
)
if kvs, err = redis.String(c.Do("GET", sid)); err != nil {
return nil, err
}
if len(kvs) == 0 {
kv = make(map[interface{}]interface{})
} else {
kv, err = session.DecodeGob([]byte(kvs))
if err != nil {
if kv, err = session.DecodeGob([]byte(kvs)); err != nil {
return nil, err
}
}
@ -216,20 +223,7 @@ func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error)
c.Do("RENAME", oldsid, sid)
c.Do("EXPIRE", sid, rp.maxlifetime)
}
kvs, err := redis.String(c.Do("GET", sid))
var kv map[interface{}]interface{}
if len(kvs) == 0 {
kv = make(map[interface{}]interface{})
} else {
kv, err = session.DecodeGob([]byte(kvs))
if err != nil {
return nil, err
}
}
rs := &SessionStore{p: rp.poollist, sid: sid, values: kv, maxlifetime: rp.maxlifetime}
return rs, nil
return rp.SessionRead(sid)
}
// SessionDestroy delete redis session by id
@ -243,7 +237,6 @@ func (rp *Provider) SessionDestroy(sid string) error {
// SessionGC Impelment method, no used.
func (rp *Provider) SessionGC() {
return
}
// SessionAll return all activeSession

View File

@ -74,21 +74,16 @@ func (st *CookieSessionStore) SessionID() string {
// SessionRelease Write cookie session to http response cookie
func (st *CookieSessionStore) SessionRelease(w http.ResponseWriter) {
str, err := encodeCookie(cookiepder.block,
cookiepder.config.SecurityKey,
cookiepder.config.SecurityName,
st.values)
if err != nil {
return
encodedCookie, err := encodeCookie(cookiepder.block, cookiepder.config.SecurityKey, cookiepder.config.SecurityName, st.values)
if err == nil {
cookie := &http.Cookie{Name: cookiepder.config.CookieName,
Value: url.QueryEscape(encodedCookie),
Path: "/",
HttpOnly: true,
Secure: cookiepder.config.Secure,
MaxAge: cookiepder.config.Maxage}
http.SetCookie(w, cookie)
}
cookie := &http.Cookie{Name: cookiepder.config.CookieName,
Value: url.QueryEscape(str),
Path: "/",
HttpOnly: true,
Secure: cookiepder.config.Secure,
MaxAge: cookiepder.config.Maxage}
http.SetCookie(w, cookie)
return
}
type cookieConfig struct {
@ -166,7 +161,6 @@ func (pder *CookieProvider) SessionDestroy(sid string) error {
// SessionGC Implement method, no used.
func (pder *CookieProvider) SessionGC() {
return
}
// SessionAll Implement method, return 0.

View File

@ -163,10 +163,7 @@ func (fp *FileProvider) SessionExist(sid string) bool {
defer filepder.lock.Unlock()
_, err := os.Stat(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid))
if err == nil {
return true
}
return false
return err == nil
}
// SessionDestroy Remove all files in this save path

View File

@ -115,7 +115,7 @@ func TestParseConfig(t *testing.T) {
if cf2.Gclifetime != 3600 {
t.Fatal("parseconfig get gclifetime error")
}
if cf2.EnableSetCookie != false {
if cf2.EnableSetCookie {
t.Fatal("parseconfig get enableSetCookie error")
}
cconfig := new(cookieConfig)

View File

@ -26,26 +26,19 @@ func (p *SsdbProvider) connectInit() error {
return errors.New("SessionInit First")
}
p.client, err = ssdb.Connect(p.host, p.port)
if err != nil {
return err
}
return nil
return err
}
func (p *SsdbProvider) SessionInit(maxLifetime int64, savePath string) error {
var e error = nil
p.maxLifetime = maxLifetime
address := strings.Split(savePath, ":")
p.host = address[0]
p.port, e = strconv.Atoi(address[1])
if e != nil {
return e
}
err := p.connectInit()
if err != nil {
var err error
if p.port, err = strconv.Atoi(address[1]); err != nil {
return err
}
return nil
return p.connectInit()
}
func (p *SsdbProvider) SessionRead(sid string) (session.Store, error) {
@ -85,8 +78,8 @@ func (p *SsdbProvider) SessionExist(sid string) bool {
return false
}
return true
}
func (p *SsdbProvider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
//conn.Do("setx", key, v, ttl)
if p.client == nil {
@ -126,14 +119,10 @@ func (p *SsdbProvider) SessionDestroy(sid string) error {
}
}
_, err := p.client.Del(sid)
if err != nil {
return err
}
return nil
return err
}
func (p *SsdbProvider) SessionGC() {
return
}
func (p *SsdbProvider) SessionAll() int {

View File

@ -90,8 +90,6 @@ func serverStaticRouter(ctx *context.Context) {
}
http.ServeContent(ctx.ResponseWriter, ctx.Request, filePath, sch.modTime, sch)
return
}
type serveContentHolder struct {
@ -109,14 +107,14 @@ var (
func openFile(filePath string, fi os.FileInfo, acceptEncoding string) (bool, string, *serveContentHolder, error) {
mapKey := acceptEncoding + ":" + filePath
mapLock.RLock()
mapFile, _ := staticFileMap[mapKey]
mapFile := staticFileMap[mapKey]
mapLock.RUnlock()
if isOk(mapFile, fi) {
return mapFile.encoding != "", mapFile.encoding, mapFile, nil
}
mapLock.Lock()
defer mapLock.Unlock()
if mapFile, _ = staticFileMap[mapKey]; !isOk(mapFile, fi) {
if mapFile = staticFileMap[mapKey]; !isOk(mapFile, fi) {
file, err := os.Open(filePath)
if err != nil {
return false, "", nil, err

View File

@ -31,11 +31,11 @@ import (
)
var (
beegoTplFuncMap = make(template.FuncMap)
beegoTplFuncMap = make(template.FuncMap)
beeViewPathTemplateLocked = false
// beeViewPathTemplates caching map and supported template file extensions per view
beeViewPathTemplates = make(map[string]map[string]*template.Template)
templatesLock sync.RWMutex
beeViewPathTemplates = make(map[string]map[string]*template.Template)
templatesLock sync.RWMutex
// beeTemplateExt stores the template extension which will build
beeTemplateExt = []string{"tpl", "html"}
// beeTemplatePreprocessors stores associations of extension -> preprocessor handler
@ -46,7 +46,7 @@ var (
// writing the output to wr.
// A template will be executed safely in parallel.
func ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
return ExecuteViewPathTemplate(wr,name, BConfig.WebConfig.ViewsPath, data)
return ExecuteViewPathTemplate(wr, name, BConfig.WebConfig.ViewsPath, data)
}
// ExecuteViewPathTemplate applies the template with name and from specific viewPath to the specified data object,
@ -57,7 +57,7 @@ func ExecuteViewPathTemplate(wr io.Writer, name string, viewPath string, data in
templatesLock.RLock()
defer templatesLock.RUnlock()
}
if beeTemplates,ok := beeViewPathTemplates[viewPath]; ok {
if beeTemplates, ok := beeViewPathTemplates[viewPath]; ok {
if t, ok := beeTemplates[name]; ok {
var err error
if t.Lookup(name) != nil {
@ -72,7 +72,7 @@ func ExecuteViewPathTemplate(wr io.Writer, name string, viewPath string, data in
}
panic("can't find templatefile in the path:" + viewPath + "/" + name)
}
panic("Uknown view path:" + viewPath)
panic("Unknown view path:" + viewPath)
}
func init() {
@ -160,11 +160,14 @@ func AddTemplateExt(ext string) {
beeTemplateExt = append(beeTemplateExt, ext)
}
// AddViewPath adds a new path to the supported view paths.
// AddViewPath adds a new path to the supported view paths.
//Can later be used by setting a controller ViewPath to this folder
//will panic if called after beego.Run()
//will panic if called after beego.Run()
func AddViewPath(viewPath string) error {
if beeViewPathTemplateLocked {
if _, exist := beeViewPathTemplates[viewPath]; exist {
return nil //Ignore if viewpath already exists
}
panic("Can not add new view paths after beego.Run()")
}
beeViewPathTemplates[viewPath] = make(map[string]*template.Template)
@ -184,7 +187,7 @@ func BuildTemplate(dir string, files ...string) error {
}
return errors.New("dir open err")
}
beeTemplates,ok := beeViewPathTemplates[dir];
beeTemplates, ok := beeViewPathTemplates[dir]
if !ok {
panic("Unknown view path: " + dir)
}
@ -214,7 +217,7 @@ func BuildTemplate(dir string, files ...string) error {
t, err = getTemplate(self.root, file, v...)
}
if err != nil {
logs.Trace("parse template err:", file, err)
logs.Error("parse template err:", file, err)
} else {
beeTemplates[file] = t
}
@ -227,9 +230,12 @@ func BuildTemplate(dir string, files ...string) error {
func getTplDeep(root, file, parent string, t *template.Template) (*template.Template, [][]string, error) {
var fileAbsPath string
var rParent string
if filepath.HasPrefix(file, "../") {
rParent = filepath.Join(filepath.Dir(parent), file)
fileAbsPath = filepath.Join(root, filepath.Dir(parent), file)
} else {
rParent = file
fileAbsPath = filepath.Join(root, file)
}
if e := utils.FileExists(fileAbsPath); !e {
@ -254,7 +260,7 @@ func getTplDeep(root, file, parent string, t *template.Template) (*template.Temp
if !HasTemplateExt(m[1]) {
continue
}
_, _, err = getTplDeep(root, m[1], file, t)
_, _, err = getTplDeep(root, m[1], rParent, t)
if err != nil {
return nil, [][]string{}, err
}
@ -293,7 +299,7 @@ func _getTemplate(t0 *template.Template, root string, subMods [][]string, others
t, subMods1, err = getTplDeep(root, otherFile, "", t)
if err != nil {
logs.Trace("template parse file err:", err)
} else if subMods1 != nil && len(subMods1) > 0 {
} else if len(subMods1) > 0 {
t, err = _getTemplate(t, root, subMods1, others...)
}
break
@ -314,7 +320,7 @@ func _getTemplate(t0 *template.Template, root string, subMods [][]string, others
t, subMods1, err = getTplDeep(root, otherFile, "", t)
if err != nil {
logs.Trace("template parse file err:", err)
} else if subMods1 != nil && len(subMods1) > 0 {
} else if len(subMods1) > 0 {
t, err = _getTemplate(t, root, subMods1, others...)
}
break

View File

@ -15,6 +15,7 @@
package beego
import (
"bytes"
"os"
"path/filepath"
"testing"
@ -142,3 +143,116 @@ func TestRelativeTemplate(t *testing.T) {
}
os.RemoveAll(dir)
}
var add = `{{ template "layout_blog.tpl" . }}
{{ define "css" }}
<link rel="stylesheet" href="/static/css/current.css">
{{ end}}
{{ define "content" }}
<h2>{{ .Title }}</h2>
<p> This is SomeVar: {{ .SomeVar }}</p>
{{ end }}
{{ define "js" }}
<script src="/static/js/current.js"></script>
{{ end}}`
var layout_blog = `<!DOCTYPE html>
<html>
<head>
<title>Lin Li</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap-theme.min.css">
{{ block "css" . }}{{ end }}
</head>
<body>
<div class="container">
{{ block "content" . }}{{ end }}
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
{{ block "js" . }}{{ end }}
</body>
</html>`
var output = `<!DOCTYPE html>
<html>
<head>
<title>Lin Li</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="/static/css/current.css">
</head>
<body>
<div class="container">
<h2>Hello</h2>
<p> This is SomeVar: val</p>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<script src="/static/js/current.js"></script>
</body>
</html>
`
func TestTemplateLayout(t *testing.T) {
dir := "_beeTmp"
files := []string{
"add.tpl",
"layout_blog.tpl",
}
if err := os.MkdirAll(dir, 0777); err != nil {
t.Fatal(err)
}
for k, name := range files {
os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777)
if f, err := os.Create(filepath.Join(dir, name)); err != nil {
t.Fatal(err)
} else {
if k == 0 {
f.WriteString(add)
} else if k == 1 {
f.WriteString(layout_blog)
}
f.Close()
}
}
if err := AddViewPath(dir); err != nil {
t.Fatal(err)
}
beeTemplates := beeViewPathTemplates[dir]
if len(beeTemplates) != 2 {
t.Fatalf("should be 2 but got %v", len(beeTemplates))
}
out := bytes.NewBufferString("")
if err := beeTemplates["add.tpl"].ExecuteTemplate(out, "add.tpl", map[string]string{"Title": "Hello", "SomeVar": "val"}); err != nil {
t.Fatal(err)
}
if out.String() != output {
t.Log(out.String())
t.Fatal("Compare failed")
}
for _, name := range files {
os.RemoveAll(filepath.Join(dir, name))
}
os.RemoveAll(dir)
}

View File

@ -26,6 +26,12 @@ import (
"time"
)
const (
formatTime = "15:04:05"
formatDate = "2006-01-02"
formatDateTime = "2006-01-02 15:04:05"
)
// Substr returns the substr from start to length.
func Substr(s string, start, length int) string {
bt := []rune(s)
@ -46,26 +52,25 @@ func Substr(s string, start, length int) string {
// HTML2str returns escaping text convert from html.
func HTML2str(html string) string {
src := string(html)
re, _ := regexp.Compile("\\<[\\S\\s]+?\\>")
src = re.ReplaceAllStringFunc(src, strings.ToLower)
html = re.ReplaceAllStringFunc(html, strings.ToLower)
//remove STYLE
re, _ = regexp.Compile("\\<style[\\S\\s]+?\\</style\\>")
src = re.ReplaceAllString(src, "")
html = re.ReplaceAllString(html, "")
//remove SCRIPT
re, _ = regexp.Compile("\\<script[\\S\\s]+?\\</script\\>")
src = re.ReplaceAllString(src, "")
html = re.ReplaceAllString(html, "")
re, _ = regexp.Compile("\\<[\\S\\s]+?\\>")
src = re.ReplaceAllString(src, "\n")
html = re.ReplaceAllString(html, "\n")
re, _ = regexp.Compile("\\s{2,}")
src = re.ReplaceAllString(src, "\n")
html = re.ReplaceAllString(html, "\n")
return strings.TrimSpace(src)
return strings.TrimSpace(html)
}
// DateFormat takes a time and a layout string and returns a string with the formatted date. Used by the template parser as "dateformat"
@ -193,7 +198,7 @@ func Str2html(raw string) template.HTML {
}
// Htmlquote returns quoted html string.
func Htmlquote(src string) string {
func Htmlquote(text string) string {
//HTML编码为实体符号
/*
Encodes `text` for raw use in HTML.
@ -201,8 +206,6 @@ func Htmlquote(src string) string {
'&lt;&#39;&amp;&quot;&gt;'
*/
text := string(src)
text = strings.Replace(text, "&", "&amp;", -1) // Must be done first!
text = strings.Replace(text, "<", "&lt;", -1)
text = strings.Replace(text, ">", "&gt;", -1)
@ -216,7 +219,7 @@ func Htmlquote(src string) string {
}
// Htmlunquote returns unquoted html string.
func Htmlunquote(src string) string {
func Htmlunquote(text string) string {
//实体符号解释为HTML
/*
Decodes `text` that's HTML quoted.
@ -227,7 +230,6 @@ func Htmlunquote(src string) string {
// strings.Replace(s, old, new, n)
// 在s字符串中把old字符串替换为new字符串n表示替换的次数小于0表示全部替换
text := string(src)
text = strings.Replace(text, "&nbsp;", " ", -1)
text = strings.Replace(text, "&rdquo;", "”", -1)
text = strings.Replace(text, "&ldquo;", "“", -1)
@ -262,19 +264,17 @@ func URLFor(endpoint string, values ...interface{}) string {
}
// AssetsJs returns script tag with src string.
func AssetsJs(src string) template.HTML {
text := string(src)
func AssetsJs(text string) template.HTML {
text = "<script src=\"" + src + "\"></script>"
text = "<script src=\"" + text + "\"></script>"
return template.HTML(text)
}
// AssetsCSS returns stylesheet link tag with src string.
func AssetsCSS(src string) template.HTML {
text := string(src)
func AssetsCSS(text string) template.HTML {
text = "<link href=\"" + src + "\" rel=\"stylesheet\" />"
text = "<link href=\"" + text + "\" rel=\"stylesheet\" />"
return template.HTML(text)
}
@ -352,11 +352,28 @@ func parseFormToStruct(form url.Values, objT reflect.Type, objV reflect.Value) e
case reflect.Struct:
switch fieldT.Type.String() {
case "time.Time":
format := time.RFC3339
if len(tags) > 1 {
format = tags[1]
var (
t time.Time
err error
)
if len(value) >= 25 {
value = value[:25]
t, err = time.ParseInLocation(time.RFC3339, value, time.Local)
} else if len(value) >= 19 {
value = value[:19]
t, err = time.ParseInLocation(formatDateTime, value, time.Local)
} else if len(value) >= 10 {
if len(value) > 10 {
value = value[:10]
}
t, err = time.ParseInLocation(formatDate, value, time.Local)
} else if len(value) >= 8 {
if len(value) > 8 {
value = value[:8]
}
t, err = time.ParseInLocation(formatTime, value, time.Local)
}
t, err := time.ParseInLocation(format, value, time.Local)
if err != nil {
return err
}

View File

@ -173,7 +173,7 @@ func TestParseForm(t *testing.T) {
if u.Intro != "I am an engineer!" {
t.Errorf("Intro should equal `I am an engineer!` but got `%v`", u.Intro)
}
if u.StrBool != true {
if !u.StrBool {
t.Errorf("strboll should equal `true`, but got `%v`", u.StrBool)
}
y, m, d := u.Date.Date()
@ -255,43 +255,43 @@ func TestParseFormTag(t *testing.T) {
objT := reflect.TypeOf(&user{}).Elem()
label, name, fType, id, class, ignored, required := parseFormTag(objT.Field(0))
if !(name == "name" && label == "年龄:" && fType == "text" && ignored == false) {
if !(name == "name" && label == "年龄:" && fType == "text" && !ignored) {
t.Errorf("Form Tag with name, label and type was not correctly parsed.")
}
label, name, fType, id, class, ignored, required = parseFormTag(objT.Field(1))
if !(name == "NoName" && label == "年龄:" && fType == "hidden" && ignored == false) {
if !(name == "NoName" && label == "年龄:" && fType == "hidden" && !ignored) {
t.Errorf("Form Tag with label and type but without name was not correctly parsed.")
}
label, name, fType, id, class, ignored, required = parseFormTag(objT.Field(2))
if !(name == "OnlyLabel" && label == "年龄:" && fType == "text" && ignored == false) {
if !(name == "OnlyLabel" && label == "年龄:" && fType == "text" && !ignored) {
t.Errorf("Form Tag containing only label was not correctly parsed.")
}
label, name, fType, id, class, ignored, required = parseFormTag(objT.Field(3))
if !(name == "name" && label == "OnlyName: " && fType == "text" && ignored == false &&
if !(name == "name" && label == "OnlyName: " && fType == "text" && !ignored &&
id == "name" && class == "form-name") {
t.Errorf("Form Tag containing only name was not correctly parsed.")
}
label, name, fType, id, class, ignored, required = parseFormTag(objT.Field(4))
if ignored == false {
if !ignored {
t.Errorf("Form Tag that should be ignored was not correctly parsed.")
}
label, name, fType, id, class, ignored, required = parseFormTag(objT.Field(5))
if !(name == "name" && required == true) {
if !(name == "name" && required) {
t.Errorf("Form Tag containing only name and required was not correctly parsed.")
}
label, name, fType, id, class, ignored, required = parseFormTag(objT.Field(6))
if !(name == "name" && required == false) {
if !(name == "name" && !required) {
t.Errorf("Form Tag containing only name and ignore required was not correctly parsed.")
}
label, name, fType, id, class, ignored, required = parseFormTag(objT.Field(7))
if !(name == "name" && required == false) {
if !(name == "name" && !required) {
t.Errorf("Form Tag containing only name and not required was not correctly parsed.")
}

View File

@ -119,7 +119,7 @@ func (m *URLMap) GetMap() map[string]interface{} {
func (m *URLMap) GetMapData() []map[string]interface{} {
m.lock.Lock()
defer m.lock.Unlock()
var resultLists []map[string]interface{}
for k, v := range m.urlmap {

View File

@ -427,6 +427,7 @@ func run() {
}
continue
case <-changed:
now = time.Now().Local()
continue
case <-stop:
return

25
tree.go
View File

@ -288,10 +288,10 @@ func (t *Tree) Match(pattern string, ctx *context.Context) (runObject interface{
return nil
}
w := make([]string, 0, 20)
return t.match(pattern, w, ctx)
return t.match(pattern[1:], pattern, w, ctx)
}
func (t *Tree) match(pattern string, wildcardValues []string, ctx *context.Context) (runObject interface{}) {
func (t *Tree) match(treePattern string, pattern string, wildcardValues []string, ctx *context.Context) (runObject interface{}) {
if len(pattern) > 0 {
i := 0
for ; i < len(pattern) && pattern[i] == '/'; i++ {
@ -301,13 +301,13 @@ func (t *Tree) match(pattern string, wildcardValues []string, ctx *context.Conte
// Handle leaf nodes:
if len(pattern) == 0 {
for _, l := range t.leaves {
if ok := l.match(wildcardValues, ctx); ok {
if ok := l.match(treePattern, wildcardValues, ctx); ok {
return l.runObject
}
}
if t.wildcard != nil {
for _, l := range t.wildcard.leaves {
if ok := l.match(wildcardValues, ctx); ok {
if ok := l.match(treePattern, wildcardValues, ctx); ok {
return l.runObject
}
}
@ -327,7 +327,12 @@ func (t *Tree) match(pattern string, wildcardValues []string, ctx *context.Conte
}
for _, subTree := range t.fixrouters {
if subTree.prefix == seg {
runObject = subTree.match(pattern, wildcardValues, ctx)
if len(pattern) != 0 && pattern[0] == '/' {
treePattern = pattern[1:]
} else {
treePattern = pattern
}
runObject = subTree.match(treePattern, pattern, wildcardValues, ctx)
if runObject != nil {
break
}
@ -339,7 +344,7 @@ func (t *Tree) match(pattern string, wildcardValues []string, ctx *context.Conte
if strings.HasSuffix(seg, str) {
for _, subTree := range t.fixrouters {
if subTree.prefix == seg[:len(seg)-len(str)] {
runObject = subTree.match(pattern, wildcardValues, ctx)
runObject = subTree.match(treePattern, pattern, wildcardValues, ctx)
if runObject != nil {
ctx.Input.SetParam(":ext", str[1:])
}
@ -349,7 +354,7 @@ func (t *Tree) match(pattern string, wildcardValues []string, ctx *context.Conte
}
}
if runObject == nil && t.wildcard != nil {
runObject = t.wildcard.match(pattern, append(wildcardValues, seg), ctx)
runObject = t.wildcard.match(treePattern, pattern, append(wildcardValues, seg), ctx)
}
if runObject == nil && len(t.leaves) > 0 {
@ -368,7 +373,7 @@ func (t *Tree) match(pattern string, wildcardValues []string, ctx *context.Conte
wildcardValues = append(wildcardValues, pattern[start:i])
}
for _, l := range t.leaves {
if ok := l.match(wildcardValues, ctx); ok {
if ok := l.match(treePattern, wildcardValues, ctx); ok {
return l.runObject
}
}
@ -386,7 +391,7 @@ type leafInfo struct {
runObject interface{}
}
func (leaf *leafInfo) match(wildcardValues []string, ctx *context.Context) (ok bool) {
func (leaf *leafInfo) match(treePattern string, wildcardValues []string, ctx *context.Context) (ok bool) {
//fmt.Println("Leaf:", wildcardValues, leaf.wildcards, leaf.regexps)
if leaf.regexps == nil {
if len(wildcardValues) == 0 && len(leaf.wildcards) == 0 { // static path
@ -394,7 +399,7 @@ func (leaf *leafInfo) match(wildcardValues []string, ctx *context.Context) (ok b
}
// match *
if len(leaf.wildcards) == 1 && leaf.wildcards[0] == ":splat" {
ctx.Input.SetParam(":splat", path.Join(wildcardValues...))
ctx.Input.SetParam(":splat", treePattern)
return true
}
// match *.* or :id

View File

@ -42,7 +42,7 @@ func init() {
routers = append(routers, testinfo{"/", "/", nil})
routers = append(routers, testinfo{"/customer/login", "/customer/login", nil})
routers = append(routers, testinfo{"/customer/login", "/customer/login.json", map[string]string{":ext": "json"}})
routers = append(routers, testinfo{"/*", "/customer/123", map[string]string{":splat": "customer/123"}})
routers = append(routers, testinfo{"/*", "/http://customer/123/", map[string]string{":splat": "http://customer/123/"}})
routers = append(routers, testinfo{"/*", "/customer/2009/12/11", map[string]string{":splat": "customer/2009/12/11"}})
routers = append(routers, testinfo{"/aa/*/bb", "/aa/2009/bb", map[string]string{":splat": "2009"}})
routers = append(routers, testinfo{"/cc/*/dd", "/cc/2009/11/dd", map[string]string{":splat": "2009/11"}})

View File

@ -474,7 +474,7 @@ func randomBrightness(c color.RGBA, max uint8) color.RGBA {
uint8(int(c.R) + n),
uint8(int(c.G) + n),
uint8(int(c.B) + n),
uint8(c.A),
c.A,
}
}

30
utils/utils.go Normal file
View File

@ -0,0 +1,30 @@
package utils
import (
"os"
"path/filepath"
"runtime"
"strings"
)
// GetGOPATHs returns all paths in GOPATH variable.
func GetGOPATHs() []string {
gopath := os.Getenv("GOPATH")
if gopath == "" && strings.Compare(runtime.Version(), "go1.8") >= 0 {
gopath = defaultGOPATH()
}
return filepath.SplitList(gopath)
}
func defaultGOPATH() string {
env := "HOME"
if runtime.GOOS == "windows" {
env = "USERPROFILE"
} else if runtime.GOOS == "plan9" {
env = "home"
}
if home := os.Getenv(env); home != "" {
return filepath.Join(home, "go")
}
return ""
}

View File

@ -349,7 +349,7 @@ func (v *Validation) RecursiveValid(objc interface{}) (bool, error) {
//Step 1: validate obj itself firstly
// fails if objc is not struct
pass, err := v.Valid(objc)
if err != nil || false == pass {
if err != nil || !pass {
return pass, err // Stop recursive validation
}
// Step 2: Validate struct's struct fields

View File

@ -214,6 +214,12 @@ func TestEmail(t *testing.T) {
if !valid.Email("suchuangji@gmail.com", "email").Ok {
t.Error("\"suchuangji@gmail.com\" is a valid email address should be true")
}
if valid.Email("@suchuangji@gmail.com", "email").Ok {
t.Error("\"@suchuangji@gmail.com\" is a valid email address should be false")
}
if valid.Email("suchuangji@gmail.com ok", "email").Ok {
t.Error("\"suchuangji@gmail.com ok\" is a valid email address should be false")
}
}
func TestIP(t *testing.T) {

View File

@ -518,7 +518,7 @@ func (a AlphaDash) GetLimitValue() interface{} {
return nil
}
var emailPattern = regexp.MustCompile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?")
var emailPattern = regexp.MustCompile("^[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?$")
// Email check struct
type Email struct {