diff --git a/49c1e3df55175b2942ad091df86272903cf709da.patch b/49c1e3df55175b2942ad091df86272903cf709da.patch new file mode 100644 index 0000000..f699d0d --- /dev/null +++ b/49c1e3df55175b2942ad091df86272903cf709da.patch @@ -0,0 +1,53 @@ +From 49c1e3df55175b2942ad091df86272903cf709da Mon Sep 17 00:00:00 2001 +From: Julien Salleyron +Date: Fri, 14 Aug 2020 11:03:58 +0200 +Subject: [PATCH] Fix server shutdown + +--- + pkg/server/server_entrypoint_tcp.go | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/pkg/server/server_entrypoint_tcp.go b/pkg/server/server_entrypoint_tcp.go +index bf8a5315b3..3b7efdf4c8 100644 +--- a/pkg/server/server_entrypoint_tcp.go ++++ b/pkg/server/server_entrypoint_tcp.go +@@ -28,12 +28,14 @@ var httpServerLogger = stdlog.New(log.WithoutContext().WriterLevel(logrus.DebugL + type httpForwarder struct { + net.Listener + connChan chan net.Conn ++ errChan chan error + } + + func newHTTPForwarder(ln net.Listener) *httpForwarder { + return &httpForwarder{ + Listener: ln, + connChan: make(chan net.Conn), ++ errChan: make(chan error), + } + } + +@@ -44,8 +46,12 @@ func (h *httpForwarder) ServeTCP(conn tcp.WriteCloser) { + + // Accept retrieves a served connection in ServeTCP. + func (h *httpForwarder) Accept() (net.Conn, error) { +- conn := <-h.connChan +- return conn, nil ++ select { ++ case conn := <-h.connChan: ++ return conn, nil ++ case err := <-h.errChan: ++ return nil, err ++ } + } + + // TCPEntryPoints holds a map of TCPEntryPoint (the entrypoint names being the keys). +@@ -169,7 +175,8 @@ func (e *TCPEntryPoint) Start(ctx context.Context) { + if netErr, ok := err.(net.Error); ok && netErr.Temporary() { + continue + } +- ++ e.httpServer.Forwarder.errChan <- err ++ e.httpsServer.Forwarder.errChan <- err + return + } + diff --git a/49ed06686b6c4be2164c65eb6d807b0fc542aea4.patch b/49ed06686b6c4be2164c65eb6d807b0fc542aea4.patch new file mode 100644 index 0000000..9eb58f6 --- /dev/null +++ b/49ed06686b6c4be2164c65eb6d807b0fc542aea4.patch @@ -0,0 +1,171 @@ +From 49ed06686b6c4be2164c65eb6d807b0fc542aea4 Mon Sep 17 00:00:00 2001 +From: Fernandez Ludovic +Date: Thu, 13 Aug 2020 19:14:25 +0200 +Subject: [PATCH] fix: HTTP smuggling fix. + +--- + pkg/middlewares/auth/forward_test.go | 47 ++++++++++++++-------------- + 1 file changed, 23 insertions(+), 24 deletions(-) + +diff --git a/pkg/middlewares/auth/forward_test.go b/pkg/middlewares/auth/forward_test.go +index 7674a1384d..44486379ac 100644 +--- a/pkg/middlewares/auth/forward_test.go ++++ b/pkg/middlewares/auth/forward_test.go +@@ -28,7 +28,7 @@ func TestForwardAuthFail(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.Error(w, "Forbidden", http.StatusForbidden) + })) +- defer server.Close() ++ t.Cleanup(server.Close) + + middleware, err := NewForward(context.Background(), next, dynamic.ForwardAuth{ + Address: server.URL, +@@ -36,7 +36,7 @@ func TestForwardAuthFail(t *testing.T) { + require.NoError(t, err) + + ts := httptest.NewServer(middleware) +- defer ts.Close() ++ t.Cleanup(ts.Close) + + req := testhelpers.MustNewRequest(http.MethodGet, ts.URL, nil) + res, err := http.DefaultClient.Do(req) +@@ -59,7 +59,7 @@ func TestForwardAuthSuccess(t *testing.T) { + w.Header().Add("X-Auth-Group", "group2") + fmt.Fprintln(w, "Success") + })) +- defer server.Close() ++ t.Cleanup(server.Close) + + next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "user@example.com", r.Header.Get("X-Auth-User")) +@@ -76,7 +76,7 @@ func TestForwardAuthSuccess(t *testing.T) { + require.NoError(t, err) + + ts := httptest.NewServer(middleware) +- defer ts.Close() ++ t.Cleanup(ts.Close) + + req := testhelpers.MustNewRequest(http.MethodGet, ts.URL, nil) + req.Header.Set("X-Auth-Group", "admin_group") +@@ -95,20 +95,19 @@ func TestForwardAuthRedirect(t *testing.T) { + authTs := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "http://example.com/redirect-test", http.StatusFound) + })) +- defer authTs.Close() ++ t.Cleanup(authTs.Close) + + next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "traefik") + }) + +- auth := dynamic.ForwardAuth{ +- Address: authTs.URL, +- } ++ auth := dynamic.ForwardAuth{Address: authTs.URL} ++ + authMiddleware, err := NewForward(context.Background(), next, auth, "authTest") + require.NoError(t, err) + + ts := httptest.NewServer(authMiddleware) +- defer ts.Close() ++ t.Cleanup(ts.Close) + + client := &http.Client{ + CheckRedirect: func(r *http.Request, via []*http.Request) error { +@@ -139,7 +138,7 @@ func TestForwardAuthRemoveHopByHopHeaders(t *testing.T) { + headers := w.Header() + for _, header := range forward.HopHeaders { + if header == forward.TransferEncoding { +- headers.Add(header, "identity") ++ headers.Set(header, "chunked") + } else { + headers.Add(header, "test") + } +@@ -147,29 +146,29 @@ func TestForwardAuthRemoveHopByHopHeaders(t *testing.T) { + + http.Redirect(w, r, "http://example.com/redirect-test", http.StatusFound) + })) +- defer authTs.Close() ++ t.Cleanup(authTs.Close) + + next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "traefik") + }) +- auth := dynamic.ForwardAuth{ +- Address: authTs.URL, +- } +- authMiddleware, err := NewForward(context.Background(), next, auth, "authTest") + +- assert.NoError(t, err, "there should be no error") ++ auth := dynamic.ForwardAuth{Address: authTs.URL} ++ ++ authMiddleware, err := NewForward(context.Background(), next, auth, "authTest") ++ require.NoError(t, err) + + ts := httptest.NewServer(authMiddleware) +- defer ts.Close() ++ t.Cleanup(ts.Close) + + client := &http.Client{ + CheckRedirect: func(r *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse + }, + } ++ + req := testhelpers.MustNewRequest(http.MethodGet, ts.URL, nil) + res, err := client.Do(req) +- assert.NoError(t, err, "there should be no error") ++ require.NoError(t, err) + assert.Equal(t, http.StatusFound, res.StatusCode, "they should be equal") + + for _, header := range forward.HopHeaders { +@@ -177,11 +176,11 @@ func TestForwardAuthRemoveHopByHopHeaders(t *testing.T) { + } + + location, err := res.Location() +- assert.NoError(t, err, "there should be no error") ++ require.NoError(t, err) + assert.Equal(t, "http://example.com/redirect-test", location.String(), "they should be equal") + + body, err := ioutil.ReadAll(res.Body) +- assert.NoError(t, err, "there should be no error") ++ require.NoError(t, err) + assert.NotEmpty(t, string(body), "there should be something in the body") + } + +@@ -192,7 +191,7 @@ func TestForwardAuthFailResponseHeaders(t *testing.T) { + w.Header().Add("X-Foo", "bar") + http.Error(w, "Forbidden", http.StatusForbidden) + })) +- defer authTs.Close() ++ t.Cleanup(authTs.Close) + + next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "traefik") +@@ -205,7 +204,7 @@ func TestForwardAuthFailResponseHeaders(t *testing.T) { + require.NoError(t, err) + + ts := httptest.NewServer(authMiddleware) +- defer ts.Close() ++ t.Cleanup(ts.Close) + + req := testhelpers.MustNewRequest(http.MethodGet, ts.URL, nil) + +@@ -407,7 +406,7 @@ func TestForwardAuthUsesTracing(t *testing.T) { + t.Errorf("expected Mockpfx-Ids-Traceid header to be present in request") + } + })) +- defer server.Close() ++ t.Cleanup(server.Close) + + next := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) + +@@ -426,7 +425,7 @@ func TestForwardAuthUsesTracing(t *testing.T) { + next = tracingMiddleware.NewEntryPoint(context.Background(), tr, "tracingTest", next) + + ts := httptest.NewServer(next) +- defer ts.Close() ++ t.Cleanup(ts.Close) + + req := testhelpers.MustNewRequest(http.MethodGet, ts.URL, nil) + res, err := http.DefaultClient.Do(req) diff --git a/PKGBUILD b/PKGBUILD index e9eef1d..1c06441 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -1,28 +1,39 @@ # Maintainer : Christian Rebischke pkgname=traefik -pkgver=2.2.2 +pkgver=2.2.8 pkgrel=1 pkgdesc="Modern reverse proxy written in Go" arch=('x86_64') url="https://containo.us/traefik/" license=('MIT') -makedepends=('go-pie' 'git' 'go-bindata-hashicorp') +makedepends=('go' 'go-bindata-hashicorp' 'patch') depends=('glibc') backup=('etc/traefik/traefik.toml' 'etc/traefik/traefik.yaml' 'etc/traefik/traefik.yml') source=("${pkgname}-${pkgver}.tar.gz::https://github.com/containous/traefik/releases/download/v${pkgver}/traefik-v${pkgver}.src.tar.gz" 'traefik.service' - 'traefik.sysusers') + 'traefik.sysusers' + 'b77cf4d0b067438c3e1758bb22ad56e644c8122f.patch' + '49ed06686b6c4be2164c65eb6d807b0fc542aea4.patch' + '49c1e3df55175b2942ad091df86272903cf709da.patch') noextract=("${pkgname}-${pkgver}.tar.gz") -sha512sums=('635067220cf22b2aecd958a1e77e5027710038841a3bc2b83391d9a03690b62f9e21ca9c10b2f775a73d61d87491092b544800e3e709233ea741c97f625140bc' +sha512sums=('b379a0408d98193ba6d77b5249f8a5ea8d0949e6ec7e817d1b114c4f3a00513a753b1d9c37019850da8af5f7352b7e717094d262b827cc618173403637324a30' '25ab1113bb69936c443fe49d5d3da7d39171fc82e8fa06f46ed4e2dfcaa89685d50ca50b58c32215852d79e5c8d4736a287c15b75420c78a853c51502cb2641a' - '5fecfed5df77bf28c2c976ebaebedb030904d41509e740821140a4889bda20327f416e78f8d19b0ee78c8bc422d1907ce05ef3562e4d3e36ddfbdbea5e860b2a') + '5fecfed5df77bf28c2c976ebaebedb030904d41509e740821140a4889bda20327f416e78f8d19b0ee78c8bc422d1907ce05ef3562e4d3e36ddfbdbea5e860b2a' + '5e280f66021c95f5f6bb493c7f62d87d8da67921a399fdecfc43ce5c17858b5262996bfc8d0a795ed09dbddb6e5c44160bf4665fdbbcf7884a83ea787780253c' + '9380eceb00cc6e0f7a1d7116d220c8c8c67b755e20d6def8dc991a99ac88c053b54956a236eaf51138c916b9c6401794e58d97a550b4ed08945d44fef689a858' + '15e25430706e1aa0f774dacff50badf98ef621793d27add83fea7a7fb64f364be38c30efe0cc3a53428b83de4b45436a98c23bdb060a103ffa0b7cda5e88d7db') prepare() { mkdir "${srcdir}/${pkgname}-${pkgver}" tar xfvz "${srcdir}/${pkgname}-${pkgver}.tar.gz" -C "${srcdir}/${pkgname}-${pkgver}" + # Apply patches for Go 1.15 upwards compatibility + cd "${srcdir}/${pkgname}-${pkgver}" + patch -p1 < "${srcdir}/49c1e3df55175b2942ad091df86272903cf709da.patch" + patch -p1 < "${srcdir}/b77cf4d0b067438c3e1758bb22ad56e644c8122f.patch" + patch -p1 < "${srcdir}/49ed06686b6c4be2164c65eb6d807b0fc542aea4.patch" } build() { diff --git a/b77cf4d0b067438c3e1758bb22ad56e644c8122f.patch b/b77cf4d0b067438c3e1758bb22ad56e644c8122f.patch new file mode 100644 index 0000000..e3d24f5 --- /dev/null +++ b/b77cf4d0b067438c3e1758bb22ad56e644c8122f.patch @@ -0,0 +1,52 @@ +From b77cf4d0b067438c3e1758bb22ad56e644c8122f Mon Sep 17 00:00:00 2001 +From: Fernandez Ludovic +Date: Thu, 13 Aug 2020 19:15:10 +0200 +Subject: [PATCH] fix: conversion from untyped int to string yields a string of + one rune + +--- + pkg/metrics/statsd_test.go | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/pkg/metrics/statsd_test.go b/pkg/metrics/statsd_test.go +index 11955a50aa..64a585609d 100644 +--- a/pkg/metrics/statsd_test.go ++++ b/pkg/metrics/statsd_test.go +@@ -3,6 +3,7 @@ package metrics + import ( + "context" + "net/http" ++ "strconv" + "testing" + "time" + +@@ -36,11 +37,11 @@ func TestStatsD(t *testing.T) { + } + + udp.ShouldReceiveAll(t, expected, func() { +- statsdRegistry.ServiceReqsCounter().With("service", "test", "code", string(http.StatusOK), "method", http.MethodGet).Add(1) +- statsdRegistry.ServiceReqsCounter().With("service", "test", "code", string(http.StatusNotFound), "method", http.MethodGet).Add(1) ++ statsdRegistry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) ++ statsdRegistry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) + statsdRegistry.ServiceRetriesCounter().With("service", "test").Add(1) + statsdRegistry.ServiceRetriesCounter().With("service", "test").Add(1) +- statsdRegistry.ServiceReqDurationHistogram().With("service", "test", "code", string(http.StatusOK)).Observe(10000) ++ statsdRegistry.ServiceReqDurationHistogram().With("service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) + statsdRegistry.ConfigReloadsCounter().Add(1) + statsdRegistry.ConfigReloadsFailureCounter().Add(1) + statsdRegistry.EntryPointReqsCounter().With("entrypoint", "test").Add(1) +@@ -76,11 +77,11 @@ func TestStatsDWithPrefix(t *testing.T) { + } + + udp.ShouldReceiveAll(t, expected, func() { +- statsdRegistry.ServiceReqsCounter().With("service", "test", "code", string(http.StatusOK), "method", http.MethodGet).Add(1) +- statsdRegistry.ServiceReqsCounter().With("service", "test", "code", string(http.StatusNotFound), "method", http.MethodGet).Add(1) ++ statsdRegistry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) ++ statsdRegistry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) + statsdRegistry.ServiceRetriesCounter().With("service", "test").Add(1) + statsdRegistry.ServiceRetriesCounter().With("service", "test").Add(1) +- statsdRegistry.ServiceReqDurationHistogram().With("service", "test", "code", string(http.StatusOK)).Observe(10000) ++ statsdRegistry.ServiceReqDurationHistogram().With("service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) + statsdRegistry.ConfigReloadsCounter().Add(1) + statsdRegistry.ConfigReloadsFailureCounter().Add(1) + statsdRegistry.EntryPointReqsCounter().With("entrypoint", "test").Add(1)