* Allow no response to be send when a connection is hijacked
At the moment there is always a HTTP response before the connection gets
hijacked. This second option to Hijack() prevents this response from
being send.
Fixes: https://github.com/valyala/fasthttp/issues/698
* Add HijackSetNoResponse method instead
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%
* Use binary-search algorithm to speed up cleaning up workers
* Speed it up when iterating the slice of workerChan
* Use sync.Pool as a more canonical way
* Add benchmark test between binary-search and linear search
* Optimize range to the slice of workerChan, avoiding elements copy
* Perfect the benchmark of work pool
* Make binary-search code inline and remove benchmark test code
- 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%
See: https://github.com/golang/go/commit/6e6f4aaf70c8b1cc81e65a26332aa9409de03ad8
Reject any non GET or HEAD requests with a 400.
We can't reject GET or HEAD requests with bad headers as we delay
parsing of these headers until the user asks for one. So in this case we
just ignore the header and don't return a value for it.