Force http/1.1 for upgrade (Traefik v2)
This commit is contained in:
parent
0c28630948
commit
dd436a689f
6 changed files with 55 additions and 16 deletions
|
@ -1,4 +1,4 @@
|
||||||
FROM golang:1.13-alpine
|
FROM golang:1.14-alpine
|
||||||
|
|
||||||
RUN apk --update upgrade \
|
RUN apk --update upgrade \
|
||||||
&& apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \
|
&& apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \
|
||||||
|
@ -19,7 +19,7 @@ RUN mkdir -p /usr/local/bin \
|
||||||
&& chmod +x /usr/local/bin/go-bindata
|
&& chmod +x /usr/local/bin/go-bindata
|
||||||
|
|
||||||
# Download golangci-lint binary to bin folder in $GOPATH
|
# Download golangci-lint binary to bin folder in $GOPATH
|
||||||
RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.23.0
|
RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.23.8
|
||||||
|
|
||||||
# Download golangci-lint and misspell binary to bin folder in $GOPATH
|
# Download golangci-lint and misspell binary to bin folder in $GOPATH
|
||||||
RUN GO111MODULE=off go get github.com/client9/misspell/cmd/misspell
|
RUN GO111MODULE=off go get github.com/client9/misspell/cmd/misspell
|
||||||
|
|
|
@ -60,7 +60,7 @@ PRE_TARGET= make test-unit
|
||||||
|
|
||||||
Requirements:
|
Requirements:
|
||||||
|
|
||||||
- `go` v1.13+
|
- `go` v1.14+
|
||||||
- environment variable `GO111MODULE=on`
|
- environment variable `GO111MODULE=on`
|
||||||
- [go-bindata](https://github.com/containous/go-bindata) `GO111MODULE=off go get -u github.com/containous/go-bindata/...`
|
- [go-bindata](https://github.com/containous/go-bindata) `GO111MODULE=off go get -u github.com/containous/go-bindata/...`
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ RUN npm install
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# BUILD
|
# BUILD
|
||||||
FROM golang:1.13-alpine as gobuild
|
FROM golang:1.14-alpine as gobuild
|
||||||
|
|
||||||
RUN apk --update upgrade \
|
RUN apk --update upgrade \
|
||||||
&& apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \
|
&& apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -1,6 +1,6 @@
|
||||||
module github.com/containous/traefik/v2
|
module github.com/containous/traefik/v2
|
||||||
|
|
||||||
go 1.13
|
go 1.14
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
||||||
|
|
|
@ -23,12 +23,12 @@ func (t *h2cTransportWrapper) RoundTrip(req *http.Request) (*http.Response, erro
|
||||||
return t.Transport.RoundTrip(req)
|
return t.Transport.RoundTrip(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createHTTPTransport creates an http.Transport configured with the Transport configuration settings.
|
// createRoundtripper creates an http.Roundtripper configured with the Transport configuration settings.
|
||||||
// For the settings that can't be configured in Traefik it uses the default http.Transport settings.
|
// For the settings that can't be configured in Traefik it uses the default http.Transport settings.
|
||||||
// An exception to this is the MaxIdleConns setting as we only provide the option MaxIdleConnsPerHost
|
// An exception to this is the MaxIdleConns setting as we only provide the option MaxIdleConnsPerHost
|
||||||
// in Traefik at this point in time. Setting this value to the default of 100 could lead to confusing
|
// in Traefik at this point in time. Setting this value to the default of 100 could lead to confusing
|
||||||
// behavior and backwards compatibility issues.
|
// behavior and backwards compatibility issues.
|
||||||
func createHTTPTransport(transportConfiguration *static.ServersTransport) (*http.Transport, error) {
|
func createRoundtripper(transportConfiguration *static.ServersTransport) (http.RoundTripper, error) {
|
||||||
if transportConfiguration == nil {
|
if transportConfiguration == nil {
|
||||||
return nil, errors.New("no transport configuration given")
|
return nil, errors.New("no transport configuration given")
|
||||||
}
|
}
|
||||||
|
@ -66,25 +66,26 @@ func createHTTPTransport(transportConfiguration *static.ServersTransport) (*http
|
||||||
transport.IdleConnTimeout = time.Duration(transportConfiguration.ForwardingTimeouts.IdleConnTimeout)
|
transport.IdleConnTimeout = time.Duration(transportConfiguration.ForwardingTimeouts.IdleConnTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
if transportConfiguration.InsecureSkipVerify {
|
if transportConfiguration.InsecureSkipVerify || len(transportConfiguration.RootCAs) > 0 {
|
||||||
transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(transportConfiguration.RootCAs) > 0 {
|
|
||||||
transport.TLSClientConfig = &tls.Config{
|
transport.TLSClientConfig = &tls.Config{
|
||||||
|
InsecureSkipVerify: transportConfiguration.InsecureSkipVerify,
|
||||||
RootCAs: createRootCACertPool(transportConfiguration.RootCAs),
|
RootCAs: createRootCACertPool(transportConfiguration.RootCAs),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := http2.ConfigureTransport(transport)
|
smartTransport, err := newSmartRoundTripper(transport)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return transport, nil
|
return smartTransport, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createRootCACertPool(rootCAs []traefiktls.FileOrContent) *x509.CertPool {
|
func createRootCACertPool(rootCAs []traefiktls.FileOrContent) *x509.CertPool {
|
||||||
|
if len(rootCAs) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
roots := x509.NewCertPool()
|
roots := x509.NewCertPool()
|
||||||
|
|
||||||
for _, cert := range rootCAs {
|
for _, cert := range rootCAs {
|
||||||
|
@ -100,7 +101,7 @@ func createRootCACertPool(rootCAs []traefiktls.FileOrContent) *x509.CertPool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupDefaultRoundTripper(conf *static.ServersTransport) http.RoundTripper {
|
func setupDefaultRoundTripper(conf *static.ServersTransport) http.RoundTripper {
|
||||||
transport, err := createHTTPTransport(conf)
|
transport, err := createRoundtripper(conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithoutContext().Errorf("Could not configure HTTP Transport, fallbacking on default transport: %v", err)
|
log.WithoutContext().Errorf("Could not configure HTTP Transport, fallbacking on default transport: %v", err)
|
||||||
return http.DefaultTransport
|
return http.DefaultTransport
|
||||||
|
|
38
pkg/server/service/smart_roundtripper.go
Normal file
38
pkg/server/service/smart_roundtripper.go
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"golang.org/x/net/http/httpguts"
|
||||||
|
"golang.org/x/net/http2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newSmartRoundTripper(transport *http.Transport) (http.RoundTripper, error) {
|
||||||
|
transportHTTP1 := transport.Clone()
|
||||||
|
|
||||||
|
err := http2.ConfigureTransport(transport)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &smartRoundTripper{
|
||||||
|
http2: transport,
|
||||||
|
http: transportHTTP1,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type smartRoundTripper struct {
|
||||||
|
http2 *http.Transport
|
||||||
|
http *http.Transport
|
||||||
|
}
|
||||||
|
|
||||||
|
// smartRoundTripper implements RoundTrip while making sure that HTTP/2 is not used
|
||||||
|
// with protocols that start with a Connection Upgrade, such as SPDY or Websocket.
|
||||||
|
func (m *smartRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
// If we have a connection upgrade, we don't use HTTP/2
|
||||||
|
if httpguts.HeaderValuesContainsToken(req.Header["Connection"], "Upgrade") {
|
||||||
|
return m.http.RoundTrip(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.http2.RoundTrip(req)
|
||||||
|
}
|
Loading…
Reference in a new issue