add api comments in file config.go, controller.go, filter.go and flash.go
Showing
4 changed files
with
126 additions
and
31 deletions
| ... | @@ -14,54 +14,81 @@ import ( | ... | @@ -14,54 +14,81 @@ import ( |
| 14 | ) | 14 | ) |
| 15 | 15 | ||
| 16 | var ( | 16 | var ( |
| 17 | // beego application | ||
| 17 | BeeApp *App | 18 | BeeApp *App |
| 19 | // application configurations | ||
| 18 | AppName string | 20 | AppName string |
| 19 | AppPath string | 21 | AppPath string |
| 20 | AppConfigPath string | 22 | AppConfigPath string |
| 21 | StaticDir map[string]string | 23 | StaticDir map[string]string |
| 24 | // template caching map | ||
| 22 | TemplateCache map[string]*template.Template | 25 | TemplateCache map[string]*template.Template |
| 23 | StaticExtensionsToGzip []string //Files which should also be compressed with gzip (.js, .css, etc) | 26 | // files with should be compressed with gzip (.js,.css,etc) |
| 27 | StaticExtensionsToGzip []string | ||
| 28 | // http server configurations | ||
| 24 | HttpAddr string | 29 | HttpAddr string |
| 25 | HttpPort int | 30 | HttpPort int |
| 26 | HttpTLS bool | 31 | HttpTLS bool |
| 27 | HttpCertFile string | 32 | HttpCertFile string |
| 28 | HttpKeyFile string | 33 | HttpKeyFile string |
| 34 | // flag of auto recover panic | ||
| 29 | RecoverPanic bool | 35 | RecoverPanic bool |
| 36 | // flag of render template automatically | ||
| 30 | AutoRender bool | 37 | AutoRender bool |
| 31 | ViewsPath string | 38 | ViewsPath string |
| 32 | RunMode string //"dev" or "prod" | 39 | // run mode, "dev" or "prod" |
| 40 | RunMode string | ||
| 33 | AppConfig config.ConfigContainer | 41 | AppConfig config.ConfigContainer |
| 34 | //related to session | 42 | // global session mananger |
| 35 | GlobalSessions *session.Manager //GlobalSessions | 43 | GlobalSessions *session.Manager |
| 36 | SessionOn bool // whether auto start session,default is false | 44 | // flag of starting session auto. default is false. |
| 37 | SessionProvider string // default session provider memory mysql redis | 45 | SessionOn bool |
| 38 | SessionName string // sessionName cookie's name | 46 | // default session provider, memory, mysql , redis ,etc. |
| 39 | SessionGCMaxLifetime int64 // session's gc maxlifetime | 47 | SessionProvider string |
| 40 | SessionSavePath string // session savepath if use mysql/redis/file this set to the connectinfo | 48 | // the cookie name when saving session id into cookie. |
| 49 | SessionName string | ||
| 50 | // session gc time for auto cleaning expired session. | ||
| 51 | SessionGCMaxLifetime int64 | ||
| 52 | // if use mysql/redis/file provider, define save path to connection info. | ||
| 53 | SessionSavePath string | ||
| 54 | // session hash generation func. | ||
| 41 | SessionHashFunc string | 55 | SessionHashFunc string |
| 56 | // session hash salt string. | ||
| 42 | SessionHashKey string | 57 | SessionHashKey string |
| 58 | // the life time of session id in cookie. | ||
| 43 | SessionCookieLifeTime int | 59 | SessionCookieLifeTime int |
| 44 | UseFcgi bool | 60 | UseFcgi bool |
| 45 | MaxMemory int64 | 61 | MaxMemory int64 |
| 46 | EnableGzip bool // enable gzip | 62 | // flag of enable gzip |
| 47 | DirectoryIndex bool //enable DirectoryIndex default is false | 63 | EnableGzip bool |
| 48 | EnableHotUpdate bool //enable HotUpdate default is false | 64 | // flag of display directory index. default is false. |
| 49 | HttpServerTimeOut int64 //set httpserver timeout | 65 | DirectoryIndex bool |
| 50 | ErrorsShow bool //set weather show errors | 66 | // flag of hot update checking in app self. default is false. |
| 51 | XSRFKEY string //set XSRF | 67 | EnableHotUpdate bool |
| 68 | HttpServerTimeOut int64 | ||
| 69 | // flag of show errors in page. if true, show error and trace info in page rendered with error template. | ||
| 70 | ErrorsShow bool | ||
| 71 | // xsrf hash salt string. | ||
| 72 | XSRFKEY string | ||
| 73 | // flag of enable xsrf. | ||
| 52 | EnableXSRF bool | 74 | EnableXSRF bool |
| 75 | // the expiry of xsrf value. | ||
| 53 | XSRFExpire int | 76 | XSRFExpire int |
| 54 | CopyRequestBody bool //When in raw application, You want to the reqeustbody | 77 | // flag of copy raw request body in context. |
| 78 | CopyRequestBody bool | ||
| 55 | TemplateLeft string | 79 | TemplateLeft string |
| 56 | TemplateRight string | 80 | TemplateRight string |
| 81 | // beego server name exported in response header. | ||
| 57 | BeegoServerName string | 82 | BeegoServerName string |
| 58 | EnableAdmin bool //enable admin module to log api time | 83 | // flag of enable admin module to log every request info. |
| 59 | AdminHttpAddr string //admin module http addr | 84 | EnableAdmin bool |
| 85 | // http server configurations for admin module. | ||
| 86 | AdminHttpAddr string | ||
| 60 | AdminHttpPort int | 87 | AdminHttpPort int |
| 61 | ) | 88 | ) |
| 62 | 89 | ||
| 63 | func init() { | 90 | func init() { |
| 64 | // create beeapp | 91 | // create beego application |
| 65 | BeeApp = NewApp() | 92 | BeeApp = NewApp() |
| 66 | 93 | ||
| 67 | // initialize default configurations | 94 | // initialize default configurations |
| ... | @@ -100,7 +127,7 @@ func init() { | ... | @@ -100,7 +127,7 @@ func init() { |
| 100 | 127 | ||
| 101 | UseFcgi = false | 128 | UseFcgi = false |
| 102 | 129 | ||
| 103 | MaxMemory = 1 << 26 //64MB | 130 | MaxMemory = 1<<26 //64MB |
| 104 | 131 | ||
| 105 | EnableGzip = false | 132 | EnableGzip = false |
| 106 | 133 | ||
| ... | @@ -135,7 +162,8 @@ func init() { | ... | @@ -135,7 +162,8 @@ func init() { |
| 135 | } | 162 | } |
| 136 | } | 163 | } |
| 137 | 164 | ||
| 138 | //parse config now only support ini, next will support json | 165 | // ParseConfig parsed default config file. |
| 166 | // now only support ini, next will support json. | ||
| 139 | func ParseConfig() (err error) { | 167 | func ParseConfig() (err error) { |
| 140 | AppConfig, err = config.NewConfig("ini", AppConfigPath) | 168 | AppConfig, err = config.NewConfig("ini", AppConfigPath) |
| 141 | if err != nil { | 169 | if err != nil { | ... | ... |
| ... | @@ -25,9 +25,12 @@ import ( | ... | @@ -25,9 +25,12 @@ import ( |
| 25 | ) | 25 | ) |
| 26 | 26 | ||
| 27 | var ( | 27 | var ( |
| 28 | // custom error when user stop request handler manually. | ||
| 28 | USERSTOPRUN = errors.New("User stop run") | 29 | USERSTOPRUN = errors.New("User stop run") |
| 29 | ) | 30 | ) |
| 30 | 31 | ||
| 32 | // Controller defines some basic http request handler operations, such as | ||
| 33 | // http context, template and view, session and xsrf. | ||
| 31 | type Controller struct { | 34 | type Controller struct { |
| 32 | Ctx *context.Context | 35 | Ctx *context.Context |
| 33 | Data map[interface{}]interface{} | 36 | Data map[interface{}]interface{} |
| ... | @@ -43,6 +46,7 @@ type Controller struct { | ... | @@ -43,6 +46,7 @@ type Controller struct { |
| 43 | AppController interface{} | 46 | AppController interface{} |
| 44 | } | 47 | } |
| 45 | 48 | ||
| 49 | // ControllerInterface is an interface to uniform all controller handler. | ||
| 46 | type ControllerInterface interface { | 50 | type ControllerInterface interface { |
| 47 | Init(ct *context.Context, controllerName, actionName string, app interface{}) | 51 | Init(ct *context.Context, controllerName, actionName string, app interface{}) |
| 48 | Prepare() | 52 | Prepare() |
| ... | @@ -59,6 +63,7 @@ type ControllerInterface interface { | ... | @@ -59,6 +63,7 @@ type ControllerInterface interface { |
| 59 | CheckXsrfCookie() bool | 63 | CheckXsrfCookie() bool |
| 60 | } | 64 | } |
| 61 | 65 | ||
| 66 | // Init generates default values of controller operations. | ||
| 62 | func (c *Controller) Init(ctx *context.Context, controllerName, actionName string, app interface{}) { | 67 | func (c *Controller) Init(ctx *context.Context, controllerName, actionName string, app interface{}) { |
| 63 | c.Data = make(map[interface{}]interface{}) | 68 | c.Data = make(map[interface{}]interface{}) |
| 64 | c.Layout = "" | 69 | c.Layout = "" |
| ... | @@ -70,42 +75,52 @@ func (c *Controller) Init(ctx *context.Context, controllerName, actionName strin | ... | @@ -70,42 +75,52 @@ func (c *Controller) Init(ctx *context.Context, controllerName, actionName strin |
| 70 | c.AppController = app | 75 | c.AppController = app |
| 71 | } | 76 | } |
| 72 | 77 | ||
| 78 | // Prepare runs after Init before request function execution. | ||
| 73 | func (c *Controller) Prepare() { | 79 | func (c *Controller) Prepare() { |
| 74 | 80 | ||
| 75 | } | 81 | } |
| 76 | 82 | ||
| 83 | // Finish runs after request function execution. | ||
| 77 | func (c *Controller) Finish() { | 84 | func (c *Controller) Finish() { |
| 78 | 85 | ||
| 79 | } | 86 | } |
| 80 | 87 | ||
| 88 | // Get adds a request function to handle GET request. | ||
| 81 | func (c *Controller) Get() { | 89 | func (c *Controller) Get() { |
| 82 | http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) | 90 | http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) |
| 83 | } | 91 | } |
| 84 | 92 | ||
| 93 | // Post adds a request function to handle POST request. | ||
| 85 | func (c *Controller) Post() { | 94 | func (c *Controller) Post() { |
| 86 | http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) | 95 | http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) |
| 87 | } | 96 | } |
| 88 | 97 | ||
| 98 | // Delete adds a request function to handle DELETE request. | ||
| 89 | func (c *Controller) Delete() { | 99 | func (c *Controller) Delete() { |
| 90 | http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) | 100 | http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) |
| 91 | } | 101 | } |
| 92 | 102 | ||
| 103 | // Put adds a request function to handle PUT request. | ||
| 93 | func (c *Controller) Put() { | 104 | func (c *Controller) Put() { |
| 94 | http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) | 105 | http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) |
| 95 | } | 106 | } |
| 96 | 107 | ||
| 108 | // Head adds a request function to handle HEAD request. | ||
| 97 | func (c *Controller) Head() { | 109 | func (c *Controller) Head() { |
| 98 | http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) | 110 | http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) |
| 99 | } | 111 | } |
| 100 | 112 | ||
| 113 | // Patch adds a request function to handle PATCH request. | ||
| 101 | func (c *Controller) Patch() { | 114 | func (c *Controller) Patch() { |
| 102 | http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) | 115 | http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) |
| 103 | } | 116 | } |
| 104 | 117 | ||
| 118 | // Options adds a request function to handle OPTIONS request. | ||
| 105 | func (c *Controller) Options() { | 119 | func (c *Controller) Options() { |
| 106 | http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) | 120 | http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) |
| 107 | } | 121 | } |
| 108 | 122 | ||
| 123 | // Render sends the response with rendered template bytes as text/html type. | ||
| 109 | func (c *Controller) Render() error { | 124 | func (c *Controller) Render() error { |
| 110 | rb, err := c.RenderBytes() | 125 | rb, err := c.RenderBytes() |
| 111 | 126 | ||
| ... | @@ -118,24 +133,26 @@ func (c *Controller) Render() error { | ... | @@ -118,24 +133,26 @@ func (c *Controller) Render() error { |
| 118 | return nil | 133 | return nil |
| 119 | } | 134 | } |
| 120 | 135 | ||
| 136 | // RenderString returns the rendered template string. Do not send out response. | ||
| 121 | func (c *Controller) RenderString() (string, error) { | 137 | func (c *Controller) RenderString() (string, error) { |
| 122 | b, e := c.RenderBytes() | 138 | b, e := c.RenderBytes() |
| 123 | return string(b), e | 139 | return string(b), e |
| 124 | } | 140 | } |
| 125 | 141 | ||
| 142 | // RenderBytes returns the bytes of renderd tempate string. Do not send out response. | ||
| 126 | func (c *Controller) RenderBytes() ([]byte, error) { | 143 | func (c *Controller) RenderBytes() ([]byte, error) { |
| 127 | //if the controller has set layout, then first get the tplname's content set the content to the layout | 144 | //if the controller has set layout, then first get the tplname's content set the content to the layout |
| 128 | if c.Layout != "" { | 145 | if c.Layout != "" { |
| 129 | if c.TplNames == "" { | 146 | if c.TplNames == "" { |
| 130 | c.TplNames = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt | 147 | c.TplNames = strings.ToLower(c.controllerName)+"/"+strings.ToLower(c.actionName)+"." + c.TplExt |
| 131 | } | 148 | } |
| 132 | if RunMode == "dev" { | 149 | if RunMode == "dev" { |
| 133 | BuildTemplate(ViewsPath) | 150 | BuildTemplate(ViewsPath) |
| 134 | } | 151 | } |
| 135 | newbytes := bytes.NewBufferString("") | 152 | newbytes := bytes.NewBufferString("") |
| 136 | if _, ok := BeeTemplates[c.TplNames]; !ok { | 153 | if _, ok := BeeTemplates[c.TplNames]; !ok { |
| 137 | panic("can't find templatefile in the path:" + c.TplNames) | 154 | panic("can't find templatefile in the path:"+c.TplNames) |
| 138 | return []byte{}, errors.New("can't find templatefile in the path:" + c.TplNames) | 155 | return []byte{}, errors.New("can't find templatefile in the path:"+c.TplNames) |
| 139 | } | 156 | } |
| 140 | err := BeeTemplates[c.TplNames].ExecuteTemplate(newbytes, c.TplNames, c.Data) | 157 | err := BeeTemplates[c.TplNames].ExecuteTemplate(newbytes, c.TplNames, c.Data) |
| 141 | if err != nil { | 158 | if err != nil { |
| ... | @@ -154,15 +171,15 @@ func (c *Controller) RenderBytes() ([]byte, error) { | ... | @@ -154,15 +171,15 @@ func (c *Controller) RenderBytes() ([]byte, error) { |
| 154 | return icontent, nil | 171 | return icontent, nil |
| 155 | } else { | 172 | } else { |
| 156 | if c.TplNames == "" { | 173 | if c.TplNames == "" { |
| 157 | c.TplNames = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt | 174 | c.TplNames = strings.ToLower(c.controllerName)+"/"+strings.ToLower(c.actionName)+"." + c.TplExt |
| 158 | } | 175 | } |
| 159 | if RunMode == "dev" { | 176 | if RunMode == "dev" { |
| 160 | BuildTemplate(ViewsPath) | 177 | BuildTemplate(ViewsPath) |
| 161 | } | 178 | } |
| 162 | ibytes := bytes.NewBufferString("") | 179 | ibytes := bytes.NewBufferString("") |
| 163 | if _, ok := BeeTemplates[c.TplNames]; !ok { | 180 | if _, ok := BeeTemplates[c.TplNames]; !ok { |
| 164 | panic("can't find templatefile in the path:" + c.TplNames) | 181 | panic("can't find templatefile in the path:"+c.TplNames) |
| 165 | return []byte{}, errors.New("can't find templatefile in the path:" + c.TplNames) | 182 | return []byte{}, errors.New("can't find templatefile in the path:"+c.TplNames) |
| 166 | } | 183 | } |
| 167 | err := BeeTemplates[c.TplNames].ExecuteTemplate(ibytes, c.TplNames, c.Data) | 184 | err := BeeTemplates[c.TplNames].ExecuteTemplate(ibytes, c.TplNames, c.Data) |
| 168 | if err != nil { | 185 | if err != nil { |
| ... | @@ -175,10 +192,12 @@ func (c *Controller) RenderBytes() ([]byte, error) { | ... | @@ -175,10 +192,12 @@ func (c *Controller) RenderBytes() ([]byte, error) { |
| 175 | return []byte{}, nil | 192 | return []byte{}, nil |
| 176 | } | 193 | } |
| 177 | 194 | ||
| 195 | // Redirect sends the redirection response to url with status code. | ||
| 178 | func (c *Controller) Redirect(url string, code int) { | 196 | func (c *Controller) Redirect(url string, code int) { |
| 179 | c.Ctx.Redirect(code, url) | 197 | c.Ctx.Redirect(code, url) |
| 180 | } | 198 | } |
| 181 | 199 | ||
| 200 | // Aborts stops controller handler and show the error data if code is defined in ErrorMap or code string. | ||
| 182 | func (c *Controller) Abort(code string) { | 201 | func (c *Controller) Abort(code string) { |
| 183 | status, err := strconv.Atoi(code) | 202 | status, err := strconv.Atoi(code) |
| 184 | if err == nil { | 203 | if err == nil { |
| ... | @@ -188,21 +207,26 @@ func (c *Controller) Abort(code string) { | ... | @@ -188,21 +207,26 @@ func (c *Controller) Abort(code string) { |
| 188 | } | 207 | } |
| 189 | } | 208 | } |
| 190 | 209 | ||
| 210 | // StopRun makes panic of USERSTOPRUN error and go to recover function if defined. | ||
| 191 | func (c *Controller) StopRun() { | 211 | func (c *Controller) StopRun() { |
| 192 | panic(USERSTOPRUN) | 212 | panic(USERSTOPRUN) |
| 193 | } | 213 | } |
| 194 | 214 | ||
| 215 | // UrlFor does another controller handler in this request function. | ||
| 216 | // it goes to this controller method if endpoint is not clear. | ||
| 195 | func (c *Controller) UrlFor(endpoint string, values ...string) string { | 217 | func (c *Controller) UrlFor(endpoint string, values ...string) string { |
| 196 | if len(endpoint) <= 0 { | 218 | if len(endpoint) <= 0 { |
| 197 | return "" | 219 | return "" |
| 198 | } | 220 | } |
| 199 | if endpoint[0] == '.' { | 221 | if endpoint[0] == '.' { |
| 200 | return UrlFor(reflect.Indirect(reflect.ValueOf(c.AppController)).Type().Name()+endpoint, values...) | 222 | return UrlFor(reflect.Indirect(reflect.ValueOf(c.AppController)).Type().Name() + endpoint, values...) |
| 201 | } else { | 223 | } else { |
| 202 | return UrlFor(endpoint, values...) | 224 | return UrlFor(endpoint, values...) |
| 203 | } | 225 | } |
| 226 | return "" | ||
| 204 | } | 227 | } |
| 205 | 228 | ||
| 229 | // ServeJson sends a json response with encoding charset. | ||
| 206 | func (c *Controller) ServeJson(encoding ...bool) { | 230 | func (c *Controller) ServeJson(encoding ...bool) { |
| 207 | var hasIndent bool | 231 | var hasIndent bool |
| 208 | var hasencoding bool | 232 | var hasencoding bool |
| ... | @@ -217,6 +241,7 @@ func (c *Controller) ServeJson(encoding ...bool) { | ... | @@ -217,6 +241,7 @@ func (c *Controller) ServeJson(encoding ...bool) { |
| 217 | c.Ctx.Output.Json(c.Data["json"], hasIndent, hasencoding) | 241 | c.Ctx.Output.Json(c.Data["json"], hasIndent, hasencoding) |
| 218 | } | 242 | } |
| 219 | 243 | ||
| 244 | // ServeJson sends a jsonp response. | ||
| 220 | func (c *Controller) ServeJsonp() { | 245 | func (c *Controller) ServeJsonp() { |
| 221 | var hasIndent bool | 246 | var hasIndent bool |
| 222 | if RunMode == "prod" { | 247 | if RunMode == "prod" { |
| ... | @@ -227,6 +252,7 @@ func (c *Controller) ServeJsonp() { | ... | @@ -227,6 +252,7 @@ func (c *Controller) ServeJsonp() { |
| 227 | c.Ctx.Output.Jsonp(c.Data["jsonp"], hasIndent) | 252 | c.Ctx.Output.Jsonp(c.Data["jsonp"], hasIndent) |
| 228 | } | 253 | } |
| 229 | 254 | ||
| 255 | // ServeJson sends xml response. | ||
| 230 | func (c *Controller) ServeXml() { | 256 | func (c *Controller) ServeXml() { |
| 231 | var hasIndent bool | 257 | var hasIndent bool |
| 232 | if RunMode == "prod" { | 258 | if RunMode == "prod" { |
| ... | @@ -237,6 +263,7 @@ func (c *Controller) ServeXml() { | ... | @@ -237,6 +263,7 @@ func (c *Controller) ServeXml() { |
| 237 | c.Ctx.Output.Xml(c.Data["xml"], hasIndent) | 263 | c.Ctx.Output.Xml(c.Data["xml"], hasIndent) |
| 238 | } | 264 | } |
| 239 | 265 | ||
| 266 | // Input returns the input data map from POST or PUT request body and query string. | ||
| 240 | func (c *Controller) Input() url.Values { | 267 | func (c *Controller) Input() url.Values { |
| 241 | ct := c.Ctx.Request.Header.Get("Content-Type") | 268 | ct := c.Ctx.Request.Header.Get("Content-Type") |
| 242 | if strings.Contains(ct, "multipart/form-data") { | 269 | if strings.Contains(ct, "multipart/form-data") { |
| ... | @@ -247,14 +274,18 @@ func (c *Controller) Input() url.Values { | ... | @@ -247,14 +274,18 @@ func (c *Controller) Input() url.Values { |
| 247 | return c.Ctx.Request.Form | 274 | return c.Ctx.Request.Form |
| 248 | } | 275 | } |
| 249 | 276 | ||
| 277 | // ParseForm maps input data map to obj struct. | ||
| 250 | func (c *Controller) ParseForm(obj interface{}) error { | 278 | func (c *Controller) ParseForm(obj interface{}) error { |
| 251 | return ParseForm(c.Input(), obj) | 279 | return ParseForm(c.Input(), obj) |
| 252 | } | 280 | } |
| 253 | 281 | ||
| 282 | // GetString returns the input value by key string. | ||
| 254 | func (c *Controller) GetString(key string) string { | 283 | func (c *Controller) GetString(key string) string { |
| 255 | return c.Input().Get(key) | 284 | return c.Input().Get(key) |
| 256 | } | 285 | } |
| 257 | 286 | ||
| 287 | // GetStrings returns the input string slice by key string. | ||
| 288 | // it's designed for multi-value input field such as checkbox(input[type=checkbox]), multi-selection. | ||
| 258 | func (c *Controller) GetStrings(key string) []string { | 289 | func (c *Controller) GetStrings(key string) []string { |
| 259 | r := c.Ctx.Request | 290 | r := c.Ctx.Request |
| 260 | if r.Form == nil { | 291 | if r.Form == nil { |
| ... | @@ -267,29 +298,36 @@ func (c *Controller) GetStrings(key string) []string { | ... | @@ -267,29 +298,36 @@ func (c *Controller) GetStrings(key string) []string { |
| 267 | return []string{} | 298 | return []string{} |
| 268 | } | 299 | } |
| 269 | 300 | ||
| 301 | // GetInt returns input value as int64. | ||
| 270 | func (c *Controller) GetInt(key string) (int64, error) { | 302 | func (c *Controller) GetInt(key string) (int64, error) { |
| 271 | return strconv.ParseInt(c.Input().Get(key), 10, 64) | 303 | return strconv.ParseInt(c.Input().Get(key), 10, 64) |
| 272 | } | 304 | } |
| 273 | 305 | ||
| 306 | // GetBool returns input value as bool. | ||
| 274 | func (c *Controller) GetBool(key string) (bool, error) { | 307 | func (c *Controller) GetBool(key string) (bool, error) { |
| 275 | return strconv.ParseBool(c.Input().Get(key)) | 308 | return strconv.ParseBool(c.Input().Get(key)) |
| 276 | } | 309 | } |
| 277 | 310 | ||
| 311 | // GetFloat returns input value as float64. | ||
| 278 | func (c *Controller) GetFloat(key string) (float64, error) { | 312 | func (c *Controller) GetFloat(key string) (float64, error) { |
| 279 | return strconv.ParseFloat(c.Input().Get(key), 64) | 313 | return strconv.ParseFloat(c.Input().Get(key), 64) |
| 280 | } | 314 | } |
| 281 | 315 | ||
| 316 | // GetFile returns the file data in file upload field named as key. | ||
| 317 | // it returns the first one of multi-uploaded files. | ||
| 282 | func (c *Controller) GetFile(key string) (multipart.File, *multipart.FileHeader, error) { | 318 | func (c *Controller) GetFile(key string) (multipart.File, *multipart.FileHeader, error) { |
| 283 | return c.Ctx.Request.FormFile(key) | 319 | return c.Ctx.Request.FormFile(key) |
| 284 | } | 320 | } |
| 285 | 321 | ||
| 322 | // SaveToFile saves uploaded file to new path. | ||
| 323 | // it only operates the first one of mutil-upload form file field. | ||
| 286 | func (c *Controller) SaveToFile(fromfile, tofile string) error { | 324 | func (c *Controller) SaveToFile(fromfile, tofile string) error { |
| 287 | file, _, err := c.Ctx.Request.FormFile(fromfile) | 325 | file, _, err := c.Ctx.Request.FormFile(fromfile) |
| 288 | if err != nil { | 326 | if err != nil { |
| 289 | return err | 327 | return err |
| 290 | } | 328 | } |
| 291 | defer file.Close() | 329 | defer file.Close() |
| 292 | f, err := os.OpenFile(tofile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) | 330 | f, err := os.OpenFile(tofile, os.O_WRONLY | os.O_CREATE | os.O_TRUNC, 0666) |
| 293 | if err != nil { | 331 | if err != nil { |
| 294 | return err | 332 | return err |
| 295 | } | 333 | } |
| ... | @@ -298,6 +336,7 @@ func (c *Controller) SaveToFile(fromfile, tofile string) error { | ... | @@ -298,6 +336,7 @@ func (c *Controller) SaveToFile(fromfile, tofile string) error { |
| 298 | return nil | 336 | return nil |
| 299 | } | 337 | } |
| 300 | 338 | ||
| 339 | // StartSession starts session and load old session data info this controller. | ||
| 301 | func (c *Controller) StartSession() session.SessionStore { | 340 | func (c *Controller) StartSession() session.SessionStore { |
| 302 | if c.CruSession == nil { | 341 | if c.CruSession == nil { |
| 303 | c.CruSession = c.Ctx.Input.CruSession | 342 | c.CruSession = c.Ctx.Input.CruSession |
| ... | @@ -305,6 +344,7 @@ func (c *Controller) StartSession() session.SessionStore { | ... | @@ -305,6 +344,7 @@ func (c *Controller) StartSession() session.SessionStore { |
| 305 | return c.CruSession | 344 | return c.CruSession |
| 306 | } | 345 | } |
| 307 | 346 | ||
| 347 | // SetSession puts value into session. | ||
| 308 | func (c *Controller) SetSession(name interface{}, value interface{}) { | 348 | func (c *Controller) SetSession(name interface{}, value interface{}) { |
| 309 | if c.CruSession == nil { | 349 | if c.CruSession == nil { |
| 310 | c.StartSession() | 350 | c.StartSession() |
| ... | @@ -312,6 +352,7 @@ func (c *Controller) SetSession(name interface{}, value interface{}) { | ... | @@ -312,6 +352,7 @@ func (c *Controller) SetSession(name interface{}, value interface{}) { |
| 312 | c.CruSession.Set(name, value) | 352 | c.CruSession.Set(name, value) |
| 313 | } | 353 | } |
| 314 | 354 | ||
| 355 | // GetSession gets value from session. | ||
| 315 | func (c *Controller) GetSession(name interface{}) interface{} { | 356 | func (c *Controller) GetSession(name interface{}) interface{} { |
| 316 | if c.CruSession == nil { | 357 | if c.CruSession == nil { |
| 317 | c.StartSession() | 358 | c.StartSession() |
| ... | @@ -319,6 +360,7 @@ func (c *Controller) GetSession(name interface{}) interface{} { | ... | @@ -319,6 +360,7 @@ func (c *Controller) GetSession(name interface{}) interface{} { |
| 319 | return c.CruSession.Get(name) | 360 | return c.CruSession.Get(name) |
| 320 | } | 361 | } |
| 321 | 362 | ||
| 363 | // SetSession removes value from session. | ||
| 322 | func (c *Controller) DelSession(name interface{}) { | 364 | func (c *Controller) DelSession(name interface{}) { |
| 323 | if c.CruSession == nil { | 365 | if c.CruSession == nil { |
| 324 | c.StartSession() | 366 | c.StartSession() |
| ... | @@ -326,19 +368,24 @@ func (c *Controller) DelSession(name interface{}) { | ... | @@ -326,19 +368,24 @@ func (c *Controller) DelSession(name interface{}) { |
| 326 | c.CruSession.Delete(name) | 368 | c.CruSession.Delete(name) |
| 327 | } | 369 | } |
| 328 | 370 | ||
| 371 | // SessionRegenerateID regenerates session id for this session. | ||
| 372 | // the session data have no changes. | ||
| 329 | func (c *Controller) SessionRegenerateID() { | 373 | func (c *Controller) SessionRegenerateID() { |
| 330 | c.CruSession = GlobalSessions.SessionRegenerateId(c.Ctx.ResponseWriter, c.Ctx.Request) | 374 | c.CruSession = GlobalSessions.SessionRegenerateId(c.Ctx.ResponseWriter, c.Ctx.Request) |
| 331 | c.Ctx.Input.CruSession = c.CruSession | 375 | c.Ctx.Input.CruSession = c.CruSession |
| 332 | } | 376 | } |
| 333 | 377 | ||
| 378 | // DestroySession cleans session data and session cookie. | ||
| 334 | func (c *Controller) DestroySession() { | 379 | func (c *Controller) DestroySession() { |
| 335 | GlobalSessions.SessionDestroy(c.Ctx.ResponseWriter, c.Ctx.Request) | 380 | GlobalSessions.SessionDestroy(c.Ctx.ResponseWriter, c.Ctx.Request) |
| 336 | } | 381 | } |
| 337 | 382 | ||
| 383 | // IsAjax returns this request is ajax or not. | ||
| 338 | func (c *Controller) IsAjax() bool { | 384 | func (c *Controller) IsAjax() bool { |
| 339 | return c.Ctx.Input.IsAjax() | 385 | return c.Ctx.Input.IsAjax() |
| 340 | } | 386 | } |
| 341 | 387 | ||
| 388 | // GetSecureCookie returns decoded cookie value from encoded browser cookie values. | ||
| 342 | func (c *Controller) GetSecureCookie(Secret, key string) (string, bool) { | 389 | func (c *Controller) GetSecureCookie(Secret, key string) (string, bool) { |
| 343 | val := c.Ctx.GetCookie(key) | 390 | val := c.Ctx.GetCookie(key) |
| 344 | if val == "" { | 391 | if val == "" { |
| ... | @@ -365,6 +412,7 @@ func (c *Controller) GetSecureCookie(Secret, key string) (string, bool) { | ... | @@ -365,6 +412,7 @@ func (c *Controller) GetSecureCookie(Secret, key string) (string, bool) { |
| 365 | return string(res), true | 412 | return string(res), true |
| 366 | } | 413 | } |
| 367 | 414 | ||
| 415 | // SetSecureCookie puts value into cookie after encoded the value. | ||
| 368 | func (c *Controller) SetSecureCookie(Secret, name, val string, age int64) { | 416 | func (c *Controller) SetSecureCookie(Secret, name, val string, age int64) { |
| 369 | vs := base64.URLEncoding.EncodeToString([]byte(val)) | 417 | vs := base64.URLEncoding.EncodeToString([]byte(val)) |
| 370 | timestamp := strconv.FormatInt(time.Now().UnixNano(), 10) | 418 | timestamp := strconv.FormatInt(time.Now().UnixNano(), 10) |
| ... | @@ -375,6 +423,7 @@ func (c *Controller) SetSecureCookie(Secret, name, val string, age int64) { | ... | @@ -375,6 +423,7 @@ func (c *Controller) SetSecureCookie(Secret, name, val string, age int64) { |
| 375 | c.Ctx.SetCookie(name, cookie, age, "/") | 423 | c.Ctx.SetCookie(name, cookie, age, "/") |
| 376 | } | 424 | } |
| 377 | 425 | ||
| 426 | // XsrfToken creates a xsrf token string and returns. | ||
| 378 | func (c *Controller) XsrfToken() string { | 427 | func (c *Controller) XsrfToken() string { |
| 379 | if c._xsrf_token == "" { | 428 | if c._xsrf_token == "" { |
| 380 | token, ok := c.GetSecureCookie(XSRFKEY, "_xsrf") | 429 | token, ok := c.GetSecureCookie(XSRFKEY, "_xsrf") |
| ... | @@ -393,6 +442,9 @@ func (c *Controller) XsrfToken() string { | ... | @@ -393,6 +442,9 @@ func (c *Controller) XsrfToken() string { |
| 393 | return c._xsrf_token | 442 | return c._xsrf_token |
| 394 | } | 443 | } |
| 395 | 444 | ||
| 445 | // CheckXsrfCookie checks xsrf token in this request is valid or not. | ||
| 446 | // the token can provided in request header "X-Xsrftoken" and "X-CsrfToken" | ||
| 447 | // or in form field value named as "_xsrf". | ||
| 396 | func (c *Controller) CheckXsrfCookie() bool { | 448 | func (c *Controller) CheckXsrfCookie() bool { |
| 397 | token := c.GetString("_xsrf") | 449 | token := c.GetString("_xsrf") |
| 398 | if token == "" { | 450 | if token == "" { |
| ... | @@ -409,16 +461,18 @@ func (c *Controller) CheckXsrfCookie() bool { | ... | @@ -409,16 +461,18 @@ func (c *Controller) CheckXsrfCookie() bool { |
| 409 | return true | 461 | return true |
| 410 | } | 462 | } |
| 411 | 463 | ||
| 464 | // XsrfFormHtml writes an input field contains xsrf token value. | ||
| 412 | func (c *Controller) XsrfFormHtml() string { | 465 | func (c *Controller) XsrfFormHtml() string { |
| 413 | return "<input type=\"hidden\" name=\"_xsrf\" value=\"" + | 466 | return "<input type=\"hidden\" name=\"_xsrf\" value=\"" + |
| 414 | c._xsrf_token + "\"/>" | 467 | c._xsrf_token + "\"/>" |
| 415 | } | 468 | } |
| 416 | 469 | ||
| 470 | // GetControllerAndAction gets the executing controller name and action name. | ||
| 417 | func (c *Controller) GetControllerAndAction() (controllerName, actionName string) { | 471 | func (c *Controller) GetControllerAndAction() (controllerName, actionName string) { |
| 418 | return c.controllerName, c.actionName | 472 | return c.controllerName, c.actionName |
| 419 | } | 473 | } |
| 420 | 474 | ||
| 421 | //utils func for controller internal | 475 | // getRandomString returns random string. |
| 422 | func getRandomString(n int) string { | 476 | func getRandomString(n int) string { |
| 423 | const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | 477 | const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" |
| 424 | var bytes = make([]byte, n) | 478 | var bytes = make([]byte, n) | ... | ... |
| ... | @@ -5,6 +5,8 @@ import ( | ... | @@ -5,6 +5,8 @@ import ( |
| 5 | "strings" | 5 | "strings" |
| 6 | ) | 6 | ) |
| 7 | 7 | ||
| 8 | // FilterRouter defines filter operation before controller handler execution. | ||
| 9 | // it can match patterned url and do filter function when action arrives. | ||
| 8 | type FilterRouter struct { | 10 | type FilterRouter struct { |
| 9 | pattern string | 11 | pattern string |
| 10 | regex *regexp.Regexp | 12 | regex *regexp.Regexp |
| ... | @@ -14,6 +16,8 @@ type FilterRouter struct { | ... | @@ -14,6 +16,8 @@ type FilterRouter struct { |
| 14 | parseParams map[string]string | 16 | parseParams map[string]string |
| 15 | } | 17 | } |
| 16 | 18 | ||
| 19 | // ValidRouter check current request is valid for this filter. | ||
| 20 | // if matched, returns parsed params in this request by defined filter router pattern. | ||
| 17 | func (mr *FilterRouter) ValidRouter(router string) (bool, map[string]string) { | 21 | func (mr *FilterRouter) ValidRouter(router string) (bool, map[string]string) { |
| 18 | if mr.pattern == "" { | 22 | if mr.pattern == "" { |
| 19 | return true, nil | 23 | return true, nil | ... | ... |
| ... | @@ -6,18 +6,22 @@ import ( | ... | @@ -6,18 +6,22 @@ import ( |
| 6 | "strings" | 6 | "strings" |
| 7 | ) | 7 | ) |
| 8 | 8 | ||
| 9 | // the separation string when encoding flash data. | ||
| 9 | const BEEGO_FLASH_SEP = "#BEEGOFLASH#" | 10 | const BEEGO_FLASH_SEP = "#BEEGOFLASH#" |
| 10 | 11 | ||
| 12 | // FlashData is a tools to maintain data when using across request. | ||
| 11 | type FlashData struct { | 13 | type FlashData struct { |
| 12 | Data map[string]string | 14 | Data map[string]string |
| 13 | } | 15 | } |
| 14 | 16 | ||
| 17 | // NewFlash return a new empty FlashData struct. | ||
| 15 | func NewFlash() *FlashData { | 18 | func NewFlash() *FlashData { |
| 16 | return &FlashData{ | 19 | return &FlashData{ |
| 17 | Data: make(map[string]string), | 20 | Data: make(map[string]string), |
| 18 | } | 21 | } |
| 19 | } | 22 | } |
| 20 | 23 | ||
| 24 | // Notice writes notice message to flash. | ||
| 21 | func (fd *FlashData) Notice(msg string, args ...interface{}) { | 25 | func (fd *FlashData) Notice(msg string, args ...interface{}) { |
| 22 | if len(args) == 0 { | 26 | if len(args) == 0 { |
| 23 | fd.Data["notice"] = msg | 27 | fd.Data["notice"] = msg |
| ... | @@ -26,6 +30,7 @@ func (fd *FlashData) Notice(msg string, args ...interface{}) { | ... | @@ -26,6 +30,7 @@ func (fd *FlashData) Notice(msg string, args ...interface{}) { |
| 26 | } | 30 | } |
| 27 | } | 31 | } |
| 28 | 32 | ||
| 33 | // Warning writes warning message to flash. | ||
| 29 | func (fd *FlashData) Warning(msg string, args ...interface{}) { | 34 | func (fd *FlashData) Warning(msg string, args ...interface{}) { |
| 30 | if len(args) == 0 { | 35 | if len(args) == 0 { |
| 31 | fd.Data["warning"] = msg | 36 | fd.Data["warning"] = msg |
| ... | @@ -34,6 +39,7 @@ func (fd *FlashData) Warning(msg string, args ...interface{}) { | ... | @@ -34,6 +39,7 @@ func (fd *FlashData) Warning(msg string, args ...interface{}) { |
| 34 | } | 39 | } |
| 35 | } | 40 | } |
| 36 | 41 | ||
| 42 | // Error writes error message to flash. | ||
| 37 | func (fd *FlashData) Error(msg string, args ...interface{}) { | 43 | func (fd *FlashData) Error(msg string, args ...interface{}) { |
| 38 | if len(args) == 0 { | 44 | if len(args) == 0 { |
| 39 | fd.Data["error"] = msg | 45 | fd.Data["error"] = msg |
| ... | @@ -42,6 +48,8 @@ func (fd *FlashData) Error(msg string, args ...interface{}) { | ... | @@ -42,6 +48,8 @@ func (fd *FlashData) Error(msg string, args ...interface{}) { |
| 42 | } | 48 | } |
| 43 | } | 49 | } |
| 44 | 50 | ||
| 51 | // Store does the saving operation of flash data. | ||
| 52 | // the data are encoded and saved in cookie. | ||
| 45 | func (fd *FlashData) Store(c *Controller) { | 53 | func (fd *FlashData) Store(c *Controller) { |
| 46 | c.Data["flash"] = fd.Data | 54 | c.Data["flash"] = fd.Data |
| 47 | var flashValue string | 55 | var flashValue string |
| ... | @@ -51,6 +59,7 @@ func (fd *FlashData) Store(c *Controller) { | ... | @@ -51,6 +59,7 @@ func (fd *FlashData) Store(c *Controller) { |
| 51 | c.Ctx.SetCookie("BEEGO_FLASH", url.QueryEscape(flashValue), 0, "/") | 59 | c.Ctx.SetCookie("BEEGO_FLASH", url.QueryEscape(flashValue), 0, "/") |
| 52 | } | 60 | } |
| 53 | 61 | ||
| 62 | // ReadFromRequest parsed flash data from encoded values in cookie. | ||
| 54 | func ReadFromRequest(c *Controller) *FlashData { | 63 | func ReadFromRequest(c *Controller) *FlashData { |
| 55 | flash := &FlashData{ | 64 | flash := &FlashData{ |
| 56 | Data: make(map[string]string), | 65 | Data: make(map[string]string), | ... | ... |
-
Please register or sign in to post a comment