Micro & pluggable web framework for Go
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

813 lines
18KB

  1. // Copyright 2015 The Tango Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package tango
  5. import (
  6. "bytes"
  7. "crypto/hmac"
  8. "crypto/sha1"
  9. "encoding/base64"
  10. "fmt"
  11. "html/template"
  12. "io/ioutil"
  13. "net/http"
  14. "strconv"
  15. "strings"
  16. "time"
  17. )
  18. func isValidCookieValue(p []byte) bool {
  19. for _, b := range p {
  20. if b <= ' ' ||
  21. b >= 127 ||
  22. b == '"' ||
  23. b == ',' ||
  24. b == ';' ||
  25. b == '\\' {
  26. return false
  27. }
  28. }
  29. return true
  30. }
  31. func isValidCookieName(s string) bool {
  32. for _, r := range s {
  33. if r <= ' ' ||
  34. r >= 127 ||
  35. strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", r) {
  36. return false
  37. }
  38. }
  39. return true
  40. }
  41. // Set describes a set interface
  42. type Set interface {
  43. String(key string) (string, error)
  44. Int(key string) (int, error)
  45. Int32(key string) (int32, error)
  46. Int64(key string) (int64, error)
  47. Uint(key string) (uint, error)
  48. Uint32(key string) (uint32, error)
  49. Uint64(key string) (uint64, error)
  50. Float32(key string) (float32, error)
  51. Float64(key string) (float64, error)
  52. Bool(key string) (bool, error)
  53. MustString(key string, defaults ...string) string
  54. MustEscape(key string, defaults ...string) string
  55. MustInt(key string, defaults ...int) int
  56. MustInt32(key string, defaults ...int32) int32
  57. MustInt64(key string, defaults ...int64) int64
  58. MustUint(key string, defaults ...uint) uint
  59. MustUint32(key string, defaults ...uint32) uint32
  60. MustUint64(key string, defaults ...uint64) uint64
  61. MustFloat32(key string, defaults ...float32) float32
  62. MustFloat64(key string, defaults ...float64) float64
  63. MustBool(key string, defaults ...bool) bool
  64. }
  65. // Cookies describes cookie interface
  66. type Cookies interface {
  67. Set
  68. Get(string) *http.Cookie
  69. Set(*http.Cookie)
  70. Expire(string, time.Time)
  71. Del(string)
  72. }
  73. type cookies Context
  74. var _ Cookies = &cookies{}
  75. // NewCookie return a http.Cookie via give name and value
  76. func NewCookie(name string, value string, age ...int64) *http.Cookie {
  77. if !isValidCookieName(name) || !isValidCookieValue([]byte(value)) {
  78. return nil
  79. }
  80. var utctime time.Time
  81. if len(age) == 0 {
  82. // 2^31 - 1 seconds (roughly 2038)
  83. utctime = time.Unix(2147483647, 0)
  84. } else {
  85. utctime = time.Unix(time.Now().Unix()+age[0], 0)
  86. }
  87. return &http.Cookie{Name: name, Value: value, Expires: utctime}
  88. }
  89. // Get return http.Cookie via key
  90. func (c *cookies) Get(key string) *http.Cookie {
  91. ck, err := c.req.Cookie(key)
  92. if err != nil {
  93. return nil
  94. }
  95. return ck
  96. }
  97. // Set set a http.Cookie
  98. func (c *cookies) Set(ck *http.Cookie) {
  99. http.SetCookie(c.ResponseWriter, ck)
  100. }
  101. // Expire let a cookie named key when expire address
  102. func (c *cookies) Expire(key string, expire time.Time) {
  103. ck := c.Get(key)
  104. if ck != nil {
  105. ck.Expires = expire
  106. ck.MaxAge = int(expire.Sub(time.Now()).Seconds())
  107. c.Set(ck)
  108. }
  109. }
  110. // Del del cookie by key
  111. func (c *cookies) Del(key string) {
  112. c.Expire(key, time.Date(1900, 1, 1, 0, 0, 0, 0, time.Local))
  113. }
  114. // String get cookie as string
  115. func (c *cookies) String(key string) (string, error) {
  116. ck, err := c.req.Cookie(key)
  117. if err != nil {
  118. return "", err
  119. }
  120. return ck.Value, nil
  121. }
  122. // Int get cookie as int
  123. func (c *cookies) Int(key string) (int, error) {
  124. ck, err := c.req.Cookie(key)
  125. if err != nil {
  126. return 0, err
  127. }
  128. return strconv.Atoi(ck.Value)
  129. }
  130. // Int32 get cookie as int32
  131. func (c *cookies) Int32(key string) (int32, error) {
  132. ck, err := c.req.Cookie(key)
  133. if err != nil {
  134. return 0, err
  135. }
  136. v, err := strconv.ParseInt(ck.Value, 10, 32)
  137. return int32(v), err
  138. }
  139. // Int64 get cookie as int64
  140. func (c *cookies) Int64(key string) (int64, error) {
  141. ck, err := c.req.Cookie(key)
  142. if err != nil {
  143. return 0, err
  144. }
  145. return strconv.ParseInt(ck.Value, 10, 64)
  146. }
  147. // Uint get cookie as uint
  148. func (c *cookies) Uint(key string) (uint, error) {
  149. ck, err := c.req.Cookie(key)
  150. if err != nil {
  151. return 0, err
  152. }
  153. v, err := strconv.ParseUint(ck.Value, 10, 64)
  154. return uint(v), err
  155. }
  156. // Uint32 get cookie as uint32
  157. func (c *cookies) Uint32(key string) (uint32, error) {
  158. ck, err := c.req.Cookie(key)
  159. if err != nil {
  160. return 0, err
  161. }
  162. v, err := strconv.ParseUint(ck.Value, 10, 32)
  163. return uint32(v), err
  164. }
  165. // Uint64 get cookie as uint64
  166. func (c *cookies) Uint64(key string) (uint64, error) {
  167. ck, err := c.req.Cookie(key)
  168. if err != nil {
  169. return 0, err
  170. }
  171. return strconv.ParseUint(ck.Value, 10, 64)
  172. }
  173. // Float32 get cookie as float32
  174. func (c *cookies) Float32(key string) (float32, error) {
  175. ck, err := c.req.Cookie(key)
  176. if err != nil {
  177. return 0, err
  178. }
  179. v, err := strconv.ParseFloat(ck.Value, 32)
  180. return float32(v), err
  181. }
  182. // Float64 get cookie as float64
  183. func (c *cookies) Float64(key string) (float64, error) {
  184. ck, err := c.req.Cookie(key)
  185. if err != nil {
  186. return 0, err
  187. }
  188. return strconv.ParseFloat(ck.Value, 32)
  189. }
  190. // Bool get cookie as bool
  191. func (c *cookies) Bool(key string) (bool, error) {
  192. ck, err := c.req.Cookie(key)
  193. if err != nil {
  194. return false, err
  195. }
  196. return strconv.ParseBool(ck.Value)
  197. }
  198. // MustString get cookie as string with default
  199. func (c *cookies) MustString(key string, defaults ...string) string {
  200. ck, err := c.req.Cookie(key)
  201. if err != nil {
  202. if len(defaults) > 0 {
  203. return defaults[0]
  204. }
  205. return ""
  206. }
  207. return ck.Value
  208. }
  209. // MustEscape get cookie as escaped string with default
  210. func (c *cookies) MustEscape(key string, defaults ...string) string {
  211. ck, err := c.req.Cookie(key)
  212. if err != nil {
  213. if len(defaults) > 0 {
  214. return defaults[0]
  215. }
  216. return ""
  217. }
  218. return template.HTMLEscapeString(ck.Value)
  219. }
  220. // MustInt get cookie as int with default
  221. func (c *cookies) MustInt(key string, defaults ...int) int {
  222. ck, err := c.req.Cookie(key)
  223. if err != nil {
  224. if len(defaults) > 0 {
  225. return defaults[0]
  226. }
  227. return 0
  228. }
  229. v, err := strconv.Atoi(ck.Value)
  230. if len(defaults) > 0 && err != nil {
  231. return defaults[0]
  232. }
  233. return v
  234. }
  235. // MustInt32 get cookie as int32 with default
  236. func (c *cookies) MustInt32(key string, defaults ...int32) int32 {
  237. ck, err := c.req.Cookie(key)
  238. if err != nil {
  239. if len(defaults) > 0 {
  240. return defaults[0]
  241. }
  242. return 0
  243. }
  244. v, err := strconv.ParseInt(ck.Value, 10, 32)
  245. if len(defaults) > 0 && err != nil {
  246. return defaults[0]
  247. }
  248. return int32(v)
  249. }
  250. // MustInt64 get cookie as int64 with default
  251. func (c *cookies) MustInt64(key string, defaults ...int64) int64 {
  252. ck, err := c.req.Cookie(key)
  253. if err != nil {
  254. if len(defaults) > 0 {
  255. return defaults[0]
  256. }
  257. return 0
  258. }
  259. v, err := strconv.ParseInt(ck.Value, 10, 64)
  260. if len(defaults) > 0 && err != nil {
  261. return defaults[0]
  262. }
  263. return v
  264. }
  265. // MustUint get cookie as uint with default
  266. func (c *cookies) MustUint(key string, defaults ...uint) uint {
  267. ck, err := c.req.Cookie(key)
  268. if err != nil {
  269. if len(defaults) > 0 {
  270. return defaults[0]
  271. }
  272. return 0
  273. }
  274. v, err := strconv.ParseUint(ck.Value, 10, 64)
  275. if len(defaults) > 0 && err != nil {
  276. return defaults[0]
  277. }
  278. return uint(v)
  279. }
  280. // MustUint32 get cookie as uint32 with default
  281. func (c *cookies) MustUint32(key string, defaults ...uint32) uint32 {
  282. ck, err := c.req.Cookie(key)
  283. if err != nil {
  284. if len(defaults) > 0 {
  285. return defaults[0]
  286. }
  287. return 0
  288. }
  289. v, err := strconv.ParseUint(ck.Value, 10, 32)
  290. if len(defaults) > 0 && err != nil {
  291. return defaults[0]
  292. }
  293. return uint32(v)
  294. }
  295. // MustUint64 get cookie as uint64 with default
  296. func (c *cookies) MustUint64(key string, defaults ...uint64) uint64 {
  297. ck, err := c.req.Cookie(key)
  298. if err != nil {
  299. if len(defaults) > 0 {
  300. return defaults[0]
  301. }
  302. return 0
  303. }
  304. v, err := strconv.ParseUint(ck.Value, 10, 64)
  305. if len(defaults) > 0 && err != nil {
  306. return defaults[0]
  307. }
  308. return v
  309. }
  310. // MustFloat32 get cookie as float32 with default
  311. func (c *cookies) MustFloat32(key string, defaults ...float32) float32 {
  312. ck, err := c.req.Cookie(key)
  313. if err != nil {
  314. if len(defaults) > 0 {
  315. return defaults[0]
  316. }
  317. return 0
  318. }
  319. v, err := strconv.ParseFloat(ck.Value, 32)
  320. if len(defaults) > 0 && err != nil {
  321. return defaults[0]
  322. }
  323. return float32(v)
  324. }
  325. // MustFloat64 get cookie as float64 with default
  326. func (c *cookies) MustFloat64(key string, defaults ...float64) float64 {
  327. ck, err := c.req.Cookie(key)
  328. if err != nil {
  329. if len(defaults) > 0 {
  330. return defaults[0]
  331. }
  332. return 0
  333. }
  334. v, err := strconv.ParseFloat(ck.Value, 32)
  335. if len(defaults) > 0 && err != nil {
  336. return defaults[0]
  337. }
  338. return v
  339. }
  340. // MustBool get cookie as bool with default
  341. func (c *cookies) MustBool(key string, defaults ...bool) bool {
  342. ck, err := c.req.Cookie(key)
  343. if err != nil {
  344. if len(defaults) > 0 {
  345. return defaults[0]
  346. }
  347. return false
  348. }
  349. v, err := strconv.ParseBool(ck.Value)
  350. if len(defaults) > 0 && err != nil {
  351. return defaults[0]
  352. }
  353. return v
  354. }
  355. // Cookie returns cookie as string with default
  356. func (ctx *Context) Cookie(key string, defaults ...string) string {
  357. return ctx.Cookies().MustString(key, defaults...)
  358. }
  359. // CookieEscape returns cookie as escaped string with default
  360. func (ctx *Context) CookieEscape(key string, defaults ...string) string {
  361. return ctx.Cookies().MustEscape(key, defaults...)
  362. }
  363. // CookieInt returns cookie as int with default
  364. func (ctx *Context) CookieInt(key string, defaults ...int) int {
  365. return ctx.Cookies().MustInt(key, defaults...)
  366. }
  367. // CookieInt32 returns cookie as int32 with default
  368. func (ctx *Context) CookieInt32(key string, defaults ...int32) int32 {
  369. return ctx.Cookies().MustInt32(key, defaults...)
  370. }
  371. // CookieInt64 returns cookie as int64 with default
  372. func (ctx *Context) CookieInt64(key string, defaults ...int64) int64 {
  373. return ctx.Cookies().MustInt64(key, defaults...)
  374. }
  375. // CookieUint returns cookie as uint with default
  376. func (ctx *Context) CookieUint(key string, defaults ...uint) uint {
  377. return ctx.Cookies().MustUint(key, defaults...)
  378. }
  379. // CookieUint32 returns cookie as uint32 with default
  380. func (ctx *Context) CookieUint32(key string, defaults ...uint32) uint32 {
  381. return ctx.Cookies().MustUint32(key, defaults...)
  382. }
  383. // CookieUint64 returns cookie as uint64 with default
  384. func (ctx *Context) CookieUint64(key string, defaults ...uint64) uint64 {
  385. return ctx.Cookies().MustUint64(key, defaults...)
  386. }
  387. // CookieFloat32 returns cookie as float32 with default
  388. func (ctx *Context) CookieFloat32(key string, defaults ...float32) float32 {
  389. return ctx.Cookies().MustFloat32(key, defaults...)
  390. }
  391. // CookieFloat64 returns cookie as float64 with default
  392. func (ctx *Context) CookieFloat64(key string, defaults ...float64) float64 {
  393. return ctx.Cookies().MustFloat64(key, defaults...)
  394. }
  395. // CookieBool returns cookie as bool with default
  396. func (ctx *Context) CookieBool(key string, defaults ...bool) bool {
  397. return ctx.Cookies().MustBool(key, defaults...)
  398. }
  399. func getCookieSig(key string, val []byte, timestamp string) string {
  400. hm := hmac.New(sha1.New, []byte(key))
  401. hm.Write(val)
  402. hm.Write([]byte(timestamp))
  403. hex := fmt.Sprintf("%02x", hm.Sum(nil))
  404. return hex
  405. }
  406. // secure cookies
  407. type secureCookies struct {
  408. *cookies
  409. secret string
  410. }
  411. var _ Cookies = &secureCookies{}
  412. func parseSecureCookie(secret string, value string) string {
  413. if strings.Count(value, "|") < 2 {
  414. return ""
  415. }
  416. parts := strings.SplitN(value, "|", 3)
  417. val, timestamp, sig := parts[0], parts[1], parts[2]
  418. if getCookieSig(secret, []byte(val), timestamp) != sig {
  419. return ""
  420. }
  421. ts, _ := strconv.ParseInt(timestamp, 0, 64)
  422. if time.Now().Unix()-31*86400 > ts {
  423. return ""
  424. }
  425. buf := bytes.NewBufferString(val)
  426. encoder := base64.NewDecoder(base64.StdEncoding, buf)
  427. res, _ := ioutil.ReadAll(encoder)
  428. return string(res)
  429. }
  430. func (c *secureCookies) Get(key string) *http.Cookie {
  431. ck := c.cookies.Get(key)
  432. if ck == nil {
  433. return nil
  434. }
  435. v := parseSecureCookie(c.secret, ck.Value)
  436. if v == "" {
  437. return nil
  438. }
  439. ck.Value = v
  440. return ck
  441. }
  442. func (c *secureCookies) String(key string) (string, error) {
  443. ck, err := c.req.Cookie(key)
  444. if err != nil {
  445. return "", err
  446. }
  447. v := parseSecureCookie(c.secret, ck.Value)
  448. return v, nil
  449. }
  450. func (c *secureCookies) Int(key string) (int, error) {
  451. ck, err := c.req.Cookie(key)
  452. if err != nil {
  453. return 0, err
  454. }
  455. s := parseSecureCookie(c.secret, ck.Value)
  456. return strconv.Atoi(s)
  457. }
  458. // Int32 gets int32 data
  459. func (c *secureCookies) Int32(key string) (int32, error) {
  460. ck, err := c.req.Cookie(key)
  461. if err != nil {
  462. return 0, err
  463. }
  464. s := parseSecureCookie(c.secret, ck.Value)
  465. v, err := strconv.ParseInt(s, 10, 32)
  466. return int32(v), err
  467. }
  468. // Int64 gets int64 data
  469. func (c *secureCookies) Int64(key string) (int64, error) {
  470. ck, err := c.req.Cookie(key)
  471. if err != nil {
  472. return 0, err
  473. }
  474. s := parseSecureCookie(c.secret, ck.Value)
  475. return strconv.ParseInt(s, 10, 64)
  476. }
  477. // Uint gets uint data
  478. func (c *secureCookies) Uint(key string) (uint, error) {
  479. ck, err := c.req.Cookie(key)
  480. if err != nil {
  481. return 0, err
  482. }
  483. s := parseSecureCookie(c.secret, ck.Value)
  484. v, err := strconv.ParseUint(s, 10, 64)
  485. return uint(v), err
  486. }
  487. // Uint32 gets uint32 data
  488. func (c *secureCookies) Uint32(key string) (uint32, error) {
  489. ck, err := c.req.Cookie(key)
  490. if err != nil {
  491. return 0, err
  492. }
  493. s := parseSecureCookie(c.secret, ck.Value)
  494. v, err := strconv.ParseUint(s, 10, 32)
  495. return uint32(v), err
  496. }
  497. // Uint64 gets unit64 data
  498. func (c *secureCookies) Uint64(key string) (uint64, error) {
  499. ck, err := c.req.Cookie(key)
  500. if err != nil {
  501. return 0, err
  502. }
  503. s := parseSecureCookie(c.secret, ck.Value)
  504. return strconv.ParseUint(s, 10, 64)
  505. }
  506. // Float32 gets float32 data
  507. func (c *secureCookies) Float32(key string) (float32, error) {
  508. ck, err := c.req.Cookie(key)
  509. if err != nil {
  510. return 0, err
  511. }
  512. s := parseSecureCookie(c.secret, ck.Value)
  513. v, err := strconv.ParseFloat(s, 32)
  514. return float32(v), err
  515. }
  516. // Float64 gets float64 data
  517. func (c *secureCookies) Float64(key string) (float64, error) {
  518. ck, err := c.req.Cookie(key)
  519. if err != nil {
  520. return 0, err
  521. }
  522. s := parseSecureCookie(c.secret, ck.Value)
  523. return strconv.ParseFloat(s, 32)
  524. }
  525. // Bool gets bool data
  526. func (c *secureCookies) Bool(key string) (bool, error) {
  527. ck, err := c.req.Cookie(key)
  528. if err != nil {
  529. return false, err
  530. }
  531. s := parseSecureCookie(c.secret, ck.Value)
  532. return strconv.ParseBool(s)
  533. }
  534. // MustString gets data
  535. func (c *secureCookies) MustString(key string, defaults ...string) string {
  536. ck, err := c.req.Cookie(key)
  537. if err != nil {
  538. if len(defaults) > 0 {
  539. return defaults[0]
  540. }
  541. return ""
  542. }
  543. s := parseSecureCookie(c.secret, ck.Value)
  544. return s
  545. }
  546. // MustEscape gets data escaped
  547. func (c *secureCookies) MustEscape(key string, defaults ...string) string {
  548. ck, err := c.req.Cookie(key)
  549. if err != nil {
  550. if len(defaults) > 0 {
  551. return defaults[0]
  552. }
  553. return ""
  554. }
  555. s := parseSecureCookie(c.secret, ck.Value)
  556. return template.HTMLEscapeString(s)
  557. }
  558. // MustInt gets data int
  559. func (c *secureCookies) MustInt(key string, defaults ...int) int {
  560. ck, err := c.req.Cookie(key)
  561. if err != nil {
  562. if len(defaults) > 0 {
  563. return defaults[0]
  564. }
  565. return 0
  566. }
  567. s := parseSecureCookie(c.secret, ck.Value)
  568. v, err := strconv.Atoi(s)
  569. if len(defaults) > 0 && err != nil {
  570. return defaults[0]
  571. }
  572. return v
  573. }
  574. // MustInt32 gets data int32
  575. func (c *secureCookies) MustInt32(key string, defaults ...int32) int32 {
  576. ck, err := c.req.Cookie(key)
  577. if err != nil {
  578. if len(defaults) > 0 {
  579. return defaults[0]
  580. }
  581. return 0
  582. }
  583. s := parseSecureCookie(c.secret, ck.Value)
  584. v, err := strconv.ParseInt(s, 10, 32)
  585. if len(defaults) > 0 && err != nil {
  586. return defaults[0]
  587. }
  588. return int32(v)
  589. }
  590. // MustInt64 gets data int64 type
  591. func (c *secureCookies) MustInt64(key string, defaults ...int64) int64 {
  592. ck, err := c.req.Cookie(key)
  593. if err != nil {
  594. if len(defaults) > 0 {
  595. return defaults[0]
  596. }
  597. return 0
  598. }
  599. s := parseSecureCookie(c.secret, ck.Value)
  600. v, err := strconv.ParseInt(s, 10, 64)
  601. if len(defaults) > 0 && err != nil {
  602. return defaults[0]
  603. }
  604. return v
  605. }
  606. // MustUint gets data unit type
  607. func (c *secureCookies) MustUint(key string, defaults ...uint) uint {
  608. ck, err := c.req.Cookie(key)
  609. if err != nil {
  610. if len(defaults) > 0 {
  611. return defaults[0]
  612. }
  613. return 0
  614. }
  615. s := parseSecureCookie(c.secret, ck.Value)
  616. v, err := strconv.ParseUint(s, 10, 64)
  617. if len(defaults) > 0 && err != nil {
  618. return defaults[0]
  619. }
  620. return uint(v)
  621. }
  622. // MustUint32 gets data uint32 type
  623. func (c *secureCookies) MustUint32(key string, defaults ...uint32) uint32 {
  624. ck, err := c.req.Cookie(key)
  625. if err != nil {
  626. if len(defaults) > 0 {
  627. return defaults[0]
  628. }
  629. return 0
  630. }
  631. s := parseSecureCookie(c.secret, ck.Value)
  632. v, err := strconv.ParseUint(s, 10, 32)
  633. if len(defaults) > 0 && err != nil {
  634. return defaults[0]
  635. }
  636. return uint32(v)
  637. }
  638. // MustUint64 gets data unit64 type
  639. func (c *secureCookies) MustUint64(key string, defaults ...uint64) uint64 {
  640. ck, err := c.req.Cookie(key)
  641. if err != nil {
  642. if len(defaults) > 0 {
  643. return defaults[0]
  644. }
  645. return 0
  646. }
  647. s := parseSecureCookie(c.secret, ck.Value)
  648. v, err := strconv.ParseUint(s, 10, 64)
  649. if len(defaults) > 0 && err != nil {
  650. return defaults[0]
  651. }
  652. return v
  653. }
  654. // MustFloat32 gets data float32 type
  655. func (c *secureCookies) MustFloat32(key string, defaults ...float32) float32 {
  656. ck, err := c.req.Cookie(key)
  657. if err != nil {
  658. if len(defaults) > 0 {
  659. return defaults[0]
  660. }
  661. return 0
  662. }
  663. s := parseSecureCookie(c.secret, ck.Value)
  664. v, err := strconv.ParseFloat(s, 32)
  665. if len(defaults) > 0 && err != nil {
  666. return defaults[0]
  667. }
  668. return float32(v)
  669. }
  670. // MustFloat64 gets data float64 type
  671. func (c *secureCookies) MustFloat64(key string, defaults ...float64) float64 {
  672. ck, err := c.req.Cookie(key)
  673. if err != nil {
  674. if len(defaults) > 0 {
  675. return defaults[0]
  676. }
  677. return 0
  678. }
  679. s := parseSecureCookie(c.secret, ck.Value)
  680. v, err := strconv.ParseFloat(s, 32)
  681. if len(defaults) > 0 && err != nil {
  682. return defaults[0]
  683. }
  684. return v
  685. }
  686. // MustBool gets data bool type
  687. func (c *secureCookies) MustBool(key string, defaults ...bool) bool {
  688. ck, err := c.req.Cookie(key)
  689. if err != nil {
  690. if len(defaults) > 0 {
  691. return defaults[0]
  692. }
  693. return false
  694. }
  695. s := parseSecureCookie(c.secret, ck.Value)
  696. v, err := strconv.ParseBool(s)
  697. if len(defaults) > 0 && err != nil {
  698. return defaults[0]
  699. }
  700. return v
  701. }
  702. func secCookieValue(secret string, vb []byte) string {
  703. timestamp := strconv.FormatInt(time.Now().Unix(), 10)
  704. sig := getCookieSig(secret, vb, timestamp)
  705. return strings.Join([]string{string(vb), timestamp, sig}, "|")
  706. }
  707. // NewSecureCookie generates a new secure cookie
  708. func NewSecureCookie(secret, name string, val string, age ...int64) *http.Cookie {
  709. var buf bytes.Buffer
  710. encoder := base64.NewEncoder(base64.StdEncoding, &buf)
  711. encoder.Write([]byte(val))
  712. encoder.Close()
  713. cookie := secCookieValue(secret, buf.Bytes())
  714. return NewCookie(name, cookie, age...)
  715. }
  716. // Expire sets key expire time
  717. func (c *secureCookies) Expire(key string, expire time.Time) {
  718. ck := c.Get(key)
  719. if ck != nil {
  720. ck.Expires = expire
  721. ck.Value = secCookieValue(c.secret, []byte(ck.Value))
  722. c.Set(ck)
  723. }
  724. }
  725. // Del deletes key
  726. func (c *secureCookies) Del(key string) {
  727. c.Expire(key, time.Date(1900, 1, 1, 0, 0, 0, 0, time.Local))
  728. }