Skip to content

Commit c9c4127

Browse files
AllanZhengYPtrivikr
authored andcommitted
fix: assure bucket endpoint middleware inserted before host-header-middleware (#574)
* fix: use host name from request instead of endpont provider * fix: assure bucketEndpointMw applies before hostHeaderMw
1 parent ae04135 commit c9c4127

File tree

6 files changed

+108
-11
lines changed

6 files changed

+108
-11
lines changed

packages/middleware-bucket-endpoint/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"devDependencies": {
2121
"@types/jest": "^24.0.12",
2222
"jest": "^24.7.1",
23-
"typescript": "~3.4.0"
23+
"typescript": "~3.4.0",
24+
"@aws-sdk/middleware-stack": "^0.1.0-preview.6"
2425
}
2526
}

packages/middleware-bucket-endpoint/src/bucketEndpointMiddleware.spec.ts

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
import { bucketEndpointMiddleware } from "./bucketEndpointMiddleware";
21
import { HttpRequest } from "@aws-sdk/protocol-http";
2+
import { MiddlewareStack } from "@aws-sdk/middleware-stack";
3+
import {
4+
bucketEndpointMiddleware,
5+
bucketEndpointMiddlewareOptions
6+
} from "./bucketEndpointMiddleware";
37
import { resolveBucketEndpointConfig } from "./configurations";
48

59
describe("bucketEndpointMiddleware", () => {
@@ -129,4 +133,29 @@ describe("bucketEndpointMiddleware", () => {
129133
expect(hostname).toBe("bucket.s3-accelerate.dualstack.amazonaws.com");
130134
expect(path).toBe("/");
131135
});
136+
137+
it("should be inserted before 'hostheaderMiddleware' if exists", async () => {
138+
const stack = new MiddlewareStack();
139+
const mockHostheaderMiddleware = (next: any) => (args: any) => {
140+
args.request.arr.push("two");
141+
return next(args);
142+
};
143+
const mockbucketEndpointMiddleware = (next: any) => (args: any) => {
144+
args.request.arr.push("one");
145+
return next(args);
146+
};
147+
stack.add(mockHostheaderMiddleware, {
148+
...bucketEndpointMiddlewareOptions,
149+
name: bucketEndpointMiddlewareOptions.toMiddleware
150+
});
151+
stack.addRelativeTo(
152+
mockbucketEndpointMiddleware,
153+
bucketEndpointMiddlewareOptions
154+
);
155+
const handler = stack.resolve(next, {} as any);
156+
expect.assertions(2);
157+
await handler({ request: { arr: [] }, input: {} } as any);
158+
expect(next.mock.calls.length).toBe(1);
159+
expect(next.mock.calls[0][0].request.arr).toEqual(["one", "two"]);
160+
});
132161
});

packages/middleware-bucket-endpoint/src/bucketEndpointMiddleware.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import {
77
BuildHandlerOutput,
88
BuildMiddleware,
99
MetadataBearer,
10-
Pluggable
10+
Pluggable,
11+
RelativeLocation
1112
} from "@aws-sdk/types";
1213
import { HttpRequest } from "@aws-sdk/protocol-http";
1314

@@ -51,17 +52,20 @@ export function bucketEndpointMiddleware(
5152
};
5253
}
5354

