From ea6052464e7221956dedf9b9a523f8f9892c3d3b Mon Sep 17 00:00:00 2001 From: Aoang Date: Sun, 14 Aug 2022 17:31:57 +0800 Subject: [PATCH] Add Go 1.19 Support (#1355) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update Go Version to Go1.19.x And add cache * Fix CI Line endings * Update test CI Go Version to Go1.19.x And add cache * Update Gosec Security Scanner CI to securego/gosec@v2.12.0 * Format comment Go 1.19 adds support for links, lists, and clearer headings in doc comments. As part of this change, gofmt now reformats doc comments to make their rendered meaning clearer. See “Go Doc Comments” for syntax details and descriptions of common mistakes now highlighted by gofmt. As another part of this change, the new package go/doc/comment provides parsing and reformatting of doc comments as well as support for rendering them to HTML, Markdown, and text. ref: https://tip.golang.org/doc/go1.19 ref: https://tip.golang.org/doc/comment * Fix doc structure --- .github/workflows/lint.yml | 40 ++++++++++++--- .github/workflows/security.yml | 16 ++---- .github/workflows/test.yml | 19 +++++++- brotli.go | 16 +++--- client.go | 2 +- compress.go | 40 +++++++-------- doc.go | 78 +++++++++++++++++------------ fasthttpadaptor/adaptor.go | 20 ++++---- fasthttpproxy/http.go | 2 + fasthttpproxy/proxy_env.go | 2 + fasthttpproxy/socks5.go | 1 + fasthttputil/pipeconns.go | 8 +-- fs.go | 31 ++++++------ header.go | 68 +++++++++++++------------- http.go | 62 +++++++++++------------ reuseport/reuseport.go | 4 +- server.go | 89 ++++++++++++++++------------------ stackless/func.go | 6 +-- tcpdialer.go | 88 ++++++++++++++++----------------- uri.go | 38 +++++++-------- 20 files changed, 342 insertions(+), 288 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6c2c7b0546..9e08c44f84 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -9,14 +9,40 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v3 with: - go-version: 1.18.x + go-version: 1.19.x + + - name: Get Go cache paths + id: go-env + run: | + echo "::set-output name=cache::$(go env GOCACHE)" + echo "::set-output name=modcache::$(go env GOMODCACHE)" + - name: Set up Go cache + uses: actions/cache@v3 + with: + key: golangci-lint-${{ runner.os }}-go-${{ hashFiles('go.mod') }} + restore-keys: golangci-lint-${{ runner.os }}-go- + path: | + ${{ steps.go-env.outputs.cache }} + ${{ steps.go-env.outputs.modcache }} + + - name: Install golangci-lint + run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.48.0 + + - name: Get golangci-lint cache path + id: golangci-lint-cache-status + run: | + echo "::set-output name=dir::$(golangci-lint cache status | head -1 | sed 's/^Dir: //')" + + - name: Set up golangci-lint cache + uses: actions/cache@v3 + with: + key: golangci-lint-${{ runner.os }}-golangci-lint-${{ hashFiles('go.mod') }} + restore-keys: golangci-lint-${{ runner.os }}-golangci-lint- + path: ${{ steps.golangci-lint-cache-status.outputs.dir }} + - run: go version - run: diff -u <(echo -n) <(gofmt -d .) - name: Run golangci-lint - run: | # https://github.com/golangci/golangci-lint/pull/2438 - export PATH=$PATH:$(go env GOPATH)/bin - go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.44.2 - golangci-lint run - + run: golangci-lint run diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 07c61ed57e..cad76439b0 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -8,20 +8,14 @@ jobs: test: strategy: matrix: - go-version: [1.18.x] + go-version: [1.19.x] platform: [ubuntu-latest] runs-on: ${{ matrix.platform }} env: GO111MODULE: on steps: - - name: Install Go - uses: actions/setup-go@v1 - with: - go-version: ${{ matrix.go-version }} - - name: Checkout code - uses: actions/checkout@v2 + - uses: actions/checkout@v2 - name: Run Gosec Security Scanner - run: | # https://github.com/securego/gosec/issues/469#issuecomment-1070608395 - export PATH=$PATH:$(go env GOPATH)/bin - go install github.com/securego/gosec/v2/cmd/gosec@latest - gosec -exclude=G104,G304,G402 ./... + uses: securego/gosec@v2.12.0 + with: + args: '-exclude=G104,G304,G402 ./...' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 429c155418..73af78bfff 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,14 +8,29 @@ jobs: test: strategy: matrix: - go-version: [1.15.x, 1.16.x, 1.17.x, 1.18.x] + go-version: [1.15.x, 1.16.x, 1.17.x, 1.18.x, 1.19.x] os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v3 with: go-version: ${{ matrix.go-version }} + + - name: Get Go cache paths + id: go-env + run: | + echo "::set-output name=cache::$(go env GOCACHE)" + echo "::set-output name=modcache::$(go env GOMODCACHE)" + - name: Set up Go cache + uses: actions/cache@v3 + with: + key: golangci-lint-${{ runner.os }}-go-${{ hashFiles('go.mod') }} + restore-keys: golangci-lint-${{ runner.os }}-go- + path: | + ${{ steps.go-env.outputs.cache }} + ${{ steps.go-env.outputs.modcache }} + - run: go version - run: go test ./... - run: go test -race ./... diff --git a/brotli.go b/brotli.go index 41e9609287..815e4b35f1 100644 --- a/brotli.go +++ b/brotli.go @@ -92,10 +92,10 @@ var ( // // Supported compression levels are: // -// * CompressBrotliNoCompression -// * CompressBrotliBestSpeed -// * CompressBrotliBestCompression -// * CompressBrotliDefaultCompression +// - CompressBrotliNoCompression +// - CompressBrotliBestSpeed +// - CompressBrotliBestCompression +// - CompressBrotliDefaultCompression func AppendBrotliBytesLevel(dst, src []byte, level int) []byte { w := &byteSliceWriter{dst} WriteBrotliLevel(w, src, level) //nolint:errcheck @@ -107,10 +107,10 @@ func AppendBrotliBytesLevel(dst, src []byte, level int) []byte { // // Supported compression levels are: // -// * CompressBrotliNoCompression -// * CompressBrotliBestSpeed -// * CompressBrotliBestCompression -// * CompressBrotliDefaultCompression +// - CompressBrotliNoCompression +// - CompressBrotliBestSpeed +// - CompressBrotliBestCompression +// - CompressBrotliDefaultCompression func WriteBrotliLevel(w io.Writer, p []byte, level int) (int, error) { switch w.(type) { case *byteSliceWriter, diff --git a/client.go b/client.go index 8cf1eccfe9..a45b8eb72a 100644 --- a/client.go +++ b/client.go @@ -1467,7 +1467,7 @@ func (e *timeoutError) Error() string { // Only implement the Timeout() function of the net.Error interface. // This allows for checks like: // -// if x, ok := err.(interface{ Timeout() bool }); ok && x.Timeout() { +// if x, ok := err.(interface{ Timeout() bool }); ok && x.Timeout() { func (e *timeoutError) Timeout() bool { return true } diff --git a/compress.go b/compress.go index 803d7cc513..49fbf3c22e 100644 --- a/compress.go +++ b/compress.go @@ -127,11 +127,11 @@ var ( // // Supported compression levels are: // -// * CompressNoCompression -// * CompressBestSpeed -// * CompressBestCompression -// * CompressDefaultCompression -// * CompressHuffmanOnly +// - CompressNoCompression +// - CompressBestSpeed +// - CompressBestCompression +// - CompressDefaultCompression +// - CompressHuffmanOnly func AppendGzipBytesLevel(dst, src []byte, level int) []byte { w := &byteSliceWriter{dst} WriteGzipLevel(w, src, level) //nolint:errcheck @@ -143,11 +143,11 @@ func AppendGzipBytesLevel(dst, src []byte, level int) []byte { // // Supported compression levels are: // -// * CompressNoCompression -// * CompressBestSpeed -// * CompressBestCompression -// * CompressDefaultCompression -// * CompressHuffmanOnly +// - CompressNoCompression +// - CompressBestSpeed +// - CompressBestCompression +// - CompressDefaultCompression +// - CompressHuffmanOnly func WriteGzipLevel(w io.Writer, p []byte, level int) (int, error) { switch w.(type) { case *byteSliceWriter, @@ -223,11 +223,11 @@ func AppendGunzipBytes(dst, src []byte) ([]byte, error) { // // Supported compression levels are: // -// * CompressNoCompression -// * CompressBestSpeed -// * CompressBestCompression -// * CompressDefaultCompression -// * CompressHuffmanOnly +// - CompressNoCompression +// - CompressBestSpeed +// - CompressBestCompression +// - CompressDefaultCompression +// - CompressHuffmanOnly func AppendDeflateBytesLevel(dst, src []byte, level int) []byte { w := &byteSliceWriter{dst} WriteDeflateLevel(w, src, level) //nolint:errcheck @@ -239,11 +239,11 @@ func AppendDeflateBytesLevel(dst, src []byte, level int) []byte { // // Supported compression levels are: // -// * CompressNoCompression -// * CompressBestSpeed -// * CompressBestCompression -// * CompressDefaultCompression -// * CompressHuffmanOnly +// - CompressNoCompression +// - CompressBestSpeed +// - CompressBestCompression +// - CompressDefaultCompression +// - CompressHuffmanOnly func WriteDeflateLevel(w io.Writer, p []byte, level int) (int, error) { switch w.(type) { case *byteSliceWriter, diff --git a/doc.go b/doc.go index efcd4a0336..f2bf58d830 100644 --- a/doc.go +++ b/doc.go @@ -3,35 +3,53 @@ Package fasthttp provides fast HTTP server and client API. Fasthttp provides the following features: - * Optimized for speed. Easily handles more than 100K qps and more than 1M - concurrent keep-alive connections on modern hardware. - * Optimized for low memory usage. - * Easy 'Connection: Upgrade' support via RequestCtx.Hijack. - * Server provides the following anti-DoS limits: - - * The number of concurrent connections. - * The number of concurrent connections per client IP. - * The number of requests per connection. - * Request read timeout. - * Response write timeout. - * Maximum request header size. - * Maximum request body size. - * Maximum request execution time. - * Maximum keep-alive connection lifetime. - * Early filtering out non-GET requests. - - * A lot of additional useful info is exposed to request handler: - - * Server and client address. - * Per-request logger. - * Unique request id. - * Request start time. - * Connection start time. - * Request sequence number for the current connection. - - * Client supports automatic retry on idempotent requests' failure. - * Fasthttp API is designed with the ability to extend existing client - and server implementations or to write custom client and server - implementations from scratch. + 1. Optimized for speed. Easily handles more than 100K qps and more than 1M + concurrent keep-alive connections on modern hardware. + + 2. Optimized for low memory usage. + + 3. Easy 'Connection: Upgrade' support via RequestCtx.Hijack. + + 4. Server provides the following anti-DoS limits: + + - The number of concurrent connections. + + - The number of concurrent connections per client IP. + + - The number of requests per connection. + + - Request read timeout. + + - Response write timeout. + + - Maximum request header size. + + - Maximum request body size. + + - Maximum request execution time. + + - Maximum keep-alive connection lifetime. + + - Early filtering out non-GET requests. + + 5. A lot of additional useful info is exposed to request handler: + + - Server and client address. + + - Per-request logger. + + - Unique request id. + + - Request start time. + + - Connection start time. + + - Request sequence number for the current connection. + + 6. Client supports automatic retry on idempotent requests' failure. + + 7. Fasthttp API is designed with the ability to extend existing client + and server implementations or to write custom client and server + implementations from scratch. */ package fasthttp diff --git a/fasthttpadaptor/adaptor.go b/fasthttpadaptor/adaptor.go index dc1b47a5e1..a2697207a0 100644 --- a/fasthttpadaptor/adaptor.go +++ b/fasthttpadaptor/adaptor.go @@ -15,11 +15,11 @@ import ( // it has the following drawbacks comparing to using manually written fasthttp // request handler: // -// * A lot of useful functionality provided by fasthttp is missing -// from net/http handler. -// * net/http -> fasthttp handler conversion has some overhead, -// so the returned handler will be always slower than manually written -// fasthttp handler. +// - A lot of useful functionality provided by fasthttp is missing +// from net/http handler. +// - net/http -> fasthttp handler conversion has some overhead, +// so the returned handler will be always slower than manually written +// fasthttp handler. // // So it is advisable using this function only for quick net/http -> fasthttp // switching. Then manually convert net/http handlers to fasthttp handlers @@ -35,11 +35,11 @@ func NewFastHTTPHandlerFunc(h http.HandlerFunc) fasthttp.RequestHandler { // it has the following drawbacks comparing to using manually written fasthttp // request handler: // -// * A lot of useful functionality provided by fasthttp is missing -// from net/http handler. -// * net/http -> fasthttp handler conversion has some overhead, -// so the returned handler will be always slower than manually written -// fasthttp handler. +// - A lot of useful functionality provided by fasthttp is missing +// from net/http handler. +// - net/http -> fasthttp handler conversion has some overhead, +// so the returned handler will be always slower than manually written +// fasthttp handler. // // So it is advisable using this function only for quick net/http -> fasthttp // switching. Then manually convert net/http handlers to fasthttp handlers diff --git a/fasthttpproxy/http.go b/fasthttpproxy/http.go index 2d918135f2..b814a4ccd5 100644 --- a/fasthttpproxy/http.go +++ b/fasthttpproxy/http.go @@ -15,6 +15,7 @@ import ( // the provided HTTP proxy. // // Example usage: +// // c := &fasthttp.Client{ // Dial: fasthttpproxy.FasthttpHTTPDialer("username:password@localhost:9050"), // } @@ -26,6 +27,7 @@ func FasthttpHTTPDialer(proxy string) fasthttp.DialFunc { // the provided HTTP proxy using the given timeout. // // Example usage: +// // c := &fasthttp.Client{ // Dial: fasthttpproxy.FasthttpHTTPDialerTimeout("username:password@localhost:9050", time.Second * 2), // } diff --git a/fasthttpproxy/proxy_env.go b/fasthttpproxy/proxy_env.go index 13e0f7c566..604724260a 100644 --- a/fasthttpproxy/proxy_env.go +++ b/fasthttpproxy/proxy_env.go @@ -24,6 +24,7 @@ const ( // the the env(HTTP_PROXY, HTTPS_PROXY and NO_PROXY) configured HTTP proxy. // // Example usage: +// // c := &fasthttp.Client{ // Dial: FasthttpProxyHTTPDialer(), // } @@ -35,6 +36,7 @@ func FasthttpProxyHTTPDialer() fasthttp.DialFunc { // the env(HTTP_PROXY, HTTPS_PROXY and NO_PROXY) configured HTTP proxy using the given timeout. // // Example usage: +// // c := &fasthttp.Client{ // Dial: FasthttpProxyHTTPDialerTimeout(time.Second * 2), // } diff --git a/fasthttpproxy/socks5.go b/fasthttpproxy/socks5.go index a3348371af..a01c2047f1 100644 --- a/fasthttpproxy/socks5.go +++ b/fasthttpproxy/socks5.go @@ -12,6 +12,7 @@ import ( // the provided SOCKS5 proxy. // // Example usage: +// // c := &fasthttp.Client{ // Dial: fasthttpproxy.FasthttpSocksDialer("socks5://localhost:9050"), // } diff --git a/fasthttputil/pipeconns.go b/fasthttputil/pipeconns.go index c992da30c6..704ec886bc 100644 --- a/fasthttputil/pipeconns.go +++ b/fasthttputil/pipeconns.go @@ -35,10 +35,10 @@ func NewPipeConns() *PipeConns { // PipeConns has the following additional features comparing to connections // returned from net.Pipe(): // -// * It is faster. -// * It buffers Write calls, so there is no need to have concurrent goroutine +// - It is faster. +// - It buffers Write calls, so there is no need to have concurrent goroutine // calling Read in order to unblock each Write call. -// * It supports read and write deadlines. +// - It supports read and write deadlines. // // PipeConns is NOT safe for concurrent use by multiple goroutines! type PipeConns struct { @@ -209,7 +209,7 @@ func (e *timeoutError) Error() string { // Only implement the Timeout() function of the net.Error interface. // This allows for checks like: // -// if x, ok := err.(interface{ Timeout() bool }); ok && x.Timeout() { +// if x, ok := err.(interface{ Timeout() bool }); ok && x.Timeout() { func (e *timeoutError) Timeout() bool { return true } diff --git a/fs.go b/fs.go index 8491864565..1e52c93d43 100644 --- a/fs.go +++ b/fs.go @@ -61,8 +61,8 @@ func ServeFileUncompressed(ctx *RequestCtx, path string) { // // HTTP response may contain uncompressed file contents in the following cases: // -// * Missing 'Accept-Encoding: gzip' request header. -// * No write access to directory containing the file. +// - Missing 'Accept-Encoding: gzip' request header. +// - No write access to directory containing the file. // // Directory contents is returned if path points to directory. // @@ -83,8 +83,8 @@ func ServeFileBytes(ctx *RequestCtx, path []byte) { // // HTTP response may contain uncompressed file contents in the following cases: // -// * Missing 'Accept-Encoding: gzip' request header. -// * No write access to directory containing the file. +// - Missing 'Accept-Encoding: gzip' request header. +// - No write access to directory containing the file. // // Directory contents is returned if path points to directory. // @@ -155,12 +155,11 @@ type PathRewriteFunc func(ctx *RequestCtx) []byte // // Examples: // -// * host=foobar.com, slashesCount=0, original path="/foo/bar". +// - host=foobar.com, slashesCount=0, original path="/foo/bar". // Resulting path: "/foobar.com/foo/bar" // -// * host=img.aaa.com, slashesCount=1, original path="/images/123/456.jpg" +// - host=img.aaa.com, slashesCount=1, original path="/images/123/456.jpg" // Resulting path: "/img.aaa.com/123/456.jpg" -// func NewVHostPathRewriter(slashesCount int) PathRewriteFunc { return func(ctx *RequestCtx) []byte { path := stripLeadingSlashes(ctx.Path(), slashesCount) @@ -189,9 +188,9 @@ var strInvalidHost = []byte("invalid-host") // // Examples: // -// * slashesCount = 0, original path: "/foo/bar", result: "/foo/bar" -// * slashesCount = 1, original path: "/foo/bar", result: "/bar" -// * slashesCount = 2, original path: "/foo/bar", result: "" +// - slashesCount = 0, original path: "/foo/bar", result: "/foo/bar" +// - slashesCount = 1, original path: "/foo/bar", result: "/bar" +// - slashesCount = 2, original path: "/foo/bar", result: "" // // The returned path rewriter may be used as FS.PathRewrite . func NewPathSlashesStripper(slashesCount int) PathRewriteFunc { @@ -205,9 +204,9 @@ func NewPathSlashesStripper(slashesCount int) PathRewriteFunc { // // Examples: // -// * prefixSize = 0, original path: "/foo/bar", result: "/foo/bar" -// * prefixSize = 3, original path: "/foo/bar", result: "o/bar" -// * prefixSize = 7, original path: "/foo/bar", result: "r" +// - prefixSize = 0, original path: "/foo/bar", result: "/foo/bar" +// - prefixSize = 3, original path: "/foo/bar", result: "o/bar" +// - prefixSize = 7, original path: "/foo/bar", result: "r" // // The returned path rewriter may be used as FS.PathRewrite . func NewPathPrefixStripper(prefixSize int) PathRewriteFunc { @@ -350,9 +349,9 @@ const FSHandlerCacheDuration = 10 * time.Second // from requested path before searching requested file in the root folder. // Examples: // -// * stripSlashes = 0, original path: "/foo/bar", result: "/foo/bar" -// * stripSlashes = 1, original path: "/foo/bar", result: "/bar" -// * stripSlashes = 2, original path: "/foo/bar", result: "" +// - stripSlashes = 0, original path: "/foo/bar", result: "/foo/bar" +// - stripSlashes = 1, original path: "/foo/bar", result: "/bar" +// - stripSlashes = 2, original path: "/foo/bar", result: "" // // The returned request handler automatically generates index pages // for directories without index.html. diff --git a/header.go b/header.go index 323b3f0cf8..4c3c0eafa8 100644 --- a/header.go +++ b/header.go @@ -109,8 +109,8 @@ func (h *ResponseHeader) SetContentRange(startPos, endPos, contentLength int) { // SetByteRange sets 'Range: bytes=startPos-endPos' header. // -// * If startPos is negative, then 'bytes=-startPos' value is set. -// * If endPos is negative, then 'bytes=startPos-' value is set. +// - If startPos is negative, then 'bytes=-startPos' value is set. +// - If endPos is negative, then 'bytes=startPos-' value is set. func (h *RequestHeader) SetByteRange(startPos, endPos int) { b := h.bufKV.value[:0] b = append(b, strBytes...) @@ -887,9 +887,9 @@ func (h *RequestHeader) Len() int { // while lowercasing all the other letters. // Examples: // -// * CONNECTION -> Connection -// * conteNT-tYPE -> Content-Type -// * foo-bar-baz -> Foo-Bar-Baz +// - CONNECTION -> Connection +// - conteNT-tYPE -> Content-Type +// - foo-bar-baz -> Foo-Bar-Baz // // Disable header names' normalization only if know what are you doing. func (h *RequestHeader) DisableNormalizing() { @@ -903,9 +903,9 @@ func (h *RequestHeader) DisableNormalizing() { // the other letters. // Examples: // -// * CONNECTION -> Connection -// * conteNT-tYPE -> Content-Type -// * foo-bar-baz -> Foo-Bar-Baz +// - CONNECTION -> Connection +// - conteNT-tYPE -> Content-Type +// - foo-bar-baz -> Foo-Bar-Baz // // This is enabled by default unless disabled using DisableNormalizing() func (h *RequestHeader) EnableNormalizing() { @@ -919,9 +919,9 @@ func (h *RequestHeader) EnableNormalizing() { // while lowercasing all the other letters. // Examples: // -// * CONNECTION -> Connection -// * conteNT-tYPE -> Content-Type -// * foo-bar-baz -> Foo-Bar-Baz +// - CONNECTION -> Connection +// - conteNT-tYPE -> Content-Type +// - foo-bar-baz -> Foo-Bar-Baz // // Disable header names' normalization only if know what are you doing. func (h *ResponseHeader) DisableNormalizing() { @@ -935,9 +935,9 @@ func (h *ResponseHeader) DisableNormalizing() { // the other letters. // Examples: // -// * CONNECTION -> Connection -// * conteNT-tYPE -> Content-Type -// * foo-bar-baz -> Foo-Bar-Baz +// - CONNECTION -> Connection +// - conteNT-tYPE -> Content-Type +// - foo-bar-baz -> Foo-Bar-Baz // // This is enabled by default unless disabled using DisableNormalizing() func (h *ResponseHeader) EnableNormalizing() { @@ -1516,13 +1516,13 @@ func (h *RequestHeader) SetCookieBytesKV(key, value []byte) { // This doesn't work for a cookie with specific domain or path, // you should delete it manually like: // -// c := AcquireCookie() -// c.SetKey(key) -// c.SetDomain("example.com") -// c.SetPath("/path") -// c.SetExpire(CookieExpireDelete) -// h.SetCookie(c) -// ReleaseCookie(c) +// c := AcquireCookie() +// c.SetKey(key) +// c.SetDomain("example.com") +// c.SetPath("/path") +// c.SetExpire(CookieExpireDelete) +// h.SetCookie(c) +// ReleaseCookie(c) // // Use DelCookie if you want just removing the cookie from response header. func (h *ResponseHeader) DelClientCookie(key string) { @@ -1539,13 +1539,13 @@ func (h *ResponseHeader) DelClientCookie(key string) { // This doesn't work for a cookie with specific domain or path, // you should delete it manually like: // -// c := AcquireCookie() -// c.SetKey(key) -// c.SetDomain("example.com") -// c.SetPath("/path") -// c.SetExpire(CookieExpireDelete) -// h.SetCookie(c) -// ReleaseCookie(c) +// c := AcquireCookie() +// c.SetKey(key) +// c.SetDomain("example.com") +// c.SetPath("/path") +// c.SetExpire(CookieExpireDelete) +// h.SetCookie(c) +// ReleaseCookie(c) // // Use DelCookieBytes if you want just removing the cookie from response header. func (h *ResponseHeader) DelClientCookieBytes(key []byte) { @@ -3176,9 +3176,9 @@ func removeNewLines(raw []byte) []byte { // after dashes are also uppercased. All the other letters are lowercased. // Examples: // -// * coNTENT-TYPe -> Content-Type -// * HOST -> Host -// * foo-bar-baz -> Foo-Bar-Baz +// - coNTENT-TYPe -> Content-Type +// - HOST -> Host +// - foo-bar-baz -> Foo-Bar-Baz func AppendNormalizedHeaderKey(dst []byte, key string) []byte { dst = append(dst, key...) normalizeHeaderKey(dst[len(dst)-len(key):], false) @@ -3192,9 +3192,9 @@ func AppendNormalizedHeaderKey(dst []byte, key string) []byte { // after dashes are also uppercased. All the other letters are lowercased. // Examples: // -// * coNTENT-TYPe -> Content-Type -// * HOST -> Host -// * foo-bar-baz -> Foo-Bar-Baz +// - coNTENT-TYPe -> Content-Type +// - HOST -> Host +// - foo-bar-baz -> Foo-Bar-Baz func AppendNormalizedHeaderKeyBytes(dst, key []byte) []byte { return AppendNormalizedHeaderKey(dst, b2s(key)) } diff --git a/http.go b/http.go index cfeeac5df9..97bf5d626c 100644 --- a/http.go +++ b/http.go @@ -255,9 +255,9 @@ func (resp *Response) IsBodyStream() bool { // // This function may be used in the following cases: // -// * if request body is too big (more than 10MB). -// * if request body is streamed from slow external sources. -// * if request body must be streamed to the server in chunks +// - if request body is too big (more than 10MB). +// - if request body is streamed from slow external sources. +// - if request body must be streamed to the server in chunks // (aka `http client push` or `chunked transfer-encoding`). // // Note that GET and HEAD requests cannot have body. @@ -272,9 +272,9 @@ func (req *Request) SetBodyStreamWriter(sw StreamWriter) { // // This function may be used in the following cases: // -// * if response body is too big (more than 10MB). -// * if response body is streamed from slow external sources. -// * if response body must be streamed to the client in chunks +// - if response body is too big (more than 10MB). +// - if response body is streamed from slow external sources. +// - if response body must be streamed to the client in chunks // (aka `http server push` or `chunked transfer-encoding`). // // See also SetBodyStream. @@ -1081,11 +1081,11 @@ func (resp *Response) resetSkipHeader() { // // If MayContinue returns true, the caller must: // -// - Either send StatusExpectationFailed response if request headers don't -// satisfy the caller. -// - Or send StatusContinue response before reading request body -// with ContinueReadBody. -// - Or close the connection. +// - Either send StatusExpectationFailed response if request headers don't +// satisfy the caller. +// - Or send StatusContinue response before reading request body +// with ContinueReadBody. +// - Or close the connection. // // io.EOF is returned if r is closed before reading the first header byte. func (req *Request) Read(r *bufio.Reader) error { @@ -1109,11 +1109,11 @@ var ErrGetOnly = errors.New("non-GET request received") // // If MayContinue returns true, the caller must: // -// - Either send StatusExpectationFailed response if request headers don't -// satisfy the caller. -// - Or send StatusContinue response before reading request body -// with ContinueReadBody. -// - Or close the connection. +// - Either send StatusExpectationFailed response if request headers don't +// satisfy the caller. +// - Or send StatusContinue response before reading request body +// with ContinueReadBody. +// - Or close the connection. // // io.EOF is returned if r is closed before reading the first header byte. func (req *Request) ReadLimitBody(r *bufio.Reader, maxBodySize int) error { @@ -1166,11 +1166,11 @@ func (req *Request) readBodyStream(r *bufio.Reader, maxBodySize int, getOnly boo // // The caller must do one of the following actions if MayContinue returns true: // -// - Either send StatusExpectationFailed response if request headers don't -// satisfy the caller. -// - Or send StatusContinue response before reading request body -// with ContinueReadBody. -// - Or close the connection. +// - Either send StatusExpectationFailed response if request headers don't +// satisfy the caller. +// - Or send StatusContinue response before reading request body +// with ContinueReadBody. +// - Or close the connection. func (req *Request) MayContinue() bool { return bytes.Equal(req.Header.peek(strExpect), str100Continue) } @@ -1562,11 +1562,11 @@ func (resp *Response) WriteGzip(w *bufio.Writer) error { // // Level is the desired compression level: // -// * CompressNoCompression -// * CompressBestSpeed -// * CompressBestCompression -// * CompressDefaultCompression -// * CompressHuffmanOnly +// - CompressNoCompression +// - CompressBestSpeed +// - CompressBestCompression +// - CompressDefaultCompression +// - CompressHuffmanOnly // // The method gzips response body and sets 'Content-Encoding: gzip' // header before writing response to w. @@ -1593,11 +1593,11 @@ func (resp *Response) WriteDeflate(w *bufio.Writer) error { // // Level is the desired compression level: // -// * CompressNoCompression -// * CompressBestSpeed -// * CompressBestCompression -// * CompressDefaultCompression -// * CompressHuffmanOnly +// - CompressNoCompression +// - CompressBestSpeed +// - CompressBestCompression +// - CompressDefaultCompression +// - CompressHuffmanOnly // // The method deflates response body and sets 'Content-Encoding: deflate' // header before writing response to w. diff --git a/reuseport/reuseport.go b/reuseport/reuseport.go index 86ad397e32..6e13acbd5b 100644 --- a/reuseport/reuseport.go +++ b/reuseport/reuseport.go @@ -21,8 +21,8 @@ import ( // The returned listener tries enabling the following TCP options, which usually // have positive impact on performance: // -// - TCP_DEFER_ACCEPT. This option expects that the server reads from accepted -// connections before writing to them. +// - TCP_DEFER_ACCEPT. This option expects that the server reads from accepted +// connections before writing to them. // // - TCP_FASTOPEN. See https://lwn.net/Articles/508865/ for details. // diff --git a/server.go b/server.go index 6af2ed8ff4..f1406fbd57 100644 --- a/server.go +++ b/server.go @@ -510,11 +510,11 @@ func CompressHandler(h RequestHandler) RequestHandler { // // Level is the desired compression level: // -// * CompressNoCompression -// * CompressBestSpeed -// * CompressBestCompression -// * CompressDefaultCompression -// * CompressHuffmanOnly +// - CompressNoCompression +// - CompressBestSpeed +// - CompressBestCompression +// - CompressDefaultCompression +// - CompressHuffmanOnly func CompressHandlerLevel(h RequestHandler, level int) RequestHandler { return func(ctx *RequestCtx) { h(ctx) @@ -532,18 +532,18 @@ func CompressHandlerLevel(h RequestHandler, level int) RequestHandler { // // brotliLevel is the desired compression level for brotli. // -// * CompressBrotliNoCompression -// * CompressBrotliBestSpeed -// * CompressBrotliBestCompression -// * CompressBrotliDefaultCompression +// - CompressBrotliNoCompression +// - CompressBrotliBestSpeed +// - CompressBrotliBestCompression +// - CompressBrotliDefaultCompression // // otherLevel is the desired compression level for gzip and deflate. // -// * CompressNoCompression -// * CompressBestSpeed -// * CompressBestCompression -// * CompressDefaultCompression -// * CompressHuffmanOnly +// - CompressNoCompression +// - CompressBestSpeed +// - CompressBestCompression +// - CompressDefaultCompression +// - CompressHuffmanOnly func CompressHandlerBrotliLevel(h RequestHandler, brotliLevel, otherLevel int) RequestHandler { return func(ctx *RequestCtx) { h(ctx) @@ -626,8 +626,8 @@ type HijackHandler func(c net.Conn) // // The server skips calling the handler in the following cases: // -// * 'Connection: close' header exists in either request or response. -// * Unexpected error during response writing to the connection. +// - 'Connection: close' header exists in either request or response. +// - Unexpected error during response writing to the connection. // // The server stops processing requests from hijacked connections. // @@ -639,9 +639,8 @@ type HijackHandler func(c net.Conn) // Arbitrary 'Connection: Upgrade' protocols may be implemented // with HijackHandler. For instance, // -// * WebSocket ( https://en.wikipedia.org/wiki/WebSocket ) -// * HTTP/2.0 ( https://en.wikipedia.org/wiki/HTTP/2 ) -// +// - WebSocket ( https://en.wikipedia.org/wiki/WebSocket ) +// - HTTP/2.0 ( https://en.wikipedia.org/wiki/HTTP/2 ) func (ctx *RequestCtx) Hijack(handler HijackHandler) { ctx.hijackHandler = handler } @@ -1084,15 +1083,15 @@ func SaveMultipartFile(fh *multipart.FileHeader, path string) (err error) { // // The value is searched in the following places: // -// * Query string. -// * POST or PUT body. +// - Query string. +// - POST or PUT body. // // There are more fine-grained methods for obtaining form values: // -// * QueryArgs for obtaining values from query string. -// * PostArgs for obtaining values from POST or PUT body. -// * MultipartForm for obtaining values from multipart form. -// * FormFile for obtaining uploaded files. +// - QueryArgs for obtaining values from query string. +// - PostArgs for obtaining values from POST or PUT body. +// - MultipartForm for obtaining values from multipart form. +// - FormFile for obtaining uploaded files. // // The returned value is valid until your request handler returns. func (ctx *RequestCtx) FormValue(key string) []byte { @@ -1254,11 +1253,11 @@ func (ctx *RequestCtx) SuccessString(contentType, body string) { // // statusCode must have one of the following values: // -// * StatusMovedPermanently (301) -// * StatusFound (302) -// * StatusSeeOther (303) -// * StatusTemporaryRedirect (307) -// * StatusPermanentRedirect (308) +// - StatusMovedPermanently (301) +// - StatusFound (302) +// - StatusSeeOther (303) +// - StatusTemporaryRedirect (307) +// - StatusPermanentRedirect (308) // // All other statusCode values are replaced by StatusFound (302). // @@ -1266,10 +1265,9 @@ func (ctx *RequestCtx) SuccessString(contentType, body string) { // request uri. Fasthttp will always send an absolute uri back to the client. // To send a relative uri you can use the following code: // -// strLocation = []byte("Location") // Put this with your top level var () declarations. -// ctx.Response.Header.SetCanonical(strLocation, "/relative?uri") -// ctx.Response.SetStatusCode(fasthttp.StatusMovedPermanently) -// +// strLocation = []byte("Location") // Put this with your top level var () declarations. +// ctx.Response.Header.SetCanonical(strLocation, "/relative?uri") +// ctx.Response.SetStatusCode(fasthttp.StatusMovedPermanently) func (ctx *RequestCtx) Redirect(uri string, statusCode int) { u := AcquireURI() ctx.URI().CopyTo(u) @@ -1283,11 +1281,11 @@ func (ctx *RequestCtx) Redirect(uri string, statusCode int) { // // statusCode must have one of the following values: // -// * StatusMovedPermanently (301) -// * StatusFound (302) -// * StatusSeeOther (303) -// * StatusTemporaryRedirect (307) -// * StatusPermanentRedirect (308) +// - StatusMovedPermanently (301) +// - StatusFound (302) +// - StatusSeeOther (303) +// - StatusTemporaryRedirect (307) +// - StatusPermanentRedirect (308) // // All other statusCode values are replaced by StatusFound (302). // @@ -1295,10 +1293,9 @@ func (ctx *RequestCtx) Redirect(uri string, statusCode int) { // request uri. Fasthttp will always send an absolute uri back to the client. // To send a relative uri you can use the following code: // -// strLocation = []byte("Location") // Put this with your top level var () declarations. -// ctx.Response.Header.SetCanonical(strLocation, "/relative?uri") -// ctx.Response.SetStatusCode(fasthttp.StatusMovedPermanently) -// +// strLocation = []byte("Location") // Put this with your top level var () declarations. +// ctx.Response.Header.SetCanonical(strLocation, "/relative?uri") +// ctx.Response.SetStatusCode(fasthttp.StatusMovedPermanently) func (ctx *RequestCtx) RedirectBytes(uri []byte, statusCode int) { s := b2s(uri) ctx.Redirect(s, statusCode) @@ -1437,9 +1434,9 @@ func (ctx *RequestCtx) SetBodyStream(bodyStream io.Reader, bodySize int) { // // This function may be used in the following cases: // -// * if response body is too big (more than 10MB). -// * if response body is streamed from slow external sources. -// * if response body must be streamed to the client in chunks. +// - if response body is too big (more than 10MB). +// - if response body is streamed from slow external sources. +// - if response body must be streamed to the client in chunks. // (aka `http server push`). func (ctx *RequestCtx) SetBodyStreamWriter(sw StreamWriter) { ctx.Response.SetBodyStreamWriter(sw) diff --git a/stackless/func.go b/stackless/func.go index 9a49bcc26b..a50b3eb26f 100644 --- a/stackless/func.go +++ b/stackless/func.go @@ -12,9 +12,9 @@ import ( // The wrapper may save a lot of stack space if the following conditions // are met: // -// - f doesn't contain blocking calls on network, I/O or channels; -// - f uses a lot of stack space; -// - the wrapper is called from high number of concurrent goroutines. +// - f doesn't contain blocking calls on network, I/O or channels; +// - f uses a lot of stack space; +// - the wrapper is called from high number of concurrent goroutines. // // The stackless wrapper returns false if the call cannot be processed // at the moment due to high load. diff --git a/tcpdialer.go b/tcpdialer.go index 294cf1418b..7e7cb84509 100644 --- a/tcpdialer.go +++ b/tcpdialer.go @@ -14,12 +14,12 @@ import ( // // This function has the following additional features comparing to net.Dial: // -// * It reduces load on DNS resolver by caching resolved TCP addressed +// - It reduces load on DNS resolver by caching resolved TCP addressed // for DNSCacheDuration. -// * It dials all the resolved TCP addresses in round-robin manner until +// - It dials all the resolved TCP addresses in round-robin manner until // connection is established. This may be useful if certain addresses // are temporarily unreachable. -// * It returns ErrDialTimeout if connection cannot be established during +// - It returns ErrDialTimeout if connection cannot be established during // DefaultDialTimeout seconds. Use DialTimeout for customizing dial timeout. // // This dialer is intended for custom code wrapping before passing @@ -30,9 +30,9 @@ import ( // // The addr passed to the function must contain port. Example addr values: // -// * foobar.baz:443 -// * foo.bar:80 -// * aaa.com:8080 +// - foobar.baz:443 +// - foo.bar:80 +// - aaa.com:8080 func Dial(addr string) (net.Conn, error) { return defaultDialer.Dial(addr) } @@ -41,9 +41,9 @@ func Dial(addr string) (net.Conn, error) { // // This function has the following additional features comparing to net.Dial: // -// * It reduces load on DNS resolver by caching resolved TCP addressed +// - It reduces load on DNS resolver by caching resolved TCP addressed // for DNSCacheDuration. -// * It dials all the resolved TCP addresses in round-robin manner until +// - It dials all the resolved TCP addresses in round-robin manner until // connection is established. This may be useful if certain addresses // are temporarily unreachable. // @@ -55,9 +55,9 @@ func Dial(addr string) (net.Conn, error) { // // The addr passed to the function must contain port. Example addr values: // -// * foobar.baz:443 -// * foo.bar:80 -// * aaa.com:8080 +// - foobar.baz:443 +// - foo.bar:80 +// - aaa.com:8080 func DialTimeout(addr string, timeout time.Duration) (net.Conn, error) { return defaultDialer.DialTimeout(addr, timeout) } @@ -66,12 +66,12 @@ func DialTimeout(addr string, timeout time.Duration) (net.Conn, error) { // // This function has the following additional features comparing to net.Dial: // -// * It reduces load on DNS resolver by caching resolved TCP addressed +// - It reduces load on DNS resolver by caching resolved TCP addressed // for DNSCacheDuration. -// * It dials all the resolved TCP addresses in round-robin manner until +// - It dials all the resolved TCP addresses in round-robin manner until // connection is established. This may be useful if certain addresses // are temporarily unreachable. -// * It returns ErrDialTimeout if connection cannot be established during +// - It returns ErrDialTimeout if connection cannot be established during // DefaultDialTimeout seconds. Use DialDualStackTimeout for custom dial // timeout. // @@ -83,9 +83,9 @@ func DialTimeout(addr string, timeout time.Duration) (net.Conn, error) { // // The addr passed to the function must contain port. Example addr values: // -// * foobar.baz:443 -// * foo.bar:80 -// * aaa.com:8080 +// - foobar.baz:443 +// - foo.bar:80 +// - aaa.com:8080 func DialDualStack(addr string) (net.Conn, error) { return defaultDialer.DialDualStack(addr) } @@ -95,9 +95,9 @@ func DialDualStack(addr string) (net.Conn, error) { // // This function has the following additional features comparing to net.Dial: // -// * It reduces load on DNS resolver by caching resolved TCP addressed +// - It reduces load on DNS resolver by caching resolved TCP addressed // for DNSCacheDuration. -// * It dials all the resolved TCP addresses in round-robin manner until +// - It dials all the resolved TCP addresses in round-robin manner until // connection is established. This may be useful if certain addresses // are temporarily unreachable. // @@ -109,9 +109,9 @@ func DialDualStack(addr string) (net.Conn, error) { // // The addr passed to the function must contain port. Example addr values: // -// * foobar.baz:443 -// * foo.bar:80 -// * aaa.com:8080 +// - foobar.baz:443 +// - foo.bar:80 +// - aaa.com:8080 func DialDualStackTimeout(addr string, timeout time.Duration) (net.Conn, error) { return defaultDialer.DialDualStackTimeout(addr, timeout) } @@ -167,12 +167,12 @@ type TCPDialer struct { // // This function has the following additional features comparing to net.Dial: // -// * It reduces load on DNS resolver by caching resolved TCP addressed +// - It reduces load on DNS resolver by caching resolved TCP addressed // for DNSCacheDuration. -// * It dials all the resolved TCP addresses in round-robin manner until +// - It dials all the resolved TCP addresses in round-robin manner until // connection is established. This may be useful if certain addresses // are temporarily unreachable. -// * It returns ErrDialTimeout if connection cannot be established during +// - It returns ErrDialTimeout if connection cannot be established during // DefaultDialTimeout seconds. Use DialTimeout for customizing dial timeout. // // This dialer is intended for custom code wrapping before passing @@ -183,9 +183,9 @@ type TCPDialer struct { // // The addr passed to the function must contain port. Example addr values: // -// * foobar.baz:443 -// * foo.bar:80 -// * aaa.com:8080 +// - foobar.baz:443 +// - foo.bar:80 +// - aaa.com:8080 func (d *TCPDialer) Dial(addr string) (net.Conn, error) { return d.dial(addr, false, DefaultDialTimeout) } @@ -194,9 +194,9 @@ func (d *TCPDialer) Dial(addr string) (net.Conn, error) { // // This function has the following additional features comparing to net.Dial: // -// * It reduces load on DNS resolver by caching resolved TCP addressed +// - It reduces load on DNS resolver by caching resolved TCP addressed // for DNSCacheDuration. -// * It dials all the resolved TCP addresses in round-robin manner until +// - It dials all the resolved TCP addresses in round-robin manner until // connection is established. This may be useful if certain addresses // are temporarily unreachable. // @@ -208,9 +208,9 @@ func (d *TCPDialer) Dial(addr string) (net.Conn, error) { // // The addr passed to the function must contain port. Example addr values: // -// * foobar.baz:443 -// * foo.bar:80 -// * aaa.com:8080 +// - foobar.baz:443 +// - foo.bar:80 +// - aaa.com:8080 func (d *TCPDialer) DialTimeout(addr string, timeout time.Duration) (net.Conn, error) { return d.dial(addr, false, timeout) } @@ -219,12 +219,12 @@ func (d *TCPDialer) DialTimeout(addr string, timeout time.Duration) (net.Conn, e // // This function has the following additional features comparing to net.Dial: // -// * It reduces load on DNS resolver by caching resolved TCP addressed +// - It reduces load on DNS resolver by caching resolved TCP addressed // for DNSCacheDuration. -// * It dials all the resolved TCP addresses in round-robin manner until +// - It dials all the resolved TCP addresses in round-robin manner until // connection is established. This may be useful if certain addresses // are temporarily unreachable. -// * It returns ErrDialTimeout if connection cannot be established during +// - It returns ErrDialTimeout if connection cannot be established during // DefaultDialTimeout seconds. Use DialDualStackTimeout for custom dial // timeout. // @@ -236,9 +236,9 @@ func (d *TCPDialer) DialTimeout(addr string, timeout time.Duration) (net.Conn, e // // The addr passed to the function must contain port. Example addr values: // -// * foobar.baz:443 -// * foo.bar:80 -// * aaa.com:8080 +// - foobar.baz:443 +// - foo.bar:80 +// - aaa.com:8080 func (d *TCPDialer) DialDualStack(addr string) (net.Conn, error) { return d.dial(addr, true, DefaultDialTimeout) } @@ -248,9 +248,9 @@ func (d *TCPDialer) DialDualStack(addr string) (net.Conn, error) { // // This function has the following additional features comparing to net.Dial: // -// * It reduces load on DNS resolver by caching resolved TCP addressed +// - It reduces load on DNS resolver by caching resolved TCP addressed // for DNSCacheDuration. -// * It dials all the resolved TCP addresses in round-robin manner until +// - It dials all the resolved TCP addresses in round-robin manner until // connection is established. This may be useful if certain addresses // are temporarily unreachable. // @@ -262,9 +262,9 @@ func (d *TCPDialer) DialDualStack(addr string) (net.Conn, error) { // // The addr passed to the function must contain port. Example addr values: // -// * foobar.baz:443 -// * foo.bar:80 -// * aaa.com:8080 +// - foobar.baz:443 +// - foo.bar:80 +// - aaa.com:8080 func (d *TCPDialer) DialDualStackTimeout(addr string, timeout time.Duration) (net.Conn, error) { return d.dial(addr, true, timeout) } diff --git a/uri.go b/uri.go index ffd68c6367..f894b1b739 100644 --- a/uri.go +++ b/uri.go @@ -715,9 +715,9 @@ func (u *URI) RequestURI() []byte { // // Examples: // -// * For /foo/bar/baz.html path returns baz.html. -// * For /foo/bar/ returns empty byte slice. -// * For /foobar.js returns foobar.js. +// - For /foo/bar/baz.html path returns baz.html. +// - For /foo/bar/ returns empty byte slice. +// - For /foobar.js returns foobar.js. // // The returned bytes are valid until the next URI method call. func (u *URI) LastPathSegment() []byte { @@ -733,14 +733,14 @@ func (u *URI) LastPathSegment() []byte { // // The following newURI types are accepted: // -// * Absolute, i.e. http://foobar.com/aaa/bb?cc . In this case the original -// uri is replaced by newURI. -// * Absolute without scheme, i.e. //foobar.com/aaa/bb?cc. In this case -// the original scheme is preserved. -// * Missing host, i.e. /aaa/bb?cc . In this case only RequestURI part -// of the original uri is replaced. -// * Relative path, i.e. xx?yy=abc . In this case the original RequestURI -// is updated according to the new relative path. +// - Absolute, i.e. http://foobar.com/aaa/bb?cc . In this case the original +// uri is replaced by newURI. +// - Absolute without scheme, i.e. //foobar.com/aaa/bb?cc. In this case +// the original scheme is preserved. +// - Missing host, i.e. /aaa/bb?cc . In this case only RequestURI part +// of the original uri is replaced. +// - Relative path, i.e. xx?yy=abc . In this case the original RequestURI +// is updated according to the new relative path. func (u *URI) Update(newURI string) { u.UpdateBytes(s2b(newURI)) } @@ -749,14 +749,14 @@ func (u *URI) Update(newURI string) { // // The following newURI types are accepted: // -// * Absolute, i.e. http://foobar.com/aaa/bb?cc . In this case the original -// uri is replaced by newURI. -// * Absolute without scheme, i.e. //foobar.com/aaa/bb?cc. In this case -// the original scheme is preserved. -// * Missing host, i.e. /aaa/bb?cc . In this case only RequestURI part -// of the original uri is replaced. -// * Relative path, i.e. xx?yy=abc . In this case the original RequestURI -// is updated according to the new relative path. +// - Absolute, i.e. http://foobar.com/aaa/bb?cc . In this case the original +// uri is replaced by newURI. +// - Absolute without scheme, i.e. //foobar.com/aaa/bb?cc. In this case +// the original scheme is preserved. +// - Missing host, i.e. /aaa/bb?cc . In this case only RequestURI part +// of the original uri is replaced. +// - Relative path, i.e. xx?yy=abc . In this case the original RequestURI +// is updated according to the new relative path. func (u *URI) UpdateBytes(newURI []byte) { u.requestURI = u.updateBytes(newURI, u.requestURI) }