koa-files 2.3.6 → 2.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -11
- package/cjs/{Send.cjs → Files.cjs} +46 -34
- package/cjs/index.cjs +5 -5
- package/cjs/utils.cjs +26 -30
- package/esm/{Send.js → Files.js} +46 -34
- package/esm/index.js +5 -5
- package/esm/utils.js +26 -30
- package/package.json +16 -15
- package/types/Files.d.ts +98 -0
- package/types/index.d.ts +2 -2
- package/types/utils.d.ts +23 -27
- package/types/Send.d.ts +0 -86
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
>
|
|
6
6
|
> [![NPM Version][npm-image]][npm-url]
|
|
7
7
|
> [![Download Status][download-image]][npm-url]
|
|
8
|
-
> [![
|
|
8
|
+
> [![Languages Status][languages-image]][github-url]
|
|
9
9
|
> ![Node Version][node-image]
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
@@ -17,13 +17,13 @@ $ npm install koa-files
|
|
|
17
17
|
## API
|
|
18
18
|
|
|
19
19
|
```js
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
import Koa from 'koa';
|
|
21
|
+
import files from 'koa-files';
|
|
22
22
|
|
|
23
23
|
const app = new Koa();
|
|
24
24
|
|
|
25
25
|
// Static files server
|
|
26
|
-
app.use(
|
|
26
|
+
app.use(files(root, options));
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
- `root` root directory string. nothing above this root directory can be served.
|
|
@@ -64,10 +64,8 @@ app.use(server(root, options));
|
|
|
64
64
|
* @author nuintun
|
|
65
65
|
*/
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const Koa = require('koa');
|
|
70
|
-
const server = require('koa-files');
|
|
67
|
+
import Koa from 'koa';
|
|
68
|
+
import files from 'koa-files';
|
|
71
69
|
|
|
72
70
|
const app = new Koa();
|
|
73
71
|
const port = process.env.PORT || 80;
|
|
@@ -82,7 +80,7 @@ function httpError(error) {
|
|
|
82
80
|
}
|
|
83
81
|
|
|
84
82
|
// Static files server
|
|
85
|
-
app.use(
|
|
83
|
+
app.use(files('tests', { cacheControl: 'public, max-age=31557600' }));
|
|
86
84
|
|
|
87
85
|
// Listen error event
|
|
88
86
|
app.on('error', error => !httpError(error) && console.error(error));
|
|
@@ -102,6 +100,6 @@ MIT
|
|
|
102
100
|
[npm-image]: https://img.shields.io/npm/v/koa-files.svg?style=flat-square
|
|
103
101
|
[npm-url]: https://www.npmjs.org/package/koa-files
|
|
104
102
|
[download-image]: https://img.shields.io/npm/dm/koa-files.svg?style=flat-square
|
|
105
|
-
[
|
|
106
|
-
[
|
|
103
|
+
[languages-image]: https://img.shields.io/github/languages/top/nuintun/koa-files?style=flat-square
|
|
104
|
+
[github-url]: https://github.com/nuintun/koa-files
|
|
107
105
|
[node-image]: https://img.shields.io/node/v/koa-files.svg?style=flat-square
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package koa-files
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 2.3.
|
|
4
|
+
* @version 2.3.8
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A static files serving middleware for koa.
|
|
7
7
|
* @see https://github.com/nuintun/koa-files#readme
|
|
@@ -27,27 +27,29 @@ const fs__default = /*#__PURE__*/ _interopDefault(fs);
|
|
|
27
27
|
const parseRange__default = /*#__PURE__*/ _interopDefault(parseRange);
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
-
* @module
|
|
30
|
+
* @module Files
|
|
31
31
|
* @license MIT
|
|
32
32
|
* @author nuintun
|
|
33
33
|
*/
|
|
34
34
|
/**
|
|
35
|
-
* @class
|
|
35
|
+
* @class Files
|
|
36
36
|
*/
|
|
37
|
-
class
|
|
37
|
+
class Files {
|
|
38
38
|
/**
|
|
39
39
|
* @constructor
|
|
40
|
-
* @
|
|
41
|
-
* @param
|
|
40
|
+
* @description Create files service
|
|
41
|
+
* @param root Files service root
|
|
42
|
+
* @param options Files service options
|
|
42
43
|
*/
|
|
43
44
|
constructor(root, options = {}) {
|
|
44
45
|
this.options = options;
|
|
45
46
|
this.root = utils.unixify(path.resolve(root));
|
|
46
47
|
}
|
|
47
48
|
/**
|
|
49
|
+
* @private
|
|
48
50
|
* @method isConditionalGET
|
|
49
|
-
* @
|
|
50
|
-
* @
|
|
51
|
+
* @description Check if request is conditional GET
|
|
52
|
+
* @param context Koa context
|
|
51
53
|
*/
|
|
52
54
|
isConditionalGET(context) {
|
|
53
55
|
const { request } = context;
|
|
@@ -59,9 +61,10 @@ class Send {
|
|
|
59
61
|
);
|
|
60
62
|
}
|
|
61
63
|
/**
|
|
64
|
+
* @private
|
|
62
65
|
* @method isPreconditionFailure
|
|
63
|
-
* @
|
|
64
|
-
* @
|
|
66
|
+
* @description Check if request precondition failure
|
|
67
|
+
* @param context Koa context
|
|
65
68
|
*/
|
|
66
69
|
isPreconditionFailure(context) {
|
|
67
70
|
const { request, response } = context;
|
|
@@ -80,9 +83,10 @@ class Send {
|
|
|
80
83
|
return false;
|
|
81
84
|
}
|
|
82
85
|
/**
|
|
86
|
+
* @private
|
|
83
87
|
* @method isRangeFresh
|
|
84
|
-
* @
|
|
85
|
-
* @
|
|
88
|
+
* @description Check if request range fresh
|
|
89
|
+
* @param context Koa context
|
|
86
90
|
*/
|
|
87
91
|
isRangeFresh(context) {
|
|
88
92
|
const { request, response } = context;
|
|
@@ -101,19 +105,21 @@ class Send {
|
|
|
101
105
|
return Date.parse(lastModified) <= Date.parse(ifRange);
|
|
102
106
|
}
|
|
103
107
|
/**
|
|
108
|
+
* @private
|
|
104
109
|
* @method isIgnore
|
|
105
|
-
* @
|
|
106
|
-
* @
|
|
110
|
+
* @description Check if path is ignore
|
|
111
|
+
* @param path File path
|
|
107
112
|
*/
|
|
108
113
|
isIgnore(path) {
|
|
109
114
|
const { ignore } = this.options;
|
|
110
115
|
return (typeof ignore === 'function' ? ignore(path) : false) === true;
|
|
111
116
|
}
|
|
112
117
|
/**
|
|
118
|
+
* @private
|
|
113
119
|
* @method parseRange
|
|
114
|
-
* @
|
|
115
|
-
* @param
|
|
116
|
-
* @
|
|
120
|
+
* @description Parse range
|
|
121
|
+
* @param context Koa context
|
|
122
|
+
* @param stats File stats
|
|
117
123
|
*/
|
|
118
124
|
parseRange(context, stats) {
|
|
119
125
|
const { size } = stats;
|
|
@@ -178,10 +184,12 @@ class Send {
|
|
|
178
184
|
return ranges.length ? ranges : [{ start: 0 }];
|
|
179
185
|
}
|
|
180
186
|
/**
|
|
187
|
+
* @private
|
|
181
188
|
* @method setupHeaders
|
|
182
|
-
* @
|
|
183
|
-
* @param
|
|
184
|
-
* @param
|
|
189
|
+
* @description Setup headers
|
|
190
|
+
* @param context Koa context
|
|
191
|
+
* @param path File path
|
|
192
|
+
* @param stats File stats
|
|
185
193
|
*/
|
|
186
194
|
setupHeaders(context, path$1, stats) {
|
|
187
195
|
const { options } = this;
|
|
@@ -213,12 +221,13 @@ class Send {
|
|
|
213
221
|
}
|
|
214
222
|
}
|
|
215
223
|
/**
|
|
224
|
+
* @private
|
|
216
225
|
* @method read
|
|
217
|
-
* @
|
|
218
|
-
* @param
|
|
219
|
-
* @param
|
|
220
|
-
* @param
|
|
221
|
-
* @
|
|
226
|
+
* @description Read file
|
|
227
|
+
* @param path File path
|
|
228
|
+
* @param range Read range
|
|
229
|
+
* @param buffer Destination stream
|
|
230
|
+
* @param end Is destory destination stream after read
|
|
222
231
|
*/
|
|
223
232
|
read(path, range, buffer, end) {
|
|
224
233
|
return new Promise((resolve, reject) => {
|
|
@@ -261,14 +270,16 @@ class Send {
|
|
|
261
270
|
});
|
|
262
271
|
}
|
|
263
272
|
/**
|
|
273
|
+
* @private
|
|
264
274
|
* @method send
|
|
265
|
-
* @
|
|
266
|
-
* @param
|
|
267
|
-
* @param
|
|
275
|
+
* @description Send file
|
|
276
|
+
* @param context Koa context
|
|
277
|
+
* @param path File path
|
|
278
|
+
* @param ranges Read ranges
|
|
268
279
|
*/
|
|
269
280
|
async send(context, path, ranges) {
|
|
270
|
-
// Ranges
|
|
271
|
-
let
|
|
281
|
+
// Ranges length
|
|
282
|
+
let { length } = ranges;
|
|
272
283
|
// Set stream body, highWaterMark 64kb
|
|
273
284
|
const stream$1 = new stream.PassThrough({ highWaterMark: 65536 });
|
|
274
285
|
// Set response body
|
|
@@ -276,7 +287,7 @@ class Send {
|
|
|
276
287
|
// Read file ranges
|
|
277
288
|
try {
|
|
278
289
|
for (const range of ranges) {
|
|
279
|
-
await this.read(path, range, stream$1, --
|
|
290
|
+
await this.read(path, range, stream$1, --length === 0);
|
|
280
291
|
}
|
|
281
292
|
} catch (error) {
|
|
282
293
|
// End stream when read exception
|
|
@@ -284,9 +295,10 @@ class Send {
|
|
|
284
295
|
}
|
|
285
296
|
}
|
|
286
297
|
/**
|
|
298
|
+
* @public
|
|
287
299
|
* @method response
|
|
288
|
-
* @
|
|
289
|
-
* @
|
|
300
|
+
* @description Response to koa context
|
|
301
|
+
* @param context Koa context
|
|
290
302
|
*/
|
|
291
303
|
async response(context) {
|
|
292
304
|
const { root } = this;
|
|
@@ -374,4 +386,4 @@ class Send {
|
|
|
374
386
|
}
|
|
375
387
|
}
|
|
376
388
|
|
|
377
|
-
module.exports =
|
|
389
|
+
module.exports = Files;
|
package/cjs/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package koa-files
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 2.3.
|
|
4
|
+
* @version 2.3.8
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A static files serving middleware for koa.
|
|
7
7
|
* @see https://github.com/nuintun/koa-files#readme
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const Files = require('./Files.cjs');
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* @module index
|
|
@@ -22,15 +22,15 @@ const Send = require('./Send.cjs');
|
|
|
22
22
|
* @param {Options} options
|
|
23
23
|
*/
|
|
24
24
|
function server(root, options) {
|
|
25
|
-
const
|
|
25
|
+
const files = new Files(root, options);
|
|
26
26
|
if (options && options.defer) {
|
|
27
27
|
return async (context, next) => {
|
|
28
28
|
await next();
|
|
29
|
-
await
|
|
29
|
+
await files.response(context);
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
return async (context, next) => {
|
|
33
|
-
if (!(await
|
|
33
|
+
if (!(await files.response(context))) {
|
|
34
34
|
await next();
|
|
35
35
|
}
|
|
36
36
|
};
|
package/cjs/utils.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package koa-files
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 2.3.
|
|
4
|
+
* @version 2.3.8
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A static files serving middleware for koa.
|
|
7
7
|
* @see https://github.com/nuintun/koa-files#readme
|
|
@@ -26,10 +26,9 @@ const fs__default = /*#__PURE__*/ _interopDefault(fs);
|
|
|
26
26
|
const CHARS = Array.from('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');
|
|
27
27
|
/**
|
|
28
28
|
* @function isOutRoot
|
|
29
|
-
* @description
|
|
30
|
-
* @param
|
|
31
|
-
* @param
|
|
32
|
-
* @returns {boolean}
|
|
29
|
+
* @description Check if path is out of root
|
|
30
|
+
* @param path The path to check
|
|
31
|
+
* @param root The root path
|
|
33
32
|
*/
|
|
34
33
|
function isOutRoot(path$1, root) {
|
|
35
34
|
path$1 = path.relative(root, path$1);
|
|
@@ -37,18 +36,16 @@ function isOutRoot(path$1, root) {
|
|
|
37
36
|
}
|
|
38
37
|
/**
|
|
39
38
|
* @function unixify
|
|
40
|
-
* @description Convert path
|
|
41
|
-
* @param
|
|
42
|
-
* @returns {string}
|
|
39
|
+
* @description Convert path to unix style
|
|
40
|
+
* @param path The path to convert
|
|
43
41
|
*/
|
|
44
42
|
function unixify(path) {
|
|
45
43
|
return path.replace(/\\/g, '/');
|
|
46
44
|
}
|
|
47
45
|
/**
|
|
48
46
|
* @function decodeURI
|
|
49
|
-
* @description Decode URI component
|
|
50
|
-
* @param
|
|
51
|
-
* @returns {string|-1}
|
|
47
|
+
* @description Decode URI component
|
|
48
|
+
* @param URI The URI to decode
|
|
52
49
|
*/
|
|
53
50
|
function decodeURI(URI) {
|
|
54
51
|
try {
|
|
@@ -59,8 +56,7 @@ function decodeURI(URI) {
|
|
|
59
56
|
}
|
|
60
57
|
/**
|
|
61
58
|
* @function boundaryGenerator
|
|
62
|
-
* @description
|
|
63
|
-
* @returns {string}
|
|
59
|
+
* @description Generate a boundary
|
|
64
60
|
*/
|
|
65
61
|
function boundaryGenerator() {
|
|
66
62
|
let boundary = '';
|
|
@@ -73,8 +69,8 @@ function boundaryGenerator() {
|
|
|
73
69
|
}
|
|
74
70
|
/**
|
|
75
71
|
* @function fstat
|
|
76
|
-
* @
|
|
77
|
-
* @
|
|
72
|
+
* @description Get file stats
|
|
73
|
+
* @param path The file path
|
|
78
74
|
*/
|
|
79
75
|
function fstat(path) {
|
|
80
76
|
return new Promise((resolve, reject) => {
|
|
@@ -85,16 +81,16 @@ function fstat(path) {
|
|
|
85
81
|
}
|
|
86
82
|
/**
|
|
87
83
|
* @function hasTrailingSlash
|
|
88
|
-
* @
|
|
89
|
-
* @
|
|
84
|
+
* @description Check if path has trailing slash
|
|
85
|
+
* @param path The path to check
|
|
90
86
|
*/
|
|
91
87
|
function hasTrailingSlash(path) {
|
|
92
88
|
return /\/$/.test(path);
|
|
93
89
|
}
|
|
94
90
|
/**
|
|
95
91
|
* @function parseTokens
|
|
96
|
-
* @description Parse
|
|
97
|
-
* @param
|
|
92
|
+
* @description Parse HTTP tokens
|
|
93
|
+
* @param value The tokens value string
|
|
98
94
|
*/
|
|
99
95
|
function parseTokens(value) {
|
|
100
96
|
let end = 0;
|
|
@@ -123,25 +119,25 @@ function parseTokens(value) {
|
|
|
123
119
|
tokens.push(value.substring(start, end));
|
|
124
120
|
return tokens;
|
|
125
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* @function isETag
|
|
124
|
+
* @description Check if etag is valid
|
|
125
|
+
* @param value The value to check
|
|
126
|
+
*/
|
|
127
|
+
function isETag(value) {
|
|
128
|
+
return /^(?:W\/)?"[\s\S]+"$/.test(value);
|
|
129
|
+
}
|
|
126
130
|
/**
|
|
127
131
|
* @function isETagFresh
|
|
128
|
-
* @
|
|
129
|
-
* @param
|
|
130
|
-
* @
|
|
132
|
+
* @description Check if etag is fresh
|
|
133
|
+
* @param match The match value
|
|
134
|
+
* @param etag The etag value
|
|
131
135
|
*/
|
|
132
136
|
function isETagFresh(match, etag) {
|
|
133
137
|
return parseTokens(match).some(match => {
|
|
134
138
|
return match === etag || match === 'W/' + etag || 'W/' + match === etag;
|
|
135
139
|
});
|
|
136
140
|
}
|
|
137
|
-
/**
|
|
138
|
-
* @function isETag
|
|
139
|
-
* @param {string} etag
|
|
140
|
-
* @returns {boolean}
|
|
141
|
-
*/
|
|
142
|
-
function isETag(etag) {
|
|
143
|
-
return /(?:W\/)?"(?:[ !#-\x7E\x80-\xFF]*|\r\n[\t ]|\\.)*"/.test(etag);
|
|
144
|
-
}
|
|
145
141
|
|
|
146
142
|
exports.boundaryGenerator = boundaryGenerator;
|
|
147
143
|
exports.decodeURI = decodeURI;
|
package/esm/{Send.js → Files.js}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package koa-files
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 2.3.
|
|
4
|
+
* @version 2.3.8
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A static files serving middleware for koa.
|
|
7
7
|
* @see https://github.com/nuintun/koa-files#readme
|
|
@@ -16,27 +16,29 @@ import { resolve, extname, join } from 'path';
|
|
|
16
16
|
import { unixify, isETagFresh, isETag, boundaryGenerator, decodeURI, isOutRoot, fstat, hasTrailingSlash } from './utils.js';
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* @module
|
|
19
|
+
* @module Files
|
|
20
20
|
* @license MIT
|
|
21
21
|
* @author nuintun
|
|
22
22
|
*/
|
|
23
23
|
/**
|
|
24
|
-
* @class
|
|
24
|
+
* @class Files
|
|
25
25
|
*/
|
|
26
|
-
class
|
|
26
|
+
class Files {
|
|
27
27
|
/**
|
|
28
28
|
* @constructor
|
|
29
|
-
* @
|
|
30
|
-
* @param
|
|
29
|
+
* @description Create files service
|
|
30
|
+
* @param root Files service root
|
|
31
|
+
* @param options Files service options
|
|
31
32
|
*/
|
|
32
33
|
constructor(root, options = {}) {
|
|
33
34
|
this.options = options;
|
|
34
35
|
this.root = unixify(resolve(root));
|
|
35
36
|
}
|
|
36
37
|
/**
|
|
38
|
+
* @private
|
|
37
39
|
* @method isConditionalGET
|
|
38
|
-
* @
|
|
39
|
-
* @
|
|
40
|
+
* @description Check if request is conditional GET
|
|
41
|
+
* @param context Koa context
|
|
40
42
|
*/
|
|
41
43
|
isConditionalGET(context) {
|
|
42
44
|
const { request } = context;
|
|
@@ -48,9 +50,10 @@ class Send {
|
|
|
48
50
|
);
|
|
49
51
|
}
|
|
50
52
|
/**
|
|
53
|
+
* @private
|
|
51
54
|
* @method isPreconditionFailure
|
|
52
|
-
* @
|
|
53
|
-
* @
|
|
55
|
+
* @description Check if request precondition failure
|
|
56
|
+
* @param context Koa context
|
|
54
57
|
*/
|
|
55
58
|
isPreconditionFailure(context) {
|
|
56
59
|
const { request, response } = context;
|
|
@@ -69,9 +72,10 @@ class Send {
|
|
|
69
72
|
return false;
|
|
70
73
|
}
|
|
71
74
|
/**
|
|
75
|
+
* @private
|
|
72
76
|
* @method isRangeFresh
|
|
73
|
-
* @
|
|
74
|
-
* @
|
|
77
|
+
* @description Check if request range fresh
|
|
78
|
+
* @param context Koa context
|
|
75
79
|
*/
|
|
76
80
|
isRangeFresh(context) {
|
|
77
81
|
const { request, response } = context;
|
|
@@ -90,19 +94,21 @@ class Send {
|
|
|
90
94
|
return Date.parse(lastModified) <= Date.parse(ifRange);
|
|
91
95
|
}
|
|
92
96
|
/**
|
|
97
|
+
* @private
|
|
93
98
|
* @method isIgnore
|
|
94
|
-
* @
|
|
95
|
-
* @
|
|
99
|
+
* @description Check if path is ignore
|
|
100
|
+
* @param path File path
|
|
96
101
|
*/
|
|
97
102
|
isIgnore(path) {
|
|
98
103
|
const { ignore } = this.options;
|
|
99
104
|
return (typeof ignore === 'function' ? ignore(path) : false) === true;
|
|
100
105
|
}
|
|
101
106
|
/**
|
|
107
|
+
* @private
|
|
102
108
|
* @method parseRange
|
|
103
|
-
* @
|
|
104
|
-
* @param
|
|
105
|
-
* @
|
|
109
|
+
* @description Parse range
|
|
110
|
+
* @param context Koa context
|
|
111
|
+
* @param stats File stats
|
|
106
112
|
*/
|
|
107
113
|
parseRange(context, stats) {
|
|
108
114
|
const { size } = stats;
|
|
@@ -167,10 +173,12 @@ class Send {
|
|
|
167
173
|
return ranges.length ? ranges : [{ start: 0 }];
|
|
168
174
|
}
|
|
169
175
|
/**
|
|
176
|
+
* @private
|
|
170
177
|
* @method setupHeaders
|
|
171
|
-
* @
|
|
172
|
-
* @param
|
|
173
|
-
* @param
|
|
178
|
+
* @description Setup headers
|
|
179
|
+
* @param context Koa context
|
|
180
|
+
* @param path File path
|
|
181
|
+
* @param stats File stats
|
|
174
182
|
*/
|
|
175
183
|
setupHeaders(context, path, stats) {
|
|
176
184
|
const { options } = this;
|
|
@@ -202,12 +210,13 @@ class Send {
|
|
|
202
210
|
}
|
|
203
211
|
}
|
|
204
212
|
/**
|
|
213
|
+
* @private
|
|
205
214
|
* @method read
|
|
206
|
-
* @
|
|
207
|
-
* @param
|
|
208
|
-
* @param
|
|
209
|
-
* @param
|
|
210
|
-
* @
|
|
215
|
+
* @description Read file
|
|
216
|
+
* @param path File path
|
|
217
|
+
* @param range Read range
|
|
218
|
+
* @param buffer Destination stream
|
|
219
|
+
* @param end Is destory destination stream after read
|
|
211
220
|
*/
|
|
212
221
|
read(path, range, buffer, end) {
|
|
213
222
|
return new Promise((resolve, reject) => {
|
|
@@ -250,14 +259,16 @@ class Send {
|
|
|
250
259
|
});
|
|
251
260
|
}
|
|
252
261
|
/**
|
|
262
|
+
* @private
|
|
253
263
|
* @method send
|
|
254
|
-
* @
|
|
255
|
-
* @param
|
|
256
|
-
* @param
|
|
264
|
+
* @description Send file
|
|
265
|
+
* @param context Koa context
|
|
266
|
+
* @param path File path
|
|
267
|
+
* @param ranges Read ranges
|
|
257
268
|
*/
|
|
258
269
|
async send(context, path, ranges) {
|
|
259
|
-
// Ranges
|
|
260
|
-
let
|
|
270
|
+
// Ranges length
|
|
271
|
+
let { length } = ranges;
|
|
261
272
|
// Set stream body, highWaterMark 64kb
|
|
262
273
|
const stream = new PassThrough({ highWaterMark: 65536 });
|
|
263
274
|
// Set response body
|
|
@@ -265,7 +276,7 @@ class Send {
|
|
|
265
276
|
// Read file ranges
|
|
266
277
|
try {
|
|
267
278
|
for (const range of ranges) {
|
|
268
|
-
await this.read(path, range, stream, --
|
|
279
|
+
await this.read(path, range, stream, --length === 0);
|
|
269
280
|
}
|
|
270
281
|
} catch (error) {
|
|
271
282
|
// End stream when read exception
|
|
@@ -273,9 +284,10 @@ class Send {
|
|
|
273
284
|
}
|
|
274
285
|
}
|
|
275
286
|
/**
|
|
287
|
+
* @public
|
|
276
288
|
* @method response
|
|
277
|
-
* @
|
|
278
|
-
* @
|
|
289
|
+
* @description Response to koa context
|
|
290
|
+
* @param context Koa context
|
|
279
291
|
*/
|
|
280
292
|
async response(context) {
|
|
281
293
|
const { root } = this;
|
|
@@ -363,4 +375,4 @@ class Send {
|
|
|
363
375
|
}
|
|
364
376
|
}
|
|
365
377
|
|
|
366
|
-
export {
|
|
378
|
+
export { Files as default };
|
package/esm/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package koa-files
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 2.3.
|
|
4
|
+
* @version 2.3.8
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A static files serving middleware for koa.
|
|
7
7
|
* @see https://github.com/nuintun/koa-files#readme
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import
|
|
10
|
+
import Files from './Files.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* @module index
|
|
@@ -20,15 +20,15 @@ import Send from './Send.js';
|
|
|
20
20
|
* @param {Options} options
|
|
21
21
|
*/
|
|
22
22
|
function server(root, options) {
|
|
23
|
-
const
|
|
23
|
+
const files = new Files(root, options);
|
|
24
24
|
if (options && options.defer) {
|
|
25
25
|
return async (context, next) => {
|
|
26
26
|
await next();
|
|
27
|
-
await
|
|
27
|
+
await files.response(context);
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
return async (context, next) => {
|
|
31
|
-
if (!(await
|
|
31
|
+
if (!(await files.response(context))) {
|
|
32
32
|
await next();
|
|
33
33
|
}
|
|
34
34
|
};
|
package/esm/utils.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package koa-files
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 2.3.
|
|
4
|
+
* @version 2.3.8
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A static files serving middleware for koa.
|
|
7
7
|
* @see https://github.com/nuintun/koa-files#readme
|
|
@@ -18,10 +18,9 @@ import { relative, isAbsolute } from 'path';
|
|
|
18
18
|
const CHARS = Array.from('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');
|
|
19
19
|
/**
|
|
20
20
|
* @function isOutRoot
|
|
21
|
-
* @description
|
|
22
|
-
* @param
|
|
23
|
-
* @param
|
|
24
|
-
* @returns {boolean}
|
|
21
|
+
* @description Check if path is out of root
|
|
22
|
+
* @param path The path to check
|
|
23
|
+
* @param root The root path
|
|
25
24
|
*/
|
|
26
25
|
function isOutRoot(path, root) {
|
|
27
26
|
path = relative(root, path);
|
|
@@ -29,18 +28,16 @@ function isOutRoot(path, root) {
|
|
|
29
28
|
}
|
|
30
29
|
/**
|
|
31
30
|
* @function unixify
|
|
32
|
-
* @description Convert path
|
|
33
|
-
* @param
|
|
34
|
-
* @returns {string}
|
|
31
|
+
* @description Convert path to unix style
|
|
32
|
+
* @param path The path to convert
|
|
35
33
|
*/
|
|
36
34
|
function unixify(path) {
|
|
37
35
|
return path.replace(/\\/g, '/');
|
|
38
36
|
}
|
|
39
37
|
/**
|
|
40
38
|
* @function decodeURI
|
|
41
|
-
* @description Decode URI component
|
|
42
|
-
* @param
|
|
43
|
-
* @returns {string|-1}
|
|
39
|
+
* @description Decode URI component
|
|
40
|
+
* @param URI The URI to decode
|
|
44
41
|
*/
|
|
45
42
|
function decodeURI(URI) {
|
|
46
43
|
try {
|
|
@@ -51,8 +48,7 @@ function decodeURI(URI) {
|
|
|
51
48
|
}
|
|
52
49
|
/**
|
|
53
50
|
* @function boundaryGenerator
|
|
54
|
-
* @description
|
|
55
|
-
* @returns {string}
|
|
51
|
+
* @description Generate a boundary
|
|
56
52
|
*/
|
|
57
53
|
function boundaryGenerator() {
|
|
58
54
|
let boundary = '';
|
|
@@ -65,8 +61,8 @@ function boundaryGenerator() {
|
|
|
65
61
|
}
|
|
66
62
|
/**
|
|
67
63
|
* @function fstat
|
|
68
|
-
* @
|
|
69
|
-
* @
|
|
64
|
+
* @description Get file stats
|
|
65
|
+
* @param path The file path
|
|
70
66
|
*/
|
|
71
67
|
function fstat(path) {
|
|
72
68
|
return new Promise((resolve, reject) => {
|
|
@@ -77,16 +73,16 @@ function fstat(path) {
|
|
|
77
73
|
}
|
|
78
74
|
/**
|
|
79
75
|
* @function hasTrailingSlash
|
|
80
|
-
* @
|
|
81
|
-
* @
|
|
76
|
+
* @description Check if path has trailing slash
|
|
77
|
+
* @param path The path to check
|
|
82
78
|
*/
|
|
83
79
|
function hasTrailingSlash(path) {
|
|
84
80
|
return /\/$/.test(path);
|
|
85
81
|
}
|
|
86
82
|
/**
|
|
87
83
|
* @function parseTokens
|
|
88
|
-
* @description Parse
|
|
89
|
-
* @param
|
|
84
|
+
* @description Parse HTTP tokens
|
|
85
|
+
* @param value The tokens value string
|
|
90
86
|
*/
|
|
91
87
|
function parseTokens(value) {
|
|
92
88
|
let end = 0;
|
|
@@ -115,24 +111,24 @@ function parseTokens(value) {
|
|
|
115
111
|
tokens.push(value.substring(start, end));
|
|
116
112
|
return tokens;
|
|
117
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* @function isETag
|
|
116
|
+
* @description Check if etag is valid
|
|
117
|
+
* @param value The value to check
|
|
118
|
+
*/
|
|
119
|
+
function isETag(value) {
|
|
120
|
+
return /^(?:W\/)?"[\s\S]+"$/.test(value);
|
|
121
|
+
}
|
|
118
122
|
/**
|
|
119
123
|
* @function isETagFresh
|
|
120
|
-
* @
|
|
121
|
-
* @param
|
|
122
|
-
* @
|
|
124
|
+
* @description Check if etag is fresh
|
|
125
|
+
* @param match The match value
|
|
126
|
+
* @param etag The etag value
|
|
123
127
|
*/
|
|
124
128
|
function isETagFresh(match, etag) {
|
|
125
129
|
return parseTokens(match).some(match => {
|
|
126
130
|
return match === etag || match === 'W/' + etag || 'W/' + match === etag;
|
|
127
131
|
});
|
|
128
132
|
}
|
|
129
|
-
/**
|
|
130
|
-
* @function isETag
|
|
131
|
-
* @param {string} etag
|
|
132
|
-
* @returns {boolean}
|
|
133
|
-
*/
|
|
134
|
-
function isETag(etag) {
|
|
135
|
-
return /(?:W\/)?"(?:[ !#-\x7E\x80-\xFF]*|\r\n[\t ]|\\.)*"/.test(etag);
|
|
136
|
-
}
|
|
137
133
|
|
|
138
134
|
export { boundaryGenerator, decodeURI, fstat, hasTrailingSlash, isETag, isETagFresh, isOutRoot, parseTokens, unixify };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koa-files",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.8",
|
|
4
4
|
"description": "A static files serving middleware for koa.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "cjs/index.cjs",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"types": "types/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
"import": "./esm/index.js",
|
|
11
|
-
"require": "./cjs/index.cjs"
|
|
11
|
+
"require": "./cjs/index.cjs",
|
|
12
|
+
"types": "./types/index.d.ts"
|
|
12
13
|
},
|
|
13
14
|
"files": [
|
|
14
15
|
"cjs",
|
|
@@ -44,10 +45,10 @@
|
|
|
44
45
|
"test": "node tests",
|
|
45
46
|
"lint": "tsc --noEmit",
|
|
46
47
|
"clean": "node tools/clean.js",
|
|
47
|
-
"format": "prettier --write .",
|
|
48
48
|
"prepublishOnly": "npm run build",
|
|
49
49
|
"build:cjs": "rollup -c tools/rollup.cjs.js",
|
|
50
50
|
"build:esm": "rollup -c tools/rollup.esm.js",
|
|
51
|
+
"format": "prettier --write . --ignore-path .prettierignore",
|
|
51
52
|
"build": "npm run clean && npm run build:main && npm run format",
|
|
52
53
|
"build:main": "npm run build:cjs && npm run build:esm && npm run build:types",
|
|
53
54
|
"build:types": "tsc --declaration --emitDeclarationOnly --declarationDir types"
|
|
@@ -56,20 +57,20 @@
|
|
|
56
57
|
"destroy": "^1.2.0",
|
|
57
58
|
"etag": "^1.8.1",
|
|
58
59
|
"range-parser": "^1.2.1",
|
|
59
|
-
"tslib": "^2.
|
|
60
|
+
"tslib": "^2.6.2"
|
|
60
61
|
},
|
|
61
62
|
"devDependencies": {
|
|
62
|
-
"@rollup/plugin-typescript": "^11.
|
|
63
|
-
"@types/destroy": "^1.0.
|
|
64
|
-
"@types/etag": "^1.8.
|
|
65
|
-
"@types/koa": "^2.
|
|
66
|
-
"@types/range-parser": "^1.2.
|
|
67
|
-
"koa": "^2.
|
|
68
|
-
"magic-string": "^0.30.
|
|
69
|
-
"prettier": "^2.
|
|
70
|
-
"rimraf": "^
|
|
71
|
-
"rollup": "^
|
|
72
|
-
"typescript": "^5.
|
|
63
|
+
"@rollup/plugin-typescript": "^11.1.6",
|
|
64
|
+
"@types/destroy": "^1.0.3",
|
|
65
|
+
"@types/etag": "^1.8.3",
|
|
66
|
+
"@types/koa": "^2.15.0",
|
|
67
|
+
"@types/range-parser": "^1.2.7",
|
|
68
|
+
"koa": "^2.15.1",
|
|
69
|
+
"magic-string": "^0.30.8",
|
|
70
|
+
"prettier": "^3.2.5",
|
|
71
|
+
"rimraf": "^5.0.5",
|
|
72
|
+
"rollup": "^4.13.0",
|
|
73
|
+
"typescript": "^5.4.2"
|
|
73
74
|
},
|
|
74
75
|
"peerDependencies": {
|
|
75
76
|
"koa": "^2.0.0"
|
package/types/Files.d.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module Files
|
|
3
|
+
* @license MIT
|
|
4
|
+
* @author nuintun
|
|
5
|
+
*/
|
|
6
|
+
import { Context } from 'koa';
|
|
7
|
+
export interface Options {
|
|
8
|
+
etag?: boolean;
|
|
9
|
+
cacheControl?: string;
|
|
10
|
+
acceptRanges?: boolean;
|
|
11
|
+
lastModified?: boolean;
|
|
12
|
+
ignore?: (path: string) => boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* @class Files
|
|
16
|
+
*/
|
|
17
|
+
export default class Files {
|
|
18
|
+
private root;
|
|
19
|
+
private options;
|
|
20
|
+
/**
|
|
21
|
+
* @constructor
|
|
22
|
+
* @description Create files service
|
|
23
|
+
* @param root Files service root
|
|
24
|
+
* @param options Files service options
|
|
25
|
+
*/
|
|
26
|
+
constructor(root: string, options?: Options);
|
|
27
|
+
/**
|
|
28
|
+
* @private
|
|
29
|
+
* @method isConditionalGET
|
|
30
|
+
* @description Check if request is conditional GET
|
|
31
|
+
* @param context Koa context
|
|
32
|
+
*/
|
|
33
|
+
private isConditionalGET;
|
|
34
|
+
/**
|
|
35
|
+
* @private
|
|
36
|
+
* @method isPreconditionFailure
|
|
37
|
+
* @description Check if request precondition failure
|
|
38
|
+
* @param context Koa context
|
|
39
|
+
*/
|
|
40
|
+
private isPreconditionFailure;
|
|
41
|
+
/**
|
|
42
|
+
* @private
|
|
43
|
+
* @method isRangeFresh
|
|
44
|
+
* @description Check if request range fresh
|
|
45
|
+
* @param context Koa context
|
|
46
|
+
*/
|
|
47
|
+
private isRangeFresh;
|
|
48
|
+
/**
|
|
49
|
+
* @private
|
|
50
|
+
* @method isIgnore
|
|
51
|
+
* @description Check if path is ignore
|
|
52
|
+
* @param path File path
|
|
53
|
+
*/
|
|
54
|
+
private isIgnore;
|
|
55
|
+
/**
|
|
56
|
+
* @private
|
|
57
|
+
* @method parseRange
|
|
58
|
+
* @description Parse range
|
|
59
|
+
* @param context Koa context
|
|
60
|
+
* @param stats File stats
|
|
61
|
+
*/
|
|
62
|
+
private parseRange;
|
|
63
|
+
/**
|
|
64
|
+
* @private
|
|
65
|
+
* @method setupHeaders
|
|
66
|
+
* @description Setup headers
|
|
67
|
+
* @param context Koa context
|
|
68
|
+
* @param path File path
|
|
69
|
+
* @param stats File stats
|
|
70
|
+
*/
|
|
71
|
+
private setupHeaders;
|
|
72
|
+
/**
|
|
73
|
+
* @private
|
|
74
|
+
* @method read
|
|
75
|
+
* @description Read file
|
|
76
|
+
* @param path File path
|
|
77
|
+
* @param range Read range
|
|
78
|
+
* @param buffer Destination stream
|
|
79
|
+
* @param end Is destory destination stream after read
|
|
80
|
+
*/
|
|
81
|
+
private read;
|
|
82
|
+
/**
|
|
83
|
+
* @private
|
|
84
|
+
* @method send
|
|
85
|
+
* @description Send file
|
|
86
|
+
* @param context Koa context
|
|
87
|
+
* @param path File path
|
|
88
|
+
* @param ranges Read ranges
|
|
89
|
+
*/
|
|
90
|
+
private send;
|
|
91
|
+
/**
|
|
92
|
+
* @public
|
|
93
|
+
* @method response
|
|
94
|
+
* @description Response to koa context
|
|
95
|
+
* @param context Koa context
|
|
96
|
+
*/
|
|
97
|
+
response(context: Context): Promise<boolean>;
|
|
98
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* @author nuintun
|
|
5
5
|
*/
|
|
6
6
|
import { Middleware } from 'koa';
|
|
7
|
-
import { Options as
|
|
8
|
-
export interface Options extends
|
|
7
|
+
import { Options as FilesOptions } from './Files';
|
|
8
|
+
export interface Options extends FilesOptions {
|
|
9
9
|
defer?: boolean;
|
|
10
10
|
}
|
|
11
11
|
/**
|
package/types/utils.d.ts
CHANGED
|
@@ -7,60 +7,56 @@
|
|
|
7
7
|
import { Stats } from 'fs';
|
|
8
8
|
/**
|
|
9
9
|
* @function isOutRoot
|
|
10
|
-
* @description
|
|
11
|
-
* @param
|
|
12
|
-
* @param
|
|
13
|
-
* @returns {boolean}
|
|
10
|
+
* @description Check if path is out of root
|
|
11
|
+
* @param path The path to check
|
|
12
|
+
* @param root The root path
|
|
14
13
|
*/
|
|
15
14
|
export declare function isOutRoot(path: string, root: string): boolean;
|
|
16
15
|
/**
|
|
17
16
|
* @function unixify
|
|
18
|
-
* @description Convert path
|
|
19
|
-
* @param
|
|
20
|
-
* @returns {string}
|
|
17
|
+
* @description Convert path to unix style
|
|
18
|
+
* @param path The path to convert
|
|
21
19
|
*/
|
|
22
20
|
export declare function unixify(path: string): string;
|
|
23
21
|
/**
|
|
24
22
|
* @function decodeURI
|
|
25
|
-
* @description Decode URI component
|
|
26
|
-
* @param
|
|
27
|
-
* @returns {string|-1}
|
|
23
|
+
* @description Decode URI component
|
|
24
|
+
* @param URI The URI to decode
|
|
28
25
|
*/
|
|
29
26
|
export declare function decodeURI(URI: string): string | -1;
|
|
30
27
|
/**
|
|
31
28
|
* @function boundaryGenerator
|
|
32
|
-
* @description
|
|
33
|
-
* @returns {string}
|
|
29
|
+
* @description Generate a boundary
|
|
34
30
|
*/
|
|
35
31
|
export declare function boundaryGenerator(): string;
|
|
36
32
|
/**
|
|
37
33
|
* @function fstat
|
|
38
|
-
* @
|
|
39
|
-
* @
|
|
34
|
+
* @description Get file stats
|
|
35
|
+
* @param path The file path
|
|
40
36
|
*/
|
|
41
37
|
export declare function fstat(path: string): Promise<Stats>;
|
|
42
38
|
/**
|
|
43
39
|
* @function hasTrailingSlash
|
|
44
|
-
* @
|
|
45
|
-
* @
|
|
40
|
+
* @description Check if path has trailing slash
|
|
41
|
+
* @param path The path to check
|
|
46
42
|
*/
|
|
47
43
|
export declare function hasTrailingSlash(path: string): boolean;
|
|
48
44
|
/**
|
|
49
45
|
* @function parseTokens
|
|
50
|
-
* @description Parse
|
|
51
|
-
* @param
|
|
46
|
+
* @description Parse HTTP tokens
|
|
47
|
+
* @param value The tokens value string
|
|
52
48
|
*/
|
|
53
49
|
export declare function parseTokens(value: string): string[];
|
|
54
50
|
/**
|
|
55
|
-
* @function
|
|
56
|
-
* @
|
|
57
|
-
* @param
|
|
58
|
-
* @returns {boolean}
|
|
51
|
+
* @function isETag
|
|
52
|
+
* @description Check if etag is valid
|
|
53
|
+
* @param value The value to check
|
|
59
54
|
*/
|
|
60
|
-
export declare function
|
|
55
|
+
export declare function isETag(value: string): boolean;
|
|
61
56
|
/**
|
|
62
|
-
* @function
|
|
63
|
-
* @
|
|
64
|
-
* @
|
|
57
|
+
* @function isETagFresh
|
|
58
|
+
* @description Check if etag is fresh
|
|
59
|
+
* @param match The match value
|
|
60
|
+
* @param etag The etag value
|
|
65
61
|
*/
|
|
66
|
-
export declare function
|
|
62
|
+
export declare function isETagFresh(match: string, etag: string): boolean;
|
package/types/Send.d.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module Send
|
|
3
|
-
* @license MIT
|
|
4
|
-
* @author nuintun
|
|
5
|
-
*/
|
|
6
|
-
import { Context } from 'koa';
|
|
7
|
-
export interface Options {
|
|
8
|
-
etag?: boolean;
|
|
9
|
-
cacheControl?: string;
|
|
10
|
-
acceptRanges?: boolean;
|
|
11
|
-
lastModified?: boolean;
|
|
12
|
-
ignore?: (path: string) => boolean;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* @class Send
|
|
16
|
-
*/
|
|
17
|
-
export default class Send {
|
|
18
|
-
private root;
|
|
19
|
-
private options;
|
|
20
|
-
/**
|
|
21
|
-
* @constructor
|
|
22
|
-
* @param {string} root
|
|
23
|
-
* @param {Options} options
|
|
24
|
-
*/
|
|
25
|
-
constructor(root: string, options?: Options);
|
|
26
|
-
/**
|
|
27
|
-
* @method isConditionalGET
|
|
28
|
-
* @param {Context} context
|
|
29
|
-
* @returns {boolean}
|
|
30
|
-
*/
|
|
31
|
-
private isConditionalGET;
|
|
32
|
-
/**
|
|
33
|
-
* @method isPreconditionFailure
|
|
34
|
-
* @param {Context} context
|
|
35
|
-
* @returns {boolean}
|
|
36
|
-
*/
|
|
37
|
-
private isPreconditionFailure;
|
|
38
|
-
/**
|
|
39
|
-
* @method isRangeFresh
|
|
40
|
-
* @param {Context} context
|
|
41
|
-
* @returns {boolean}
|
|
42
|
-
*/
|
|
43
|
-
private isRangeFresh;
|
|
44
|
-
/**
|
|
45
|
-
* @method isIgnore
|
|
46
|
-
* @param {string} path
|
|
47
|
-
* @returns {boolean}
|
|
48
|
-
*/
|
|
49
|
-
private isIgnore;
|
|
50
|
-
/**
|
|
51
|
-
* @method parseRange
|
|
52
|
-
* @param {Context} context
|
|
53
|
-
* @param {Stats} stats
|
|
54
|
-
* @returns {Ranges}
|
|
55
|
-
*/
|
|
56
|
-
private parseRange;
|
|
57
|
-
/**
|
|
58
|
-
* @method setupHeaders
|
|
59
|
-
* @param {Context} context
|
|
60
|
-
* @param {string} path
|
|
61
|
-
* @param {Stats} stats
|
|
62
|
-
*/
|
|
63
|
-
private setupHeaders;
|
|
64
|
-
/**
|
|
65
|
-
* @method read
|
|
66
|
-
* @param {string} path
|
|
67
|
-
* @param {Range} range
|
|
68
|
-
* @param {PassThrough} buffer
|
|
69
|
-
* @param {boolean} end
|
|
70
|
-
* @returns {Promise<true>}
|
|
71
|
-
*/
|
|
72
|
-
private read;
|
|
73
|
-
/**
|
|
74
|
-
* @method send
|
|
75
|
-
* @param {Context} context
|
|
76
|
-
* @param {string} path
|
|
77
|
-
* @param {Range[]} ranges
|
|
78
|
-
*/
|
|
79
|
-
private send;
|
|
80
|
-
/**
|
|
81
|
-
* @method response
|
|
82
|
-
* @param {Context} context
|
|
83
|
-
* @returns {Promise<boolean>}
|
|
84
|
-
*/
|
|
85
|
-
response(context: Context): Promise<boolean>;
|
|
86
|
-
}
|