Commit Graph

202 Commits

Author SHA1 Message Date
Sergey Ponomarev 35aca7b6df BodyDecoded() for request and responses (#1308)
* header.go ContentEncoding() getter and setters

For Response the CE header is stored into a separate field because compressed responses are often used.
But for the Request let's just peek and store it from headers map

* http.go: New BodyUncompressed() method for request and responses

The new method returns a body and uncompress if it's gzipped
2022-06-06 08:59:16 +02:00
Sergey Ponomarev c9f43eaa1b Response.ContentEncoding(): store as field and avoid using Header.SetCanonical() (#1311)
* Response.ContentEncoding(): store as field

The CE is not so often used for plain APIs responses and even not so often used for static files and on the fly compression.
But still it should be checked each time.
Also having a dedicated field getter and setter simplifies code

* header.go Use shorter Response.setNonSpecial() and Request.setNonSpecial() methods instead of SetCanonical()

The change should improve performance because the setSpecialHeader() call is omitted.
As a downside on adding a new basic header field all putHeader() must be replaced with a direct getter and setter.
2022-06-05 15:47:59 +02:00
Erik Dubbelboer 7cc6f4c513 Fix DoTimeout Streaming body bug 2022-04-26 00:45:51 +02:00
zzzzwc f0e1be5665 add nil check of req.body and resp.body on ReleaseBody (#1266) 2022-04-08 18:56:18 +02:00
Erik Dubbelboer 7a5afddf5b Use %v for errors and %q for strings (#1262)
Mostly in tests.
2022-04-01 18:11:16 +02:00
ArminBTVS 1a5f2f40c6 Read response when client closes connection #1232 (#1233)
* Read response when client closes connection #1232

* Fix edge case were client responds with invalid header

* Follow linter suggestions for tests

* Changes after review

* Reafactor error check after review

* Handle connection reset on windows

* Remove format string from test where not needed

* Run connection reset tests not on Windows
2022-03-14 10:53:16 +01:00
Rennbon f54ffa14ac feature: Keep the memory usage of the service at a stable level (#1216)
* feature: add request and response body size limit, it prevents the large body from slowly stretching the memory of the entire service

* fix: http.go fmt

* refact: optimize code naming

* Update http.go

Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>

* Update http.go

Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>

* Update http.go

Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>

* Update http.go

Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>

* Update http.go

Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>

Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>
2022-03-03 13:46:32 +01:00
Tolyar c727b9981b Release UseHostHeader in ReleaseRequest() (#1185)
* Fix UseHostHeader for DoTimeout + tests

* Release UseHostHeader in ReleaseRequest() + tests
2021-12-28 19:26:04 +08:00
Tolyar 6c0518b89a Fix UseHostHeader for DoTimeout + tests (#1184) 2021-12-26 21:08:23 +08:00
Tolyar 4517204499 Allow to set Host header for Client (#1169)
* Allow to set Host header for Client

* Allow to change Host header without tests violation

* Rename AllowToChangeHostHeader and add tests.

* Allow to use empty uri.Host() when req.Header.Host() does not empty
2021-12-17 06:26:17 +01:00
Erik Dubbelboer e9db537178 Use %w to wrap errors (#1175) 2021-12-13 09:41:34 +01:00
ichx da7ff7a208 Add trailer support (#1165)
* Add trailer support

* fix issue and add documentation

* remove redundant code

* add error return for add/set trailer method

* fix lint error

* fix bad trailer error return issue and update bad content-length error

* update errNonNumericChars

* update errNonNumericChars

* fix issue about error and fix typo
2021-12-05 14:11:51 +01:00
Sergey Ponomarev 8febad0797 http.go: Request.SetURI() (Fix #1141) (#1148)
Currently, the only way to set URI for a request is to call SetRequestURI(string).
Then when a request performed the string will be parsed into a fasthttp.URI struct.
If there are many requests with the same URI then we'll waste CPU for a parsing of the same URI string.
With the new SetURI(*URI) method we can once parse a URI string into a fasthttp.URI struct and then reuse it for many requests.
Unfortunately the URI will be copied because may be modified inside the request.
But anyway this will be more lightweight than parsing.
2021-11-08 13:09:35 +01:00
Shivansh Vij 528dd62239 feat: ability to read body separate from header (#1130)
* Adding ConvertHTTPRequest and renaming ConvertRequest to ConvertFastRequest

* Removing forServer boolean from ConvertHTTPRequest

* Preparing for PR

* Reverting adaptor changes

* Fixing godoc, adding req.ReadBody function as well

* Update comment to be more clear

As per @erikdubbelboer suggestion

Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>

Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>
2021-10-22 21:00:40 +02:00
Erik Dubbelboer ffab77a59d Improve return value reusability documentation 2021-10-01 13:38:31 +02:00
Evgenii 06b464f084 fix typo in deadline (#1099) 2021-09-11 12:05:40 +02:00
Meng 4ed933a2e7 fix: set content-length properly when StreanRequestBody was enabled (#1049)
* fix: set content-length properly when StreanRequestBody was enabled

* fix: add test cases for validating content length of streaming request
2021-06-18 13:43:29 +02:00
Erik Dubbelboer b8b065b0d7 Don't unwrap io.LimitedReader
This is not needed anymore to trigger sendfile. The Go wrapper around
sendfile already does this: https://github.com/golang/go/blob/9d46ee5ac4acd6602692f70c5149a3f6db058558/src/net/sendfile_linux.go#L23-L33
2021-06-12 13:16:36 +02:00
MoreFreeze 097fa05a69 Fix ignoreBody still set content length (#1022)
* Fix ignore body should not set content-length

* Add TestRequestReadNoBody

Co-authored-by: liuchenxing <liuchenxing@bytedance.com>
2021-05-14 10:08:51 +02:00
Roman Khimov 19fcd40863 Fix chunked streaming (#1015)
* http: refactor out crlf reading function

Make it a bit simpler and make it reusable.

* streaming: fix chunked stream test

This test is supposed to check for stream unchunking, but it's not really
effective with that because chunks created by createChunkedBody() get wrapped
into another chunk by writeBodyStream(), so we end up with chunkedBody in
request handler although what we really want is plain body.

Deduplicate test and benchmark also.

* streaming: fix Read interface

It wasn't actually compatible with io.Reader as io.Reader _never_ returns n >
len(p) while this function easily did that for chunked payloads confusing its
users:

panic: runtime error: slice bounds out of range [:528] with capacity 512

goroutine 562 [running]:
io.ReadAll(0x9f4380, 0xc0003be1a0, 0xc0004fcd80, 0x0, 0x0, 0xc00086bc30, 0x46f99b)
        /usr/lib64/go/1.16/src/io/io.go:634 +0x205
io/ioutil.ReadAll(...)
        /usr/lib64/go/1.16/src/io/ioutil/ioutil.go:27
github.com/valyala/fasthttp.getChunkedTestEnv.func1(0xc001fdc680)
        /home/rik/dev/fasthttp/streaming_test.go:108 +0x6c
github.com/valyala/fasthttp.(*Server).serveConn(0xc000416d80, 0xa034e8, 0xc0004da880, 0x0, 0x0)
        /home/rik/dev/fasthttp/server.go:2219 +0x12ee
github.com/valyala/fasthttp.(*workerPool).workerFunc(0xc000148960, 0xc0003be160)
        /home/rik/dev/fasthttp/workerpool.go:223 +0xba
github.com/valyala/fasthttp.(*workerPool).getCh.func1(0xc000148960, 0xc0003be160, 0x8b4ec0, 0xc0003be160)
        /home/rik/dev/fasthttp/workerpool.go:195 +0x35
created by github.com/valyala/fasthttp.(*workerPool).getCh
        /home/rik/dev/fasthttp/workerpool.go:194 +0x11f

It also returned len(p) in some cases where it read less than that.
2021-05-04 12:55:54 +02:00
Daniel Firsht 2a6f7db5bb Adding support for securing error logs (#1001)
Co-authored-by: Daniel Firsht <firsht@amazon.com>
2021-03-26 10:46:57 +01:00
Vladimir Shteinman 0cd7349686 ImmediateHeaderFlush when no body (#995) 2021-03-15 18:10:51 +01:00
Erik Dubbelboer 3cd0862fbb Streaming fixes (#970)
- Allow DisablePreParseMultipartForm in combination with
StreamRequestBody.
- Support streaming into MultipartForm instead of reading the whole body
  first.
- Support calling ctx.PostBody() when streaming is enabled.
2021-02-16 21:53:53 +01:00
Kirill Danshin 0956208cc6 Add request body streaming. Fixes #622 (#911)
* Add request body streaming. Fixes #622
* Add test cases for StreamRequestBody

Co-authored-by: Kiyon <kiyonlin@163.com>
Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>
Co-authored-by: Fiber
2021-02-06 23:03:23 +03:00
kiyon cb0aaaa266 Improve round2 performance (#914) 2020-11-19 17:52:42 +01:00
Erik Dubbelboer ce7b94fee9 Add Request.SetBodyRaw
Fixes https://github.com/valyala/fasthttp/issues/891
2020-11-02 22:22:01 +01:00
Mohammad Alian 9ed328c168 remove unnecessary type conversion (#890)
Co-authored-by: Mohammad Alian <ts-mohammad.alian@rakuten.com>
2020-10-29 20:53:41 +01:00
So-chiru a7c7ef2367 Fix comment typo 2020-08-02 12:33:42 +02:00
Erik Dubbelboer 34a61fe63f Update linting (#851) 2020-07-17 14:22:28 +02:00
Erik Dubbelboer 9468c66e25 URI.Parse now returns an error 2020-05-31 15:16:54 +02:00
Erik Dubbelboer 24410e58c0 Merge pull request #810 from valyala/brotli
Add Brotli support
2020-05-18 18:30:48 +02:00
Erik Dubbelboer 339ad36634 Add Brotli support
New Functions:

    CompressHandlerBrotliLevel(h RequestHandler, brotliLevel, otherLevel int) RequestHandler
    Request.BodyUnbrotli() ([]byte, error)
    Response.BodyUnbrotli() ([]byte, error)
    AppendBrotliBytesLevel(dst, src []byte, level int) []byte
    WriteBrotliLevel(w io.Writer, p []byte, level int) (int, error)
    WriteBrotli(w io.Writer, p []byte) (int, error)
    AppendBrotliBytes(dst, src []byte) []byte
    WriteUnbrotli(w io.Writer, p []byte) (int, error)
    AppendUnbrotliBytes(dst, src []byte) ([]byte, error)

New Constants:

    CompressBrotliNoCompression
    CompressBrotliBestSpeed
    CompressBrotliBestCompression
    CompressBrotliDefaultCompression

Brotli compression levels are different from gzip/flate. Because of this we have separate level constants and CompressHandlerBrotliLevel takes 2 levels.

I didn't add Brotli support to CompressHandler as this could cause a spike in CPU usage when users upgrade fasthttp.

fasthttp.CompressBrotliDefaultCompression is not the same as
brotli.DefaultCompression. brotli.DefaultCompression is more than twice
as slow as fasthttp.CompressBrotliDefaultCompression which I thought was
unreasonable as default.
2020-05-15 15:36:26 +02:00
Erik Dubbelboer dacd0353f9 HostClient can't switch between protocols 2020-05-02 21:01:52 +02:00
Markmerc db18810c87 Add configuration to not pre-parse multipart form data (#778)
Co-authored-by: Mercurio <mmmercur@amazon.com>
2020-04-14 18:17:57 +02:00
Daniel Qian 70b1d3bce7 feat: make client to wait when no free connections (#764)
* feat: make client to wait when no free connections

* feat: make client to wait when no free connections

use AcquireTimer to do timeout instead of using context

* feat: make client to wait when no free connections

Add BenchmarkClientGetEndToEndWaitConn* to test heap allocation
in waiting for free connection situation

* feat: make client to wait when no free connections

Add BenchmarkHTTPClientGetEndToEndWaitConn* to test heap allocation
in waiting for free connection situation

* feat: make client to wait when no free connections

fix bug in BenchmarkHTTPClientGetEndToEndWaitConn*

* feat: make client to wait when no free connections

fix bug in TestHostClientMaxConnWaitTimeoutSuccess make it wait
longer to avoid ErrNoFreeConns on travis-ci

* feat: make client to wait when no free connections

fix do not compile benchmark(NetHTTP?)ClientGetEndToEndWaitConn
if go version < 1.11.x

* feat: make client to wait when no free connections

fix the bug that if deadline is earlier than MaxConnWaitTimeout,
still wait MaxConnWaitTimeout which later than deadline.

* feat: make client to wait when no free connections

fix race condition in TestHostClientMaxConnWaitTimeoutError

* feat: make client to wait when no free connections

fix bug in TestHostClientMaxConnWaitTimeoutWithEarlierDeadline
2020-04-03 17:12:50 +02:00
Erik Dubbelboer 39dd1045bb Allow a body for GET requests (#703)
This means we can't skip parsing headers for GET requests anymore. This
can be seen as good as it also allows us to reject malformed GET
requests, something we didn't do before this. Performance also isn't
affect much:

benchmark                                            old ns/op     new ns/op     delta
BenchmarkClientGetEndToEnd1Inmemory-16               640           641           +0.16%
BenchmarkClientGetEndToEnd10Inmemory-16              713           710           -0.42%
BenchmarkClientGetEndToEnd100Inmemory-16             732           749           +2.32%
BenchmarkClientGetEndToEnd1000Inmemory-16            759           774           +1.98%
BenchmarkClientGetEndToEnd10KInmemory-16             785           808           +2.93%
BenchmarkNetHTTPClientGetEndToEnd1Inmemory-16        5045          4954          -1.80%
BenchmarkNetHTTPClientGetEndToEnd10Inmemory-16       5806          6225          +7.22%
BenchmarkNetHTTPClientGetEndToEnd100Inmemory-16      7877          7998          +1.54%
BenchmarkNetHTTPClientGetEndToEnd1000Inmemory-16     16603         16559         -0.27%
2019-12-01 09:44:11 +01:00
Erik Dubbelboer 32793db72d Run golangci-lint using a Github Action 2019-11-16 18:09:28 +01:00
Vladimir Shteinman 70223a183c Recover from panic in body write (#687)
* Recover from panic in body stream write

* CR + Add tests
2019-11-06 14:35:52 +01:00
alexDango 9bc6da1219 fix: when multipartform no data,FormValue do not panic (#677) 2019-10-25 14:55:11 +08:00
Erik Dubbelboer d428e1b05e Fix race condition in tests, fix URI bug
- Some tests can't be run in parallel.
- `URI` had a pointer to `RequestHeader` which was updated with
`RequestHeader.CopyTo` which resulted in the URI pointing to the wrong
`RequestHeader` causing bugs and race conditions.

The only reason `URI` contained a pointer to `RequestHeader` was to delay the
call to `RequestHeader.Host()` until really needed. But these days instead
of parsing all headers, `RequestHeader.Host()` uses
`RequestHeader.peekRawHeader()` which is rather fast. So we can remove the
pointer in `URI` and completely decouple the two structs improving code
quality and fixing the bug.

For some reason this results in faster code on average as well:
benchmark                                          old ns/op     new ns/op     delta
BenchmarkClientGetEndToEnd1Inmemory-8              1189          1369          +15.14%
BenchmarkClientGetEndToEnd10Inmemory-8             1143          1161          +1.57%
BenchmarkClientGetEndToEnd100Inmemory-8            1228          1236          +0.65%
BenchmarkClientGetEndToEnd1000Inmemory-8           1213          1213          +0.00%
BenchmarkClientGetEndToEnd10KInmemory-8            1362          1350          -0.88%
BenchmarkClientEndToEndBigResponse1Inmemory-8      139967        130070        -7.07%
BenchmarkClientEndToEndBigResponse10Inmemory-8     142233        131809        -7.33%
BenchmarkServerGet1ReqPerConn-8                    1726          1593          -7.71%
BenchmarkServerGet2ReqPerConn-8                    882           927           +5.10%
BenchmarkServerGet10ReqPerConn-8                   440           436           -0.91%
BenchmarkServerGet10KReqPerConn-8                  341           339           -0.59%
BenchmarkServerPost1ReqPerConn-8                   1728          1706          -1.27%
BenchmarkServerPost2ReqPerConn-8                   968           963           -0.52%
BenchmarkServerPost10ReqPerConn-8                  506           505           -0.20%
BenchmarkServerPost10KReqPerConn-8                 424           420           -0.94%
BenchmarkServerGet1ReqPerConn10KClients-8          1117          1051          -5.91%
BenchmarkServerGet2ReqPerConn10KClients-8          565           514           -9.03%
BenchmarkServerGet10ReqPerConn10KClients-8         390           387           -0.77%
BenchmarkServerGet100ReqPerConn10KClients-8        355           348           -1.97%
BenchmarkServerHijack-8                            339           348           +2.65%
BenchmarkServerMaxConnsPerIP-8                     326           325           -0.31%
BenchmarkServerTimeoutError-8                      24355         24180         -0.72%
2019-10-19 21:02:31 +02:00
Erik Dubbelboer 1d6a7e0493 The Authorization header should include the Basic keyword
Thanks to https://github.com/paween1980
2019-09-27 17:29:44 +02:00
Erik Dubbelboer 2edabf3b76 Add support for user:pass in URLs (#614)
Fixes #609
2019-08-18 11:23:33 +02:00
Marcelo Pires ccaae97f5b Support {readTimeout,maxBodySize,writeTimeout} per request based on the headers. (#598) 2019-07-12 14:42:07 +02:00
Vladimir Shteinman 74ad0f8e9b Export struct var and add specs 2019-05-22 23:23:02 +03:00
Vladimir Shteinman 9551d9544d Option for immediate header flush 2019-05-18 17:04:30 +03:00
Ciprian Dorin Craciun 733a6505a9 Support huge read-only []byte response bodies (#477)
* Add `Response.SetBodyRaw` method that serves a `[]byte` slice without touching it  (as an alternative to `SetBody`)
* Update various response related functions that are impacted after the incoduction of `Response.bodyRaw`
* Add a few test-cases in relation to `Response.SetBodyRaw`
2019-02-24 08:32:54 +00:00
xuecai 10b98c2cdf add conn's address info in Response (#537)
* reset commit
* fix response copy bug; add tests;
2019-02-16 10:50:14 +00:00
Erik Dubbelboer 65955d6208 Don't reset headers when reading the body fails
Not doing this means people using Client can still inspect the response
headers when reading the body fails (for example when it is too big).

fixes #456
2018-11-16 00:24:33 +08:00
Berezhnoy Pavel e771b6fe43 #457: allow to rewrite system error response (#458)
* #457: allow to rewrite system error response

* #457: review fixes

* #457: more review issues fixed
2018-11-13 15:41:42 +03:00
Gabriel Pérez S 996610f021 Schema changes detection with HostClient
Related with the issue https://github.com/valyala/fasthttp/issues/244
2018-10-14 16:19:09 +03:00