Skip to content

Commit 9d3cbb6

Browse files
fix(lib-storage): location in upload result should include custom port (#6282)
1 parent b963a51 commit 9d3cbb6

File tree

2 files changed

+69
-14
lines changed

2 files changed

+69
-14
lines changed

Diff for: lib/lib-storage/src/Upload.spec.ts

+65-11
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ const putObjectTaggingMock = jest.fn().mockResolvedValue({
2222
});
2323

2424
let hostname = "s3.region.amazonaws.com";
25+
let port: number | undefined;
2526
const endpointMock = jest.fn().mockImplementation(() => ({
2627
hostname,
27-
port: undefined,
28+
port,
2829
protocol: "https:",
2930
path: "/",
3031
query: undefined,
@@ -249,6 +250,7 @@ describe(Upload.name, () => {
249250
describe("bucket hostname deduplication", () => {
250251
afterEach(() => {
251252
hostname = "s3.region.amazonaws.com";
253+
port = undefined;
252254
});
253255
it("should dedupe bucket in endpoint hostname when forcePathStyle = false", async () => {
254256
hostname = "example-bucket.example-host.com";
@@ -280,20 +282,72 @@ describe(Upload.name, () => {
280282
expect(result.Bucket).toEqual("example-bucket");
281283
expect(result.Location).toEqual("https://example-bucket.example-host.com/example-key");
282284
});
285+
it("should dedupe bucket in endpoint hostname and port when forcePathStyle = false and explicit port is provided", async () => {
286+
hostname = "example-bucket.example-host.com";
287+
port = 8443;
288+
const buffer = Buffer.from("");
289+
const actionParams = { ...params, Body: buffer };
290+
const upload = new Upload({
291+
params: actionParams,
292+
client: new S3({
293+
forcePathStyle: false,
294+
}),
295+
});
296+
const result = (await upload.done()) as CompleteMultipartUploadCommandOutput;
297+
expect(result.Key).toEqual("example-key");
298+
expect(result.Bucket).toEqual("example-bucket");
299+
expect(result.Location).toEqual("https://example-bucket.example-host.com:8443/example-key");
300+
});
301+
it("should prepend bucket in endpoint hostname and port when it does not already contain it and forcePathStyle = false and explicit port is provided", async () => {
302+
hostname = "example-host.com";
303+
port = 8443;
304+
const buffer = Buffer.from("");
305+
const actionParams = { ...params, Body: buffer };
306+
const upload = new Upload({
307+
params: actionParams,
308+
client: new S3({
309+
forcePathStyle: false,
310+
}),
311+
});
312+
const result = (await upload.done()) as CompleteMultipartUploadCommandOutput;
313+
expect(result.Key).toEqual("example-key");
314+
expect(result.Bucket).toEqual("example-bucket");
315+
expect(result.Location).toEqual("https://example-bucket.example-host.com:8443/example-key");
316+
});
283317
});
284318

285-
it("should return a Location field formatted in path style when forcePathStyle is true", async () => {
286-
const buffer = Buffer.from("");
287-
const actionParams = { ...params, Body: buffer };
288-
const s3Client = new S3({});
289-
s3Client.config.forcePathStyle = true;
290-
const upload = new Upload({
291-
params: actionParams,
292-
client: s3Client,
319+
describe("forcePathStyle support", () => {
320+
afterEach(() => {
321+
port = undefined;
322+
});
323+
it("should return a Location field formatted in path style when forcePathStyle is true", async () => {
324+
const buffer = Buffer.from("");
325+
const actionParams = { ...params, Body: buffer };
326+
const s3Client = new S3({});
327+
s3Client.config.forcePathStyle = true;
328+
const upload = new Upload({
329+
params: actionParams,
330+
client: s3Client,
331+
});
332+
333+
const result = (await upload.done()) as CompleteMultipartUploadCommandOutput;
334+
expect(result.Location).toEqual("https://s3.region.amazonaws.com/example-bucket/example-key");
293335
});
294336

295-
const result = (await upload.done()) as CompleteMultipartUploadCommandOutput;
296-
expect(result.Location).toEqual("https://s3.region.amazonaws.com/example-bucket/example-key");
337+
it("should return a Location field with explicit port and formatted in path style when forcePathStyle is true and explicit port is provided", async () => {
338+
port = 8443;
339+
const buffer = Buffer.from("");
340+
const actionParams = { ...params, Body: buffer };
341+
const s3Client = new S3({});
342+
s3Client.config.forcePathStyle = true;
343+
const upload = new Upload({
344+
params: actionParams,
345+
client: s3Client,
346+
});
347+
348+
const result = (await upload.done()) as CompleteMultipartUploadCommandOutput;
349+
expect(result.Location).toEqual("https://s3.region.amazonaws.com:8443/example-bucket/example-key");
350+
});
297351
});
298352

299353
it("should return a Location field with decoded slash symbols", async () => {

Diff for: lib/lib-storage/src/Upload.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -168,13 +168,14 @@ export class Upload extends EventEmitter {
168168
const Location: string = (() => {
169169
const endpointHostnameIncludesBucket = endpoint.hostname.startsWith(`${locationBucket}.`);
170170
const forcePathStyle = this.client.config.forcePathStyle;
171+
const optionalPort = endpoint.port ? `:${endpoint.port}` : ``;
171172
if (forcePathStyle) {
172-
return `${endpoint.protocol}//${endpoint.hostname}/${locationBucket}/${locationKey}`;
173+
return `${endpoint.protocol}//${endpoint.hostname}${optionalPort}/${locationBucket}/${locationKey}`;
173174
}
174175
if (endpointHostnameIncludesBucket) {
175-
return `${endpoint.protocol}//${endpoint.hostname}/${locationKey}`;
176+
return `${endpoint.protocol}//${endpoint.hostname}${optionalPort}/${locationKey}`;
176177
}
177-
return `${endpoint.protocol}//${locationBucket}.${endpoint.hostname}/${locationKey}`;
178+
return `${endpoint.protocol}//${locationBucket}.${endpoint.hostname}${optionalPort}/${locationKey}`;
178179
})();
179180

180181
this.singleUploadResult = {

0 commit comments

Comments
 (0)