Skip to content

Commit 947c8bc

Browse files
authored
fix(endpoint): dedupe clientContext/builtIn params, fix s3 unit test (#4051)
* fix(endpoint): dedupe clientContext/builtIn params, fix s3 unit test * fix(endpoint): fix unit tests for parseURL * fix(endpoint): parseURL unit tests
1 parent 79e11d7 commit 947c8bc

File tree

4 files changed

+80
-17
lines changed

4 files changed

+80
-17
lines changed

clients/client-s3/test/S3.spec.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,11 @@ describe("endpoint", () => {
1919
expect(request.protocol).to.equal("http:");
2020
expect(request.hostname).to.equal("localhost");
2121
expect(request.port).to.equal(8080);
22-
//query and path should not be overwritten
23-
expect(request.query).not.to.contain({ foo: "bar" });
24-
expect(request.path).not.to.equal("/path");
22+
expect(request.path).to.equal("/path/bucket/key");
2523
return Promise.resolve({ output: {} as any, response: {} as any });
2624
};
27-
const client = new S3({ endpoint: "http://localhost:8080/path?foo=bar" });
25+
const client = new S3({ endpoint: "http://localhost:8080/path", forcePathStyle: true });
26+
2827
client.middlewareStack.add(endpointValidator, {
2928
step: "serialize",
3029
name: "endpointValidator",

codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddEndpointsV2ParameterNameMap.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ public AddEndpointsV2ParameterNameMap() {
3030
"ForcePathStyle", "forcePathStyle",
3131
"Accelerate", "useAccelerateEndpoint",
3232
"DisableMRAP", "disableMultiregionAccessPoints",
33-
"UseArnRegion", "useArnRegion"
33+
"DisableMultiRegionAccessPoints", "disableMultiregionAccessPoints",
34+
"UseArnRegion", "useArnRegion",
35+
"Endpoint", "endpoint",
36+
"UseGlobalEndpoint", "useGlobalEndpoint"
3437
));
3538
}
3639
}
Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,42 @@
1+
import { Endpoint, EndpointURL, EndpointURLScheme } from "@aws-sdk/types";
2+
13
import { parseURL } from "./parseURL";
24

35
describe(parseURL.name, () => {
4-
it.each([
5-
["https://example.com", { scheme: "https", authority: "example.com", path: "/", normalizedPath: "/", isIp: false }],
6+
const testCases: [string, EndpointURL][] = [
7+
[
8+
"https://example.com",
9+
{ scheme: EndpointURLScheme.HTTPS, authority: "example.com", path: "/", normalizedPath: "/", isIp: false },
10+
],
611
[
712
"http://example.com:80/foo/bar",
8-
{ scheme: "http", authority: "example.com:80", path: "/foo/bar", normalizedPath: "/foo/bar/", isIp: false },
13+
{
14+
scheme: EndpointURLScheme.HTTP,
15+
authority: "example.com:80",
16+
path: "/foo/bar",
17+
normalizedPath: "/foo/bar/",
18+
isIp: false,
19+
},
20+
],
21+
[
22+
"https://127.0.0.1",
23+
{ scheme: EndpointURLScheme.HTTPS, authority: "127.0.0.1", path: "/", normalizedPath: "/", isIp: true },
924
],
10-
["https://127.0.0.1", { scheme: "https", authority: "127.0.0.1", path: "/", normalizedPath: "/", isIp: true }],
1125
[
1226
"https://127.0.0.1:8443",
13-
{ scheme: "https", authority: "127.0.0.1:8443", path: "/", normalizedPath: "/", isIp: true },
27+
{ scheme: EndpointURLScheme.HTTPS, authority: "127.0.0.1:8443", path: "/", normalizedPath: "/", isIp: true },
28+
],
29+
[
30+
"https://[fe80::1]",
31+
{ scheme: EndpointURLScheme.HTTPS, authority: "[fe80::1]", path: "/", normalizedPath: "/", isIp: true },
1432
],
15-
["https://[fe80::1]", { scheme: "https", authority: "[fe80::1]", path: "/", normalizedPath: "/", isIp: true }],
1633
[
1734
"https://[fe80::1]:8443",
18-
{ scheme: "https", authority: "[fe80::1]:8443", path: "/", normalizedPath: "/", isIp: true },
35+
{ scheme: EndpointURLScheme.HTTPS, authority: "[fe80::1]:8443", path: "/", normalizedPath: "/", isIp: true },
1936
],
20-
])("test '%s'", (input, output) => {
37+
];
38+
39+
it.each(testCases)("test '%s'", (input: string, output: EndpointURL) => {
2140
expect(parseURL(input)).toEqual(output);
2241
});
2342

@@ -32,4 +51,27 @@ describe(parseURL.name, () => {
3251
it("returns null for invalid URL", () => {
3352
expect(parseURL("invalid")).toBeNull();
3453
});
54+
55+
it.each(testCases)("test as URL '%s'", (input: string, output: EndpointURL) => {
56+
const url = new URL(input);
57+
expect(parseURL(url)).toEqual({
58+
...output,
59+
authority: url.hostname + (url.port ? `:${url.port}` : ""),
60+
});
61+
});
62+
63+
it.each(testCases)("test as EndpointV1 '%s'", (input: string, output: EndpointURL) => {
64+
const url = new URL(input);
65+
const endpointV1: Endpoint = {
66+
protocol: url.protocol,
67+
hostname: url.hostname,
68+
port: url.port ? Number(url.port) : undefined,
69+
path: url.pathname,
70+
};
71+
72+
expect(parseURL(endpointV1)).toEqual({
73+
...output,
74+
authority: url.hostname + (url.port ? `:${url.port}` : ""),
75+
});
76+
});
3577
});

packages/util-endpoints/src/lib/parseURL.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { EndpointURL, EndpointURLScheme } from "@aws-sdk/types";
1+
import { Endpoint, EndpointURL, EndpointURLScheme } from "@aws-sdk/types";
22

33
import { isIpAddress } from "./isIpAddress";
44

@@ -8,21 +8,35 @@ const DEFAULT_PORTS: Record<EndpointURLScheme, number> = {
88
};
99

1010
/**
11-
* Parses a string into it’s Endpoint URL components.
11+
* Parses a string, URL, or Endpoint into it’s Endpoint URL components.
1212
*/
13-
export const parseURL = (value: string): EndpointURL | null => {
13+
export const parseURL = (value: string | URL | Endpoint): EndpointURL | null => {
1414
const whatwgURL = (() => {
1515
try {
16+
if (value instanceof URL) {
17+
return value;
18+
}
19+
if (typeof value === "object" && "hostname" in value) {
20+
const { hostname, port, protocol = "", path = "", query = {} } = value as Endpoint;
21+
const url = new URL(`${protocol}//${hostname}${port ? `:${port}` : ""}${path}`);
22+
url.search = Object.entries(query)
23+
.map(([k, v]) => `${k}=${v}`)
24+
.join("&");
25+
return url;
26+
}
1627
return new URL(value);
1728
} catch (error) {
1829
return null;
1930
}
2031
})();
2132

2233
if (!whatwgURL) {
34+
console.error(`Unable to parse ${JSON.stringify(value)} as a whatwg URL.`);
2335
return null;
2436
}
2537

38+
const urlString = whatwgURL.href;
39+
2640
const { host, hostname, pathname, protocol, search } = whatwgURL;
2741

2842
if (search) {
@@ -35,7 +49,12 @@ export const parseURL = (value: string): EndpointURL | null => {
3549
}
3650

3751
const isIp = isIpAddress(hostname);
38-
const authority = `${host}${value.includes(`${host}:${DEFAULT_PORTS[scheme]}`) ? `:${DEFAULT_PORTS[scheme]}` : ``}`;
52+
53+
const inputContainsDefaultPort =
54+
urlString.includes(`${host}:${DEFAULT_PORTS[scheme]}`) ||
55+
(typeof value === "string" && value.includes(`${host}:${DEFAULT_PORTS[scheme]}`));
56+
57+
const authority = `${host}${inputContainsDefaultPort ? `:${DEFAULT_PORTS[scheme]}` : ``}`;
3958

4059
return {
4160
scheme,

0 commit comments

Comments
 (0)