1
0
mirror of https://github.com/astaxie/beego.git synced 2024-06-30 20:34:13 +00:00

Merge pull request #400 from fuxiaohei/master

add api comments
This commit is contained in:
astaxie 2013-12-20 07:23:12 -08:00
commit 2ad399db05
6 changed files with 173 additions and 43 deletions

43
app.go
View File

@ -10,19 +10,22 @@ import (
"github.com/astaxie/beego/context" "github.com/astaxie/beego/context"
) )
// FilterFunc defines filter function type.
type FilterFunc func(*context.Context) type FilterFunc func(*context.Context)
// App defines beego application with a new PatternServeMux.
type App struct { type App struct {
Handlers *ControllerRegistor Handlers *ControllerRegistor
} }
// New returns a new PatternServeMux. // NewApp returns a new beego application.
func NewApp() *App { func NewApp() *App {
cr := NewControllerRegistor() cr := NewControllerRegistor()
app := &App{Handlers: cr} app := &App{Handlers: cr}
return app return app
} }
// Run beego application.
func (app *App) Run() { func (app *App) Run() {
addr := HttpAddr addr := HttpAddr
@ -84,39 +87,77 @@ func (app *App) Run() {
} }
} }
// Router adds a url-patterned controller handler.
// The path argument supports regex rules and specific placeholders.
// The c argument needs a controller handler implemented beego.ControllerInterface.
// The mapping methods argument only need one string to define custom router rules.
// usage:
// simple router
// beego.Router("/admin", &admin.UserController{})
// beego.Router("/admin/index", &admin.ArticleController{})
//
// regex router
//
// beego.Router(“/api/:id([0-9]+)“, &controllers.RController{})
//
// custom rules
// beego.Router("/api/list",&RestController{},"*:ListFood")
// beego.Router("/api/create",&RestController{},"post:CreateFood")
// beego.Router("/api/update",&RestController{},"put:UpdateFood")
// beego.Router("/api/delete",&RestController{},"delete:DeleteFood")
func (app *App) Router(path string, c ControllerInterface, mappingMethods ...string) *App { func (app *App) Router(path string, c ControllerInterface, mappingMethods ...string) *App {
app.Handlers.Add(path, c, mappingMethods...) app.Handlers.Add(path, c, mappingMethods...)
return app return app
} }
// AutoRouter adds beego-defined controller handler.
// if beego.AddAuto(&MainContorlller{}) and MainController has methods List and Page,
// visit the url /main/list to exec List function or /main/page to exec Page function.
func (app *App) AutoRouter(c ControllerInterface) *App { func (app *App) AutoRouter(c ControllerInterface) *App {
app.Handlers.AddAuto(c) app.Handlers.AddAuto(c)
return app return app
} }
// UrlFor does another controller handler with params in current context.
// The endpoint is formed as path.controller.name to defined the controller method which will run.
// The values need key-pair data to assign into controller method.
func (app *App) UrlFor(endpoint string, values ...string) string { func (app *App) UrlFor(endpoint string, values ...string) string {
return app.Handlers.UrlFor(endpoint, values...) return app.Handlers.UrlFor(endpoint, values...)
} }
// [Deprecated] use InsertFilter.
// Filter adds a FilterFunc under pattern condition and named action.
// The actions contains BeforeRouter,AfterStatic,BeforeExec,AfterExec and FinishRouter.
func (app *App) Filter(pattern, action string, filter FilterFunc) *App { func (app *App) Filter(pattern, action string, filter FilterFunc) *App {
app.Handlers.AddFilter(pattern, action, filter) app.Handlers.AddFilter(pattern, action, filter)
return app return app
} }
// InsertFilter adds a FilterFunc with pattern condition and action constant.
// The pos means action constant including
// beego.BeforeRouter, beego.AfterStatic, beego.BeforeExec, beego.AfterExec and beego.FinishRouter.
func (app *App) InsertFilter(pattern string, pos int, filter FilterFunc) *App { func (app *App) InsertFilter(pattern string, pos int, filter FilterFunc) *App {
app.Handlers.InsertFilter(pattern, pos, filter) app.Handlers.InsertFilter(pattern, pos, filter)
return app return app
} }
// SetViewsPath sets view directory path in beego application.
// it returns beego application self.
func (app *App) SetViewsPath(path string) *App { func (app *App) SetViewsPath(path string) *App {
ViewsPath = path ViewsPath = path
return app return app
} }
// SetStaticPath sets static directory path and proper url pattern in beego application.
// if beego.SetStaticPath("static","public"), visit /static/* to load static file in folder "public".
// it returns beego application self.
func (app *App) SetStaticPath(url string, path string) *App { func (app *App) SetStaticPath(url string, path string) *App {
StaticDir[url] = path StaticDir[url] = path
return app return app
} }
// DelStaticPath removes the static folder setting in this url pattern in beego application.
// it returns beego application self.
func (app *App) DelStaticPath(url string) *App { func (app *App) DelStaticPath(url string) *App {
delete(StaticDir, url) delete(StaticDir, url)
return app return app

View File

@ -10,34 +10,50 @@ import (
"github.com/astaxie/beego/session" "github.com/astaxie/beego/session"
) )
// beego web framework version.
const VERSION = "1.0.0" const VERSION = "1.0.0"
// Router adds a patterned controller handler to BeeApp.
// it's an alias method of App.Router.
func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *App { func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *App {
BeeApp.Router(rootpath, c, mappingMethods...) BeeApp.Router(rootpath, c, mappingMethods...)
return BeeApp return BeeApp
} }
// RESTRouter adds a restful controller handler to BeeApp.
// its' controller implements beego.ControllerInterface and
// defines a param "pattern/:objectId" to visit each resource.
func RESTRouter(rootpath string, c ControllerInterface) *App { func RESTRouter(rootpath string, c ControllerInterface) *App {
Router(rootpath, c) Router(rootpath, c)
Router(path.Join(rootpath, ":objectId"), c) Router(path.Join(rootpath, ":objectId"), c)
return BeeApp return BeeApp
} }
// AutoRouter adds defined controller handler to BeeApp.
// it's same to App.AutoRouter.
func AutoRouter(c ControllerInterface) *App { func AutoRouter(c ControllerInterface) *App {
BeeApp.AutoRouter(c) BeeApp.AutoRouter(c)
return BeeApp return BeeApp
} }
// ErrorHandler registers http.HandlerFunc to each http err code string.
// usage:
// beego.ErrorHandler("404",NotFound)
// beego.ErrorHandler("500",InternalServerError)
func Errorhandler(err string, h http.HandlerFunc) *App { func Errorhandler(err string, h http.HandlerFunc) *App {
middleware.Errorhandler(err, h) middleware.Errorhandler(err, h)
return BeeApp return BeeApp
} }
// SetViewsPath sets view directory to BeeApp.
// it's alias of App.SetViewsPath.
func SetViewsPath(path string) *App { func SetViewsPath(path string) *App {
BeeApp.SetViewsPath(path) BeeApp.SetViewsPath(path)
return BeeApp return BeeApp
} }
// SetStaticPath sets static directory and url prefix to BeeApp.
// it's alias of App.SetStaticPath.
func SetStaticPath(url string, path string) *App { func SetStaticPath(url string, path string) *App {
if !strings.HasPrefix(url, "/") { if !strings.HasPrefix(url, "/") {
url = "/" + url url = "/" + url
@ -46,27 +62,33 @@ func SetStaticPath(url string, path string) *App {
return BeeApp return BeeApp
} }
// DelStaticPath removes the static folder setting in this url pattern in beego application.
// it's alias of App.DelStaticPath.
func DelStaticPath(url string) *App { func DelStaticPath(url string) *App {
delete(StaticDir, url) delete(StaticDir, url)
return BeeApp return BeeApp
} }
//!!DEPRECATED!! use InsertFilter // [Deprecated] use InsertFilter.
//action has four values: // Filter adds a FilterFunc under pattern condition and named action.
//BeforRouter // The actions contains BeforeRouter,AfterStatic,BeforeExec,AfterExec and FinishRouter.
//AfterStatic // it's alias of App.Filter.
//BeforExec
//AfterExec
func AddFilter(pattern, action string, filter FilterFunc) *App { func AddFilter(pattern, action string, filter FilterFunc) *App {
BeeApp.Filter(pattern, action, filter) BeeApp.Filter(pattern, action, filter)
return BeeApp return BeeApp
} }
// InsertFilter adds a FilterFunc with pattern condition and action constant.
// The pos means action constant including
// beego.BeforeRouter, beego.AfterStatic, beego.BeforeExec, beego.AfterExec and beego.FinishRouter.
// it's alias of App.InsertFilter.
func InsertFilter(pattern string, pos int, filter FilterFunc) *App { func InsertFilter(pattern string, pos int, filter FilterFunc) *App {
BeeApp.InsertFilter(pattern, pos, filter) BeeApp.InsertFilter(pattern, pos, filter)
return BeeApp return BeeApp
} }
// Run beego application.
// it's alias of App.Run.
func Run() { func Run() {
// if AppConfigPath not In the conf/app.conf reParse config // if AppConfigPath not In the conf/app.conf reParse config
if AppConfigPath != filepath.Join(AppPath, "conf", "app.conf") { if AppConfigPath != filepath.Join(AppPath, "conf", "app.conf") {

View File

@ -14,54 +14,53 @@ import (
) )
var ( var (
BeeApp *App BeeApp *App // beego application
AppName string AppName string
AppPath string AppPath string
AppConfigPath string AppConfigPath string
StaticDir map[string]string StaticDir map[string]string
TemplateCache map[string]*template.Template TemplateCache map[string]*template.Template // template caching map
StaticExtensionsToGzip []string //Files which should also be compressed with gzip (.js, .css, etc) StaticExtensionsToGzip []string // files with should be compressed with gzip (.js,.css,etc)
HttpAddr string HttpAddr string
HttpPort int HttpPort int
HttpTLS bool HttpTLS bool
HttpCertFile string HttpCertFile string
HttpKeyFile string HttpKeyFile string
RecoverPanic bool RecoverPanic bool // flag of auto recover panic
AutoRender bool AutoRender bool // flag of render template automatically
ViewsPath string ViewsPath string
RunMode string //"dev" or "prod" RunMode string // run mode, "dev" or "prod"
AppConfig config.ConfigContainer AppConfig config.ConfigContainer
//related to session GlobalSessions *session.Manager // global session mananger
GlobalSessions *session.Manager //GlobalSessions SessionOn bool // flag of starting session auto. default is false.
SessionOn bool // whether auto start session,default is false SessionProvider string // default session provider, memory, mysql , redis ,etc.
SessionProvider string // default session provider memory mysql redis SessionName string // the cookie name when saving session id into cookie.
SessionName string // sessionName cookie's name SessionGCMaxLifetime int64 // session gc time for auto cleaning expired session.
SessionGCMaxLifetime int64 // session's gc maxlifetime SessionSavePath string // if use mysql/redis/file provider, define save path to connection info.
SessionSavePath string // session savepath if use mysql/redis/file this set to the connectinfo SessionHashFunc string // session hash generation func.
SessionHashFunc string SessionHashKey string // session hash salt string.
SessionHashKey string SessionCookieLifeTime int // the life time of session id in cookie.
SessionCookieLifeTime int UseFcgi bool
UseFcgi bool MaxMemory int64
MaxMemory int64 EnableGzip bool // flag of enable gzip
EnableGzip bool // enable gzip DirectoryIndex bool // flag of display directory index. default is false.
DirectoryIndex bool //enable DirectoryIndex default is false EnableHotUpdate bool // flag of hot update checking by app self. default is false.
EnableHotUpdate bool //enable HotUpdate default is false HttpServerTimeOut int64
HttpServerTimeOut int64 //set httpserver timeout ErrorsShow bool // flag of show errors in page. if true, show error and trace info in page rendered with error template.
ErrorsShow bool //set weather show errors XSRFKEY string // xsrf hash salt string.
XSRFKEY string //set XSRF EnableXSRF bool // flag of enable xsrf.
EnableXSRF bool XSRFExpire int // the expiry of xsrf value.
XSRFExpire int CopyRequestBody bool // flag of copy raw request body in context.
CopyRequestBody bool //When in raw application, You want to the reqeustbody TemplateLeft string
TemplateLeft string TemplateRight string
TemplateRight string BeegoServerName string // beego server name exported in response header.
BeegoServerName string EnableAdmin bool // flag of enable admin module to log every request info.
EnableAdmin bool //enable admin module to log api time AdminHttpAddr string // http server configurations for admin module.
AdminHttpAddr string //admin module http addr AdminHttpPort int
AdminHttpPort int
) )
func init() { func init() {
// create beeapp // create beego application
BeeApp = NewApp() BeeApp = NewApp()
// initialize default configurations // initialize default configurations
@ -135,7 +134,8 @@ func init() {
} }
} }
//parse config now only support ini, next will support json // ParseConfig parsed default config file.
// now only support ini, next will support json.
func ParseConfig() (err error) { func ParseConfig() (err error) {
AppConfig, err = config.NewConfig("ini", AppConfigPath) AppConfig, err = config.NewConfig("ini", AppConfigPath)
if err != nil { if err != nil {

View File

@ -25,9 +25,12 @@ import (
) )
var ( var (
// custom error when user stop request handler manually.
USERSTOPRUN = errors.New("User stop run") USERSTOPRUN = errors.New("User stop run")
) )
// Controller defines some basic http request handler operations, such as
// http context, template and view, session and xsrf.
type Controller struct { type Controller struct {
Ctx *context.Context Ctx *context.Context
Data map[interface{}]interface{} Data map[interface{}]interface{}
@ -43,6 +46,7 @@ type Controller struct {
AppController interface{} AppController interface{}
} }
// ControllerInterface is an interface to uniform all controller handler.
type ControllerInterface interface { type ControllerInterface interface {
Init(ct *context.Context, controllerName, actionName string, app interface{}) Init(ct *context.Context, controllerName, actionName string, app interface{})
Prepare() Prepare()
@ -59,6 +63,7 @@ type ControllerInterface interface {
CheckXsrfCookie() bool CheckXsrfCookie() bool
} }
// Init generates default values of controller operations.
func (c *Controller) Init(ctx *context.Context, controllerName, actionName string, app interface{}) { func (c *Controller) Init(ctx *context.Context, controllerName, actionName string, app interface{}) {
c.Data = make(map[interface{}]interface{}) c.Data = make(map[interface{}]interface{})
c.Layout = "" c.Layout = ""
@ -70,42 +75,52 @@ func (c *Controller) Init(ctx *context.Context, controllerName, actionName strin
c.AppController = app c.AppController = app
} }
// Prepare runs after Init before request function execution.
func (c *Controller) Prepare() { func (c *Controller) Prepare() {
} }
// Finish runs after request function execution.
func (c *Controller) Finish() { func (c *Controller) Finish() {
} }
// Get adds a request function to handle GET request.
func (c *Controller) Get() { func (c *Controller) Get() {
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405)
} }
// Post adds a request function to handle POST request.
func (c *Controller) Post() { func (c *Controller) Post() {
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405)
} }
// Delete adds a request function to handle DELETE request.
func (c *Controller) Delete() { func (c *Controller) Delete() {
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405)
} }
// Put adds a request function to handle PUT request.
func (c *Controller) Put() { func (c *Controller) Put() {
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405)
} }
// Head adds a request function to handle HEAD request.
func (c *Controller) Head() { func (c *Controller) Head() {
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405)
} }
// Patch adds a request function to handle PATCH request.
func (c *Controller) Patch() { func (c *Controller) Patch() {
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405)
} }
// Options adds a request function to handle OPTIONS request.
func (c *Controller) Options() { func (c *Controller) Options() {
http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405) http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405)
} }
// Render sends the response with rendered template bytes as text/html type.
func (c *Controller) Render() error { func (c *Controller) Render() error {
rb, err := c.RenderBytes() rb, err := c.RenderBytes()
@ -118,11 +133,13 @@ func (c *Controller) Render() error {
return nil return nil
} }
// RenderString returns the rendered template string. Do not send out response.
func (c *Controller) RenderString() (string, error) { func (c *Controller) RenderString() (string, error) {
b, e := c.RenderBytes() b, e := c.RenderBytes()
return string(b), e return string(b), e
} }
// RenderBytes returns the bytes of renderd tempate string. Do not send out response.
func (c *Controller) RenderBytes() ([]byte, error) { func (c *Controller) RenderBytes() ([]byte, error) {
//if the controller has set layout, then first get the tplname's content set the content to the layout //if the controller has set layout, then first get the tplname's content set the content to the layout
if c.Layout != "" { if c.Layout != "" {
@ -175,10 +192,12 @@ func (c *Controller) RenderBytes() ([]byte, error) {
return []byte{}, nil return []byte{}, nil
} }
// Redirect sends the redirection response to url with status code.
func (c *Controller) Redirect(url string, code int) { func (c *Controller) Redirect(url string, code int) {
c.Ctx.Redirect(code, url) c.Ctx.Redirect(code, url)
} }
// Aborts stops controller handler and show the error data if code is defined in ErrorMap or code string.
func (c *Controller) Abort(code string) { func (c *Controller) Abort(code string) {
status, err := strconv.Atoi(code) status, err := strconv.Atoi(code)
if err == nil { if err == nil {
@ -188,10 +207,13 @@ func (c *Controller) Abort(code string) {
} }
} }
// StopRun makes panic of USERSTOPRUN error and go to recover function if defined.
func (c *Controller) StopRun() { func (c *Controller) StopRun() {
panic(USERSTOPRUN) panic(USERSTOPRUN)
} }
// UrlFor does another controller handler in this request function.
// it goes to this controller method if endpoint is not clear.
func (c *Controller) UrlFor(endpoint string, values ...string) string { func (c *Controller) UrlFor(endpoint string, values ...string) string {
if len(endpoint) <= 0 { if len(endpoint) <= 0 {
return "" return ""
@ -201,8 +223,10 @@ func (c *Controller) UrlFor(endpoint string, values ...string) string {
} else { } else {
return UrlFor(endpoint, values...) return UrlFor(endpoint, values...)
} }
return ""
} }
// ServeJson sends a json response with encoding charset.
func (c *Controller) ServeJson(encoding ...bool) { func (c *Controller) ServeJson(encoding ...bool) {
var hasIndent bool var hasIndent bool
var hasencoding bool var hasencoding bool
@ -217,6 +241,7 @@ func (c *Controller) ServeJson(encoding ...bool) {
c.Ctx.Output.Json(c.Data["json"], hasIndent, hasencoding) c.Ctx.Output.Json(c.Data["json"], hasIndent, hasencoding)
} }
// ServeJson sends a jsonp response.
func (c *Controller) ServeJsonp() { func (c *Controller) ServeJsonp() {
var hasIndent bool var hasIndent bool
if RunMode == "prod" { if RunMode == "prod" {
@ -227,6 +252,7 @@ func (c *Controller) ServeJsonp() {
c.Ctx.Output.Jsonp(c.Data["jsonp"], hasIndent) c.Ctx.Output.Jsonp(c.Data["jsonp"], hasIndent)
} }
// ServeJson sends xml response.
func (c *Controller) ServeXml() { func (c *Controller) ServeXml() {
var hasIndent bool var hasIndent bool
if RunMode == "prod" { if RunMode == "prod" {
@ -237,6 +263,7 @@ func (c *Controller) ServeXml() {
c.Ctx.Output.Xml(c.Data["xml"], hasIndent) c.Ctx.Output.Xml(c.Data["xml"], hasIndent)
} }
// Input returns the input data map from POST or PUT request body and query string.
func (c *Controller) Input() url.Values { func (c *Controller) Input() url.Values {
ct := c.Ctx.Request.Header.Get("Content-Type") ct := c.Ctx.Request.Header.Get("Content-Type")
if strings.Contains(ct, "multipart/form-data") { if strings.Contains(ct, "multipart/form-data") {
@ -247,14 +274,18 @@ func (c *Controller) Input() url.Values {
return c.Ctx.Request.Form return c.Ctx.Request.Form
} }
// ParseForm maps input data map to obj struct.
func (c *Controller) ParseForm(obj interface{}) error { func (c *Controller) ParseForm(obj interface{}) error {
return ParseForm(c.Input(), obj) return ParseForm(c.Input(), obj)
} }
// GetString returns the input value by key string.
func (c *Controller) GetString(key string) string { func (c *Controller) GetString(key string) string {
return c.Input().Get(key) return c.Input().Get(key)
} }
// GetStrings returns the input string slice by key string.
// it's designed for multi-value input field such as checkbox(input[type=checkbox]), multi-selection.
func (c *Controller) GetStrings(key string) []string { func (c *Controller) GetStrings(key string) []string {
r := c.Ctx.Request r := c.Ctx.Request
if r.Form == nil { if r.Form == nil {
@ -267,22 +298,29 @@ func (c *Controller) GetStrings(key string) []string {
return []string{} return []string{}
} }
// GetInt returns input value as int64.
func (c *Controller) GetInt(key string) (int64, error) { func (c *Controller) GetInt(key string) (int64, error) {
return strconv.ParseInt(c.Input().Get(key), 10, 64) return strconv.ParseInt(c.Input().Get(key), 10, 64)
} }
// GetBool returns input value as bool.
func (c *Controller) GetBool(key string) (bool, error) { func (c *Controller) GetBool(key string) (bool, error) {
return strconv.ParseBool(c.Input().Get(key)) return strconv.ParseBool(c.Input().Get(key))
} }
// GetFloat returns input value as float64.
func (c *Controller) GetFloat(key string) (float64, error) { func (c *Controller) GetFloat(key string) (float64, error) {
return strconv.ParseFloat(c.Input().Get(key), 64) return strconv.ParseFloat(c.Input().Get(key), 64)
} }
// GetFile returns the file data in file upload field named as key.
// it returns the first one of multi-uploaded files.
func (c *Controller) GetFile(key string) (multipart.File, *multipart.FileHeader, error) { func (c *Controller) GetFile(key string) (multipart.File, *multipart.FileHeader, error) {
return c.Ctx.Request.FormFile(key) return c.Ctx.Request.FormFile(key)
} }
// SaveToFile saves uploaded file to new path.
// it only operates the first one of mutil-upload form file field.
func (c *Controller) SaveToFile(fromfile, tofile string) error { func (c *Controller) SaveToFile(fromfile, tofile string) error {
file, _, err := c.Ctx.Request.FormFile(fromfile) file, _, err := c.Ctx.Request.FormFile(fromfile)
if err != nil { if err != nil {
@ -298,6 +336,7 @@ func (c *Controller) SaveToFile(fromfile, tofile string) error {
return nil return nil
} }
// StartSession starts session and load old session data info this controller.
func (c *Controller) StartSession() session.SessionStore { func (c *Controller) StartSession() session.SessionStore {
if c.CruSession == nil { if c.CruSession == nil {
c.CruSession = c.Ctx.Input.CruSession c.CruSession = c.Ctx.Input.CruSession
@ -305,6 +344,7 @@ func (c *Controller) StartSession() session.SessionStore {
return c.CruSession return c.CruSession
} }
// SetSession puts value into session.
func (c *Controller) SetSession(name interface{}, value interface{}) { func (c *Controller) SetSession(name interface{}, value interface{}) {
if c.CruSession == nil { if c.CruSession == nil {
c.StartSession() c.StartSession()
@ -312,6 +352,7 @@ func (c *Controller) SetSession(name interface{}, value interface{}) {
c.CruSession.Set(name, value) c.CruSession.Set(name, value)
} }
// GetSession gets value from session.
func (c *Controller) GetSession(name interface{}) interface{} { func (c *Controller) GetSession(name interface{}) interface{} {
if c.CruSession == nil { if c.CruSession == nil {
c.StartSession() c.StartSession()
@ -319,6 +360,7 @@ func (c *Controller) GetSession(name interface{}) interface{} {
return c.CruSession.Get(name) return c.CruSession.Get(name)
} }
// SetSession removes value from session.
func (c *Controller) DelSession(name interface{}) { func (c *Controller) DelSession(name interface{}) {
if c.CruSession == nil { if c.CruSession == nil {
c.StartSession() c.StartSession()
@ -326,19 +368,24 @@ func (c *Controller) DelSession(name interface{}) {
c.CruSession.Delete(name) c.CruSession.Delete(name)
} }
// SessionRegenerateID regenerates session id for this session.
// the session data have no changes.
func (c *Controller) SessionRegenerateID() { func (c *Controller) SessionRegenerateID() {
c.CruSession = GlobalSessions.SessionRegenerateId(c.Ctx.ResponseWriter, c.Ctx.Request) c.CruSession = GlobalSessions.SessionRegenerateId(c.Ctx.ResponseWriter, c.Ctx.Request)
c.Ctx.Input.CruSession = c.CruSession c.Ctx.Input.CruSession = c.CruSession
} }
// DestroySession cleans session data and session cookie.
func (c *Controller) DestroySession() { func (c *Controller) DestroySession() {
GlobalSessions.SessionDestroy(c.Ctx.ResponseWriter, c.Ctx.Request) GlobalSessions.SessionDestroy(c.Ctx.ResponseWriter, c.Ctx.Request)
} }
// IsAjax returns this request is ajax or not.
func (c *Controller) IsAjax() bool { func (c *Controller) IsAjax() bool {
return c.Ctx.Input.IsAjax() return c.Ctx.Input.IsAjax()
} }
// GetSecureCookie returns decoded cookie value from encoded browser cookie values.
func (c *Controller) GetSecureCookie(Secret, key string) (string, bool) { func (c *Controller) GetSecureCookie(Secret, key string) (string, bool) {
val := c.Ctx.GetCookie(key) val := c.Ctx.GetCookie(key)
if val == "" { if val == "" {
@ -365,6 +412,7 @@ func (c *Controller) GetSecureCookie(Secret, key string) (string, bool) {
return string(res), true return string(res), true
} }
// SetSecureCookie puts value into cookie after encoded the value.
func (c *Controller) SetSecureCookie(Secret, name, val string, age int64) { func (c *Controller) SetSecureCookie(Secret, name, val string, age int64) {
vs := base64.URLEncoding.EncodeToString([]byte(val)) vs := base64.URLEncoding.EncodeToString([]byte(val))
timestamp := strconv.FormatInt(time.Now().UnixNano(), 10) timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
@ -375,6 +423,7 @@ func (c *Controller) SetSecureCookie(Secret, name, val string, age int64) {
c.Ctx.SetCookie(name, cookie, age, "/") c.Ctx.SetCookie(name, cookie, age, "/")
} }
// XsrfToken creates a xsrf token string and returns.
func (c *Controller) XsrfToken() string { func (c *Controller) XsrfToken() string {
if c._xsrf_token == "" { if c._xsrf_token == "" {
token, ok := c.GetSecureCookie(XSRFKEY, "_xsrf") token, ok := c.GetSecureCookie(XSRFKEY, "_xsrf")
@ -393,6 +442,9 @@ func (c *Controller) XsrfToken() string {
return c._xsrf_token return c._xsrf_token
} }
// CheckXsrfCookie checks xsrf token in this request is valid or not.
// the token can provided in request header "X-Xsrftoken" and "X-CsrfToken"
// or in form field value named as "_xsrf".
func (c *Controller) CheckXsrfCookie() bool { func (c *Controller) CheckXsrfCookie() bool {
token := c.GetString("_xsrf") token := c.GetString("_xsrf")
if token == "" { if token == "" {
@ -409,16 +461,18 @@ func (c *Controller) CheckXsrfCookie() bool {
return true return true
} }
// XsrfFormHtml writes an input field contains xsrf token value.
func (c *Controller) XsrfFormHtml() string { func (c *Controller) XsrfFormHtml() string {
return "<input type=\"hidden\" name=\"_xsrf\" value=\"" + return "<input type=\"hidden\" name=\"_xsrf\" value=\"" +
c._xsrf_token + "\"/>" c._xsrf_token + "\"/>"
} }
// GetControllerAndAction gets the executing controller name and action name.
func (c *Controller) GetControllerAndAction() (controllerName, actionName string) { func (c *Controller) GetControllerAndAction() (controllerName, actionName string) {
return c.controllerName, c.actionName return c.controllerName, c.actionName
} }
//utils func for controller internal // getRandomString returns random string.
func getRandomString(n int) string { func getRandomString(n int) string {
const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
var bytes = make([]byte, n) var bytes = make([]byte, n)

View File

@ -5,6 +5,8 @@ import (
"strings" "strings"
) )
// FilterRouter defines filter operation before controller handler execution.
// it can match patterned url and do filter function when action arrives.
type FilterRouter struct { type FilterRouter struct {
pattern string pattern string
regex *regexp.Regexp regex *regexp.Regexp
@ -14,6 +16,8 @@ type FilterRouter struct {
parseParams map[string]string parseParams map[string]string
} }
// ValidRouter check current request is valid for this filter.
// if matched, returns parsed params in this request by defined filter router pattern.
func (mr *FilterRouter) ValidRouter(router string) (bool, map[string]string) { func (mr *FilterRouter) ValidRouter(router string) (bool, map[string]string) {
if mr.pattern == "" { if mr.pattern == "" {
return true, nil return true, nil

View File

@ -6,18 +6,22 @@ import (
"strings" "strings"
) )
// the separation string when encoding flash data.
const BEEGO_FLASH_SEP = "#BEEGOFLASH#" const BEEGO_FLASH_SEP = "#BEEGOFLASH#"
// FlashData is a tools to maintain data when using across request.
type FlashData struct { type FlashData struct {
Data map[string]string Data map[string]string
} }
// NewFlash return a new empty FlashData struct.
func NewFlash() *FlashData { func NewFlash() *FlashData {
return &FlashData{ return &FlashData{
Data: make(map[string]string), Data: make(map[string]string),
} }
} }
// Notice writes notice message to flash.
func (fd *FlashData) Notice(msg string, args ...interface{}) { func (fd *FlashData) Notice(msg string, args ...interface{}) {
if len(args) == 0 { if len(args) == 0 {
fd.Data["notice"] = msg fd.Data["notice"] = msg
@ -26,6 +30,7 @@ func (fd *FlashData) Notice(msg string, args ...interface{}) {
} }
} }
// Warning writes warning message to flash.
func (fd *FlashData) Warning(msg string, args ...interface{}) { func (fd *FlashData) Warning(msg string, args ...interface{}) {
if len(args) == 0 { if len(args) == 0 {
fd.Data["warning"] = msg fd.Data["warning"] = msg
@ -34,6 +39,7 @@ func (fd *FlashData) Warning(msg string, args ...interface{}) {
} }
} }
// Error writes error message to flash.
func (fd *FlashData) Error(msg string, args ...interface{}) { func (fd *FlashData) Error(msg string, args ...interface{}) {
if len(args) == 0 { if len(args) == 0 {
fd.Data["error"] = msg fd.Data["error"] = msg
@ -42,6 +48,8 @@ func (fd *FlashData) Error(msg string, args ...interface{}) {
} }
} }
// Store does the saving operation of flash data.
// the data are encoded and saved in cookie.
func (fd *FlashData) Store(c *Controller) { func (fd *FlashData) Store(c *Controller) {
c.Data["flash"] = fd.Data c.Data["flash"] = fd.Data
var flashValue string var flashValue string
@ -51,6 +59,7 @@ func (fd *FlashData) Store(c *Controller) {
c.Ctx.SetCookie("BEEGO_FLASH", url.QueryEscape(flashValue), 0, "/") c.Ctx.SetCookie("BEEGO_FLASH", url.QueryEscape(flashValue), 0, "/")
} }
// ReadFromRequest parsed flash data from encoded values in cookie.
func ReadFromRequest(c *Controller) *FlashData { func ReadFromRequest(c *Controller) *FlashData {
flash := &FlashData{ flash := &FlashData{
Data: make(map[string]string), Data: make(map[string]string),