From 06c9fb3da571bf7780533cb52221073dff22a16c Mon Sep 17 00:00:00 2001 From: Jacopo Rota Date: Thu, 12 Oct 2023 09:14:13 +0200 Subject: [PATCH] fix: do not duplicate the oauth headers in case of retry --- client_test.go | 20 ++++++++++++++++++++ oauth.go | 2 +- testing.go | 9 +++++++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/client_test.go b/client_test.go index a0db8b3..1cff8a4 100644 --- a/client_test.go +++ b/client_test.go @@ -94,6 +94,26 @@ func (suite *ClientSuite) TestClientDispatchRequestRetries409(c *gc.C) { c.Check(*server.nbRequests, gc.Equals, NumberOfRetries+1) } +// See https://bugs.launchpad.net/maas/+bug/2039105 +func (suite *ClientSuite) TestClientDispatchRequestRetries409WithoutDuplicatedHeaders(c *gc.C) { + URI := "/some/url/?param1=test" + server := newFlakyServer(URI, 409, NumberOfRetries) + defer server.Close() + client, err := NewAuthenticatedClient(server.URL, "the:api:key") + c.Assert(err, jc.ErrorIsNil) + content := "content" + request, err := http.NewRequest("GET", server.URL+URI, io.NopCloser(strings.NewReader(content))) + c.Assert(err, jc.ErrorIsNil) + + _, err = client.dispatchRequest(request) + + c.Assert(err, jc.ErrorIsNil) + c.Check(*server.nbRequests, gc.Equals, NumberOfRetries+1) + for _, headers := range *server.headers { + c.Check(len(headers.Values("Authorization")), gc.Equals, 1) + } +} + func (suite *ClientSuite) TestTLSClientDispatchRequestRetries503NilBody(c *gc.C) { URI := "/some/path" server := newFlakyTLSServer(URI, 503, NumberOfRetries) diff --git a/oauth.go b/oauth.go index 920960d..b6d5e2d 100644 --- a/oauth.go +++ b/oauth.go @@ -75,6 +75,6 @@ func (signer plainTextOAuthSigner) OAuthSign(request *http.Request) error { authHeader = append(authHeader, fmt.Sprintf(`%s="%s"`, key, url.QueryEscape(value))) } strHeader := "OAuth " + strings.Join(authHeader, ", ") - request.Header.Add("Authorization", strHeader) + request.Header.Set("Authorization", strHeader) return nil } diff --git a/testing.go b/testing.go index 8d45759..4794965 100644 --- a/testing.go +++ b/testing.go @@ -51,6 +51,7 @@ type flakyServer struct { *httptest.Server nbRequests *int requests *[][]byte + headers *[]http.Header } // newFlakyServer creates a "flaky" test http server which will @@ -58,6 +59,7 @@ type flakyServer struct { func newFlakyServer(uri string, code int, nbFlakyResponses int) *flakyServer { nbRequests := 0 requests := make([][]byte, nbFlakyResponses+1) + headers := make([]http.Header, nbFlakyResponses+1) handler := func(writer http.ResponseWriter, request *http.Request) { nbRequests += 1 body, err := readAndClose(request.Body) @@ -65,6 +67,7 @@ func newFlakyServer(uri string, code int, nbFlakyResponses int) *flakyServer { panic(err) } requests[nbRequests-1] = body + headers[nbRequests-1] = request.Header if request.URL.String() != uri { errorMsg := fmt.Sprintf("Error 404: page not found (expected '%v', got '%v').", uri, request.URL.String()) http.Error(writer, errorMsg, http.StatusNotFound) @@ -81,12 +84,13 @@ func newFlakyServer(uri string, code int, nbFlakyResponses int) *flakyServer { } server := httptest.NewServer(http.HandlerFunc(handler)) - return &flakyServer{server, &nbRequests, &requests} + return &flakyServer{server, &nbRequests, &requests, &headers} } func newFlakyTLSServer(uri string, code int, nbFlakyResponses int) *flakyServer { nbRequests := 0 requests := make([][]byte, nbFlakyResponses+1) + headers := make([]http.Header, nbFlakyResponses+1) var server *httptest.Server handler := func(writer http.ResponseWriter, request *http.Request) { @@ -96,6 +100,7 @@ func newFlakyTLSServer(uri string, code int, nbFlakyResponses int) *flakyServer panic(err) } requests[nbRequests-1] = body + headers[nbRequests-1] = request.Header if request.URL.String() != uri { errorMsg := fmt.Sprintf("Error 404: page not found (expected '%v', got '%v').", uri, request.URL.String()) http.Error(writer, errorMsg, http.StatusNotFound) @@ -111,7 +116,7 @@ func newFlakyTLSServer(uri string, code int, nbFlakyResponses int) *flakyServer } } server = httptest.NewTLSServer(http.HandlerFunc(handler)) - return &flakyServer{server, &nbRequests, &requests} + return &flakyServer{server, &nbRequests, &requests, &headers} } type simpleResponse struct {