controller.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. // Copyright 2014 beego Author. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package beego
  15. import (
  16. "bytes"
  17. "errors"
  18. "html/template"
  19. "io"
  20. "mime/multipart"
  21. "net/http"
  22. "net/url"
  23. "os"
  24. "reflect"
  25. "strconv"
  26. "strings"
  27. "github.com/cnlh/nps/vender/github.com/astaxie/beego/context"
  28. "github.com/cnlh/nps/vender/github.com/astaxie/beego/context/param"
  29. "github.com/cnlh/nps/vender/github.com/astaxie/beego/session"
  30. )
  31. var (
  32. // ErrAbort custom error when user stop request handler manually.
  33. ErrAbort = errors.New("User stop run")
  34. // GlobalControllerRouter store comments with controller. pkgpath+controller:comments
  35. GlobalControllerRouter = make(map[string][]ControllerComments)
  36. )
  37. // ControllerFilter store the filter for controller
  38. type ControllerFilter struct {
  39. Pattern string
  40. Pos int
  41. Filter FilterFunc
  42. ReturnOnOutput bool
  43. ResetParams bool
  44. }
  45. // ControllerFilterComments store the comment for controller level filter
  46. type ControllerFilterComments struct {
  47. Pattern string
  48. Pos int
  49. Filter string // NOQA
  50. ReturnOnOutput bool
  51. ResetParams bool
  52. }
  53. // ControllerImportComments store the import comment for controller needed
  54. type ControllerImportComments struct {
  55. ImportPath string
  56. ImportAlias string
  57. }
  58. // ControllerComments store the comment for the controller method
  59. type ControllerComments struct {
  60. Method string
  61. Router string
  62. Filters []*ControllerFilter
  63. ImportComments []*ControllerImportComments
  64. FilterComments []*ControllerFilterComments
  65. AllowHTTPMethods []string
  66. Params []map[string]string
  67. MethodParams []*param.MethodParam
  68. }
  69. // ControllerCommentsSlice implements the sort interface
  70. type ControllerCommentsSlice []ControllerComments
  71. func (p ControllerCommentsSlice) Len() int { return len(p) }
  72. func (p ControllerCommentsSlice) Less(i, j int) bool { return p[i].Router < p[j].Router }
  73. func (p ControllerCommentsSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
  74. // Controller defines some basic http request handler operations, such as
  75. // http context, template and view, session and xsrf.
  76. type Controller struct {
  77. // context data
  78. Ctx *context.Context
  79. Data map[interface{}]interface{}
  80. // route controller info
  81. controllerName string
  82. actionName string
  83. methodMapping map[string]func() //method:routertree
  84. gotofunc string
  85. AppController interface{}
  86. // template data
  87. TplName string
  88. ViewPath string
  89. Layout string
  90. LayoutSections map[string]string // the key is the section name and the value is the template name
  91. TplPrefix string
  92. TplExt string
  93. EnableRender bool
  94. // xsrf data
  95. _xsrfToken string
  96. XSRFExpire int
  97. EnableXSRF bool
  98. // session
  99. CruSession session.Store
  100. }
  101. // ControllerInterface is an interface to uniform all controller handler.
  102. type ControllerInterface interface {
  103. Init(ct *context.Context, controllerName, actionName string, app interface{})
  104. Prepare()
  105. Get()
  106. Post()
  107. Delete()
  108. Put()
  109. Head()
  110. Patch()
  111. Options()
  112. Finish()
  113. Render() error
  114. XSRFToken() string
  115. CheckXSRFCookie() bool
  116. HandlerFunc(fn string) bool
  117. URLMapping()
  118. }
  119. // Init generates default values of controller operations.
  120. func (c *Controller) Init(ctx *context.Context, controllerName, actionName string, app interface{}) {
  121. c.Layout = ""
  122. c.TplName = ""
  123. c.controllerName = controllerName
  124. c.actionName = actionName
  125. c.Ctx = ctx
  126. c.TplExt = "tpl"
  127. c.AppController = app
  128. c.EnableRender = true
  129. c.EnableXSRF = true
  130. c.Data = ctx.Input.Data()
  131. c.methodMapping = make(map[string]func())
  132. }
  133. // Prepare runs after Init before request function execution.
  134. func (c *Controller) Prepare() {}
  135. // Finish runs after request function execution.
  136. func (c *Controller) Finish() {}
  137. // Get adds a request function to handle GET request.
  138. func (c *Controller) Get() {
  139. http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405)
  140. }
  141. // Post adds a request function to handle POST request.
  142. func (c *Controller) Post() {
  143. http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405)
  144. }
  145. // Delete adds a request function to handle DELETE request.
  146. func (c *Controller) Delete() {
  147. http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405)
  148. }
  149. // Put adds a request function to handle PUT request.
  150. func (c *Controller) Put() {
  151. http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405)
  152. }
  153. // Head adds a request function to handle HEAD request.
  154. func (c *Controller) Head() {
  155. http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405)
  156. }
  157. // Patch adds a request function to handle PATCH request.
  158. func (c *Controller) Patch() {
  159. http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405)
  160. }
  161. // Options adds a request function to handle OPTIONS request.
  162. func (c *Controller) Options() {
  163. http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405)
  164. }
  165. // HandlerFunc call function with the name
  166. func (c *Controller) HandlerFunc(fnname string) bool {
  167. if v, ok := c.methodMapping[fnname]; ok {
  168. v()
  169. return true
  170. }
  171. return false
  172. }
  173. // URLMapping register the internal Controller router.
  174. func (c *Controller) URLMapping() {}
  175. // Mapping the method to function
  176. func (c *Controller) Mapping(method string, fn func()) {
  177. c.methodMapping[method] = fn
  178. }
  179. // Render sends the response with rendered template bytes as text/html type.
  180. func (c *Controller) Render() error {
  181. if !c.EnableRender {
  182. return nil
  183. }
  184. rb, err := c.RenderBytes()
  185. if err != nil {
  186. return err
  187. }
  188. if c.Ctx.ResponseWriter.Header().Get("Content-Type") == "" {
  189. c.Ctx.Output.Header("Content-Type", "text/html; charset=utf-8")
  190. }
  191. return c.Ctx.Output.Body(rb)
  192. }
  193. // RenderString returns the rendered template string. Do not send out response.
  194. func (c *Controller) RenderString() (string, error) {
  195. b, e := c.RenderBytes()
  196. return string(b), e
  197. }
  198. // RenderBytes returns the bytes of rendered template string. Do not send out response.
  199. func (c *Controller) RenderBytes() ([]byte, error) {
  200. buf, err := c.renderTemplate()
  201. //if the controller has set layout, then first get the tplName's content set the content to the layout
  202. if err == nil && c.Layout != "" {
  203. c.Data["LayoutContent"] = template.HTML(buf.String())
  204. if c.LayoutSections != nil {
  205. for sectionName, sectionTpl := range c.LayoutSections {
  206. if sectionTpl == "" {
  207. c.Data[sectionName] = ""
  208. continue
  209. }
  210. buf.Reset()
  211. err = ExecuteViewPathTemplate(&buf, sectionTpl, c.viewPath(), c.Data)
  212. if err != nil {
  213. return nil, err
  214. }
  215. c.Data[sectionName] = template.HTML(buf.String())
  216. }
  217. }
  218. buf.Reset()
  219. ExecuteViewPathTemplate(&buf, c.Layout, c.viewPath(), c.Data)
  220. }
  221. return buf.Bytes(), err
  222. }
  223. func (c *Controller) renderTemplate() (bytes.Buffer, error) {
  224. var buf bytes.Buffer
  225. if c.TplName == "" {
  226. c.TplName = strings.ToLower(c.controllerName) + "/" + strings.ToLower(c.actionName) + "." + c.TplExt
  227. }
  228. if c.TplPrefix != "" {
  229. c.TplName = c.TplPrefix + c.TplName
  230. }
  231. if BConfig.RunMode == DEV {
  232. buildFiles := []string{c.TplName}
  233. if c.Layout != "" {
  234. buildFiles = append(buildFiles, c.Layout)
  235. if c.LayoutSections != nil {
  236. for _, sectionTpl := range c.LayoutSections {
  237. if sectionTpl == "" {
  238. continue
  239. }
  240. buildFiles = append(buildFiles, sectionTpl)
  241. }
  242. }
  243. }
  244. BuildTemplate(c.viewPath(), buildFiles...)
  245. }
  246. return buf, ExecuteViewPathTemplate(&buf, c.TplName, c.viewPath(), c.Data)
  247. }
  248. func (c *Controller) viewPath() string {
  249. if c.ViewPath == "" {
  250. return BConfig.WebConfig.ViewsPath
  251. }
  252. return c.ViewPath
  253. }
  254. // Redirect sends the redirection response to url with status code.
  255. func (c *Controller) Redirect(url string, code int) {
  256. logAccess(c.Ctx, nil, code)
  257. c.Ctx.Redirect(code, url)
  258. }
  259. // Set the data depending on the accepted
  260. func (c *Controller) SetData(data interface{}) {
  261. accept := c.Ctx.Input.Header("Accept")
  262. switch accept {
  263. case context.ApplicationYAML:
  264. c.Data["yaml"] = data
  265. case context.ApplicationXML, context.TextXML:
  266. c.Data["xml"] = data
  267. default:
  268. c.Data["json"] = data
  269. }
  270. }
  271. // Abort stops controller handler and show the error data if code is defined in ErrorMap or code string.
  272. func (c *Controller) Abort(code string) {
  273. status, err := strconv.Atoi(code)
  274. if err != nil {
  275. status = 200
  276. }
  277. c.CustomAbort(status, code)
  278. }
  279. // CustomAbort stops controller handler and show the error data, it's similar Aborts, but support status code and body.
  280. func (c *Controller) CustomAbort(status int, body string) {
  281. // first panic from ErrorMaps, it is user defined error functions.
  282. if _, ok := ErrorMaps[body]; ok {
  283. c.Ctx.Output.Status = status
  284. panic(body)
  285. }
  286. // last panic user string
  287. c.Ctx.ResponseWriter.WriteHeader(status)
  288. c.Ctx.ResponseWriter.Write([]byte(body))
  289. panic(ErrAbort)
  290. }
  291. // StopRun makes panic of USERSTOPRUN error and go to recover function if defined.
  292. func (c *Controller) StopRun() {
  293. panic(ErrAbort)
  294. }
  295. // URLFor does another controller handler in this request function.
  296. // it goes to this controller method if endpoint is not clear.
  297. func (c *Controller) URLFor(endpoint string, values ...interface{}) string {
  298. if len(endpoint) == 0 {
  299. return ""
  300. }
  301. if endpoint[0] == '.' {
  302. return URLFor(reflect.Indirect(reflect.ValueOf(c.AppController)).Type().Name()+endpoint, values...)
  303. }
  304. return URLFor(endpoint, values...)
  305. }
  306. // ServeJSON sends a json response with encoding charset.
  307. func (c *Controller) ServeJSON(encoding ...bool) {
  308. var (
  309. hasIndent = BConfig.RunMode != PROD
  310. hasEncoding = len(encoding) > 0 && encoding[0]
  311. )
  312. c.Ctx.Output.JSON(c.Data["json"], hasIndent, hasEncoding)
  313. }
  314. // ServeJSONP sends a jsonp response.
  315. func (c *Controller) ServeJSONP() {
  316. hasIndent := BConfig.RunMode != PROD
  317. c.Ctx.Output.JSONP(c.Data["jsonp"], hasIndent)
  318. }
  319. // ServeXML sends xml response.
  320. func (c *Controller) ServeXML() {
  321. hasIndent := BConfig.RunMode != PROD
  322. c.Ctx.Output.XML(c.Data["xml"], hasIndent)
  323. }
  324. // ServeXML sends xml response.
  325. func (c *Controller) ServeYAML() {
  326. c.Ctx.Output.YAML(c.Data["yaml"])
  327. }
  328. // ServeFormatted serve YAML, XML OR JSON, depending on the value of the Accept header
  329. func (c *Controller) ServeFormatted(encoding ...bool) {
  330. hasIndent := BConfig.RunMode != PROD
  331. hasEncoding := len(encoding) > 0 && encoding[0]
  332. c.Ctx.Output.ServeFormatted(c.Data, hasIndent, hasEncoding)
  333. }
  334. // Input returns the input data map from POST or PUT request body and query string.
  335. func (c *Controller) Input() url.Values {
  336. if c.Ctx.Request.Form == nil {
  337. c.Ctx.Request.ParseForm()
  338. }
  339. return c.Ctx.Request.Form
  340. }
  341. // ParseForm maps input data map to obj struct.
  342. func (c *Controller) ParseForm(obj interface{}) error {
  343. return ParseForm(c.Input(), obj)
  344. }
  345. // GetString returns the input value by key string or the default value while it's present and input is blank
  346. func (c *Controller) GetString(key string, def ...string) string {
  347. if v := c.Ctx.Input.Query(key); v != "" {
  348. return v
  349. }
  350. if len(def) > 0 {
  351. return def[0]
  352. }
  353. return ""
  354. }
  355. // GetStrings returns the input string slice by key string or the default value while it's present and input is blank
  356. // it's designed for multi-value input field such as checkbox(input[type=checkbox]), multi-selection.
  357. func (c *Controller) GetStrings(key string, def ...[]string) []string {
  358. var defv []string
  359. if len(def) > 0 {
  360. defv = def[0]
  361. }
  362. if f := c.Input(); f == nil {
  363. return defv
  364. } else if vs := f[key]; len(vs) > 0 {
  365. return vs
  366. }
  367. return defv
  368. }
  369. // GetInt returns input as an int or the default value while it's present and input is blank
  370. func (c *Controller) GetInt(key string, def ...int) (int, error) {
  371. strv := c.Ctx.Input.Query(key)
  372. if len(strv) == 0 && len(def) > 0 {
  373. return def[0], nil
  374. }
  375. return strconv.Atoi(strv)
  376. }
  377. // GetInt8 return input as an int8 or the default value while it's present and input is blank
  378. func (c *Controller) GetInt8(key string, def ...int8) (int8, error) {
  379. strv := c.Ctx.Input.Query(key)
  380. if len(strv) == 0 && len(def) > 0 {
  381. return def[0], nil
  382. }
  383. i64, err := strconv.ParseInt(strv, 10, 8)
  384. return int8(i64), err
  385. }
  386. // GetUint8 return input as an uint8 or the default value while it's present and input is blank
  387. func (c *Controller) GetUint8(key string, def ...uint8) (uint8, error) {
  388. strv := c.Ctx.Input.Query(key)
  389. if len(strv) == 0 && len(def) > 0 {
  390. return def[0], nil
  391. }
  392. u64, err := strconv.ParseUint(strv, 10, 8)
  393. return uint8(u64), err
  394. }
  395. // GetInt16 returns input as an int16 or the default value while it's present and input is blank
  396. func (c *Controller) GetInt16(key string, def ...int16) (int16, error) {
  397. strv := c.Ctx.Input.Query(key)
  398. if len(strv) == 0 && len(def) > 0 {
  399. return def[0], nil
  400. }
  401. i64, err := strconv.ParseInt(strv, 10, 16)
  402. return int16(i64), err
  403. }
  404. // GetUint16 returns input as an uint16 or the default value while it's present and input is blank
  405. func (c *Controller) GetUint16(key string, def ...uint16) (uint16, error) {
  406. strv := c.Ctx.Input.Query(key)
  407. if len(strv) == 0 && len(def) > 0 {
  408. return def[0], nil
  409. }
  410. u64, err := strconv.ParseUint(strv, 10, 16)
  411. return uint16(u64), err
  412. }
  413. // GetInt32 returns input as an int32 or the default value while it's present and input is blank
  414. func (c *Controller) GetInt32(key string, def ...int32) (int32, error) {
  415. strv := c.Ctx.Input.Query(key)
  416. if len(strv) == 0 && len(def) > 0 {
  417. return def[0], nil
  418. }
  419. i64, err := strconv.ParseInt(strv, 10, 32)
  420. return int32(i64), err
  421. }
  422. // GetUint32 returns input as an uint32 or the default value while it's present and input is blank
  423. func (c *Controller) GetUint32(key string, def ...uint32) (uint32, error) {
  424. strv := c.Ctx.Input.Query(key)
  425. if len(strv) == 0 && len(def) > 0 {
  426. return def[0], nil
  427. }
  428. u64, err := strconv.ParseUint(strv, 10, 32)
  429. return uint32(u64), err
  430. }
  431. // GetInt64 returns input value as int64 or the default value while it's present and input is blank.
  432. func (c *Controller) GetInt64(key string, def ...int64) (int64, error) {
  433. strv := c.Ctx.Input.Query(key)
  434. if len(strv) == 0 && len(def) > 0 {
  435. return def[0], nil
  436. }
  437. return strconv.ParseInt(strv, 10, 64)
  438. }
  439. // GetUint64 returns input value as uint64 or the default value while it's present and input is blank.
  440. func (c *Controller) GetUint64(key string, def ...uint64) (uint64, error) {
  441. strv := c.Ctx.Input.Query(key)
  442. if len(strv) == 0 && len(def) > 0 {
  443. return def[0], nil
  444. }
  445. return strconv.ParseUint(strv, 10, 64)
  446. }
  447. // GetBool returns input value as bool or the default value while it's present and input is blank.
  448. func (c *Controller) GetBool(key string, def ...bool) (bool, error) {
  449. strv := c.Ctx.Input.Query(key)
  450. if len(strv) == 0 && len(def) > 0 {
  451. return def[0], nil
  452. }
  453. return strconv.ParseBool(strv)
  454. }
  455. // GetFloat returns input value as float64 or the default value while it's present and input is blank.
  456. func (c *Controller) GetFloat(key string, def ...float64) (float64, error) {
  457. strv := c.Ctx.Input.Query(key)
  458. if len(strv) == 0 && len(def) > 0 {
  459. return def[0], nil
  460. }
  461. return strconv.ParseFloat(strv, 64)
  462. }
  463. // GetFile returns the file data in file upload field named as key.
  464. // it returns the first one of multi-uploaded files.
  465. func (c *Controller) GetFile(key string) (multipart.File, *multipart.FileHeader, error) {
  466. return c.Ctx.Request.FormFile(key)
  467. }
  468. // GetFiles return multi-upload files
  469. // files, err:=c.GetFiles("myfiles")
  470. // if err != nil {
  471. // http.Error(w, err.Error(), http.StatusNoContent)
  472. // return
  473. // }
  474. // for i, _ := range files {
  475. // //for each fileheader, get a handle to the actual file
  476. // file, err := files[i].Open()
  477. // defer file.Close()
  478. // if err != nil {
  479. // http.Error(w, err.Error(), http.StatusInternalServerError)
  480. // return
  481. // }
  482. // //create destination file making sure the path is writeable.
  483. // dst, err := os.Create("upload/" + files[i].Filename)
  484. // defer dst.Close()
  485. // if err != nil {
  486. // http.Error(w, err.Error(), http.StatusInternalServerError)
  487. // return
  488. // }
  489. // //copy the uploaded file to the destination file
  490. // if _, err := io.Copy(dst, file); err != nil {
  491. // http.Error(w, err.Error(), http.StatusInternalServerError)
  492. // return
  493. // }
  494. // }
  495. func (c *Controller) GetFiles(key string) ([]*multipart.FileHeader, error) {
  496. if files, ok := c.Ctx.Request.MultipartForm.File[key]; ok {
  497. return files, nil
  498. }
  499. return nil, http.ErrMissingFile
  500. }
  501. // SaveToFile saves uploaded file to new path.
  502. // it only operates the first one of mutil-upload form file field.
  503. func (c *Controller) SaveToFile(fromfile, tofile string) error {
  504. file, _, err := c.Ctx.Request.FormFile(fromfile)
  505. if err != nil {
  506. return err
  507. }
  508. defer file.Close()
  509. f, err := os.OpenFile(tofile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
  510. if err != nil {
  511. return err
  512. }
  513. defer f.Close()
  514. io.Copy(f, file)
  515. return nil
  516. }
  517. // StartSession starts session and load old session data info this controller.
  518. func (c *Controller) StartSession() session.Store {
  519. if c.CruSession == nil {
  520. c.CruSession = c.Ctx.Input.CruSession
  521. }
  522. return c.CruSession
  523. }
  524. // SetSession puts value into session.
  525. func (c *Controller) SetSession(name interface{}, value interface{}) {
  526. if c.CruSession == nil {
  527. c.StartSession()
  528. }
  529. c.CruSession.Set(name, value)
  530. }
  531. // GetSession gets value from session.
  532. func (c *Controller) GetSession(name interface{}) interface{} {
  533. if c.CruSession == nil {
  534. c.StartSession()
  535. }
  536. return c.CruSession.Get(name)
  537. }
  538. // DelSession removes value from session.
  539. func (c *Controller) DelSession(name interface{}) {
  540. if c.CruSession == nil {
  541. c.StartSession()
  542. }
  543. c.CruSession.Delete(name)
  544. }
  545. // SessionRegenerateID regenerates session id for this session.
  546. // the session data have no changes.
  547. func (c *Controller) SessionRegenerateID() {
  548. if c.CruSession != nil {
  549. c.CruSession.SessionRelease(c.Ctx.ResponseWriter)
  550. }
  551. c.CruSession = GlobalSessions.SessionRegenerateID(c.Ctx.ResponseWriter, c.Ctx.Request)
  552. c.Ctx.Input.CruSession = c.CruSession
  553. }
  554. // DestroySession cleans session data and session cookie.
  555. func (c *Controller) DestroySession() {
  556. c.Ctx.Input.CruSession.Flush()
  557. c.Ctx.Input.CruSession = nil
  558. GlobalSessions.SessionDestroy(c.Ctx.ResponseWriter, c.Ctx.Request)
  559. }
  560. // IsAjax returns this request is ajax or not.
  561. func (c *Controller) IsAjax() bool {
  562. return c.Ctx.Input.IsAjax()
  563. }
  564. // GetSecureCookie returns decoded cookie value from encoded browser cookie values.
  565. func (c *Controller) GetSecureCookie(Secret, key string) (string, bool) {
  566. return c.Ctx.GetSecureCookie(Secret, key)
  567. }
  568. // SetSecureCookie puts value into cookie after encoded the value.
  569. func (c *Controller) SetSecureCookie(Secret, name, value string, others ...interface{}) {
  570. c.Ctx.SetSecureCookie(Secret, name, value, others...)
  571. }
  572. // XSRFToken creates a CSRF token string and returns.
  573. func (c *Controller) XSRFToken() string {
  574. if c._xsrfToken == "" {
  575. expire := int64(BConfig.WebConfig.XSRFExpire)
  576. if c.XSRFExpire > 0 {
  577. expire = int64(c.XSRFExpire)
  578. }
  579. c._xsrfToken = c.Ctx.XSRFToken(BConfig.WebConfig.XSRFKey, expire)
  580. }
  581. return c._xsrfToken
  582. }
  583. // CheckXSRFCookie checks xsrf token in this request is valid or not.
  584. // the token can provided in request header "X-Xsrftoken" and "X-CsrfToken"
  585. // or in form field value named as "_xsrf".
  586. func (c *Controller) CheckXSRFCookie() bool {
  587. if !c.EnableXSRF {
  588. return true
  589. }
  590. return c.Ctx.CheckXSRFCookie()
  591. }
  592. // XSRFFormHTML writes an input field contains xsrf token value.
  593. func (c *Controller) XSRFFormHTML() string {
  594. return `<input type="hidden" name="_xsrf" value="` +
  595. c.XSRFToken() + `" />`
  596. }
  597. // GetControllerAndAction gets the executing controller name and action name.
  598. func (c *Controller) GetControllerAndAction() (string, string) {
  599. return c.controllerName, c.actionName
  600. }