Skip to content

Commit 55f45b9

Browse files
committed
fix(middleware-sdk-transcribe-streaming): unsign the non host headers
1 parent d018293 commit 55f45b9

File tree

2 files changed

+56
-4
lines changed

2 files changed

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

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)