@@ -6,10 +6,11 @@ import app from '../app'
6
6
import { getConfig , mergeConfig } from '../config'
7
7
import { signJWT } from '@internal/auth'
8
8
import { Obj , backends } from '../storage'
9
- import { useMockObject , useMockQueue } from './common'
9
+ import { getInvalidObjectName , getUnicodeObjectName , useMockObject , useMockQueue } from './common'
10
10
import { getServiceKeyUser , getPostgresConnection } from '@internal/database'
11
11
import { Knex } from 'knex'
12
12
import { ErrorCode , StorageBackendError } from '@internal/errors'
13
+ import { randomUUID } from 'crypto'
13
14
14
15
const { jwtSecret, serviceKey, tenantId } = getConfig ( )
15
16
const anonKey = process . env . ANON_KEY || ''
@@ -2456,3 +2457,90 @@ describe('testing list objects', () => {
2456
2457
expect ( responseJSON [ 1 ] . name ) . toBe ( 'sadcat-upload23.png' )
2457
2458
} )
2458
2459
} )
2460
+
2461
+ describe ( 'Object key with Unicode characters' , ( ) => {
2462
+ test ( 'can upload, get and list' , async ( ) => {
2463
+ const prefix = `test-utf8-${ randomUUID ( ) } `
2464
+ const objectName = getUnicodeObjectName ( )
2465
+
2466
+ const form = new FormData ( )
2467
+ form . append ( 'file' , fs . createReadStream ( `./src/test/assets/sadcat.jpg` ) )
2468
+ const headers = Object . assign ( { } , form . getHeaders ( ) , {
2469
+ authorization : `Bearer ${ serviceKey } ` ,
2470
+ 'x-upsert' : 'true' ,
2471
+ } )
2472
+
2473
+ const uploadResponse = await app ( ) . inject ( {
2474
+ method : 'POST' ,
2475
+ url : `/object/bucket2/${ prefix } /${ encodeURIComponent ( objectName ) } ` ,
2476
+ headers : {
2477
+ ...headers ,
2478
+ ...form . getHeaders ( ) ,
2479
+ } ,
2480
+ payload : form ,
2481
+ } )
2482
+ expect ( uploadResponse . statusCode ) . toBe ( 200 )
2483
+
2484
+ const getResponse = await app ( ) . inject ( {
2485
+ method : 'GET' ,
2486
+ url : `/object/bucket2/${ prefix } /${ encodeURIComponent ( objectName ) } ` ,
2487
+ headers : {
2488
+ authorization : `Bearer ${ serviceKey } ` ,
2489
+ } ,
2490
+ } )
2491
+ expect ( getResponse . statusCode ) . toBe ( 200 )
2492
+ expect ( getResponse . headers [ 'etag' ] ) . toBe ( 'abc' )
2493
+ expect ( getResponse . headers [ 'last-modified' ] ) . toBe ( 'Thu, 12 Aug 2021 16:00:00 GMT' )
2494
+ expect ( getResponse . headers [ 'cache-control' ] ) . toBe ( 'no-cache' )
2495
+
2496
+ const listResponse = await app ( ) . inject ( {
2497
+ method : 'POST' ,
2498
+ url : `/object/list/bucket2` ,
2499
+ headers : {
2500
+ authorization : `Bearer ${ serviceKey } ` ,
2501
+ } ,
2502
+ payload : { prefix } ,
2503
+ } )
2504
+ expect ( listResponse . statusCode ) . toBe ( 200 )
2505
+ const listResponseJSON = JSON . parse ( listResponse . body )
2506
+ expect ( listResponseJSON ) . toHaveLength ( 1 )
2507
+ expect ( listResponseJSON [ 0 ] . name ) . toBe ( objectName . split ( '/' ) [ 0 ] )
2508
+
2509
+ const deleteResponse = await app ( ) . inject ( {
2510
+ method : 'DELETE' ,
2511
+ url : `/object/bucket2/${ prefix } /${ encodeURIComponent ( objectName ) } ` ,
2512
+ headers : {
2513
+ authorization : `Bearer ${ serviceKey } ` ,
2514
+ } ,
2515
+ } )
2516
+ expect ( deleteResponse . statusCode ) . toBe ( 200 )
2517
+ } )
2518
+
2519
+ test ( 'should not be allowed to upload objects with invalid names' , async ( ) => {
2520
+ const invalidObjectName = getInvalidObjectName ( )
2521
+ const form = new FormData ( )
2522
+ form . append ( 'file' , fs . createReadStream ( `./src/test/assets/sadcat.jpg` ) )
2523
+ const headers = Object . assign ( { } , form . getHeaders ( ) , {
2524
+ authorization : `Bearer ${ serviceKey } ` ,
2525
+ 'x-upsert' : 'true' ,
2526
+ } )
2527
+ const uploadResponse = await app ( ) . inject ( {
2528
+ method : 'POST' ,
2529
+ url : `/object/bucket2/${ encodeURIComponent ( invalidObjectName ) } ` ,
2530
+ headers : {
2531
+ ...headers ,
2532
+ ...form . getHeaders ( ) ,
2533
+ } ,
2534
+ payload : form ,
2535
+ } )
2536
+ expect ( uploadResponse . statusCode ) . toBe ( 400 )
2537
+ expect ( S3Backend . prototype . uploadObject ) . not . toHaveBeenCalled ( )
2538
+ expect ( uploadResponse . body ) . toBe (
2539
+ JSON . stringify ( {
2540
+ statusCode : '400' ,
2541
+ error : 'InvalidKey' ,
2542
+ message : `Invalid key: ${ encodeURIComponent ( invalidObjectName ) } ` ,
2543
+ } )
2544
+ )
2545
+ } )
2546
+ } )
0 commit comments