@@ -60,6 +60,14 @@ const tmp_fs_root = path.join(TMP_PATH, 'test_bucket_namespace_fs');
60
60
// on Containerized - new_buckets_path is the directory
61
61
const new_bucket_path_param = get_new_buckets_path_by_test_env ( tmp_fs_root , '/' ) ;
62
62
63
+ // response headers
64
+ const response_content_disposition = 'attachment' ;
65
+ const response_content_language = 'hebrew' ;
66
+ const response_content_type = 'application/json' ;
67
+ const response_cache_control = 'no-cache' ;
68
+ const response_expires = new Date ( ) ;
69
+ response_expires . setMilliseconds ( 0 ) ;
70
+
63
71
// currently will pass only when running locally
64
72
mocha . describe ( 'bucket operations - namespace_fs' , function ( ) {
65
73
const nsr = 'nsr' ;
@@ -2242,6 +2250,115 @@ mocha.describe('Presigned URL tests', function() {
2242
2250
const expected_err = new S3Error ( S3Error . AuthorizationQueryParametersError ) ;
2243
2251
await assert_throws_async ( fetchData ( invalid_expiry_presigned_url ) , expected_err . message ) ;
2244
2252
} ) ;
2253
+
2254
+ it ( 'get-object - fetch valid presigned URL - 604800 seconds - epoch expiry - should return object data + return response headers' , async ( ) => {
2255
+ const response_queries = {
2256
+ ResponseContentDisposition : response_content_disposition ,
2257
+ ResponseContentLanguage : response_content_language ,
2258
+ ResponseContentType : response_content_type ,
2259
+ ResponseCacheControl : response_cache_control ,
2260
+ ResponseExpires : response_expires
2261
+ } ;
2262
+ const presigned_url_params_with_response_headers = { ...presigned_url_params , response_queries } ;
2263
+ const url_with_response_headers = cloud_utils . get_signed_url ( presigned_url_params_with_response_headers , 604800 ) ;
2264
+ const headers = await fetchHeaders ( url_with_response_headers ) ;
2265
+ assert . equal ( headers . get ( 'content-disposition' ) , response_content_disposition ) ;
2266
+ assert . equal ( headers . get ( 'content-language' ) , response_content_language ) ;
2267
+ assert . equal ( headers . get ( 'content-type' ) , response_content_type ) ;
2268
+ assert . equal ( headers . get ( 'cache-control' ) , response_cache_control ) ;
2269
+ assert . deepStrictEqual ( headers . get ( 'expires' ) , response_expires . toUTCString ( ) ) ;
2270
+ } ) ;
2271
+
2272
+ it ( 'head-object - fetch valid presigned URL - 604800 seconds - epoch expiry - should return object data + return response headers' , async ( ) => {
2273
+ const response_queries = {
2274
+ ResponseContentDisposition : response_content_disposition ,
2275
+ ResponseContentLanguage : response_content_language ,
2276
+ ResponseContentType : response_content_type ,
2277
+ ResponseCacheControl : response_cache_control ,
2278
+ ResponseExpires : response_expires
2279
+ } ;
2280
+ const presigned_url_params_with_response_headers = { ...presigned_url_params , response_queries } ;
2281
+ const url_with_response_headers = cloud_utils . get_signed_url ( presigned_url_params_with_response_headers , 604800 , 'headObject' ) ;
2282
+ const headers = await fetchHeaders ( url_with_response_headers , { method : 'HEAD' } ) ;
2283
+ assert . equal ( headers . get ( 'content-disposition' ) , response_content_disposition ) ;
2284
+ assert . equal ( headers . get ( 'content-language' ) , response_content_language ) ;
2285
+ assert . equal ( headers . get ( 'content-type' ) , response_content_type ) ;
2286
+ assert . equal ( headers . get ( 'cache-control' ) , response_cache_control ) ;
2287
+ assert . deepStrictEqual ( headers . get ( 'expires' ) , response_expires . toUTCString ( ) ) ;
2288
+ } ) ;
2289
+ } ) ;
2290
+
2291
+ mocha . describe ( 'response headers test - regular request' , function ( ) {
2292
+ this . timeout ( 50000 ) ; // eslint-disable-line no-invalid-this
2293
+ const nsr = 'response_headers_nsr' ;
2294
+ const account_name = 'response_header_account' ;
2295
+ const fs_path = path . join ( TMP_PATH , 'response_header_tests/' ) ;
2296
+ const response_header_bucket = 'response-headerbucket' ;
2297
+ const response_header_object = 'response-header-object.txt' ;
2298
+ const response_header_body = 'response_header_body' ;
2299
+ let s3_client ;
2300
+ let access_key ;
2301
+ let secret_key ;
2302
+ CORETEST_ENDPOINT = coretest . get_http_address ( ) ;
2303
+
2304
+ mocha . before ( async function ( ) {
2305
+ await fs_utils . create_fresh_path ( fs_path ) ;
2306
+ await rpc_client . pool . create_namespace_resource ( { name : nsr , nsfs_config : { fs_root_path : fs_path } } ) ;
2307
+ const new_buckets_path = is_nc_coretest ? fs_path : '/' ;
2308
+ const nsfs_account_config = {
2309
+ uid : process . getuid ( ) , gid : process . getgid ( ) , new_buckets_path, nsfs_only : true
2310
+ } ;
2311
+ const account_params = { ...new_account_params , email : `${ account_name } @noobaa.io` , name : account_name , default_resource : nsr , nsfs_account_config } ;
2312
+ const res = await rpc_client . account . create_account ( account_params ) ;
2313
+ access_key = res . access_keys [ 0 ] . access_key ;
2314
+ secret_key = res . access_keys [ 0 ] . secret_key ;
2315
+ s3_client = generate_s3_client ( access_key . unwrap ( ) , secret_key . unwrap ( ) , CORETEST_ENDPOINT ) ;
2316
+ await s3_client . createBucket ( { Bucket : response_header_bucket } ) ;
2317
+ await s3_client . putObject ( { Bucket : response_header_bucket , Key : response_header_object , Body : response_header_body } ) ;
2318
+ } ) ;
2319
+
2320
+ mocha . after ( async function ( ) {
2321
+ if ( ! is_nc_coretest ) return ;
2322
+ await s3_client . deleteObject ( { Bucket : response_header_bucket , Key : response_header_object } ) ;
2323
+ await s3_client . deleteBucket ( { Bucket : response_header_bucket } ) ;
2324
+ await rpc_client . account . delete_account ( { email : `${ account_name } @noobaa.io` } ) ;
2325
+ await fs_utils . folder_delete ( fs_path ) ;
2326
+ } ) ;
2327
+
2328
+ it ( 'get-object - response headers' , async ( ) => {
2329
+ const res = await s3_client . getObject ( {
2330
+ Bucket : response_header_bucket ,
2331
+ Key : response_header_object ,
2332
+ ResponseContentDisposition : response_content_disposition ,
2333
+ ResponseContentLanguage : response_content_language ,
2334
+ ResponseContentType : response_content_type ,
2335
+ ResponseCacheControl : response_cache_control ,
2336
+ ResponseExpires : response_expires ,
2337
+ } ) ;
2338
+ assert . equal ( res . ContentDisposition , response_content_disposition ) ;
2339
+ assert . equal ( res . ContentLanguage , response_content_language ) ;
2340
+ assert . equal ( res . ContentType , response_content_type ) ;
2341
+ assert . equal ( res . CacheControl , response_cache_control ) ;
2342
+ assert . deepStrictEqual ( res . Expires , response_expires ) ;
2343
+ } ) ;
2344
+
2345
+ it ( 'head-object - response headers' , async ( ) => {
2346
+ const res = await s3_client . headObject ( {
2347
+ Bucket : response_header_bucket ,
2348
+ Key : response_header_object ,
2349
+ ResponseContentDisposition : response_content_disposition ,
2350
+ ResponseContentLanguage : response_content_language ,
2351
+ ResponseContentType : response_content_type ,
2352
+ ResponseCacheControl : response_cache_control ,
2353
+ ResponseExpires : response_expires ,
2354
+ } ) ;
2355
+ assert . equal ( res . ContentDisposition , response_content_disposition ) ;
2356
+ assert . equal ( res . ContentLanguage , response_content_language ) ;
2357
+ assert . equal ( res . ContentType , response_content_type ) ;
2358
+ assert . equal ( res . CacheControl , response_cache_control ) ;
2359
+ assert . deepStrictEqual ( res . Expires , response_expires ) ;
2360
+ } ) ;
2361
+
2245
2362
} ) ;
2246
2363
2247
2364
async function fetchData ( presigned_url ) {
@@ -2257,3 +2374,17 @@ async function fetchData(presigned_url) {
2257
2374
data = await response . text ( ) ;
2258
2375
return data . trim ( ) ;
2259
2376
}
2377
+
2378
+ async function fetchHeaders ( presigned_url , options ) {
2379
+ const response = await fetch ( presigned_url , { ...options , agent : new http . Agent ( { keepAlive : false } ) } ) ;
2380
+ let data ;
2381
+ if ( ! response . ok ) {
2382
+ data = ( await response . text ( ) ) . trim ( ) ;
2383
+ const err_json = ( await http_utils . parse_xml_to_js ( data ) ) . Error ;
2384
+ const err = new Error ( err_json . Message ) ;
2385
+ err . code = err_json . Code ;
2386
+ throw err ;
2387
+ }
2388
+ return response . headers ;
2389
+ }
2390
+
0 commit comments