Reputation: 15599
I'm interacting with a server (that is out of my control) in which protocol upgrade is not performed by the server if a request contains content (POST, PUT, PATCH with payload). It's unclear exactly what the issue with the server is, but I noticed that when I query with --http2-prior-knowledge
, the protocol is upgraded:
❯ curl -i -PUT --http2-prior-knowledge http://localhost:8081/document/v1/foo -d '{"fields": {"docid": "123"}}'
HTTP/2 200
date: Tue, 08 Nov 2022 13:26:50 GMT
content-type: application/json;charset=utf-8
vary: Accept-Encoding
content-length: 78
The same request without --http2-prior-knowledge
is stuck at HTTP/1.1. This seems closer to the default behaviour of Go's HTTP client
❯ curl -i -PUT --http2 http://localhost:8081/document/v1/foo -d '{"fields": {"docid": "123"}}'
HTTP/1.1 200 OK
Date: Tue, 08 Nov 2022 01:37:17 GMT
Content-Type: application/json;charset=utf-8
Vary: Accept-Encoding
Content-Length: 78
When I call this same API using Go's default client, the protocol is not upgraded. I've tried setting ForceAttemptHTTP2: true
on the transport, but each http.Response
contains a .Proto
of HTTP/1.1
I think what I need to understand is how I can mimic curl's prior-knowledge flag in Go. Is this possible?
Upvotes: 2
Views: 846
Reputation: 15599
I solved this issue by specifying a custom http2.Transport
which skipped TLS dial. The ideal solution, in retrospect, is to use an SSL certificate (self-signed is sufficient) which would better guarantee the use of HTTP2. Leaving some links for posterity
c := &http.Client{
// Skip TLS Dial
Transport: &http2.Transport{
AllowHTTP: true,
DialTLS: func(netw, addr string, cfg *tls.Config) (net.Conn, error) {
return net.Dial(netw, addr)
},
},
}
And links:
Upvotes: 1