54-
export const bucketEndpointMiddlewareOptions: BuildHandlerOptions = {
55+
export const bucketEndpointMiddlewareOptions: BuildHandlerOptions &
56+
RelativeLocation<any, any> = {
5557
step: "build",
5658
tags: ["BUCKET_ENDPOINT"],
57-
name: "bucketEndpointMiddleware"
59+
name: "bucketEndpointMiddleware",
60+
relation: "before",
61+
toMiddleware: "hostHeaderMiddleware"
5862
};
5963

6064
export const getBucketEndpointPlugin = (
6165
options: BucketEndpointResolvedConfig
6266
): Pluggable<any, any> => ({
6367
applyToStack: clientStack => {
64-
clientStack.add(
68+
clientStack.addRelativeTo(
6569
bucketEndpointMiddleware(options),
6670
bucketEndpointMiddlewareOptions
6771
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const base = require("../../jest.config.base.js");
2+
3+
module.exports = {
4+
...base
5+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { hostHeaderMiddleware } from "./index";
2+
import { HttpRequest } from "@aws-sdk/protocol-http";
3+
describe("hostHeaderMiddleware", () => {
4+
const mockNextHandler = jest.fn();
5+
6+
beforeEach(() => {
7+
jest.clearAllMocks();
8+
});
9+
10+
it("should set host header if not already set", async () => {
11+
expect.assertions(2);
12+
const middleware = hostHeaderMiddleware({ requestHandler: {} as any });
13+
const handler = middleware(mockNextHandler, {} as any);
14+
await handler({
15+
input: {},
16+
request: new HttpRequest({ hostname: "foo.amazonaws.com" })
17+
});
18+
expect(mockNextHandler.mock.calls.length).toEqual(1);
19+
expect(mockNextHandler.mock.calls[0][0].request.headers.host).toBe(
20+
"foo.amazonaws.com"
21+
);
22+
});
23+
24+
it("should not set host header if already set", async () => {
25+
expect.assertions(2);
26+
const middleware = hostHeaderMiddleware({ requestHandler: {} as any });
27+
const handler = middleware(mockNextHandler, {} as any);
28+
await handler({
29+
input: {},
30+
request: new HttpRequest({
31+
hostname: "foo.amazonaws.com",
32+
headers: { host: "random host" }
33+
})
34+
});
35+
expect(mockNextHandler.mock.calls.length).toEqual(1);
36+
expect(mockNextHandler.mock.calls[0][0].request.headers.host).toBe(
37+
"random host"
38+
);
39+
});
40+
41+
it("should set :authority header for H2 requests", async () => {
42+
expect.assertions(3);
43+
const middleware = hostHeaderMiddleware({
44+
requestHandler: { metadata: { handlerProtocol: "h2" } }
45+
} as any);
46+
const handler = middleware(mockNextHandler, {} as any);
47+
await handler({
48+
input: {},
49+
request: new HttpRequest({
50+
hostname: "foo.amazonaws.com",
51+
headers: { host: "random host" }
52+
})
53+
});
54+
expect(mockNextHandler.mock.calls.length).toEqual(1);
55+
expect(
56+
mockNextHandler.mock.calls[0][0].request.headers.host
57+
).not.toBeDefined();
58+
expect(
59+
mockNextHandler.mock.calls[0][0].request.headers[":authority"]
60+
).toEqual("");
61+
});
62+
});

packages/middleware-host-header/src/index.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ import { HttpRequest } from "@aws-sdk/protocol-http";
22
import {
33
RequestHandler,
44
BuildMiddleware,
5-
Provider,
6-
Endpoint,
75
BuildHandlerOptions,
86
AbsoluteLocation,
97
Pluggable
@@ -12,11 +10,9 @@ import {
1210
export interface HostHeaderInputConfig {}
1311
interface PreviouslyResolved {
1412
requestHandler: RequestHandler<any, any>;
15-
endpoint: Provider<Endpoint>;
1613
}
1714
export interface HostHeaderResolvedConfig {
1815
requestHandler: RequestHandler<any, any>;
19-
endpoint: Provider<Endpoint>;
2016
}
2117
export function resolveHostHeaderConfig<T>(
2218
input: T & PreviouslyResolved & HostHeaderInputConfig
@@ -40,7 +36,7 @@ export const hostHeaderMiddleware = <
4036
request.headers[":authority"] = "";
4137
//non-H2 request and 'host' header is not set, set the 'host' header to request's hostname.
4238
} else if (!request.headers["host"]) {
43-
request.headers["host"] = (await options.endpoint()).hostname;
39+
request.headers["host"] = request.hostname;
4440
}
4541
return next(args);
4642
};

0 commit comments

Comments
 (0)