mirror of
https://github.com/gin-gonic/gin.git
synced 2025-12-11 19:47:00 +08:00
feat(context): support chaining
This commit is contained in:
parent
e88fc8927a
commit
322da9ca24
26
context.go
26
context.go
@ -280,7 +280,7 @@ func (c *Context) Error(err error) *Error {
|
||||
|
||||
// Set is used to store a new key/value pair exclusively for this context.
|
||||
// It also lazy initializes c.Keys if it was not used previously.
|
||||
func (c *Context) Set(key any, value any) {
|
||||
func (c *Context) Set(key any, value any) *Context {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if c.Keys == nil {
|
||||
@ -288,6 +288,7 @@ func (c *Context) Set(key any, value any) {
|
||||
}
|
||||
|
||||
c.Keys[key] = value
|
||||
return c
|
||||
}
|
||||
|
||||
// Get returns the value for the given key, ie: (value, true).
|
||||
@ -506,8 +507,9 @@ func (c *Context) Param(key string) string {
|
||||
// Example Route: "/user/:id"
|
||||
// AddParam("id", 1)
|
||||
// Result: "/user/1"
|
||||
func (c *Context) AddParam(key, value string) {
|
||||
func (c *Context) AddParam(key, value string) *Context {
|
||||
c.Params = append(c.Params, Param{Key: key, Value: value})
|
||||
return c
|
||||
}
|
||||
|
||||
// Query returns the keyed url query value if it exists,
|
||||
@ -1052,19 +1054,21 @@ func bodyAllowedForStatus(status int) bool {
|
||||
}
|
||||
|
||||
// Status sets the HTTP response code.
|
||||
func (c *Context) Status(code int) {
|
||||
func (c *Context) Status(code int) *Context {
|
||||
c.Writer.WriteHeader(code)
|
||||
return c
|
||||
}
|
||||
|
||||
// Header is an intelligent shortcut for c.Writer.Header().Set(key, value).
|
||||
// It writes a header in the response.
|
||||
// If value == "", this method removes the header `c.Writer.Header().Del(key)`
|
||||
func (c *Context) Header(key, value string) {
|
||||
func (c *Context) Header(key, value string) *Context {
|
||||
if value == "" {
|
||||
c.Writer.Header().Del(key)
|
||||
return
|
||||
return c
|
||||
}
|
||||
c.Writer.Header().Set(key, value)
|
||||
return c
|
||||
}
|
||||
|
||||
// GetHeader returns value from request headers.
|
||||
@ -1081,14 +1085,15 @@ func (c *Context) GetRawData() ([]byte, error) {
|
||||
}
|
||||
|
||||
// SetSameSite with cookie
|
||||
func (c *Context) SetSameSite(samesite http.SameSite) {
|
||||
func (c *Context) SetSameSite(samesite http.SameSite) *Context {
|
||||
c.sameSite = samesite
|
||||
return c
|
||||
}
|
||||
|
||||
// SetCookie adds a Set-Cookie header to the ResponseWriter's headers.
|
||||
// The provided cookie must have a valid Name. Invalid cookies may be
|
||||
// silently dropped.
|
||||
func (c *Context) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool) {
|
||||
func (c *Context) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool) *Context {
|
||||
if path == "" {
|
||||
path = "/"
|
||||
}
|
||||
@ -1102,12 +1107,13 @@ func (c *Context) SetCookie(name, value string, maxAge int, path, domain string,
|
||||
Secure: secure,
|
||||
HttpOnly: httpOnly,
|
||||
})
|
||||
return c
|
||||
}
|
||||
|
||||
// SetCookieData adds a Set-Cookie header to the ResponseWriter's headers.
|
||||
// It accepts a pointer to http.Cookie structure for more flexibility in setting cookie attributes.
|
||||
// The provided cookie must have a valid Name. Invalid cookies may be silently dropped.
|
||||
func (c *Context) SetCookieData(cookie *http.Cookie) {
|
||||
func (c *Context) SetCookieData(cookie *http.Cookie) *Context {
|
||||
if cookie.Path == "" {
|
||||
cookie.Path = "/"
|
||||
}
|
||||
@ -1115,6 +1121,7 @@ func (c *Context) SetCookieData(cookie *http.Cookie) {
|
||||
cookie.SameSite = c.sameSite
|
||||
}
|
||||
http.SetCookie(c.Writer, cookie)
|
||||
return c
|
||||
}
|
||||
|
||||
// Cookie returns the named cookie provided in the request or
|
||||
@ -1394,8 +1401,9 @@ func (c *Context) NegotiateFormat(offered ...string) string {
|
||||
}
|
||||
|
||||
// SetAccepted sets Accept header data.
|
||||
func (c *Context) SetAccepted(formats ...string) {
|
||||
func (c *Context) SetAccepted(formats ...string) *Context {
|
||||
c.Accepted = formats
|
||||
return c
|
||||
}
|
||||
|
||||
/************************************/
|
||||
|
||||
@ -3677,3 +3677,46 @@ func BenchmarkGetMapFromFormData(b *testing.B) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextChaining(t *testing.T) {
|
||||
c, _ := CreateTestContext(httptest.NewRecorder())
|
||||
// Basic cookie settings
|
||||
cookie := &http.Cookie{
|
||||
Name: "name",
|
||||
Value: "gin",
|
||||
MaxAge: 1,
|
||||
Path: "/",
|
||||
Domain: "localhost",
|
||||
Secure: true,
|
||||
HttpOnly: true,
|
||||
}
|
||||
|
||||
c.Set("foo", "bar").
|
||||
AddParam("id", "1").
|
||||
SetSameSite(http.SameSiteLaxMode).
|
||||
SetCookie("user", "gin", 1, "/", "localhost", true, true).
|
||||
SetCookieData(cookie).
|
||||
Header("Content-Type", "text/plain").
|
||||
Header("X-Custom", "value").
|
||||
SetAccepted(MIMEJSON, MIMEXML).
|
||||
Status(200)
|
||||
|
||||
value, err := c.Get("foo")
|
||||
assert.Equal(t, "bar", value)
|
||||
assert.True(t, err)
|
||||
|
||||
v, ok := c.Params.Get("id")
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, "1", v)
|
||||
|
||||
assert.Equal(t, []string{"user=gin; Path=/; Domain=localhost; Max-Age=1; HttpOnly; Secure; SameSite=Lax", "name=gin; Path=/; Domain=localhost; Max-Age=1; HttpOnly; Secure"}, c.Writer.Header().Values("Set-Cookie"))
|
||||
|
||||
assert.Equal(t, "text/plain", c.Writer.Header().Get("Content-Type"))
|
||||
assert.Equal(t, "value", c.Writer.Header().Get("X-Custom"))
|
||||
|
||||
assert.Equal(t, MIMEJSON, c.NegotiateFormat(MIMEJSON, MIMEXML)) //nolint:testifylint
|
||||
assert.Equal(t, MIMEXML, c.NegotiateFormat(MIMEXML, MIMEHTML))
|
||||
assert.Equal(t, MIMEJSON, c.NegotiateFormat(MIMEJSON)) //nolint:testifylint
|
||||
|
||||
assert.Equal(t, 200, c.Writer.Status())
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user