@@ -10,6 +10,7 @@ import {
10
10
ObjectMetadata ,
11
11
ObjectResponse ,
12
12
withOptionalVersion ,
13
+ BrowserCacheHeaders ,
13
14
} from './generic'
14
15
import { StorageBackendError } from '../errors'
15
16
const pipeline = promisify ( stream . pipeline )
@@ -52,33 +53,58 @@ export class FileBackend implements StorageBackendAdapter {
52
53
* @param bucketName
53
54
* @param key
54
55
* @param version
56
+ * @param headers
55
57
*/
56
58
async getObject (
57
59
bucketName : string ,
58
60
key : string ,
59
- version : string | undefined
61
+ version : string | undefined ,
62
+ headers ?: BrowserCacheHeaders
60
63
) : Promise < ObjectResponse > {
64
+ // 'Range: bytes=#######-######
61
65
const file = path . resolve ( this . filePath , withOptionalVersion ( `${ bucketName } /${ key } ` , version ) )
62
- const body = fs . createReadStream ( file )
63
66
const data = await fs . stat ( file )
67
+ const checksum = await fileChecksum ( file )
68
+ const fileSize = data . size
64
69
const { cacheControl, contentType } = await this . getFileMetadata ( file )
65
70
const lastModified = new Date ( 0 )
66
71
lastModified . setUTCMilliseconds ( data . mtimeMs )
67
72
68
- const checksum = await fileChecksum ( file )
73
+ if ( headers ?. range ) {
74
+ const parts = headers . range . replace ( / b y t e s = / , '' ) . split ( '-' )
75
+ const startRange = parseInt ( parts [ 0 ] , 10 )
76
+ const endRange = parts [ 1 ] ? parseInt ( parts [ 1 ] , 10 ) : fileSize - 1
77
+ const size = endRange - startRange
78
+ const chunkSize = size + 1
79
+ const body = fs . createReadStream ( file , { start : startRange , end : endRange } )
69
80
70
- return {
71
- metadata : {
72
- cacheControl : cacheControl || 'no-cache' ,
73
- mimetype : contentType || 'application/octet-stream' ,
74
- lastModified : lastModified ,
75
- // contentRange: data.ContentRange, @todo: support range requests
76
- httpStatusCode : 200 ,
77
- size : data . size ,
78
- eTag : checksum ,
79
- contentLength : data . size ,
80
- } ,
81
- body,
81
+ return {
82
+ metadata : {
83
+ cacheControl : cacheControl || 'no-cache' ,
84
+ mimetype : contentType || 'application/octet-stream' ,
85
+ lastModified : lastModified ,
86
+ contentRange : `bytes ${ startRange } -${ endRange } /${ fileSize } ` ,
87
+ httpStatusCode : 206 ,
88
+ size : size ,
89
+ eTag : checksum ,
90
+ contentLength : chunkSize ,
91
+ } ,
92
+ body,
93
+ }
94
+ } else {
95
+ const body = fs . createReadStream ( file )
96
+ return {
97
+ metadata : {
98
+ cacheControl : cacheControl || 'no-cache' ,
99
+ mimetype : contentType || 'application/octet-stream' ,
100
+ lastModified : lastModified ,
101
+ httpStatusCode : 200 ,
102
+ size : data . size ,
103
+ eTag : checksum ,
104
+ contentLength : fileSize ,
105
+ } ,
106
+ body,
107
+ }
82
108
}
83
109
}
84
110
0 commit comments