aboutsummaryrefslogtreecommitdiffstats
path: root/client/go/internal/util/http.go
diff options
context:
space:
mode:
Diffstat (limited to 'client/go/internal/util/http.go')
-rw-r--r--client/go/internal/util/http.go65
1 files changed, 48 insertions, 17 deletions
diff --git a/client/go/internal/util/http.go b/client/go/internal/util/http.go
index b18f9a00c6a..cb35932c8e7 100644
--- a/client/go/internal/util/http.go
+++ b/client/go/internal/util/http.go
@@ -2,22 +2,22 @@
package util
import (
+ "bytes"
"crypto/tls"
"fmt"
"net/http"
"time"
"github.com/vespa-engine/vespa/client/go/internal/build"
+ "golang.org/x/net/http2"
)
type HTTPClient interface {
Do(request *http.Request, timeout time.Duration) (response *http.Response, error error)
- Transport() *http.Transport
}
type defaultHTTPClient struct {
- client *http.Client
- transport *http.Transport
+ client *http.Client
}
func (c *defaultHTTPClient) Do(request *http.Request, timeout time.Duration) (response *http.Response, error error) {
@@ -31,24 +31,55 @@ func (c *defaultHTTPClient) Do(request *http.Request, timeout time.Duration) (re
return c.client.Do(request)
}
-func (c *defaultHTTPClient) Transport() *http.Transport { return c.transport }
-
func SetCertificate(client HTTPClient, certificates []tls.Certificate) {
- client.Transport().TLSClientConfig = &tls.Config{
- Certificates: certificates,
- MinVersion: tls.VersionTLS12,
+ c, ok := client.(*defaultHTTPClient)
+ if !ok {
+ return
+ }
+ // Use HTTP/2 transport explicitly. Connection reuse does not work properly when using regular http.Transport, even
+ // though it upgrades to HTTP/2 automatically
+ // https://github.com/golang/go/issues/16582
+ // https://github.com/golang/go/issues/22091
+ var transport *http2.Transport
+ if _, ok := c.client.Transport.(*http.Transport); ok {
+ transport = &http2.Transport{}
+ c.client.Transport = transport
+ } else if t, ok := c.client.Transport.(*http2.Transport); ok {
+ transport = t
+ } else {
+ panic(fmt.Sprintf("unknown transport type: %T", c.client.Transport))
+ }
+ if ok && !c.hasCertificates(transport.TLSClientConfig, certificates) {
+ transport.TLSClientConfig = &tls.Config{
+ Certificates: certificates,
+ MinVersion: tls.VersionTLS12,
+ }
}
}
-func CreateClient(timeout time.Duration) HTTPClient {
- transport := http.Transport{
- ForceAttemptHTTP2: true,
+func (c *defaultHTTPClient) hasCertificates(tlsConfig *tls.Config, certs []tls.Certificate) bool {
+ if tlsConfig == nil {
+ return false
}
- return &defaultHTTPClient{
- client: &http.Client{
- Timeout: timeout,
- Transport: &transport,
- },
- transport: &transport,
+ if len(tlsConfig.Certificates) != len(certs) {
+ return false
}
+ for i := 0; i < len(certs); i++ {
+ if len(tlsConfig.Certificates[i].Certificate) != len(certs[i].Certificate) {
+ return false
+ }
+ for j := 0; j < len(certs[i].Certificate); j++ {
+ if !bytes.Equal(tlsConfig.Certificates[i].Certificate[j], certs[i].Certificate[j]) {
+ return false
+ }
+ }
+ }
+ return true
+}
+
+func CreateClient(timeout time.Duration) HTTPClient {
+ return &defaultHTTPClient{client: &http.Client{
+ Timeout: timeout,
+ Transport: http.DefaultTransport,
+ }}
}