Skip to content

Commit 6f0734a

Browse files
zeripathunknwon6543
authored
Create functional option for ctx.SetCookie (#208)
Co-authored-by: ᴜɴᴋɴᴡᴏɴ <[email protected]> Co-authored-by: 6543 <[email protected]>
1 parent d229aed commit 6f0734a

File tree

4 files changed

+138
-23
lines changed

4 files changed

+138
-23
lines changed

context.go

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,15 @@ type Request struct {
6868
*http.Request
6969
}
7070

71+
// Body returns a RequestBody for the request
7172
func (r *Request) Body() *RequestBody {
7273
return &RequestBody{r.Request.Body}
7374
}
7475

7576
// ContextInvoker is an inject.FastInvoker wrapper of func(ctx *Context).
7677
type ContextInvoker func(ctx *Context)
7778

79+
// Invoke implements inject.FastInvoker which simplifies calls of `func(ctx *Context)` function.
7880
func (invoke ContextInvoker) Invoke(params []interface{}) ([]reflect.Value, error) {
7981
invoke(params[0].(*Context))
8082
return nil, nil
@@ -97,41 +99,43 @@ type Context struct {
9799
Data map[string]interface{}
98100
}
99101

100-
func (c *Context) handler() Handler {
101-
if c.index < len(c.handlers) {
102-
return c.handlers[c.index]
102+
func (ctx *Context) handler() Handler {
103+
if ctx.index < len(ctx.handlers) {
104+
return ctx.handlers[ctx.index]
103105
}
104-
if c.index == len(c.handlers) {
105-
return c.action
106+
if ctx.index == len(ctx.handlers) {
107+
return ctx.action
106108
}
107109
panic("invalid index for context handler")
108110
}
109111

110-
func (c *Context) Next() {
111-
c.index += 1
112-
c.run()
112+
// Next runs the next handler in the context chain
113+
func (ctx *Context) Next() {
114+
ctx.index++
115+
ctx.run()
113116
}
114117

115-
func (c *Context) Written() bool {
116-
return c.Resp.Written()
118+
// Written returns whether the context response has been written to
119+
func (ctx *Context) Written() bool {
120+
return ctx.Resp.Written()
117121
}
118122

119-
func (c *Context) run() {
120-
for c.index <= len(c.handlers) {
121-
vals, err := c.Invoke(c.handler())
123+
func (ctx *Context) run() {
124+
for ctx.index <= len(ctx.handlers) {
125+
vals, err := ctx.Invoke(ctx.handler())
122126
if err != nil {
123127
panic(err)
124128
}
125-
c.index += 1
129+
ctx.index++
126130

127131
// if the handler returned something, write it to the http response
128132
if len(vals) > 0 {
129-
ev := c.GetVal(reflect.TypeOf(ReturnHandler(nil)))
133+
ev := ctx.GetVal(reflect.TypeOf(ReturnHandler(nil)))
130134
handleReturn := ev.Interface().(ReturnHandler)
131-
handleReturn(c, vals)
135+
handleReturn(ctx, vals)
132136
}
133137

134-
if c.Written() {
138+
if ctx.Written() {
135139
return
136140
}
137141
}
@@ -172,6 +176,7 @@ func (ctx *Context) HTMLSet(status int, setName, tplName string, data ...interfa
172176
ctx.renderHTML(status, setName, tplName, data...)
173177
}
174178

179+
// Redirect sends a redirect response
175180
func (ctx *Context) Redirect(location string, status ...int) {
176181
code := http.StatusFound
177182
if len(status) == 1 {
@@ -181,7 +186,7 @@ func (ctx *Context) Redirect(location string, status ...int) {
181186
http.Redirect(ctx.Resp, ctx.Req.Request, location, code)
182187
}
183188

184-
// Maximum amount of memory to use when parsing a multipart form.
189+
// MaxMemory is the maximum amount of memory to use when parsing a multipart form.
185190
// Set this to whatever value you prefer; default is 10 MB.
186191
var MaxMemory = int64(1024 * 1024 * 10)
187192

@@ -341,26 +346,34 @@ func (ctx *Context) SetCookie(name string, value string, others ...interface{})
341346
cookie.MaxAge = int(v)
342347
case int32:
343348
cookie.MaxAge = int(v)
349+
case func(*http.Cookie):
350+
v(&cookie)
344351
}
345352
}
346353

347354
cookie.Path = "/"
348355
if len(others) > 1 {
349356
if v, ok := others[1].(string); ok && len(v) > 0 {
350357
cookie.Path = v
358+
} else if v, ok := others[1].(func(*http.Cookie)); ok {
359+
v(&cookie)
351360
}
352361
}
353362

354363
if len(others) > 2 {
355364
if v, ok := others[2].(string); ok && len(v) > 0 {
356365
cookie.Domain = v
366+
} else if v, ok := others[1].(func(*http.Cookie)); ok {
367+
v(&cookie)
357368
}
358369
}
359370

360371
if len(others) > 3 {
361372
switch v := others[3].(type) {
362373
case bool:
363374
cookie.Secure = v
375+
case func(*http.Cookie):
376+
v(&cookie)
364377
default:
365378
if others[3] != nil {
366379
cookie.Secure = true
@@ -371,13 +384,25 @@ func (ctx *Context) SetCookie(name string, value string, others ...interface{})
371384
if len(others) > 4 {
372385
if v, ok := others[4].(bool); ok && v {
373386
cookie.HttpOnly = true
387+
} else if v, ok := others[1].(func(*http.Cookie)); ok {
388+
v(&cookie)
374389
}
375390
}
376391

377392
if len(others) > 5 {
378393
if v, ok := others[5].(time.Time); ok {
379394
cookie.Expires = v
380395
cookie.RawExpires = v.Format(time.UnixDate)
396+
} else if v, ok := others[1].(func(*http.Cookie)); ok {
397+
v(&cookie)
398+
}
399+
}
400+
401+
if len(others) > 6 {
402+
for _, other := range others[6:] {
403+
if v, ok := other.(func(*http.Cookie)); ok {
404+
v(&cookie)
405+
}
381406
}
382407
}
383408

context_test.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"time"
2828

2929
"github.com/unknwon/com"
30+
"gopkg.in/macaron.v1/cookie"
3031

3132
. "github.com/smartystreets/goconvey/convey"
3233
)
@@ -209,7 +210,18 @@ func Test_Context(t *testing.T) {
209210
So(err, ShouldBeNil)
210211
ctx.SetCookie("user", "Unknwon", 1, "/", "localhost", true, true, t)
211212
ctx.SetCookie("user", "Unknwon", int32(1), "/", "localhost", 1)
212-
ctx.SetCookie("user", "Unknwon", int64(1))
213+
called := false
214+
ctx.SetCookie("user", "Unknwon", int64(1), func(c *http.Cookie) {
215+
called = true
216+
})
217+
So(called, ShouldBeTrue)
218+
ctx.SetCookie("user", "Unknown",
219+
cookie.Secure(true),
220+
cookie.HttpOnly(true),
221+
cookie.Path("/"),
222+
cookie.MaxAge(1),
223+
cookie.Domain("localhost"),
224+
)
213225
})
214226

215227
resp := httptest.NewRecorder()

cookie/helper.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2020 The Macaron Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"): you may
4+
// not use this file except in compliance with the License. You may obtain
5+
// 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, WITHOUT
11+
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
// License for the specific language governing permissions and limitations
13+
// under the License.
14+
15+
// Package cookie contains helper functions for setting cookie values.
16+
package cookie
17+
18+
import (
19+
"net/http"
20+
"time"
21+
)
22+
23+
// MaxAge sets the maximum age for a provided cookie
24+
func MaxAge(maxAge int) func(*http.Cookie) {
25+
return func(c *http.Cookie) {
26+
c.MaxAge = maxAge
27+
}
28+
}
29+
30+
// Path sets the path for a provided cookie
31+
func Path(path string) func(*http.Cookie) {
32+
return func(c *http.Cookie) {
33+
c.Path = path
34+
}
35+
}
36+
37+
// Domain sets the domain for a provided cookie
38+
func Domain(domain string) func(*http.Cookie) {
39+
return func(c *http.Cookie) {
40+
c.Domain = domain
41+
}
42+
}
43+
44+
// Secure sets the secure setting for a provided cookie
45+
func Secure(secure bool) func(*http.Cookie) {
46+
return func(c *http.Cookie) {
47+
c.Secure = secure
48+
}
49+
}
50+
51+
// HttpOnly sets the HttpOnly setting for a provided cookie
52+
func HttpOnly(httpOnly bool) func(*http.Cookie) {
53+
return func(c *http.Cookie) {
54+
c.HttpOnly = httpOnly
55+
}
56+
}
57+
58+
// HTTPOnly sets the HttpOnly setting for a provided cookie
59+
func HTTPOnly(httpOnly bool) func(*http.Cookie) {
60+
return func(c *http.Cookie) {
61+
c.HttpOnly = httpOnly
62+
}
63+
}
64+
65+
// Expires sets the expires and rawexpires for a provided cookie
66+
func Expires(expires time.Time) func(*http.Cookie) {
67+
return func(c *http.Cookie) {
68+
c.Expires = expires
69+
c.RawExpires = expires.Format(time.UnixDate)
70+
}
71+
}
72+
73+
// SameSite sets the SameSite for a provided cookie
74+
func SameSite(sameSite http.SameSite) func(*http.Cookie) {
75+
return func(c *http.Cookie) {
76+
c.SameSite = sameSite
77+
}
78+
}

tree_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ func Test_getWildcards(t *testing.T) {
3434
":id([0-9]+)_:name": result{"([0-9]+)_(.+)", ":id :name"},
3535
"article_:id_:page.html": result{"article_(.+)_(.+).html", ":id :page"},
3636
"article_:id:int_:page:string.html": result{"article_([0-9]+)_([\\w]+).html", ":id :page"},
37-
"*": result{"*", ""},
38-
"*.*": result{"*.*", ""},
37+
"*": result{"*", ""},
38+
"*.*": result{"*.*", ""},
3939
}
4040
Convey("Get wildcards", t, func() {
4141
for key, result := range cases {
@@ -56,8 +56,8 @@ func Test_getRawPattern(t *testing.T) {
5656
"article_:id_:page.html": "article_:id_:page.html",
5757
"article_:id:int_:page:string.html": "article_:id_:page.html",
5858
"article_:id([0-9]+)_:page([\\w]+).html": "article_:id_:page.html",
59-
"*": "*",
60-
"*.*": "*.*",
59+
"*": "*",
60+
"*.*": "*.*",
6161
}
6262
Convey("Get raw pattern", t, func() {
6363
for k, v := range cases {

0 commit comments

Comments
 (0)