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) }