diff --git a/admin.go b/admin.go
index fa4b1db0..ddc936ef 100644
--- a/admin.go
+++ b/admin.go
@@ -107,7 +107,7 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
m["SessionGCMaxLifetime"] = SessionGCMaxLifetime
m["SessionProviderConfig"] = SessionProviderConfig
m["SessionCookieLifeTime"] = SessionCookieLifeTime
- m["EnabelFcgi"] = EnabelFcgi
+ m["EnableFcgi"] = EnableFcgi
m["MaxMemory"] = MaxMemory
m["EnableGzip"] = EnableGzip
m["DirectoryIndex"] = DirectoryIndex
diff --git a/app.go b/app.go
index d10d436c..ed57b978 100644
--- a/app.go
+++ b/app.go
@@ -64,7 +64,7 @@ func (app *App) Run() {
)
endRunning := make(chan bool, 1)
- if EnabelFcgi {
+ if EnableFcgi {
if EnableStdIo {
err = fcgi.Serve(nil, app.Handlers) // standard I/O
if err == nil {
@@ -89,6 +89,7 @@ func (app *App) Run() {
}
} else {
if Graceful {
+ httpsAddr := addr
app.Server.Addr = addr
app.Server.Handler = app.Handlers
app.Server.ReadTimeout = time.Duration(HTTPServerTimeOut) * time.Second
@@ -97,11 +98,12 @@ func (app *App) Run() {
go func() {
time.Sleep(20 * time.Microsecond)
if HTTPSPort != 0 {
- addr = fmt.Sprintf("%s:%d", HTTPAddr, HTTPSPort)
- app.Server.Addr = addr
+ httpsAddr = fmt.Sprintf("%s:%d", HTTPAddr, HTTPSPort)
+ app.Server.Addr = httpsAddr
}
- server := grace.NewServer(addr, app.Handlers)
- server.Server = app.Server
+ server := grace.NewServer(httpsAddr, app.Handlers)
+ server.Server.ReadTimeout = app.Server.ReadTimeout
+ server.Server.WriteTimeout = app.Server.WriteTimeout
err := server.ListenAndServeTLS(HTTPCertFile, HTTPKeyFile)
if err != nil {
BeeLogger.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
@@ -113,8 +115,9 @@ func (app *App) Run() {
if EnableHTTPListen {
go func() {
server := grace.NewServer(addr, app.Handlers)
- server.Server = app.Server
- if ListenTCP4 && HTTPAddr == "" {
+ server.Server.ReadTimeout = app.Server.ReadTimeout
+ server.Server.WriteTimeout = app.Server.WriteTimeout
+ if ListenTCP4 {
server.Network = "tcp4"
}
err := server.ListenAndServe()
@@ -151,7 +154,7 @@ func (app *App) Run() {
go func() {
app.Server.Addr = addr
BeeLogger.Info("http server Running on %s", app.Server.Addr)
- if ListenTCP4 && HTTPAddr == "" {
+ if ListenTCP4 {
ln, err := net.Listen("tcp4", app.Server.Addr)
if err != nil {
BeeLogger.Critical("ListenAndServe: ", err)
diff --git a/config.go b/config.go
index c2f23f67..d9ff624c 100644
--- a/config.go
+++ b/config.go
@@ -60,15 +60,15 @@ var (
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
+ // EnableFcgi turn on the fcgi Listen, default is false
+ EnableFcgi 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 works with EnableFcgi Use FCGI via standard I/O
EnableStdIo bool
// EnableXSRF whether turn on xsrf. default is false
EnableXSRF bool
@@ -435,8 +435,8 @@ func ParseConfig() (err error) {
SessionCookieLifeTime = sesscookielifetime
}
- if enabelFcgi, err := AppConfig.Bool("EnabelFcgi"); err == nil {
- EnabelFcgi = enabelFcgi
+ if enableFcgi, err := AppConfig.Bool("EnableFcgi"); err == nil {
+ EnableFcgi = enableFcgi
}
if enablegzip, err := AppConfig.Bool("EnableGzip"); err == nil {
@@ -529,7 +529,6 @@ func ParseConfig() (err error) {
if ext == "" {
continue
}
- ext = strings.ToLower(ext)
if !strings.HasPrefix(ext, ".") {
ext = "." + ext
}
diff --git a/context/context.go b/context/context.go
index fb9c6d96..8f1144f3 100644
--- a/context/context.go
+++ b/context/context.go
@@ -55,7 +55,6 @@ func (ctx *Context) Redirect(status int, localurl string) {
// Abort stops this request.
// if beego.ErrorMaps exists, panic body.
func (ctx *Context) Abort(status int, body string) {
- ctx.ResponseWriter.WriteHeader(status)
panic(body)
}
diff --git a/context/output.go b/context/output.go
index a4bb3d09..d132e392 100644
--- a/context/output.go
+++ b/context/output.go
@@ -103,7 +103,19 @@ func (output *BeegoOutput) Cookie(name string, value string, others ...interface
//fix cookie not work in IE
if len(others) > 0 {
switch v := others[0].(type) {
- case int, int32, int64:
+ case int:
+ if v > 0 {
+ fmt.Fprintf(&b, "; Expires=%s; Max-Age=%d", time.Now().Add(time.Duration(v)*time.Second).UTC().Format(time.RFC1123), v)
+ } else if v <= 0 {
+ fmt.Fprintf(&b, "; Max-Age=0")
+ }
+ case int64:
+ if v > 0 {
+ fmt.Fprintf(&b, "; Expires=%s; Max-Age=%d", time.Now().Add(time.Duration(v)*time.Second).UTC().Format(time.RFC1123), v)
+ } else if v <= 0 {
+ fmt.Fprintf(&b, "; Max-Age=0")
+ }
+ case int32:
if v > 0 {
fmt.Fprintf(&b, "; Expires=%s; Max-Age=%d", time.Now().Add(time.Duration(v)*time.Second).UTC().Format(time.RFC1123), v)
} else if v <= 0 {
diff --git a/controller.go b/controller.go
index 7fbf6dc5..0750daf4 100644
--- a/controller.go
+++ b/controller.go
@@ -647,8 +647,8 @@ func (c *Controller) CheckXSRFCookie() bool {
// XSRFFormHTML writes an input field contains xsrf token value.
func (c *Controller) XSRFFormHTML() string {
- return ""
+ return ``
}
// GetControllerAndAction gets the executing controller name and action name.
diff --git a/memzipfile.go b/memzipfile.go
index 1e5239f5..376a1ae9 100644
--- a/memzipfile.go
+++ b/memzipfile.go
@@ -219,9 +219,9 @@ func getAcceptEncodingZip(r *http.Request) string {
ss = strings.ToLower(ss)
if strings.Contains(ss, "gzip") {
return "gzip"
- }
- if strings.Contains(ss, "deflate") {
+ } else if strings.Contains(ss, "deflate") {
return "deflate"
+ } else {
+ return ""
}
- return ""
}
diff --git a/orm/cmd_utils.go b/orm/cmd_utils.go
index 5b40fd07..bddada7c 100644
--- a/orm/cmd_utils.go
+++ b/orm/cmd_utils.go
@@ -45,13 +45,14 @@ func getDbDropSQL(al *alias) (sqls []string) {
func getColumnTyp(al *alias, fi *fieldInfo) (col string) {
T := al.DbBaser.DbTypes()
fieldType := fi.fieldType
+ fieldSize := fi.size
checkColumn:
switch fieldType {
case TypeBooleanField:
col = T["bool"]
case TypeCharField:
- col = fmt.Sprintf(T["string"], fi.size)
+ col = fmt.Sprintf(T["string"], fieldSize)
case TypeTextField:
col = T["string-text"]
case TypeDateField:
@@ -89,6 +90,7 @@ checkColumn:
}
case RelForeignKey, RelOneToOne:
fieldType = fi.relModelInfo.fields.pk.fieldType
+ fieldSize = fi.relModelInfo.fields.pk.size
goto checkColumn
}
diff --git a/orm/db.go b/orm/db.go
index 2f2c52da..b62c165b 100644
--- a/orm/db.go
+++ b/orm/db.go
@@ -488,7 +488,8 @@ func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.
d.ins.ReplaceMarks(&query)
- if res, err := q.Exec(query, setValues...); err == nil {
+ res, err := q.Exec(query, setValues...)
+ if err == nil {
return res.RowsAffected()
}
return 0, err
diff --git a/orm/models_boot.go b/orm/models_boot.go
index 808b7822..3690557b 100644
--- a/orm/models_boot.go
+++ b/orm/models_boot.go
@@ -266,7 +266,10 @@ func bootStrap() {
if found == false {
mForC:
for _, ffi := range fi.relModelInfo.fields.fieldsByType[RelManyToMany] {
- if ffi.relModelInfo == mi {
+ conditions := fi.relThrough != "" && fi.relThrough == ffi.relThrough ||
+ fi.relTable != "" && fi.relTable == ffi.relTable ||
+ fi.relThrough == "" && fi.relTable == ""
+ if ffi.relModelInfo == mi && conditions {
found = true
fi.reverseField = ffi.reverseFieldInfoTwo.name
diff --git a/orm/models_info_f.go b/orm/models_info_f.go
index 66dcc23a..14e1f2c6 100644
--- a/orm/models_info_f.go
+++ b/orm/models_info_f.go
@@ -223,6 +223,11 @@ checkType:
break checkType
case "many":
fieldType = RelReverseMany
+ if tv := tags["rel_table"]; tv != "" {
+ fi.relTable = tv
+ } else if tv := tags["rel_through"]; tv != "" {
+ fi.relThrough = tv
+ }
break checkType
default:
err = fmt.Errorf("error")
diff --git a/router.go b/router.go
index c0a50988..1e8144bf 100644
--- a/router.go
+++ b/router.go
@@ -15,10 +15,7 @@
package beego
import (
- "bufio"
- "errors"
"fmt"
- "net"
"net/http"
"os"
"path"
@@ -353,7 +350,7 @@ func (p *ControllerRegister) Handler(pattern string, h http.Handler, options ...
route.handler = h
if len(options) > 0 {
if _, ok := options[0].(bool); ok {
- pattern = path.Join(pattern, "?:all")
+ pattern = path.Join(pattern, "?:all(.*)")
}
}
for _, m := range HTTPMETHOD {
@@ -581,7 +578,7 @@ func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request)
var runMethod string
var routerInfo *controllerInfo
- w := &responseWriter{writer: rw}
+ w := &responseWriter{rw, false, 0}
if RunMode == "dev" {
w.Header().Set("Server", BeegoServerName)
@@ -856,7 +853,7 @@ Admin:
// Call WriteHeader if status code has been set changed
if context.Output.Status != 0 {
- w.writer.WriteHeader(context.Output.Status)
+ w.WriteHeader(context.Output.Status)
}
}
@@ -895,14 +892,14 @@ func (p *ControllerRegister) recoverPanic(context *beecontext.Context) {
//responseWriter is a wrapper for the http.ResponseWriter
//started set to true if response was written to then don't execute other handler
type responseWriter struct {
- writer http.ResponseWriter
+ http.ResponseWriter
started bool
status int
}
// Header returns the header map that will be sent by WriteHeader.
func (w *responseWriter) Header() http.Header {
- return w.writer.Header()
+ return w.ResponseWriter.Header()
}
// Write writes the data to the connection as part of an HTTP reply,
@@ -910,7 +907,7 @@ func (w *responseWriter) Header() http.Header {
// started means the response has sent out.
func (w *responseWriter) Write(p []byte) (int, error) {
w.started = true
- return w.writer.Write(p)
+ return w.ResponseWriter.Write(p)
}
// WriteHeader sends an HTTP response header with status code,
@@ -918,23 +915,7 @@ func (w *responseWriter) Write(p []byte) (int, error) {
func (w *responseWriter) WriteHeader(code int) {
w.status = code
w.started = true
- w.writer.WriteHeader(code)
-}
-
-// hijacker for http
-func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
- hj, ok := w.writer.(http.Hijacker)
- if !ok {
- return nil, nil, errors.New("webserver doesn't support hijacking")
- }
- return hj.Hijack()
-}
-
-func (w *responseWriter) Flush() {
- f, ok := w.writer.(http.Flusher)
- if ok {
- f.Flush()
- }
+ w.ResponseWriter.WriteHeader(code)
}
func tourl(params map[string]string) string {
diff --git a/router_test.go b/router_test.go
index c6ec9c92..9598f99c 100644
--- a/router_test.go
+++ b/router_test.go
@@ -333,6 +333,18 @@ func TestRouterHandler(t *testing.T) {
}
}
+func TestRouterHandlerAll(t *testing.T) {
+ r, _ := http.NewRequest("POST", "/sayhi/a/b/c", nil)
+ w := httptest.NewRecorder()
+
+ handler := NewControllerRegister()
+ handler.Handler("/sayhi", http.HandlerFunc(sayhello), true)
+ handler.ServeHTTP(w, r)
+ if w.Body.String() != "sayhello" {
+ t.Errorf("TestRouterHandler can't run")
+ }
+}
+
//
// Benchmarks NewApp:
//
diff --git a/staticfile.go b/staticfile.go
index e1fc4f73..de530b0c 100644
--- a/staticfile.go
+++ b/staticfile.go
@@ -96,9 +96,8 @@ func serverStaticRouter(ctx *context.Context) {
}
isStaticFileToCompress := false
- lowerFileName := strings.ToLower(filePath)
for _, statExtension := range StaticExtensionsToGzip {
- if strings.HasSuffix(lowerFileName, statExtension) {
+ if strings.HasSuffix(strings.ToLower(filePath), strings.ToLower(statExtension)) {
isStaticFileToCompress = true
break
}
diff --git a/validation/validators.go b/validation/validators.go
index ec1545fb..2662b701 100644
--- a/validation/validators.go
+++ b/validation/validators.go
@@ -74,6 +74,33 @@ func (r Required) IsSatisfied(obj interface{}) bool {
if i, ok := obj.(int); ok {
return i != 0
}
+ if i, ok := obj.(uint); ok {
+ return i != 0
+ }
+ if i, ok := obj.(int8); ok {
+ return i != 0
+ }
+ if i, ok := obj.(uint8); ok {
+ return i != 0
+ }
+ if i, ok := obj.(int16); ok {
+ return i != 0
+ }
+ if i, ok := obj.(uint16); ok {
+ return i != 0
+ }
+ if i, ok := obj.(uint32); ok {
+ return i != 0
+ }
+ if i, ok := obj.(int32); ok {
+ return i != 0
+ }
+ if i, ok := obj.(int64); ok {
+ return i != 0
+ }
+ if i, ok := obj.(uint64); ok {
+ return i != 0
+ }
if t, ok := obj.(time.Time); ok {
return !t.IsZero()
}