The getClientName() checks if !NoDefaultUserAgentHeader then returns the Client.Name field.
But it also saves it to atomic field clientName. This is not needed and logic can be simplified.
Previously the clientName vas a byte slice that was copied from c.Name and cached. See 02e0722fb7Fix#1458
* client.go Make addMissingPort() public
It's needed for those who creates the instance of the HostClient manually.
* client.go fix AddMissingPort()
Previously for IPv6 addresses the default port wasn't added.
The fix adding a test and optimization that should avoid itoa() call and reduce a memory usage
* Request.SetTimeout
This functionally works the same as e.g. Client.DoTimeout(), but we can
also use it for Client.DoRedirect(). There is no way as far as I can
tell to set a timeout on a DoRedirect call, so this makes it possible.
* tests
* docs
* use timeout insteadof read/writetimeout when timeout lower than read/writetimeout
* use deadtime; fix test timeout;
Co-authored-by: 徐焱 <xuyan4@staff.sina.com.cn>
* 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
* uri_test.go replace xxx.com with example.com
* uri_test.go replace foobar.com with example.com
* uri_test.go use example.com inside of testURIUpdate()
* uri_test.go use example.com instead of google.com
* uri_test.go use example.com instead of google.com
* uri_test.go testURIUpdate() host with port
* Fix scheme check for not yet parsed requests
At this point the request might not be parsed yet and set. In that case uri is empty and isHttps() returns always false. I don't expect this is intended?
Otherwise URL() must be called before actually passing the request to client.Do()
* Add test
* Please linter
* fix: Unexpected panic for PipelineClient
PipelineClient would panic when calling `Do` with a nil Response as
the second parm
This commit fixes the unexpected panic by checking nil first before
setting fields for Response
* Add tests to ensure nil resp is valid for PipelineClient
* 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
This commit adds a `DoRedirects` method to both `HostClient` and
`Client` as well as top level convenience function of the same name that
is called with the package level `defaultClient`.
Re-implementing this redirect logic in user code is harder than
necessary.
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%
- 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.