Skip to content

Commit

Permalink
feat(s3): add s3UrlForObject
Browse files Browse the repository at this point in the history
fixes #7507
  • Loading branch information
christophgysin committed Apr 22, 2020
1 parent 51aecde commit 3d12684
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 13 deletions.
50 changes: 40 additions & 10 deletions packages/@aws-cdk/aws-s3/lib/bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ export interface IBucket extends IResource {
*/
urlForObject(key?: string): string;

/**
* The S3 URL of an S3 object. For example:
* @example s3://onlybucket
* @example s3://bucket/key
* @param key The S3 key of the object. If not specified, the S3 URL of the
* bucket is returned.
* @returns an ObjectS3Url token
*/
s3UrlForObject(key?: string): string;

/**
* Returns an ARN that represents all objects within the bucket that match
* the key pattern specified. To represent all keys, specify ``"*"``.
Expand Down Expand Up @@ -418,6 +428,23 @@ abstract class BucketBase extends Resource implements IBucket {
}
}

private buildUrl(prefix: string, key?: string): string {
const components = [
prefix,
];

if (key) {
// trim prepending '/'
if (typeof key === 'string' && key.startsWith('/')) {
key = key.substr(1);
}
components.push('/');
components.push(key);
}

return components.join('');
}

/**
* The https URL of an S3 object. For example:
* @example https://s3.us-west-1.amazonaws.com/onlybucket
Expand All @@ -429,17 +456,20 @@ abstract class BucketBase extends Resource implements IBucket {
*/
public urlForObject(key?: string): string {
const stack = Stack.of(this);
const components = [ `https://s3.${stack.region}.${stack.urlSuffix}/${this.bucketName}` ];
if (key) {
// trim prepending '/'
if (typeof key === 'string' && key.startsWith('/')) {
key = key.substr(1);
}
components.push('/');
components.push(key);
}
const prefix = `https://s3.${stack.region}.${stack.urlSuffix}/${this.bucketName}`;
return this.buildUrl(prefix, key);
}

return components.join('');
/**
* The S3 URL of an S3 object. For example:
* @example s3://onlybucket
* @example s3://bucket/key
* @param key The S3 key of the object. If not specified, the S3 URL of the
* bucket is returned.
* @returns an ObjectS3Url token
*/
public s3UrlForObject(key?: string): string {
return this.buildUrl('s3://', key);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"Resources": {
"MyBucketF68F3FF0": {
"Type": "AWS::S3::Bucket",
"DeletionPolicy": "Delete",
"UpdateReplacePolicy": "Delete"
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
}
},
"Outputs": {
Expand Down Expand Up @@ -38,4 +38,4 @@
}
}
}
}
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-s3/test/integ.bucket.url.lit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class TestStack extends cdk.Stack {

new cdk.CfnOutput(this, 'BucketURL', { value: bucket.bucketWebsiteUrl });
new cdk.CfnOutput(this, 'ObjectURL', { value: bucket.urlForObject('myfolder/myfile.txt') });
new cdk.CfnOutput(this, 'S3ObjectURL', { value: bucket.s3UrlForObject('myfolder/myfile.txt') });
/// !hide
}
}
Expand Down
64 changes: 64 additions & 0 deletions packages/@aws-cdk/aws-s3/test/test.bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1388,6 +1388,70 @@ export = {
test.done();
},

's3UrlForObject returns a token with the S3 URL of the token'(test: Test) {
const stack = new cdk.Stack();
const bucket = new s3.Bucket(stack, 'MyBucket');

new cdk.CfnOutput(stack, 'BucketS3URL', { value: bucket.s3UrlForObject() });
new cdk.CfnOutput(stack, 'MyFileS3URL', { value: bucket.s3UrlForObject('my/file.txt') });
new cdk.CfnOutput(stack, 'YourFileS3URL', { value: bucket.s3UrlForObject('/your/file.txt') }); // "/" is optional

expect(stack).toMatch({
'Resources': {
'MyBucketF68F3FF0': {
'Type': 'AWS::S3::Bucket',
'DeletionPolicy': 'Retain',
'UpdateReplacePolicy': 'Retain',
},
},
'Outputs': {
'BucketS3URL': {
'Value': {
'Fn::Join': [
'',
[
's3://',
{
'Ref': 'MyBucketF68F3FF0',
},
],
],
},
},
'MyFileS3URL': {
'Value': {
'Fn::Join': [
'',
[
's3://',
{
'Ref': 'MyBucketF68F3FF0',
},
'/my/file.txt',
],
],
},
},
'YourFileS3URL': {
'Value': {
'Fn::Join': [
'',
[
's3://',
{
'Ref': 'MyBucketF68F3FF0',
},
'/your/file.txt',
],
],
},
},
},
});

test.done();
},

'grantPublicAccess': {
'by default, grants s3:GetObject to all objects'(test: Test) {
// GIVEN
Expand Down

0 comments on commit 3d12684

Please sign in to comment.