Replace use of httputil in client hijack#46920
Conversation
I haven't looked at the other uses of this; is it complicated to address those as well? If we could, we could remove these exceptions from the golangci-lint config; Lines 116 to 123 in 86cd6da |
|
Failure is a flaky test; |
|
oh; maybe the other bits were already addressed (see #39927) in; |
|
Okay, not entirely; the Let me know if you want to address that last one in this PR as well, otherwise, we can already remove this one only; Lines 120 to 123 in 86cd6da |
|
@thaJeztah sure! I'll take a look. If others are comfortable with this approach I can complete this change. It is much simpler than the |
|
Updated with the lint exceptions removed and authz test updated. |
|
|
||
| // Server hijacks the connection, error 'connection closed' expected | ||
| resp, err := clientconn.Do(req) | ||
| resp, err := client.Do(req) |
There was a problem hiding this comment.
The workflow with httputil.ClientConn was (simplified): construct a ClientConn, round-trip one HTTP request, then take its net.Conn. Looking at the implementation, (*httputil.ClientConn).Do() looks uncannily similar to (*hijackedConn).RoundTrip(). And when you ignore the pipelining cruft in the httputil code (waiting until the last request has been fully written before writing the next one to the conn) which does not come into play when only a single round-trip is made with the instance, they are functionally indistinguishable.
http.Client does a lot of things above and beyond httputil.ClientConn. For instance, it handles 3xx redirect responses by internally making a follow-up request to the new location. For this to work as expected, the http.RoundTripper assigned to the client's Transport field has to adhere to the interface contract, particularly the ability to make independent requests to different servers depending on the request URL. I think it's safe to say that things would not go well if the HTTP client tried to follow a redirect using hijackedConn as the RoundTripper.
| resp, err := client.Do(req) | |
| resp, err := hc.RoundTrip(req) |
As a bonus, it would then be possible to wrap hc in an otelhttp.Transport for injecting the span context into the request headers.
|
@dmcgowan while working on this, perhaps you have time to look at these as well; |
ea5e142 to
2543bf0
Compare
|
@thaJeztah that code has changed and Brian added a case for the tls config when the otel change was put in. The original issue may no longer exist. @corhere updated to just use |
2543bf0 to
365c43d
Compare
thaJeztah
left a comment
There was a problem hiding this comment.
some minor comments in the second commit, but looks good otherwise 😅
| req = req.WithContext(ctx) | ||
| resp, err := c.Do(req) | ||
| req.URL.Scheme = "http" | ||
| req.URL.Host = daemonURL.Path |
There was a problem hiding this comment.
So we need to use client.DummyHost here instead? (see #45942)
| req.URL.Host = daemonURL.Path | |
| req.URL.Host = client.DummyHost |
There was a problem hiding this comment.
I don't think our integration tests need to be compatible with Go 1.20.6, 1.20.7 or 1.21.0. It was a regression, and has been fixed since Go 1.20.8, 1.21.1. We don't have to work around it any longer.
There was a problem hiding this comment.
DummyHost is maybe clearer, at least it would be much better for constructing a full URL. Without setting any of this it fails and setting the Host to path is still weird with the slashes encoded.
Simplify the hijack process by just performing the http request/response on the connection and returning the raw conn after success. The client conn from httputil is deprecated and easily replaced. Signed-off-by: Derek McGowan <[email protected]>
Signed-off-by: Derek McGowan <[email protected]>
Signed-off-by: Derek McGowan <[email protected]>
Signed-off-by: Derek McGowan <[email protected]>
365c43d to
eb9ce77
Compare
|
@thaJeztah updated the authz test to use DummyHost |
Simplify the hijack process by just performing the http request/response on the connection and returning the raw conn after success. The client conn from httputil is deprecated and easily replaced.
Just a draft to see if the tests are ok with it.