Skip to content

Commit 4b148a3

Browse files
committed
fix(middleware-sdk-transcribe-streaming): unsign the non host headers
1 parent 4e31b7d commit 4b148a3

File tree

2 files changed

+62
-4
lines changed

2 files changed

+62
-4
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { HttpRequest } from "@aws-sdk/protocol-http";
2+
import { SignatureV4 } from "./signer";
3+
describe("transcribe streaming", () => {
4+
describe("WebSocket request signer", () => {
5+
const toSign = new HttpRequest({
6+
headers: {
7+
"x-amz-foo": "foo",
8+
bar: "bar",
9+
"amz-sdk-invocation-id": "123",
10+
"amz-sdk-request": "attempt=1",
11+
host: "aws.amazon.com"
12+
},
13+
body: "hello world",
14+
query: {
15+
prop1: "A",
16+
prop2: "B"
17+
}
18+
});
19+
beforeEach(() => {
20+
jest.mock("@aws-sdk/protocol-http");
21+
((HttpRequest as any) as jest.Mock).mockReturnValue({
22+
isInstance: () => true
23+
});
24+
});
25+
it("should invoke base SigV4 signer correctly", async () => {
26+
expect.assertions(5);
27+
const mockBaseSigner = {
28+
presign: jest
29+
.fn()
30+
.mockImplementation(request => Promise.resolve(request))
31+
};
32+
const signer = new SignatureV4({ signer: mockBaseSigner as any });
33+
const signed = await signer.sign(toSign);
34+
expect(toSign).toMatchObject(signed);
35+
expect(mockBaseSigner.presign).toBeCalled();
36+
// The request's body should not be presigned
37+
expect(mockBaseSigner.presign.mock.calls[0][0].body).toEqual("");
38+
expect(
39+
mockBaseSigner.presign.mock.calls[0][1]!.unsignableHeaders
40+
).toBeDefined();
41+
const unsignableHeaders: Set<string> = mockBaseSigner.presign.mock
42+
.calls[0][1]!.unsignableHeaders;
43+
expect([...unsignableHeaders.entries()].map(([value]) => value)).toEqual(
44+
Object.keys(toSign.headers).filter(a => a !== "host")
45+
);
46+
});
47+
});
48+
});

packages/middleware-sdk-transcribe-streaming/src/signer.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,20 @@ export class SignatureV4 implements RequestSigner, RequestPresigner {
2727
): Promise<IHttpRequest> {
2828
if (HttpRequest.isInstance(toSign)) {
2929
// Presign the endpoint url with empty body, otherwise
30-
// the payload hash would be UNSINGED_PAYLOAD
31-
const signedRequest = await this.signer.presign({ ...toSign, body: "" }, {
32-
expiresIn: 5 * 60 // presigned url must be expired within 5 mins
33-
} as any);
30+
// the payload hash would be UNSINGED-PAYLOAD
31+
const signedRequest = await this.signer.presign(
32+
{ ...toSign, body: "" },
33+
{
34+
// presigned url must be expired within 5 mins.
35+
expiresIn: 5 * 60,
36+
// Not to sign headers. Transcribe-streaming WebSocket
37+
// request omits headers except for required 'host' header. If we sign
38+
// the other headers, the signature could be mismatch.
39+
unsignableHeaders: new Set(
40+
Object.keys(toSign.headers).filter(header => header !== "host")
41+
)
42+
}
43+
);
3444
return {
3545
...signedRequest,
3646
body: toSign.body

0 commit comments

Comments
 (0)