请求
URI
func (ctx *RequestContext) Host() []byte
func (ctx *RequestContext) FullPath() string
func (ctx *RequestContext) SetFullPath(p string)
func (ctx *RequestContext) Path() []byte
func (ctx *RequestContext) Param(key string) string
func (ctx *RequestContext) Query(key string) string
func (ctx *RequestContext) DefaultQuery(key, defaultValue string) string
func (ctx *RequestContext) GetQuery(key string) (string, bool)
func (ctx *RequestContext) QueryArgs() *protocol.Args
func (ctx *RequestContext) URI() *protocol.URI
Host
获取请求的主机地址。
函数签名:
func (ctx *RequestContext) Host() []byte
示例:
// GET http://example.com
h.GET("/", func(c context.Context, ctx *app.RequestContext) {
host := ctx.Host() // host == []byte("example.com")
})
FullPath
获取匹配的路由完整路径,对于未匹配的路由返回空字符串。
函数签名:
func (ctx *RequestContext) FullPath() string
示例:
h := server.Default(server.WithHandleMethodNotAllowed(true))
// GET http://example.com/user/bar
h.GET("/user/:name", func(c context.Context, ctx *app.RequestContext) {
fpath := ctx.FullPath() // fpath == "/user/:name"
})
// GET http://example.com/bar
h.NoRoute(func(c context.Context, ctx *app.RequestContext) {
fpath := ctx.FullPath() // fpath == ""
})
// POST http://example.com/user/bar
h.NoMethod(func(c context.Context, ctx *app.RequestContext) {
fpath := ctx.FullPath() // fpath == ""
})
SetFullPath
设置 FullPath 的值。
注意:FullPath 由路由查找时分配,通常你不需要使用 SetFullPath 去覆盖它。
函数签名:
func (ctx *RequestContext) SetFullPath(p string)
示例:
h.GET("/user/:name", func(c context.Context, ctx *app.RequestContext) {
ctx.SetFullPath("/v1/user/:name")
fpath := ctx.FullPath() // fpath == "/v1/user/:name"
})
Path
获取请求的路径。
注意:出现参数路由时 Path 给出命名参数匹配后的路径,而 FullPath 给出原始路径。
函数签名:
func (ctx *RequestContext) Path() []byte
示例:
// GET http://example.com/user/bar
h.GET("/user/:name", func(c context.Context, ctx *app.RequestContext) {
path := ctx.Path() // path == []byte("/user/bar")
})
Param
获取路由参数的值。
函数签名:
func (ctx *RequestContext) Param(key string) string
示例:
// GET http://example.com/user/bar
h.GET("/user/:name", func(c context.Context, ctx *app.RequestContext) {
name := ctx.Param("name") // name == "bar"
id := ctx.Param("id") // id == ""
})
Query
获取路由 Query String
参数中指定属性的值,如果没有返回空字符串。
函数签名:
func (ctx *RequestContext) Query(key string) string
示例:
// GET http://example.com/user?name=bar
h.GET("/user", func(c context.Context, ctx *app.RequestContext) {
name := ctx.Query("name") // name == "bar"
id := ctx.Query("id") // id == ""
})
DefaultQuery
获取路由 Query String
参数中指定属性的值,如果没有返回设置的默认值。
函数签名:
func (ctx *RequestContext) DefaultQuery(key, defaultValue string) string
示例:
// GET http://example.com/user?name=bar&&age=
h.GET("/user", func(c context.Context, ctx *app.RequestContext) {
name := ctx.DefaultQuery("name", "tom") // name == "bar"
id := ctx.DefaultQuery("id", "123") // id == "123"
age := ctx.DefaultQuery("age", "45") // age == ""
})
GetQuery
获取路由 Query String
参数中指定属性的值以及属性是否存在。
函数签名:
func (ctx *RequestContext) GetQuery(key string) (string, bool)
示例:
// GET http://example.com/user?name=bar&&age=
h.GET("/user", func(c context.Context, ctx *app.RequestContext) {
name, hasName := ctx.GetQuery("name") // name == "bar", hasName == true
id, hasId := ctx.GetQuery("id") // id == "", hasId == false
age, hasAge := ctx.GetQuery("age") // age == "", hasAge == true
})
QueryArgs
获取路由 Query String
参数对象。
函数签名:
func (ctx *RequestContext) QueryArgs() *protocol.Args
Args 对象
Args 对象提供了以下方法获取/设置 Query String 参数。
函数签名 | 说明 |
---|---|
func (a *Args) Set(key, value string) |
设置 Args 对象 key 的值 |
func (a *Args) Reset() |
重置 Args 对象 |
func (a *Args) CopyTo(dst *Args) |
将 Args 对象拷贝到 dst |
func (a *Args) Del(key string) |
删除 Args 对象 key 的键值对 |
func (a *Args) DelBytes(key []byte) |
删除 Args 对象字节数组类型 key 的键值对 |
func (a *Args) Has(key string) bool |
获取 Args 对象是否存在 key 的键值对 |
func (a *Args) String() string |
将 Args 对象转换为字符串类型的 Query String |
func (a *Args) QueryString() []byte |
将 Args 对象转换为字节数组类型的 Query String |
func (a *Args) ParseBytes(b []byte) |
解析字节数组并将键值对存入 Args 对象 |
func (a *Args) Peek(key string) []byte |
获取 Args 对象 key 的值 |
func (a *Args) PeekExists(key string) (string, bool) |
获取 Args 对象 key 的值以及是否存在 |
func (a *Args) PeekAll(key string) [][]byte |
获取 Args 对象 key 的所有值 |
func (a *Args) Len() int |
获取 Args 对象键值对数量 |
func (a *Args) AppendBytes(dst []byte) []byte |
将 Args 对象 Query String 附加到 dst 中并返回 |
func (a *Args) VisitAll(f func(key, value []byte)) |
遍历 Args 对象所有的键值对 |
func (a *Args) WriteTo(w io.Writer) (int64, error) |
将 Args 对象 Query String 写入 io.Writer 中 |
func (a *Args) Add(key, value string) |
添加 Args 对象键为 key 的值 |
示例:
// GET http://example.com/user?name=bar&&age=&&pets=dog&&pets=cat
h.GET("/user", func(c context.Context, ctx *app.RequestContext) {
args := ctx.QueryArgs()
// get information from args
s := args.String() // s == "name=bar&age=&pets=dog&pets=cat"
qs := args.QueryString() // qs == []byte("name=bar&age=&pets=dog&pets=cat")
cpqs := args.AppendBytes([]byte(nil)) // cpqs == []byte("name=bar&age=&pets=dog&pets=cat")
name := args.Peek("name") // name == []byte("bar")
hasName := args.Has("name") // hasName == true
age, hasAge := args.PeekExists("age") // age == "", hasAge == true
len := args.Len() // len == 4
args.VisitAll(func(key, value []byte) {
// 1. key == []byte("name"), value == []byte("bar")
// 2. key == []byte("age"), value == nil
// 3. key == []byte("pets"), value == []byte("dog")
// 4. key == []byte("pets"), value == []byte("cat")
})
pets := args.PeekAll("pets") // pets == [][]byte{[]byte("dog"), []byte("cat")}
// send information to io.Writer
req := protocol.AcquireRequest()
n, err := args.WriteTo(req.BodyWriter())
// n == 31 err == nil
s := req.BodyBuffer().String()
// s == "name=bar&age=&pets=dog&pets=cat"
// change args
var newArgs protocol.Args
args.CopyTo(&newArgs)
newArgs.Set("version", "v1")
version := newArgs.Peek("version") //version == []byte("v1")
newArgs.Del("age")
hasAgeAfterDel := newArgs.Has("age") // hasAgeAfterDel == false
newArgs.DelBytes([]byte("name"))
hasNameAfterDel := newArgs.Has("name") // hasNameAfterDel == false
newArgs.Add("name", "foo")
newName := newArgs.Peek("name") //newName == []byte("foo")
newArgs.Reset()
empty := newArgs.String() // empty == ""
// parse args
var newArgs2 protocol.Args
newArgs2.ParseBytes([]byte("name=bar&age=20"))
nqs2 := newArgs2.String() // nqs2 == "name=bar&age=20"
})
URI
返回请求的 URI
对象。
函数签名:
func (ctx *RequestContext) URI() *protocol.URI
URI 对象
URI 对象提供了以下方法获取/设置 URI。
函数签名 | 说明 |
---|---|
func (u *URI) CopyTo(dst *URI) |
拷贝 URI 对象的副本到 dst |
func (u *URI) QueryArgs() *Args |
获取 Args 对象 |
func (u *URI) Hash() []byte |
获取 Hash 值,比如 http://example.com/user?baz=123#qwe 的 Hash 是 qwe |
func (u *URI) SetHash(hash string) |
设置 Hash |
func (u *URI) SetHashBytes(hash []byte) |
设置 []byte 类型 Hash |
func (u *URI) Username() []byte |
获取 Username |
func (u *URI) SetUsername(username string) |
设置 Username |
func (u *URI) SetUsernameBytes(username []byte) |
设置 []byte 类型 Username |
func (u *URI) Password() []byte |
获取 Password |
func (u *URI) SetPassword(password string) |
设置 Password |
func (u *URI) SetPasswordBytes(password []byte) |
设置 []byte 类型 Password |
func (u *URI) QueryString() []byte |
获取 Query String ,比如 http://example.com/user?baz=123 的 Query String 是 baz=123 |
func (u *URI) SetQueryString(queryString string) |
设置 Query String ,注意,在该方法之后使用 RequestHeader.SetRequestURI 可能会覆盖掉原来想设置的值 |
func (u *URI) SetQueryStringBytes(queryString []byte) |
设置 []byte 类型的 Query String ,注意,在该方法之后使用 RequestHeader.SetRequestURI 可能会覆盖掉原来想设置的值 |
func (u *URI) Path() []byte |
获取 Path,比如 http://example.com/user/he%20rtz 的 Path 是 /user/he rtz |
func (u *URI) PathOriginal() []byte |
获取未转义的 Path,比如 http://example.com/user/he%20rtz 的 Path 是 /user/he%20rtz |
func (u *URI) SetPath(path string) |
设置 Path |
func (u *URI) SetPathBytes(path []byte) |
设置 []byte 类型 Path |
func (u *URI) String() string |
获取完整 URI 比如 http://example.com/user?baz=123 的完整 URI 是 http://example.com/user?baz=123 |
func (u *URI) FullURI() []byte |
获取 []byte 类型的完整 URI |
func (u *URI) Scheme() []byte |
获取协议,如 http |
func (u *URI) SetScheme(scheme string) |
设置协议 |
func (u *URI) SetSchemeBytes(scheme []byte) |
设置 []byte 类型的协议 |
func (u *URI) Host() []byte |
获取 Host,比如 http://example.com/user 的 Host 是 example.com |
func (u *URI) SetHost(host string) |
设置 Host |
func (u *URI) SetHostBytes(host []byte) |
设置 []byte 类型 Host |
func (u *URI) LastPathSegment() []byte |
获取 Path 的最后一部分,比如 Path /foo/bar/baz.html 的最后一部分是 baz.html |
func (u *URI) Update(newURI string) |
更新 URI |
func (u *URI) UpdateBytes(newURI []byte) |
更新 []byte 类型的 URI |
func (u *URI) Parse(host, uri []byte) |
初始化 URI |
func (u *URI) AppendBytes(dst []byte) []byte |
将完整的 URI 赋值到 dst 中并返回 dst |
func (u *URI) RequestURI() []byte |
获取 RequestURI,比如 http://example.com/user?baz=123 的 RequestURI 是 /user?baz=123 |
func (u *URI) Reset() |
重置 URI |
Header
// RequestHeader
func (h *RequestHeader) Add(key, value string)
func (h *RequestHeader) Set(key, value string)
func (h *RequestHeader) Header() []byte
func (h *RequestHeader) String() string
func (h *RequestHeader) VisitAll(f func(key, value []byte))
// RequestContext
func (ctx *RequestContext) IsGet() bool
func (ctx *RequestContext) IsHead() bool
func (ctx *RequestContext) IsPost() bool
func (ctx *RequestContext) Method() []byte
func (ctx *RequestContext) ContentType() []byte
func (ctx *RequestContext) IfModifiedSince(lastModified time.Time) bool
func (ctx *RequestContext) Cookie(key string) []byte
func (ctx *RequestContext) UserAgent() []byte
func (ctx *RequestContext) GetHeader(key string) []byte
Add
添加或设置键为 key 的 Header。
注意:Add 通常用于为同一个 Key 设置多个 Header,若要为同一个 Key 设置单个 Header 请使用 Set。当作用于 Content-Type, Content-Length, Connection, Cookie, Transfer-Encoding, Host, User-Agent 这些 Header 时,使用多个 Add 会覆盖掉旧值。
函数签名:
func (h *RequestHeader) Add(key, value string)
示例:
hertz.GET("/example", func(c context.Context, ctx *app.RequestContext) {
ctx.Request.Header.Add("hertz1", "value1")
ctx.Request.Header.Add("hertz1", "value2")
ctx.Request.Header.SetContentTypeBytes([]byte("application/x-www-form-urlencoded"))
contentType1 := ctx.Request.Header.ContentType()
// contentType1 == []byte("application/x-www-form-urlencoded")
ctx.Request.Header.Add("Content-Type", "application/json; charset=utf-8")
hertz1 := ctx.Request.Header.GetAll("hertz1")
// hertz1 == []string{"value1", "value2"}
contentType2 := ctx.Request.Header.ContentType()
// contentType2 == []byte("application/json; charset=utf-8")
})
Set
设置 Header 键值。
注意:Set 通常用于为同一个 Key 设置单个 Header,若要为同一个 Key 设置多个 Header 请使用 Add。
函数签名:
func (h *RequestHeader) Set(key, value string)
示例:
hertz.GET("/example", func(c context.Context, ctx *app.RequestContext) {
ctx.Request.Header.Set("hertz1", "value1")
ctx.Request.Header.Set("hertz1", "value2")
ctx.Request.Header.SetContentTypeBytes([]byte("application/x-www-form-urlencoded"))
contentType1 := ctx.Request.Header.ContentType()
// contentType1 == []byte("application/x-www-form-urlencoded")
ctx.Request.Header.Set("Content-Type", "application/json; charset=utf-8")
hertz1 := ctx.Request.Header.GetAll("hertz1")
// hertz1 == []string{"value2"}
contentType2 := ctx.Request.Header.ContentType()
// contentType2 == []byte("application/json; charset=utf-8")
})
Header
获取 []byte
类型的完整的 Header。
函数签名:
func (h *RequestHeader) Header() []byte
示例:
hertz.GET("/example", func(c context.Context, ctx *app.RequestContext) {
ctx.Request.Header.Set("hertz1", "value1")
header := ctx.Request.Header.Header()
// header == []byte("GET /example HTTP/1.1
//User-Agent: PostmanRuntime-ApipostRuntime/1.1.0
//Host: localhost:8888
//Cache-Control: no-cache
//Accept: */*
//Accept-Encoding: gzip, deflate, br
//Connection: keep-alive
//Hertz1: value1")
})
String
获取完整的 Header。
函数签名:
func (h *RequestHeader) String() string
示例:
hertz.GET("/example", func(c context.Context, ctx *app.RequestContext) {
ctx.Request.Header.Set("hertz1", "value1")
header := ctx.Request.Header.String()
// header == "GET /example HTTP/1.1
//User-Agent: PostmanRuntime-ApipostRuntime/1.1.0
//Host: localhost:8888
//Cache-Control: no-cache
//Accept: */*
//Accept-Encoding: gzip, deflate, br
//Connection: keep-alive
//Hertz1: value1"
})
遍历 Header
遍历所有 Header 的键值并执行 f 函数。
函数签名:
func (h *RequestHeader) VisitAll(f func(key, value []byte))
示例:
hertz.GET("/example", func(c context.Context, ctx *app.RequestContext) {
ctx.Request.Header.Add("Hertz1", "value1")
ctx.Request.Header.Add("Hertz1", "value2")
var hertzString []string
ctx.Request.Header.VisitAll(func(key, value []byte) {
if string(key) == "Hertz1" {
hertzString = append(hertzString, string(value))
}
})
// hertzString == []string{"value1", "value2"}
})
Method
获取请求方法的类型。
函数签名:
func (ctx *RequestContext) Method() []byte
示例:
// POST http://example.com/user
h.Any("/user", func(c context.Context, ctx *app.RequestContext) {
method := ctx.Method() // method == []byte("POST")
})
ContentType
获取请求头 Content-Type
的值。
函数签名:
func (ctx *RequestContext) ContentType() []byte
示例:
// POST http://example.com/user
// Content-Type: application/json
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {
contentType := ctx.ContentType() // contentType == []byte("application/json")
})
IfModifiedSince
判断时间是否超过请求头 If-Modified-Since
的值。
注意:如果请求头不包含 If-Modified-Since 也返回 true。
函数签名:
func (ctx *RequestContext) IfModifiedSince(lastModified time.Time) bool
示例:
// POST http://example.com/user
// If-Modified-Since: Wed, 21 Oct 2023 07:28:00 GMT
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {
t2022, _ := time.Parse(time.RFC1123, "Wed, 21 Oct 2022 07:28:00 GMT")
ifModifiedSince := ctx.IfModifiedSince(t2022) // ifModifiedSince == false
t2024, _ := time.Parse(time.RFC1123, "Wed, 21 Oct 2024 07:28:00 GMT")
ifModifiedSince = ctx.IfModifiedSince(t2024) // ifModifiedSince == true
})
Cookie
获取请求头 Cookie
中 key 的值。
函数签名:
func (ctx *RequestContext) Cookie(key string) []byte
示例:
// POST http://example.com/user
// Cookie: foo_cookie=choco; bar_cookie=strawberry
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {
fCookie := ctx.Cookie("foo_cookie") // fCookie == []byte("choco")
bCookie := ctx.Cookie("bar_cookie") // bCookie == []byte("strawberry")
noneCookie := ctx.Cookie("none_cookie") // noneCookie == nil
})
UserAgent
获取请求头 User-Agent
的值。
函数签名:
func (ctx *RequestContext) UserAgent() []byte
示例:
// POST http://example.com/user
// User-Agent: Chrome/51.0.2704.103 Safari/537.36
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {
ua := ctx.UserAgent() // ua == []byte("Chrome/51.0.2704.103 Safari/537.36")
})
GetHeader
获取请求头中 key 的值。
函数签名:
func (ctx *RequestContext) GetHeader(key string) []byte
示例:
// POST http://example.com/user
// Say-Hello: hello
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {
customHeader := ctx.GetHeader("Say-Hello") // customHeader == []byte("hello")
})
RequestHeader 对象
使用 RequestContext.Request.Header
获取 RequestHeader 对象,该对象提供了以下方法获取/设置请求头部。
函数签名 | 说明 |
---|---|
func (h *RequestHeader) Method() []byte |
获取 Method |
func (h *RequestHeader) SetMethod(method string) |
设置 Method |
func (h *RequestHeader) SetMethodBytes(method []byte) |
设置 []byte 类型的 Method |
func (h *RequestHeader) IsGet() bool |
判断 Method 是否是 GET |
func (h *RequestHeader) IsHead() bool |
判断 Method 是否是 HEAD |
func (h *RequestHeader) IsPost() bool |
判断 Method 是否是 POST |
func (h *RequestHeader) IsPut() bool |
判断 Method 是否是 PUT |
func (h *RequestHeader) IsDelete() bool |
判断 Method 是否是 DELETE |
func (h *RequestHeader) IsConnect() bool |
判断 Method 是否是 CONNECT |
func (h *RequestHeader) IsOptions() bool |
判断 Method 是否是 OPTIONS |
func (h *RequestHeader) IsTrace() bool |
判断 Method 是否是 TRACE |
func (h *RequestHeader) IgnoreBody() bool |
判断是否忽略 Body (Method GET/HEAD 忽略 Body) |
func (h *RequestHeader) RequestURI() []byte |
获取 RequestURI |
func (h *RequestHeader) SetRequestURI(requestURI string) |
设置 RequestURI |
func (h *RequestHeader) SetRequestURIBytes(requestURI []byte) |
设置 []byte 类型的 RequestURI |
func (h *RequestHeader) SetProtocol(p string) |
设置协议类型,比如 HTTP/1.0 |
func (h *RequestHeader) GetProtocol() string |
获取协议类型,比如 HTTP/1.1 |
func (h *RequestHeader) IsHTTP11() bool |
判断是否是 HTTP/1.1 |
func (h *RequestHeader) SetNoHTTP11(b bool) |
设置是否不是 HTTP/1.1 |
func (h *RequestHeader) Host() []byte |
获取 Host |
func (h *RequestHeader) SetHost(host string) |
设置 Host |
func (h *RequestHeader) SetHostBytes(host []byte) |
设置 []byte 类型的 Host |
func (h *RequestHeader) ContentLength() int |
获取 Content-Length |
func (h *RequestHeader) ContentLengthBytes() []byte |
获取 []byte 类型的 Content-Length |
func (h *RequestHeader) SetContentLength(contentLength int) |
设置 Content-Length |
func (h *RequestHeader) SetContentLengthBytes(contentLength []byte) |
设置 []byte 类型的 Content-Length |
func (h *RequestHeader) InitContentLengthWithValue(contentLength int) |
初始化 Content-Length |
func (h *RequestHeader) ContentType() []byte |
获取 Content-Type |
func (h *RequestHeader) SetContentTypeBytes(contentType []byte) |
设置 Content-Type |
func (h *RequestHeader) SetNoDefaultContentType(b bool) |
控制未指定 Content-Type 时的默认发送行为,false 发送默认 Content-Type 的值,true 不发送 Content-Type |
func (h *RequestHeader) UserAgent() []byte |
获取 User-Agent |
func (h *RequestHeader) SetUserAgentBytes(userAgent []byte) |
设置 User-Agent |
func (h *RequestHeader) ConnectionClose() bool |
判断是否包含 Connection: close |
func (h *RequestHeader) SetConnectionClose(close bool) |
设置 connectionClose 标志 |
func (h *RequestHeader) ResetConnectionClose() |
重置 connectionClose 标志为 false 并删除 Connection Header |
func (h *RequestHeader) SetByteRange(startPos, endPos int) |
设置 Range (Range: bytes=startPos-endPos) |
func (h *RequestHeader) SetMultipartFormBoundary(boundary string) |
当 Content-Type=multipart/form-data 时为其设置 boundary |
func (h *RequestHeader) MultipartFormBoundary() []byte |
获取 boundary 的值 |
func (h *RequestHeader) Trailer() *Trailer |
获取 Trailer |
func (h *RequestHeader) Cookie(key string) []byte |
获取 Cookie 键为 key 的值 |
func (h *RequestHeader) SetCookie(key, value string) |
设置 Cookie 的键值 |
func (h *RequestHeader) DelCookie(key string) |
删除键为 key 的 Cookie |
func (h *RequestHeader) DelAllCookies() |
删除所有 Cookie |
func (h *RequestHeader) FullCookie() []byte |
获取所有 Cookie |
func (h *RequestHeader) Cookies() []*Cookie |
获取所有 Cookie 对象 |
func (h *RequestHeader) VisitAllCookie(f func(key, value []byte)) |
遍历所有 Cookie 的键值并执行 f 函数 |
func (h *RequestHeader) Peek(key string) []byte |
获取 []byte 类型的键为 key 的值 |
func (h *RequestHeader) Get(key string) string |
获取键为 key 的值 |
func (h *RequestHeader) PeekArgBytes(key []byte) []byte |
获取键为 key 的值 |
func (h *RequestHeader) PeekAll(key string) [][]byte |
获取 []byte 类型的键为 key 的所有值(用于获取存在相同 key 的多个值) |
func (h *RequestHeader) GetAll(key string) []string |
获取键为 key 的所有值 |
func (h *RequestHeader) PeekIfModifiedSinceBytes() []byte |
获取 If-Modified-Since |
func (h *RequestHeader) PeekContentEncoding() []byte |
获取 Content-Encoding |
func (h *RequestHeader) PeekRange() []byte |
获取 Range |
func (h *RequestHeader) HasAcceptEncodingBytes(acceptEncoding []byte) bool |
判断是否存在 Accept-Encoding 以及 Accept-Encoding 是否包含 acceptEncoding |
func (h *RequestHeader) RawHeaders() []byte |
获取原始 Header |
func (h *RequestHeader) SetRawHeaders(r []byte) |
设置原始 Header |
func (h *RequestHeader) Add(key, value string) |
添加或设置键为 key 的 Header,用于为同一个 Key 设置多个 Header,但 key 会覆盖以下 Header: Content-Type, Content-Length, Connection, Cookie, Transfer-Encoding, Host, User-Agent |
func (h *RequestHeader) InitBufValue(size int) |
初始化缓冲区大小 |
func (h *RequestHeader) GetBufValue() []byte |
获取缓冲区的值 |
func (h *RequestHeader) SetCanonical(key, value []byte) |
设置 Header 键值,假设该键是规范形式 |
func (h *RequestHeader) Set(key, value string) |
设置 Header 键值,用于为同一个 Key 设置单个 Header |
func (h *RequestHeader) SetBytesKV(key, value []byte) |
设置 []byte 类型的 Header 键值,用于为同一个 Key 设置单个 Header |
func (h *RequestHeader) DelBytes(key []byte) |
删除 Header 中键为 key 的键值对 |
func (h *RequestHeader) AddArgBytes(key, value []byte, noValue bool) |
添加 Header 键值(与 Add 不同,key 一定不会被规范化且 key 为 Content-Type, Content-Length, Connection, Cookie, Transfer-Encoding, Host, User-Agent 时不会做特殊处理) |
func (h *RequestHeader) SetArgBytes(key, value []byte, noValue bool) |
设置 Header 键值(与 Set 不同,key 一定不会被规范化且 key 为 Content-Type, Content-Length, Connection, Cookie, Transfer-Encoding, Host, User-Agent 时不会做特殊处理) |
func (h *RequestHeader) AppendBytes(dst []byte) []byte |
将完整的 Header 附加到 dst 中并返回 |
func (h *RequestHeader) Header() []byte |
获取 []byte 类型的完整的 Header |
func (h *RequestHeader) String() string |
获取完整的 Header |
func (h *RequestHeader) CopyTo(dst *RequestHeader) |
获取 RequestHeader 的副本 |
func (h *RequestHeader) VisitAll(f func(key, value []byte)) |
遍历所有 Header 的键值并执行 f 函数 |
func (h *RequestHeader) VisitAllCustomHeader(f func(key, value []byte)) |
遍历所有 Header 的键值并执行 f 函数,以下 key 除外:Content-Type, Content-Length, Cookie, Host, User-Agent) |
func (h *RequestHeader) Len() int |
返回 Header 的数量 |
func (h *RequestHeader) DisableNormalizing() |
禁用 Header 名字的规范化 (首字母和破折号后第一个字母大写) |
func (h *RequestHeader) IsDisableNormalizing() bool |
是否禁用 Header 名字的规范化,默认不禁用 |
func (h *RequestHeader) ResetSkipNormalize() |
重置 Headers,除了 disableNormalizing 状态 |
func (h *RequestHeader) Reset() |
重置 Headers |
Body
func (ctx *RequestContext) GetRawData() []byte
func (ctx *RequestContext) Body() ([]byte, error)
func (ctx *RequestContext) RequestBodyStream() io.Reader
func (ctx *RequestContext) MultipartForm() (*multipart.Form, error)
func (ctx *RequestContext) PostForm(key string) string
func (ctx *RequestContext) DefaultPostForm(key, defaultValue string) string
func (ctx *RequestContext) GetPostForm(key string) (string, bool)
func (ctx *RequestContext) PostArgs() *protocol.Args
func (ctx *RequestContext) FormValue(key string) []byte
func (ctx *RequestContext) SetFormValueFunc(f FormValueFunc)
Body
获取请求的 body 数据,如果发生错误返回 error。
函数签名:
func (ctx *RequestContext) Body() ([]byte, error)
示例:
// POST http://example.com/pet
// Content-Type: application/json
// {"pet":"cat"}
h.Post("/pet", func(c context.Context, ctx *app.RequestContext) {
data, err := ctx.Body() // data == []byte("{\"pet\":\"cat\"}") , err == nil
})
RequestBodyStream
获取请求的 BodyStream。
函数签名:
func (ctx *RequestContext) RequestBodyStream() io.Reader
示例:
// POST http://example.com/user
// Content-Type: text/plain
// abcdefg
h := server.Default(server.WithStreamBody(true))
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {
sr := ctx.RequestBodyStream()
data, _ := io.ReadAll(sr) // data == []byte("abcdefg")
})
MultipartForm
获取 multipart.Form
对象,(详情请参考 multipart#Form)
注意:此函数既可以获取普通值也可以获取文件,此处给出了获取普通值的示例代码,获取文件的示例代码可参考 MultipartForm。
函数签名:
func (ctx *RequestContext) MultipartForm() (*multipart.Form, error)
示例:
// POST http://example.com/user
// Content-Type: multipart/form-data;
// Content-Disposition: form-data; name="name"
// tom
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
form, err := ctx.MultipartForm()
name := form.Value["name"][0] // name == "tom"
})
PostForm
按名称检索 multipart.Form.Value
,返回给定 name 的第一个值。
注意:该函数支持从 application/x-www-form-urlencoded 和 multipart/form-data 这两种类型的 content-type 中获取 value 值,且不支持获取文件值。
函数签名:
func (ctx *RequestContext) PostForm(key string) string
示例:
// POST http://example.com/user
// Content-Type: multipart/form-data;
// Content-Disposition: form-data; name="name"
// tom
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
name := ctx.PostForm("name") // name == "tom"
})
DefaultPostForm
按名称检索 multipart.Form.Value
,返回给定 name 的第一个值,如果不存在返回 defaultValue。
注意:该函数支持从 application/x-www-form-urlencoded 和 multipart/form-data 这两种类型的 content-type 中获取 value 值,且不支持获取文件值。
函数签名:
func (ctx *RequestContext) DefaultPostForm(key, defaultValue string) string
示例:
// POST http://example.com/user
// Content-Type: multipart/form-data;
// Content-Disposition: form-data; name="name"
// tom
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
name := ctx.PostForm("name", "jack") // name == "tom"
age := ctx.PostForm("age", "10") // age == "10"
})
PostArgs
获取 application/x-www-form-urlencoded
参数对象。(详情请参考 Args 对象)
函数签名:
func (ctx *RequestContext) PostArgs() *protocol.Args
示例:
// POST http://example.com/user
// Content-Type: application/x-www-form-urlencoded
// name=tom&pet=cat&pet=dog
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
args := ctx.PostArgs()
name := args.Peek("name") // name == "tom"
var pets []string
args.VisitAll(func(key, value []byte) {
if string(key) == "pet" {
pets = append(pets, string(value))
}
})
// pets == []string{"cat", "dog"}
})
FormValue
按照以下顺序获取 key 的值。
- 从 QueryArgs 中获取值。
- 从 PostArgs 中获取值。
- 从 MultipartForm 中获取值。
函数签名:
func (ctx *RequestContext) FormValue(key string) []byte
示例:
// POST http://example.com/user?name=tom
// Content-Type: application/x-www-form-urlencoded
// age=10
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
name := ctx.FormValue("name") // name == []byte("tom"), get by QueryArgs
age := ctx.FormValue("age") // age == []byte("10"), get by PostArgs
})
// POST http://example.com/user
// Content-Type: multipart/form-data;
// Content-Disposition: form-data; name="name"
// tom
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
name := ctx.FormValue("name") // name == []byte("tom"), get by MultipartForm
})
SetFormValueFunc
若 FormValue 函数提供的默认获取 key 的值的方式不满足需求,用户可以使用该函数自定义获取 key 的值的方式。
函数签名:
func (ctx *RequestContext) SetFormValueFunc(f FormValueFunc)
示例:
// POST http://example.com/user?name=tom
// Content-Type: multipart/form-data;
// Content-Disposition: form-data; name="age"
// 10
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
// only return multipart form value
ctx.SetFormValueFunc(func(rc *app.RequestContext, s string) []byte {
mf, err := rc.MultipartForm()
if err == nil && mf.Value != nil {
vv := mf.Value[s]
if len(vv) > 0 {
return []byte(vv[0])
}
}
return nil
})
name := ctx.FormValue("name") // name == nil
age := ctx.FormValue("age") // age == []byte("10")
})
文件操作
func (ctx *RequestContext) MultipartForm() (*multipart.Form, error)
func (ctx *RequestContext) FormFile(name string) (*multipart.FileHeader, error)
func (ctx *RequestContext) SaveUploadedFile(file *multipart.FileHeader, dst string) error
MultipartForm
获取 multipart.Form
对象。(详情请参考 multipart#Form)
注意:此函数既可以获取普通值也可以获取文件,此处给出了获取文件值的示例代码,获取普通值的示例代码可参考 MultipartForm。
函数签名:
func (ctx *RequestContext) MultipartForm() (*multipart.Form, error)
示例:
// POST http://example.com/user
// Content-Type: multipart/form-data;
// Content-Disposition: form-data; name="avatar"; filename="abc.jpg"
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
form, err := ctx.MultipartForm()
avatarFile := form.File["avatar"][0] // avatarFile.Filename == "abc.jpg"
})
FormFile
按名称检索 multipart.Form.File
,返回给定 name 的第一个 multipart.FileHeader
。(详情请参考 multipart#FileHeader)
函数签名:
func (ctx *RequestContext) FormFile(name string) (*multipart.FileHeader, error)
示例:
// POST http://example.com/user
// Content-Type: multipart/form-data;
// Content-Disposition: form-data; name="avatar"; filename="abc.jpg"
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {
avatarFile, err := ctx.FormFile("avatar") // avatarFile.Filename == "abc.jpg", err == nil
})
SaveUploadedFile
保存 multipart 文件到磁盘。
函数签名:
func (ctx *RequestContext) SaveUploadedFile(file *multipart.FileHeader, dst string) error
示例:
// POST http://example.com/user
// Content-Type: multipart/form-data;
// Content-Disposition: form-data; name="avatar"; filename="abc.jpg"
h.Post("/user", func(c context.Context, ctx *app.RequestContext) {
avatarFile, err := ctx.FormFile("avatar") // avatarFile.Filename == "abc.jpg", err == nil
// save file
ctx.SaveUploadedFile(avatarFile, avatarFile.Filename) // save file "abc.jpg"
})
RequestContext 元数据存储
注意:RequestContext 在请求结束后会被回收,元数据会被置为 nil。如需异步使用,请使用 Copy 方法。
函数签名 | 说明 |
---|---|
func (ctx *RequestContext) Set(key string, value interface{}) |
在上下文中存储键值对 |
func (ctx *RequestContext) Value(key interface{}) interface{} |
获取上下文键为 key 的值 |
func (ctx *RequestContext) Get(key string) (value interface{}, exists bool) |
获取上下文键为 key 的值以及 key 是否存在 |
func (ctx *RequestContext) MustGet(key string) interface{} |
获取上下文键为 key 的值,如果不存在会发生 panic |
func (ctx *RequestContext) GetString(key string) (s string) |
获取上下文键为 key 的值,并转换为 string 类型 |
func (ctx *RequestContext) GetBool(key string) (b bool) |
获取上下文键为 key 的值,并转换为 bool 类型 |
func (ctx *RequestContext) GetInt(key string) (i int) |
获取上下文键为 key 的值,并转换为 int 类型 |
func (ctx *RequestContext) GetInt32(key string) (i32 int32) |
获取上下文键为 key 的值,并转换为 int32 类型 |
func (ctx *RequestContext) GetInt64(key string) (i64 int64) |
获取上下文键为 key 的值,并转换为 int64 类型 |
func (ctx *RequestContext) GetUint(key string) (ui uint) |
获取上下文键为 key 的值,并转换为 uint 类型 |
func (ctx *RequestContext) GetUint32(key string) (ui32 uint32) |
获取上下文键为 key 的值,并转换为 uint32 类型 |
func (ctx *RequestContext) GetUint64(key string) (ui64 uint64) |
获取上下文键为 key 的值,并转换为 uint64 类型 |
func (ctx *RequestContext) GetFloat32(key string) (f32 float32) |
获取上下文键为 key 的值,并转换为 float32 类型 |
func (ctx *RequestContext) GetFloat64(key string) (f64 float64) |
获取上下文键为 key 的值,并转换为 float64 类型 |
func (ctx *RequestContext) GetTime(key string) (t time.Time) |
获取上下文键为 key 的值,并转换为 time.Time 类型 |
func (ctx *RequestContext) GetDuration(key string) (d time.Duration) |
获取上下文键为 key 的值,并转换为 time.Duration 类型 |
func (ctx *RequestContext) GetStringSlice(key string) (ss []string) |
获取上下文键为 key 的值,并转换为 []string 类型 |
func (ctx *RequestContext) GetStringMap(key string) (sm map[string]interface{}) |
获取上下文键为 key 的值,并转换为 map[string]interface{} 类型 |
func (ctx *RequestContext) GetStringMapString(key string) (sms map[string]string) |
获取上下文键为 key 的值,并转换为 map[string]string 类型 |
func (ctx *RequestContext) GetStringMapStringSlice(key string) (smss map[string][]string) |
获取上下文键为 key 的值,并转换为 map[string][]string 类型 |
func (ctx *RequestContext) ForEachKey(fn func(k string, v interface{})) |
为上下文中的每个键值对调用 fn |
示例:
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
ctx.Set("version1", "v1")
v := ctx.Value("version1") // v == interface{}(string) "v1"
ctx.Set("version2", "v2")
v, exists := ctx.Get("version2") // v == interface{}(string) "v2", exists == true
v, exists = ctx.Get("pet") // v == interface{} nil, exists == false
ctx.Set("version3", "v3")
v := ctx.MustGet("version3") // v == interface{}(string) "v3"
ctx.Set("version4", "v4")
vString := ctx.GetString("version4") // vString == "v4"
ctx.Set("isAdmin", true)
vBool := ctx.GetBool("isAdmin") // vBool == true
ctx.Set("age1", 20)
vInt := ctx.GetInt("age1") // vInt == 20
ctx.Set("age2", int32(20))
vInt32 := ctx.GetInt32("age2") // vInt32 == 20
ctx.Set("age3", int64(20))
vInt64 := ctx.GetInt64("age3") // vInt64 == 20
ctx.Set("age4", uint(20))
vUInt := ctx.GetUint("age4") // vUInt == 20
ctx.Set("age5", uint32(20))
vUInt32 := ctx.GetUint32("age5") // vUInt32 == 20
ctx.Set("age6", uint64(20))
vUInt64 := ctx.GetUint64("age6") // vUInt64 == 20
ctx.Set("age7", float32(20.1))
vFloat32 := ctx.GetFloat32("age7") // vFloat32 == 20.1
ctx.Set("age8", 20.1)
vFloat64 := ctx.GetFloat64("age8") // vFloat64 == 20.1
t2022, _ := time.Parse(time.RFC1123, "Wed, 21 Oct 2022 07:28:00 GMT")
ctx.Set("birthday", t2022)
vTime := ctx.GetTime("birthday") // vTime == t2022
ctx.Set("duration", time.Minute)
vDuration := ctx.GetDuration("duration") // vDuration == time.Minute
ctx.Set("pet", []string{"cat", "dog"})
vStringSlice := ctx.GetStringSlice("pet") // vStringSlice == []string{"cat", "dog"}
ctx.Set("info1", map[string]interface{}{"name": "tom"})
vStringMap := ctx.GetStringMap("info1") // vStringMap == map[string]interface{}{"name": "tom"}
ctx.Set("info2", map[string]string{"name": "tom"})
vStringMapString := ctx.GetStringMapString("info2")
// vStringMapString == map[string]string{}{"name": "tom"}
ctx.Set("smss", map[string][]string{"pets": {"cat", "dog"}})
vStringMapStringSlice := ctx.GetStringMapStringSlice("smss")
// vStringMapStringSlice == map[string][]string{"pets": {"cat", "dog"}}
ctx.Set("duration", time.Minute)
ctx.Set("version", "v1")
ctx.ForEachKey(func(k string, v interface{}) {
// 1. k == "duration", v == interface{}(time.Duration) time.Minute
// 2. k == "version", v == interface{}(string) "v1"
})
})
Handler
func (ctx *RequestContext) Next(c context.Context)
func (ctx *RequestContext) Handlers() HandlersChain
func (ctx *RequestContext) Handler() HandlerFunc
func (ctx *RequestContext) SetHandlers(hc HandlersChain)
func (ctx *RequestContext) HandlerName() string
func (ctx *RequestContext) GetIndex() int8
func (ctx *RequestContext) Abort()
func (ctx *RequestContext) IsAborted() bool
Next
执行下一个 handler,该函数通常用于中间件 handler 中。
函数签名:
func (ctx *RequestContext) Next(c context.Context)
示例:
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
ctx.Next(c)
v := ctx.GetString("version") // v == "v1"
}, func(c context.Context, ctx *app.RequestContext) {
ctx.Set("version", "v1")
})
Handlers
获取 handlers chain。
函数签名:
func (ctx *RequestContext) Handlers() HandlersChain
示例:
middleware1 := func(c context.Context, ctx *app.RequestContext) {
}
handler1 := func(c context.Context, ctx *app.RequestContext) {
handlers := ctx.Handlers() // []Handler{middleware1, handler1}
}
h.POST("/user", middleware1, handler1)
Handler
获取 handlers chain 的最后一个 handler,一般来说,最后一个 handler 是 main handler。
函数签名:
func (ctx *RequestContext) Handler() HandlerFunc
示例:
middleware1 := func(c context.Context, ctx *app.RequestContext) {
lastHandler := ctx.Handler() // lastHandler == handler1
}
handler1 := func(c context.Context, ctx *app.RequestContext) {
}
h.POST("/user", middleware1, handler1)
SetHandlers
设置 handlers chain。
函数签名:
func (ctx *RequestContext) SetHandlers(hc HandlersChain)
示例:
handler1 := func(c context.Context, ctx *app.RequestContext) {
ctx.Set("current", "handler1")
}
handler := func(c context.Context, ctx *app.RequestContext) {
hc := app.HandlersChain{ctx.Handlers()[0], handler1} // append handler1 into handlers chain
ctx.SetHandlers(hc)
ctx.Next(c)
current := ctx.GetString("current") // current == "handler1"
ctx.String(consts.StatusOK, current)
}
h.POST("/user", handler)
HandlerName
获取最后一个 handler 的函数名称。
函数签名:
func (ctx *RequestContext) HandlerName() string
示例:
package main
func main() {
h := server.New()
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
hn := ctx.HandlerName() // hn == "main.main.func1"
})
}
GetIndex
获取当前执行的 handler 在 handlers chain 中的 index。
函数签名:
func (ctx *RequestContext) GetIndex() int8
示例:
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
index := ctx.GetIndex() // index == 0
}, func(c context.Context, ctx *app.RequestContext) {
index := ctx.GetIndex() // index == 1
})
Abort
终止后续的 handler 执行。
函数签名:
func (ctx *RequestContext) Abort()
示例:
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
ctx.Abort()
}, func(c context.Context, ctx *app.RequestContext) {
// will not execute
})
IsAborted
获取后续的 handler 执行状态是否被终止。
函数签名:
func (ctx *RequestContext) IsAborted() bool
示例:
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
ctx.Abort()
isAborted := ctx.IsAborted() // isAborted == true
}, func(c context.Context, ctx *app.RequestContext) {
// will not execute
})
参数绑定与校验
(更多内容请参考 binding-and-validate)
func (ctx *RequestContext) Bind(obj interface{}) error
func (ctx *RequestContext) Validate(obj interface{}) error
func (ctx *RequestContext) BindAndValidate(obj interface{}) error
获取 ClientIP
func (ctx *RequestContext) ClientIP() string
func (ctx *RequestContext) SetClientIPFunc(f ClientIP)
ClientIP
获取客户端 IP 的地址。
该函数的默认行为:若 X-Forwarded-For
或 X-Real-IP
Header 中存在 ip,则从这两个 Header 中读 ip 并返回(优先级 X-Forwarded-For
大于 X-Real-IP
),否则返回 remote address。
函数签名:
func (ctx *RequestContext) ClientIP() string
示例:
// X-Forwarded-For: 20.20.20.20, 30.30.30.30
// X-Real-IP: 10.10.10.10
h.Use(func(c context.Context, ctx *app.RequestContext) {
ip := ctx.ClientIP() // 20.20.20.20
})
SetClientIPFunc
若 ClientIP 函数提供的默认方式不满足需求,用户可以使用该函数自定义获取客户端 ip 的方式。
用户可以自己实现自定义函数,也可以通过设置 app.ClientIPOptions
实现。
注意:在设置
app.ClientIPOptions
时,TrustedCIDRs
需用户自定义(若不设置则固定返回 remote address),代表可信任的路由。若 remote address 位于可信任的路由范围内,则会选择从RemoteIPHeaders
中获取 ip,否则返回 remote address。
函数签名:
func (ctx *RequestContext) SetClientIPFunc(f ClientIP)
示例:
// POST http://example.com/user
// X-Forwarded-For: 30.30.30.30
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
// method 1
customClientIPFunc := func(ctx *app.RequestContext) string {
return "127.0.0.1"
}
ctx.SetClientIPFunc(customClientIPFunc)
ip := ctx.ClientIP() // ip == "127.0.0.1"
// method 2
_, cidr, _ := net.ParseCIDR("127.0.0.1/32")
opts := app.ClientIPOptions{
RemoteIPHeaders: []string{"X-Forwarded-For", "X-Real-IP"},
TrustedCIDRs: []*net.IPNet{cidr},
}
ctx.SetClientIPFunc(app.ClientIPWithOption(opts))
ip = ctx.ClientIP() // ip == "30.30.30.30"
})
并发安全
func (ctx *RequestContext) Copy() *RequestContext
Copy
拷贝 RequestContext 副本,提供协程安全的访问方式。
函数签名:
func (ctx *RequestContext) Copy() *RequestContext
示例:
h.POST("/user", func(c context.Context, ctx *app.RequestContext) {
ctx1 := ctx.Copy()
go func(context *app.RequestContext) {
// safely
}(ctx1)
})