Commit Graph

175 Commits

Author SHA1 Message Date
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
Tommy Chen d459e257bf Use form headers in WriteMultipartForm
CreateFormFile always set Content-Type header to application/octet-stream.
Use CreatePart instead so all headers in the multipart form can be used.
2018-10-05 19:02:16 +03:00
Erik Dubbelboer d4f0cf56d8 Remove fasthttp.ByteBuffer
As advertised in https://github.com/valyala/fasthttp/commit/b5f96d4b4120bb1e09c23ac32baf21a14da4a71d
2018-10-01 14:15:29 +08:00
Erik Dubbelboer c67f81e5f9 Use PostArgs in client
See: https://github.com/erikdubbelboer/fasthttp/issues/17
2018-09-20 15:22:18 +08:00
Erik Dubbelboer 26aa8e51e8 Allow whitespace after chunk size
There seems to be servers/load balancers that insert whitespaces
between the chunk-size number and \r\n.
2018-08-27 21:42:46 +00:00
Erik Dubbelboer cf6f6e7fca Read GET/HEAD body if it exists
Previously, GET/HEAD bodies were not read. The HTTP 1.1 specification
states:

"A server SHOULD read and forward a message-body on any request; if the
request method does not include defined semantics for an entity-body,
then the message-body SHOULD be ignored when handling the request.
I suspect this code is at fault."

This change reads the body on such request and continues the previous
behavior of returning a "Content-Length" of 0 to the application.

See: https://github.com/valyala/fasthttp/issues/159
2018-08-24 16:21:17 +03:00
xPushkin f24d00fcc6 A lot of typo fixes 2017-10-08 13:30:35 +01:00
Aliaksandr Valialkin 5116aa64e0 Mention that the body returned from Request.Body and Response.Body is valid until the Request/Response modification 2017-09-12 13:15:57 +03:00
Aliaksandr Valialkin 8948e047bf Issue #176: reset Content-Length when compression is enabled for streamed response body 2017-06-27 20:50:04 +03:00
Aliaksandr Valialkin b154429ca9 Compress responses only if their content-type starts with text/ or application/ 2017-05-17 17:10:29 +03:00
Aliaksandr Valialkin 103adc311e Do not compress responses with sizes smaller than 200 bytes
Compressing small bodies has little sense, since the compressed result size
may exceed the original body size.

This should save CPU time when the server responds with small responses.
2017-05-17 16:17:53 +03:00
Aliaksandr Valialkin 30e92af08f Limit heap memory usage when compressing high number of concurrent responses
Previously each concurrent compression could allocate huge compression state
with the size up to 1Mb each. So 10K concurrent connections could result in
10Gb of compression state in the heap.

This CL limits the number of compression states among concurrent requests
when {Append,Write}{Gzip,Deflate}* functions are called to O(GOMAXPROCS).
These functions are used by CompressHandler* for non-streaming responses,
i.e. it should cover the majority of use cases.

Memory usage for 10K concurrent connections that compress responses drops
from 10Gb to 200Mb after this CL.
2017-05-17 14:45:31 +03:00
Aliaksandr Valialkin b0de56d13b Properly set "https" scheme in RequestCtx.URI() for TLS connections 2017-01-15 00:26:21 +02:00
Aliaksandr Valialkin 4ee6517626 Issue #193: properly handle nil body when calling WriteGzip* and WriteDeflate* on Response struct 2016-10-31 13:41:50 +02:00
Aliaksandr Valialkin 3e1cb31dcd Added SwapBody to Request and Response for zero-copy body pass between Request and Response objects 2016-09-12 13:42:59 +03:00
Aliaksandr Valialkin 834fb48f10 Immediately write compressed response data to the connection after the user flushes the data from StreamWriter 2016-08-18 13:03:57 +03:00
Aliaksandr Valialkin 8e21bc7f60 do not compress response body again if Content-Encoding is set 2016-08-17 14:50:58 +03:00
Aliaksandr Valialkin d055141f64 Propagate 'https' scheme to request URI for TLS connections 2016-08-17 14:01:35 +03:00
Aliaksandr Valialkin 45915c69f6 Optimization: recycle request and response body buffers only if Server.ReduceMemoryUsage is set 2016-07-18 17:46:52 +03:00
Aliaksandr Valialkin 778f83ed89 Discourage using ReleaseBody, since now bytebufferpool should properly handle the case mentioned in #102 2016-06-27 18:26:56 +03:00
Aliaksandr Valialkin 00868f2226 Use separate pools for request and response bodies.
This should reduce potential memory waste related to byte buffers' pool usage.
2016-06-24 15:15:59 +03:00
Aliaksandr Valialkin 8ca66d3de8 Use github.com/valyala/bytebufferpool, which should protect against memory fragmentation in the pool of byte buffers like mentioned in the PR #102 2016-06-22 20:32:00 +03:00
Aliaksandr Valialkin 83a24c301b Issue #114: added SetHost and Host helper methods to Request 2016-06-15 20:32:54 +03:00
Aliaksandr Valialkin 8db7d05839 Close base response body streams when wrapping them into gzip or deflate stream writers 2016-06-10 20:19:15 +03:00
Aliaksandr Valialkin 90baa054bc Export IsBodyStream on RequestCtx, Request and Response
These methods may help writing proper request handler wrappers
for request handlers, which may set body either via SetBodyStream*
or via usual body methods.
2016-06-03 17:07:13 +03:00
Aliaksandr Valialkin 1fc1f4cbf5 Reduce memory usage under high load by pooling request/response bodies.
- Use request/response body pools.
- Defer request/response body allocation until it is really required.
- Return request/response bodies to the pool as soon as they become unused.

This minimizes the total amount of memory occupied by active request/response
bodies under high load.
2016-06-03 16:54:22 +03:00
Aliaksandr Valialkin bdd73c3261 small cleanup after 117f109c29 2016-05-27 16:11:29 +03:00
Jason Fesler 117f109c29 Add func (resp *Response) ReleaseBody(size int) (#102) 2016-05-24 15:49:08 +03:00