mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 10:41:03 +01:00
Some minor but helpful additions, like CookieOption
. Relative: https://github.com/kataras/iris/issues/1018. Simple cookies example added too. Cookie encoding (side by side with the already session's cookie id encoding) and version upgrade will come tomorrow with a new HISTORY.md entry as well, stay tuned!
Former-commit-id: d14181fac998d32d77690b1b3e42b6c7c72f1ace
This commit is contained in:
parent
f84248cb4e
commit
fcff62d5b4
|
@ -395,6 +395,10 @@ iris cache library lives on its own [package](https://github.com/kataras/iris/tr
|
||||||
|
|
||||||
> You're free to use your own favourite caching package if you'd like so.
|
> You're free to use your own favourite caching package if you'd like so.
|
||||||
|
|
||||||
|
### Cookies
|
||||||
|
|
||||||
|
- [Basic](cookies/basic/main.go)
|
||||||
|
|
||||||
### Sessions
|
### Sessions
|
||||||
|
|
||||||
iris session manager lives on its own [package](https://github.com/kataras/iris/tree/master/sessions).
|
iris session manager lives on its own [package](https://github.com/kataras/iris/tree/master/sessions).
|
||||||
|
|
|
@ -394,6 +394,10 @@ Iris 独立缓存包 [package](https://github.com/kataras/iris/tree/master/cache
|
||||||
|
|
||||||
> 可以随意使用自定义的缓存包。
|
> 可以随意使用自定义的缓存包。
|
||||||
|
|
||||||
|
### Cookies
|
||||||
|
|
||||||
|
- [Basic](cookies/basic/main.go)
|
||||||
|
|
||||||
### Sessions
|
### Sessions
|
||||||
|
|
||||||
Iris session 管理独立包 [package](https://github.com/kataras/iris/tree/master/sessions).
|
Iris session 管理独立包 [package](https://github.com/kataras/iris/tree/master/sessions).
|
||||||
|
|
64
_examples/cookies/basic/main.go
Normal file
64
_examples/cookies/basic/main.go
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/kataras/iris"
|
||||||
|
|
||||||
|
func newApp() *iris.Application {
|
||||||
|
app := iris.New()
|
||||||
|
|
||||||
|
// Set A Cookie.
|
||||||
|
app.Get("/cookies/{name}/{value}", func(ctx iris.Context) {
|
||||||
|
name := ctx.Params().Get("name")
|
||||||
|
value := ctx.Params().Get("value")
|
||||||
|
|
||||||
|
ctx.SetCookieKV(name, value) // <--
|
||||||
|
// Alternatively: ctx.SetCookie(&http.Cookie{...})
|
||||||
|
//
|
||||||
|
// If you want to set custom the path:
|
||||||
|
// ctx.SetCookieKV(name, value, iris.CookiePath("/custom/path/cookie/will/be/stored"))
|
||||||
|
//
|
||||||
|
// If you want to be visible only to current request path:
|
||||||
|
// (note that client should be responsible for that if server sent an empty cookie's path, all browsers are compatible)
|
||||||
|
// ctx.SetCookieKV(name, value, iris.CookieCleanPath /* or iris.CookiePath("") */)
|
||||||
|
// More:
|
||||||
|
// iris.CookieExpires(time.Duration)
|
||||||
|
// iris.CookieHTTPOnly(false)
|
||||||
|
|
||||||
|
ctx.Writef("cookie added: %s = %s", name, value)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Retrieve A Cookie.
|
||||||
|
app.Get("/cookies/{name}", func(ctx iris.Context) {
|
||||||
|
name := ctx.Params().Get("name")
|
||||||
|
|
||||||
|
value := ctx.GetCookie(name) // <--
|
||||||
|
// If you want more than the value then:
|
||||||
|
// cookie, err := ctx.Request().Cookie(name)
|
||||||
|
// if err != nil {
|
||||||
|
// handle error.
|
||||||
|
// }
|
||||||
|
|
||||||
|
ctx.WriteString(value)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Delete A Cookie.
|
||||||
|
app.Delete("/cookies/{name}", func(ctx iris.Context) {
|
||||||
|
name := ctx.Params().Get("name")
|
||||||
|
|
||||||
|
ctx.RemoveCookie(name) // <--
|
||||||
|
// If you want to set custom the path:
|
||||||
|
// ctx.SetCookieKV(name, value, iris.CookiePath("/custom/path/cookie/will/be/stored"))
|
||||||
|
|
||||||
|
ctx.Writef("cookie %s removed", name)
|
||||||
|
})
|
||||||
|
|
||||||
|
return app
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := newApp()
|
||||||
|
|
||||||
|
// GET: http://localhost:8080/cookies/my_name/my_value
|
||||||
|
// GET: http://localhost:8080/cookies/my_name
|
||||||
|
// DELETE: http://localhost:8080/cookies/my_name
|
||||||
|
app.Run(iris.Addr(":8080"))
|
||||||
|
}
|
32
_examples/cookies/basic/main_test.go
Normal file
32
_examples/cookies/basic/main_test.go
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/kataras/iris/httptest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCookiesBasic(t *testing.T) {
|
||||||
|
app := newApp()
|
||||||
|
e := httptest.New(t, app, httptest.URL("http://example.com"))
|
||||||
|
|
||||||
|
cookieName, cookieValue := "my_cookie_name", "my_cookie_value"
|
||||||
|
|
||||||
|
// Test Set A Cookie.
|
||||||
|
t1 := e.GET(fmt.Sprintf("/cookies/%s/%s", cookieName, cookieValue)).Expect().Status(httptest.StatusOK)
|
||||||
|
t1.Cookie(cookieName).Value().Equal(cookieValue) // validate cookie's existence, it should be there now.
|
||||||
|
t1.Body().Contains(cookieValue)
|
||||||
|
|
||||||
|
// Test Retrieve A Cookie.
|
||||||
|
t2 := e.GET(fmt.Sprintf("/cookies/%s", cookieName)).Expect().Status(httptest.StatusOK)
|
||||||
|
t2.Body().Equal(cookieValue)
|
||||||
|
|
||||||
|
// Test Remove A Cookie.
|
||||||
|
t3 := e.DELETE(fmt.Sprintf("/cookies/%s", cookieName)).Expect().Status(httptest.StatusOK)
|
||||||
|
t3.Body().Contains(cookieName)
|
||||||
|
|
||||||
|
t4 := e.GET(fmt.Sprintf("/cookies/%s", cookieName)).Expect().Status(httptest.StatusOK)
|
||||||
|
t4.Cookies().Empty()
|
||||||
|
t4.Body().Empty()
|
||||||
|
}
|
|
@ -854,18 +854,41 @@ type Context interface {
|
||||||
// | Cookies |
|
// | Cookies |
|
||||||
// +------------------------------------------------------------+
|
// +------------------------------------------------------------+
|
||||||
|
|
||||||
// SetCookie adds a cookie
|
// SetCookie adds a cookie.
|
||||||
SetCookie(cookie *http.Cookie)
|
// Use of the "options" is not required, they can be used to amend the "cookie".
|
||||||
// SetCookieKV adds a cookie, receives just a name(string) and a value(string)
|
|
||||||
//
|
//
|
||||||
// If you use this method, it expires at 2 hours
|
// Example: https://github.com/kataras/iris/tree/master/_examples/cookies/basic
|
||||||
// use ctx.SetCookie or http.SetCookie if you want to change more fields.
|
SetCookie(cookie *http.Cookie, options ...CookieOption)
|
||||||
SetCookieKV(name, value string)
|
// SetCookieKV adds a cookie, requires the name(string) and the value(string).
|
||||||
|
//
|
||||||
|
// By default it expires at 2 hours and it's added to the root path,
|
||||||
|
// use the `CookieExpires` and `CookiePath` to modify them.
|
||||||
|
// Alternatively: ctx.SetCookie(&http.Cookie{...})
|
||||||
|
//
|
||||||
|
// If you want to set custom the path:
|
||||||
|
// ctx.SetCookieKV(name, value, iris.CookiePath("/custom/path/cookie/will/be/stored"))
|
||||||
|
//
|
||||||
|
// If you want to be visible only to current request path:
|
||||||
|
// ctx.SetCookieKV(name, value, iris.CookieCleanPath/iris.CookiePath(""))
|
||||||
|
// More:
|
||||||
|
// iris.CookieExpires(time.Duration)
|
||||||
|
// iris.CookieHTTPOnly(false)
|
||||||
|
//
|
||||||
|
// Example: https://github.com/kataras/iris/tree/master/_examples/cookies/basic
|
||||||
|
SetCookieKV(name, value string, options ...CookieOption)
|
||||||
// GetCookie returns cookie's value by it's name
|
// GetCookie returns cookie's value by it's name
|
||||||
// returns empty string if nothing was found.
|
// returns empty string if nothing was found.
|
||||||
GetCookie(name string) string
|
//
|
||||||
// RemoveCookie deletes a cookie by it's name.
|
// If you want more than the value then:
|
||||||
RemoveCookie(name string)
|
// cookie, err := ctx.Request().Cookie("name")
|
||||||
|
//
|
||||||
|
// Example: https://github.com/kataras/iris/tree/master/_examples/cookies/basic
|
||||||
|
GetCookie(name string, options ...CookieOption) string
|
||||||
|
// RemoveCookie deletes a cookie by it's name and path = "/".
|
||||||
|
// Tip: change the cookie's path to the current one by: RemoveCookie("name", iris.CookieCleanPath)
|
||||||
|
//
|
||||||
|
// Example: https://github.com/kataras/iris/tree/master/_examples/cookies/basic
|
||||||
|
RemoveCookie(name string, options ...CookieOption)
|
||||||
// VisitAllCookies takes a visitor which loops
|
// VisitAllCookies takes a visitor which loops
|
||||||
// on each (request's) cookies' name and value.
|
// on each (request's) cookies' name and value.
|
||||||
VisitAllCookies(visitor func(name string, value string))
|
VisitAllCookies(visitor func(name string, value string))
|
||||||
|
@ -1233,7 +1256,7 @@ func (ctx *context) HandlerName() string {
|
||||||
// It can be changed to a customized one if needed (very advanced usage).
|
// It can be changed to a customized one if needed (very advanced usage).
|
||||||
//
|
//
|
||||||
// See `DefaultNext` for more information about this and why it's exported like this.
|
// See `DefaultNext` for more information about this and why it's exported like this.
|
||||||
var Next = DefaultNext ///TODO: add an example for this usecase, i.e describe handlers and skip only file handlers.
|
var Next = DefaultNext
|
||||||
|
|
||||||
// DefaultNext is the default function that executed on each middleware if `ctx.Next()`
|
// DefaultNext is the default function that executed on each middleware if `ctx.Next()`
|
||||||
// is called.
|
// is called.
|
||||||
|
@ -2992,57 +3015,144 @@ func (ctx *context) SendFile(filename string, destinationName string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// +------------------------------------------------------------+
|
// +------------------------------------------------------------+
|
||||||
// | Cookies, Session and Flashes |
|
// | Cookies |
|
||||||
// +------------------------------------------------------------+
|
// +------------------------------------------------------------+
|
||||||
|
|
||||||
// SetCookie adds a cookie
|
// CookieOption is the type of function that is accepted on
|
||||||
func (ctx *context) SetCookie(cookie *http.Cookie) {
|
// context's methods like `SetCookieKV`, `RemoveCookie` and `SetCookie`
|
||||||
|
// as their (last) variadic input argument to amend the end cookie's form.
|
||||||
|
//
|
||||||
|
// Any custom or built'n `CookieOption` is valid,
|
||||||
|
// see `CookiePath`, `CookieCleanPath`, `CookieExpires` and `CookieHTTPOnly` for more.
|
||||||
|
type CookieOption func(*http.Cookie)
|
||||||
|
|
||||||
|
// CookiePath is a `CookieOption`.
|
||||||
|
// Use it to change the cookie's Path field.
|
||||||
|
func CookiePath(path string) CookieOption {
|
||||||
|
return func(c *http.Cookie) {
|
||||||
|
c.Path = path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CookieCleanPath is a `CookieOption`.
|
||||||
|
// Use it to clear the cookie's Path field, exactly the same as `CookiePath("")`.
|
||||||
|
func CookieCleanPath(c *http.Cookie) {
|
||||||
|
c.Path = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// CookieExpires is a `CookieOption`.
|
||||||
|
// Use it to change the cookie's Expires and MaxAge fields by passing the lifetime of the cookie.
|
||||||
|
func CookieExpires(durFromNow time.Duration) CookieOption {
|
||||||
|
return func(c *http.Cookie) {
|
||||||
|
c.Expires = time.Now().Add(durFromNow)
|
||||||
|
c.MaxAge = int(durFromNow.Seconds())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CookieHTTPOnly is a `CookieOption`.
|
||||||
|
// Use it to set the cookie's HttpOnly field to false or true.
|
||||||
|
// HttpOnly field defaults to true for `RemoveCookie` and `SetCookieKV`.
|
||||||
|
func CookieHTTPOnly(httpOnly bool) CookieOption {
|
||||||
|
return func(c *http.Cookie) {
|
||||||
|
c.HttpOnly = httpOnly
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCookie adds a cookie.
|
||||||
|
// Use of the "options" is not required, they can be used to amend the "cookie".
|
||||||
|
//
|
||||||
|
// Example: https://github.com/kataras/iris/tree/master/_examples/cookies/basic
|
||||||
|
func (ctx *context) SetCookie(cookie *http.Cookie, options ...CookieOption) {
|
||||||
|
for _, opt := range options {
|
||||||
|
opt(cookie)
|
||||||
|
}
|
||||||
|
|
||||||
http.SetCookie(ctx.writer, cookie)
|
http.SetCookie(ctx.writer, cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
// SetCookieKV adds a cookie, requires the name(string) and the value(string).
|
||||||
// SetCookieKVExpiration is 2 hours by-default
|
|
||||||
// you can change it or simple, use the SetCookie for more control.
|
|
||||||
SetCookieKVExpiration = time.Duration(120) * time.Minute
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetCookieKV adds a cookie, receives just a name(string) and a value(string)
|
|
||||||
//
|
//
|
||||||
// If you use this method, it expires at 2 hours
|
// By default it expires at 2 hours and it's added to the root path,
|
||||||
// use ctx.SetCookie or http.SetCookie if you want to change more fields.
|
// use the `CookieExpires` and `CookiePath` to modify them.
|
||||||
func (ctx *context) SetCookieKV(name, value string) {
|
// Alternatively: ctx.SetCookie(&http.Cookie{...})
|
||||||
|
//
|
||||||
|
// If you want to set custom the path:
|
||||||
|
// ctx.SetCookieKV(name, value, iris.CookiePath("/custom/path/cookie/will/be/stored"))
|
||||||
|
//
|
||||||
|
// If you want to be visible only to current request path:
|
||||||
|
// (note that client should be responsible for that if server sent an empty cookie's path, all browsers are compatible)
|
||||||
|
// ctx.SetCookieKV(name, value, iris.CookieCleanPath/iris.CookiePath(""))
|
||||||
|
// More:
|
||||||
|
// iris.CookieExpires(time.Duration)
|
||||||
|
// iris.CookieHTTPOnly(false)
|
||||||
|
//
|
||||||
|
// Examples: https://github.com/kataras/iris/tree/master/_examples/cookies/basic
|
||||||
|
func (ctx *context) SetCookieKV(name, value string, options ...CookieOption) {
|
||||||
c := &http.Cookie{}
|
c := &http.Cookie{}
|
||||||
|
c.Path = "/"
|
||||||
c.Name = name
|
c.Name = name
|
||||||
c.Value = url.QueryEscape(value)
|
c.Value = url.QueryEscape(value)
|
||||||
c.HttpOnly = true
|
c.HttpOnly = true
|
||||||
c.Expires = time.Now().Add(SetCookieKVExpiration)
|
c.Expires = time.Now().Add(SetCookieKVExpiration)
|
||||||
c.MaxAge = int(SetCookieKVExpiration.Seconds())
|
c.MaxAge = int(SetCookieKVExpiration.Seconds())
|
||||||
ctx.SetCookie(c)
|
ctx.SetCookie(c, options...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCookie returns cookie's value by it's name
|
// GetCookie returns cookie's value by it's name
|
||||||
// returns empty string if nothing was found.
|
// returns empty string if nothing was found.
|
||||||
func (ctx *context) GetCookie(name string) string {
|
//
|
||||||
|
// If you want more than the value then:
|
||||||
|
// cookie, err := ctx.Request().Cookie("name")
|
||||||
|
//
|
||||||
|
// Example: https://github.com/kataras/iris/tree/master/_examples/cookies/basic
|
||||||
|
func (ctx *context) GetCookie(name string, options ...CookieOption) string {
|
||||||
cookie, err := ctx.request.Cookie(name)
|
cookie, err := ctx.request.Cookie(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// Q: Why named as `CookieOption` and not like `CookieInterceptor`?
|
||||||
|
// A: Because an interceptor would be able to modify the cookie AND stop the 'x' operation, but we don't want to cancel anything.
|
||||||
|
//
|
||||||
|
// Q: Why "Cookie Options" here?
|
||||||
|
// A: Because of the future suport of cookie encoding like I did with sessions.
|
||||||
|
// Two impl ideas:
|
||||||
|
// - Do it so each caller of `GetCookie/SetCookieKV/SetCookie` can have each own encoding or share one, no limit.
|
||||||
|
// - Do it so every of the above three methods will use the same encoding, therefore to the Application's level, limit per Iris app.
|
||||||
|
// We'll see...
|
||||||
|
//
|
||||||
|
// Finally, I should not forget to add links for the new translated READMEs(2) and push a new version with the minor changes so far,
|
||||||
|
// API is stable, so relax and do it on the next commit tomorrow, need sleep.
|
||||||
|
for _, opt := range options {
|
||||||
|
opt(cookie)
|
||||||
|
}
|
||||||
|
|
||||||
value, _ := url.QueryUnescape(cookie.Value)
|
value, _ := url.QueryUnescape(cookie.Value)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveCookie deletes a cookie by it's name.
|
// SetCookieKVExpiration is 2 hours by-default
|
||||||
func (ctx *context) RemoveCookie(name string) {
|
// you can change it or simple, use the SetCookie for more control.
|
||||||
|
//
|
||||||
|
// See `SetCookieKVExpiration` and `CookieExpires` for more.
|
||||||
|
var SetCookieKVExpiration = time.Duration(120) * time.Minute
|
||||||
|
|
||||||
|
// RemoveCookie deletes a cookie by it's name and path = "/".
|
||||||
|
// Tip: change the cookie's path to the current one by: RemoveCookie("name", iris.CookieCleanPath)
|
||||||
|
//
|
||||||
|
// Example: https://github.com/kataras/iris/tree/master/_examples/cookies/basic
|
||||||
|
func (ctx *context) RemoveCookie(name string, options ...CookieOption) {
|
||||||
c := &http.Cookie{}
|
c := &http.Cookie{}
|
||||||
c.Name = name
|
c.Name = name
|
||||||
c.Value = ""
|
c.Value = ""
|
||||||
c.Path = "/"
|
c.Path = "/" // if user wants to change it, use of the CookieOption `CookiePath` is required if not `ctx.SetCookie`.
|
||||||
c.HttpOnly = true
|
c.HttpOnly = true
|
||||||
// RFC says 1 second, but let's do it 1 minute to make sure is working
|
// RFC says 1 second, but let's do it 1 to make sure is working
|
||||||
exp := time.Now().Add(-time.Duration(1) * time.Minute)
|
exp := time.Now().Add(-time.Duration(1) * time.Minute)
|
||||||
c.Expires = exp
|
c.Expires = exp
|
||||||
c.MaxAge = -1
|
c.MaxAge = -1
|
||||||
ctx.SetCookie(c)
|
ctx.SetCookie(c, options...)
|
||||||
// delete request's cookie also, which is temporary available.
|
// delete request's cookie also, which is temporary available.
|
||||||
ctx.request.Header.Set("Cookie", "")
|
ctx.request.Header.Set("Cookie", "")
|
||||||
}
|
}
|
||||||
|
|
10
go19.go
10
go19.go
|
@ -71,4 +71,14 @@ type (
|
||||||
//
|
//
|
||||||
// See `ExecutionRules` and `core/router/Party#SetExecutionRules` for more.
|
// See `ExecutionRules` and `core/router/Party#SetExecutionRules` for more.
|
||||||
ExecutionOptions = router.ExecutionOptions
|
ExecutionOptions = router.ExecutionOptions
|
||||||
|
|
||||||
|
// CookieOption is the type of function that is accepted on
|
||||||
|
// context's methods like `SetCookieKV`, `RemoveCookie` and `SetCookie`
|
||||||
|
// as their (last) variadic input argument to amend the end cookie's form.
|
||||||
|
//
|
||||||
|
// Any custom or built'n `CookieOption` is valid,
|
||||||
|
// see `CookiePath`, `CookieCleanPath`, `CookieExpires` and `CookieHTTPOnly` for more.
|
||||||
|
//
|
||||||
|
// An alias for the `context/Context#CookieOption`.
|
||||||
|
CookieOption = context.CookieOption
|
||||||
)
|
)
|
||||||
|
|
|
@ -87,6 +87,7 @@ func New(t *testing.T, app *iris.Application, setters ...OptionSetter) *httpexpe
|
||||||
// set the logger or disable it (default) and disable the updater (for any case).
|
// set the logger or disable it (default) and disable the updater (for any case).
|
||||||
app.Configure(iris.WithoutVersionChecker)
|
app.Configure(iris.WithoutVersionChecker)
|
||||||
app.Logger().SetLevel(conf.LogLevel)
|
app.Logger().SetLevel(conf.LogLevel)
|
||||||
|
|
||||||
if err := app.Build(); err != nil {
|
if err := app.Build(); err != nil {
|
||||||
if conf.Debug && (conf.LogLevel == "disable" || conf.LogLevel == "disabled") {
|
if conf.Debug && (conf.LogLevel == "disable" || conf.LogLevel == "disabled") {
|
||||||
app.Logger().Println(err.Error())
|
app.Logger().Println(err.Error())
|
||||||
|
|
22
iris.go
22
iris.go
|
@ -422,6 +422,28 @@ var (
|
||||||
//
|
//
|
||||||
// A shortcut of the `cache#Cache304`.
|
// A shortcut of the `cache#Cache304`.
|
||||||
Cache304 = cache.Cache304
|
Cache304 = cache.Cache304
|
||||||
|
|
||||||
|
// CookiePath is a `CookieOption`.
|
||||||
|
// Use it to change the cookie's Path field.
|
||||||
|
//
|
||||||
|
// A shortcut for the `context#CookiePath`.
|
||||||
|
CookiePath = context.CookiePath
|
||||||
|
// CookieCleanPath is a `CookieOption`.
|
||||||
|
// Use it to clear the cookie's Path field, exactly the same as `CookiePath("")`.
|
||||||
|
//
|
||||||
|
// A shortcut for the `context#CookieCleanPath`.
|
||||||
|
CookieCleanPath = context.CookieCleanPath
|
||||||
|
// CookieExpires is a `CookieOption`.
|
||||||
|
// Use it to change the cookie's Expires and MaxAge fields by passing the lifetime of the cookie.
|
||||||
|
//
|
||||||
|
// A shortcut for the `context#CookieExpires`.
|
||||||
|
CookieExpires = context.CookieExpires
|
||||||
|
// CookieHTTPOnly is a `CookieOption`.
|
||||||
|
// Use it to set the cookie's HttpOnly field to false or true.
|
||||||
|
// HttpOnly field defaults to true for `RemoveCookie` and `SetCookieKV`.
|
||||||
|
//
|
||||||
|
// A shortcut for the `context#CookieHTTPOnly`.
|
||||||
|
CookieHTTPOnly = context.CookieHTTPOnly
|
||||||
)
|
)
|
||||||
|
|
||||||
// SPA accepts an "assetHandler" which can be the result of an
|
// SPA accepts an "assetHandler" which can be the result of an
|
||||||
|
|
Loading…
Reference in New Issue
Block a user