Skip to content

Commit f6d2fbc

Browse files
authored
fix: base64 encode for metadata in headers (#519)
1 parent d0f0348 commit f6d2fbc

File tree

4 files changed

+60
-57
lines changed

4 files changed

+60
-57
lines changed

package-lock.json

Lines changed: 16 additions & 49 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"@aws-sdk/lib-storage": "3.515.0",
3030
"@aws-sdk/s3-request-presigner": "3.421.0",
3131
"@fastify/accepts": "^4.3.0",
32-
"@fastify/multipart": "^7.6.0",
32+
"@fastify/multipart": "^8.3.0",
3333
"@fastify/rate-limit": "^7.6.0",
3434
"@fastify/swagger": "^8.3.1",
3535
"@fastify/swagger-ui": "^1.7.0",

src/storage/uploader.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -326,12 +326,9 @@ export class Uploader {
326326
const customMd = request.headers['x-metadata']
327327

328328
if (typeof customMd === 'string') {
329-
if (userMetadata && Buffer.byteLength(customMd, 'utf8') > MAX_CUSTOM_METADATA_SIZE) {
330-
throw ERRORS.EntityTooLarge(undefined, 'metadata')
331-
}
332-
333329
try {
334-
userMetadata = JSON.parse(customMd)
330+
const json = Buffer.from(customMd, 'base64').toString('utf8')
331+
userMetadata = JSON.parse(json)
335332
} catch (e) {
336333
// no-op
337334
}

src/test/object.test.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ describe('testing POST object via multipart upload', () => {
354354
expect(S3Backend.prototype.uploadObject).toHaveBeenCalled()
355355
})
356356

357-
test('successfully uploading an object with custom metadata', async () => {
357+
test('successfully uploading an object with custom metadata using form data', async () => {
358358
const form = new FormData()
359359
form.append('file', fs.createReadStream(`./src/test/assets/sadcat.jpg`))
360360
form.append(
@@ -395,6 +395,45 @@ describe('testing POST object via multipart upload', () => {
395395
})
396396
})
397397

398+
test('successfully uploading an object with custom metadata using stream', async () => {
399+
const file = fs.createReadStream(`./src/test/assets/sadcat.jpg`)
400+
401+
const headers = {
402+
authorization: `Bearer ${serviceKey}`,
403+
'x-upsert': 'true',
404+
'x-metadata': Buffer.from(
405+
JSON.stringify({
406+
test1: 'test1',
407+
test2: 'test2',
408+
})
409+
).toString('base64'),
410+
}
411+
412+
const response = await app().inject({
413+
method: 'POST',
414+
url: '/object/bucket2/sadcat-upload3018.png',
415+
headers,
416+
payload: file,
417+
})
418+
expect(response.statusCode).toBe(200)
419+
expect(S3Backend.prototype.uploadObject).toHaveBeenCalled()
420+
421+
const client = await getSuperuserPostgrestClient()
422+
423+
const object = await client
424+
.table('objects')
425+
.select('*')
426+
.where('name', 'sadcat-upload3018.png')
427+
.where('bucket_id', 'bucket2')
428+
.first()
429+
430+
expect(object).not.toBeFalsy()
431+
expect(object?.user_metadata).toEqual({
432+
test1: 'test1',
433+
test2: 'test2',
434+
})
435+
})
436+
398437
test('fetch object metadata', async () => {
399438
const form = new FormData()
400439
form.append('file', fs.createReadStream(`./src/test/assets/sadcat.jpg`))
@@ -2121,7 +2160,7 @@ describe('testing list objects', () => {
21212160
})
21222161
expect(response.statusCode).toBe(200)
21232162
const responseJSON = JSON.parse(response.body)
2124-
expect(responseJSON).toHaveLength(8)
2163+
expect(responseJSON).toHaveLength(9)
21252164
const names = responseJSON.map((ele: any) => ele.name)
21262165
expect(names).toContain('curlimage.jpg')
21272166
expect(names).toContain('private')

0 commit comments

Comments
 (0)