diff --git a/src/interceptor.test.ts b/src/interceptor.test.ts index ed6a4d8b..d9b13f74 100644 --- a/src/interceptor.test.ts +++ b/src/interceptor.test.ts @@ -73,7 +73,7 @@ describe("interceptor", () => { ); }); - it("signs url query paremeters in GET requests", async () => { + it("signs url query parameters in GET requests", async () => { // Arrange const request: InternalAxiosRequestConfig = { method: "GET", @@ -107,7 +107,7 @@ describe("interceptor", () => { ); }); - it("signs query paremeters in GET requests", async () => { + it("signs query parameters in GET requests", async () => { // Arrange const request: InternalAxiosRequestConfig = { method: "GET", @@ -548,4 +548,49 @@ describe("credentials", () => { }, ); }); + + it("supports retries", async () => { + // Arrange + const data = { foo: "bar" }; + + const request: InternalAxiosRequestConfig = { + method: "POST", + url: "https://example.com/foobar", + data, + headers: getDefaultHeaders(), + transformRequest: getDefaultTransformRequest(), + }; + + + (sign as jest.Mock).mockImplementation((request) => { + // neither call should contain the previous Authorization header + expect(request).toEqual({ + service: "execute-api", + path: "/foobar", + method: "POST", + region: "local", + host: "example.com", + body: '{"foo":"bar"}', + headers: { "Content-Type": "application/json" }, + signQuery: undefined + }) + request.headers['Authorization'] = 'signed'; + return request; + }) + + const interceptor = aws4Interceptor({ + options: { + region: "local", + service: "execute-api", + }, + instance: axios, + }); + + // Act + await interceptor(request); + await interceptor(request); + await interceptor(request); + + expect(sign).toBeCalledTimes(3) + }); }); diff --git a/src/interceptor.ts b/src/interceptor.ts index 64b69f90..6936b807 100644 --- a/src/interceptor.ts +++ b/src/interceptor.ts @@ -1,5 +1,6 @@ import { Request as AWS4Request, sign } from "aws4"; import axios, { + AxiosHeaders, AxiosInstance, AxiosRequestConfig, AxiosRequestHeaders, @@ -133,12 +134,20 @@ export const aws4Interceptor = ({ const { host, pathname, search } = new URL(url); const { data, method } = config; - const headers = config.headers; - + const transformRequest = getTransformer(config); transformRequest.bind(config); + // Save, and reset headers on retry + if (config._originalHeaders) { + config.headers = new AxiosHeaders(config._originalHeaders); + } else { + config._originalHeaders = new AxiosHeaders(config.headers); + } + + const headers = config.headers; + // @ts-expect-error we bound the function to the config object const transformedData = transformRequest(data, headers);