Skip to content

Commit 4d089d1

Browse files
author
Robert-Jan Huijsman
committed
Add shim to fix GCS media links with slashes, remove shim that removed spurious GCS events.
1 parent 50ba370 commit 4d089d1

File tree

2 files changed

+55
-36
lines changed

2 files changed

+55
-36
lines changed

spec/providers/storage.spec.ts

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -70,38 +70,52 @@ describe('storage.FunctionBuilder', () => {
7070
expect(() => storage.bucket('bad/bucket/format')).to.throw(Error);
7171
});
7272

73-
it('should filter out spurious deploy-time events', () => {
74-
let functionRan = false;
75-
let cloudFunction = storage.object().onChange(() => {
76-
functionRan = true;
77-
return null;
73+
it('should correct nested media links using a single literal slash', () => {
74+
let cloudFunction = storage.object().onChange((event) => {
75+
return event.data.mediaLink;
7876
});
77+
let badMediaLinkEvent = {
78+
data: {
79+
mediaLink: 'https://www.googleapis.com/storage/v1/b/mybucket.appspot.com'
80+
+ '/o/nestedfolder/myobject.file?generation=12345&alt=media',
81+
},
82+
};
83+
return cloudFunction(badMediaLinkEvent).then(result => {
84+
expect(result).equals(
85+
'https://www.googleapis.com/storage/v1/b/mybucket.appspot.com'
86+
+ '/o/nestedfolder%2Fmyobject.file?generation=12345&alt=media');
87+
});
88+
});
7989

80-
let spuriousEvent = {
81-
timestamp: '2017-03-06T20:02:05.192Z',
82-
eventType: 'providers/cloud.storage/eventTypes/object.change',
83-
resource: 'projects/_/buckets/rjh-20170306.appspot.com/objects/#0',
90+
it('should correct nested media links using multiple literal slashes', () => {
91+
let cloudFunction = storage.object().onChange((event) => {
92+
return event.data.mediaLink;
93+
});
94+
let badMediaLinkEvent = {
95+
data: {
96+
mediaLink: 'https://www.googleapis.com/storage/v1/b/mybucket.appspot.com'
97+
+ '/o/nestedfolder/anotherfolder/myobject.file?generation=12345&alt=media',
98+
},
99+
};
100+
return cloudFunction(badMediaLinkEvent).then(result => {
101+
expect(result).equals(
102+
'https://www.googleapis.com/storage/v1/b/mybucket.appspot.com'
103+
+ '/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media');
104+
});
105+
});
106+
107+
it('should not mess with media links using non-literal slashes', () => {
108+
let cloudFunction = storage.object().onChange((event) => {
109+
return event.data.mediaLink;
110+
});
111+
let goodMediaLinkEvent = {
84112
data: {
85-
kind: 'storage#object',
86-
resourceState: 'exists',
87-
id: 'rjh-20170306.appspot.com//0',
88-
selfLink: 'https://www.googleapis.com/storage/v1/b/rjh-20170306.appspot.com/o/',
89-
bucket: 'rjh-20170306.appspot.com',
90-
generation: '0',
91-
metageneration: '0',
92-
contentType: '',
93-
timeCreated: '1970-01-01T00:00:00.000Z',
94-
updated: '1970-01-01T00:00:00.000Z',
95-
size: '0',
96-
md5Hash: '',
97-
mediaLink: 'https://www.googleapis.com/storage/v1/b/rjh-20170306.appspot.com/o/?generation=0&alt=media',
98-
crc32c: 'AAAAAA==',
113+
mediaLink: 'https://www.googleapis.com/storage/v1/b/mybucket.appspot.com'
114+
+ '/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media',
99115
},
100-
params: {},
101116
};
102-
return cloudFunction(spuriousEvent).then((result) => {
103-
expect(result).equals(null);
104-
expect(functionRan).equals(false);
117+
return cloudFunction(goodMediaLinkEvent).then(result => {
118+
expect(result).equals(goodMediaLinkEvent.data.mediaLink);
105119
});
106120
});
107121
});

src/providers/storage.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ export class BucketBuilder {
5252
}
5353
}
5454

55+
// A RegExp that matches on a GCS media link that points at a _nested_ object (one that uses a path/with/slashes).
56+
const nestedMediaLinkRE = new RegExp('https://www.googleapis.com/storage/v1/b/([^/]+)/o/(.*)');
57+
5558
export class ObjectBuilder {
5659
/** @internal */
5760
constructor(private resource) { }
@@ -60,19 +63,21 @@ export class ObjectBuilder {
6063
* Handle any change to any object.
6164
*/
6265
onChange(handler: (event: Event<ObjectMetadata>) => PromiseLike<any> | any): CloudFunction<ObjectMetadata> {
63-
// This is a temporary shim to filter out spurious events due to Functions deployments.
64-
// BUG(34123812): clean this up when backend fix for bug is deployed.
65-
let filterDeployEvents = (event: Event<ObjectMetadata>) => {
66-
if (event.data.timeCreated === '1970-01-01T00:00:00.000Z' && event.data.crc32c === 'AAAAAA==') {
67-
console.log(
68-
'Function triggered unneccessarily by Cloud Function deployment; function execution elided. ' +
69-
'This is a spurious event that will go away soon, sorry for the spam!');
70-
return null;
66+
// This is a temporary shim to fix the 'mediaLink' for nested objects.
67+
// BUG(37962789): clean this up when backend fix for bug is deployed.
68+
let correctMediaLink = (event: Event<ObjectMetadata>) => {
69+
let deconstructedNestedLink = event.data.mediaLink.match(nestedMediaLinkRE);
70+
if (deconstructedNestedLink != null) {
71+
// The media link for a nested object uses an illegal URL (using literal slashes instead of "%2F".
72+
// Fix up the URL.
73+
let bucketName = deconstructedNestedLink[1];
74+
let fixedTail = deconstructedNestedLink[2].replace(/\//g, '%2F'); // "/\//g" means "all forward slashes".
75+
event.data.mediaLink = 'https://www.googleapis.com/storage/v1/b/' + bucketName + '/o/' + fixedTail;
7176
}
7277
return handler(event);
7378
};
7479
return makeCloudFunction(
75-
{ provider, handler: filterDeployEvents, resource: this.resource, eventType: 'object.change' });
80+
{ provider, handler: correctMediaLink, resource: this.resource, eventType: 'object.change' });
7681
}
7782
}
7883

0 commit comments

Comments
 (0)