koa-files 3.1.4 → 3.1.6
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 +1 -1
- package/cjs/Service.cjs +1 -1
- package/cjs/index.cjs +1 -1
- package/cjs/utils/fs.cjs +1 -1
- package/cjs/utils/hash.cjs +1 -1
- package/cjs/utils/http.cjs +1 -1
- package/cjs/utils/path.cjs +1 -1
- package/cjs/utils/stream.cjs +46 -15
- package/esm/Service.js +1 -1
- package/esm/index.js +1 -1
- package/esm/utils/fs.js +1 -1
- package/esm/utils/hash.js +1 -1
- package/esm/utils/http.js +1 -1
- package/esm/utils/path.js +1 -1
- package/esm/utils/stream.js +46 -15
- package/package.json +1 -1
- package/types/utils/stream.d.ts +8 -1
package/README.md
CHANGED
|
@@ -91,7 +91,7 @@ export default function server(root: string, options?: Options): Middleware;
|
|
|
91
91
|
|
|
92
92
|
##### `highWaterMark`
|
|
93
93
|
|
|
94
|
-
- Defaults to `
|
|
94
|
+
- Defaults to `65536` (64 KiB).
|
|
95
95
|
- Set the high water mark for the read stream.
|
|
96
96
|
|
|
97
97
|
##### `ignore`
|
package/cjs/Service.cjs
CHANGED
package/cjs/index.cjs
CHANGED
package/cjs/utils/fs.cjs
CHANGED
package/cjs/utils/hash.cjs
CHANGED
package/cjs/utils/http.cjs
CHANGED
package/cjs/utils/path.cjs
CHANGED
package/cjs/utils/stream.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package koa-files
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 3.1.
|
|
4
|
+
* @version 3.1.6
|
|
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
|
|
@@ -15,6 +15,7 @@ const stream = require('stream');
|
|
|
15
15
|
/**
|
|
16
16
|
* @module stream
|
|
17
17
|
*/
|
|
18
|
+
const DISPOSE_EVENT = Symbol('dispose');
|
|
18
19
|
class FileReadStream extends stream.Readable {
|
|
19
20
|
/**
|
|
20
21
|
* @constructor
|
|
@@ -23,9 +24,10 @@ class FileReadStream extends stream.Readable {
|
|
|
23
24
|
* @param options The stream options.
|
|
24
25
|
*/
|
|
25
26
|
constructor(path, ranges, options) {
|
|
26
|
-
const { fs, encoding, highWaterMark } = options;
|
|
27
|
+
const { fs, encoding, highWaterMark = 65536 } = options;
|
|
27
28
|
super({ encoding, highWaterMark });
|
|
28
29
|
this.bytesRead = 0;
|
|
30
|
+
this.fd = null;
|
|
29
31
|
this.reading = false;
|
|
30
32
|
this.currentRangeIndex = 0;
|
|
31
33
|
this.readState = 0 /* ReadState.PREFIX */;
|
|
@@ -77,6 +79,7 @@ class FileReadStream extends stream.Readable {
|
|
|
77
79
|
let bytesRead = 0;
|
|
78
80
|
const padding = this.getPadding(range);
|
|
79
81
|
const hasRangePadding = padding != null;
|
|
82
|
+
// If padding exists.
|
|
80
83
|
if (hasRangePadding) {
|
|
81
84
|
const { length } = padding;
|
|
82
85
|
const begin = this.bytesRead;
|
|
@@ -87,9 +90,11 @@ class FileReadStream extends stream.Readable {
|
|
|
87
90
|
this.bytesRead = end;
|
|
88
91
|
}
|
|
89
92
|
}
|
|
93
|
+
// If no padding or read completed.
|
|
90
94
|
if (bytesRead <= 0) {
|
|
91
95
|
this.bytesRead = 0;
|
|
92
96
|
const { readState } = this;
|
|
97
|
+
// Change read state.
|
|
93
98
|
switch (readState) {
|
|
94
99
|
case 0 /* ReadState.PREFIX */:
|
|
95
100
|
this.readState = 1 /* ReadState.RANGE */;
|
|
@@ -119,21 +124,27 @@ class FileReadStream extends stream.Readable {
|
|
|
119
124
|
this.reading = true;
|
|
120
125
|
const { bytesRead } = this;
|
|
121
126
|
const position = range.offset + bytesRead;
|
|
122
|
-
const buffer$1 = buffer.Buffer.
|
|
127
|
+
const buffer$1 = buffer.Buffer.allocUnsafeSlow(Math.min(size, range.length - bytesRead));
|
|
128
|
+
// Read file range.
|
|
123
129
|
this.fs.read(fd, buffer$1, 0, buffer$1.length, position, (readError, bytesRead, buffer) => {
|
|
124
|
-
|
|
125
|
-
|
|
130
|
+
this.reading = false;
|
|
131
|
+
// Tell ._destroy() that it's safe to close the fd now.
|
|
132
|
+
if (this.destroyed) {
|
|
133
|
+
this.emit(DISPOSE_EVENT, readError);
|
|
126
134
|
} else {
|
|
127
|
-
if (
|
|
128
|
-
this.
|
|
129
|
-
this.bytesRead += bytesRead;
|
|
135
|
+
if (readError != null) {
|
|
136
|
+
this.destroy(readError);
|
|
130
137
|
} else {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
138
|
+
if (bytesRead > 0) {
|
|
139
|
+
this.push(buffer.subarray(0, bytesRead));
|
|
140
|
+
this.bytesRead += bytesRead;
|
|
141
|
+
} else {
|
|
142
|
+
this.bytesRead = 0;
|
|
143
|
+
this.readState = 2 /* ReadState.SUFFIX */;
|
|
144
|
+
this.readFilePadding(fd, range, size);
|
|
145
|
+
}
|
|
134
146
|
}
|
|
135
147
|
}
|
|
136
|
-
this.reading = false;
|
|
137
148
|
});
|
|
138
149
|
}
|
|
139
150
|
/**
|
|
@@ -145,10 +156,12 @@ class FileReadStream extends stream.Readable {
|
|
|
145
156
|
if (!this.reading) {
|
|
146
157
|
const { fd } = this;
|
|
147
158
|
const range = this.getRange();
|
|
159
|
+
// If fd or range is null, finish stream.
|
|
148
160
|
if (fd == null || range == null) {
|
|
149
161
|
this.push(null);
|
|
150
162
|
} else {
|
|
151
163
|
const { readState } = this;
|
|
164
|
+
// Read bytes from range.
|
|
152
165
|
switch (readState) {
|
|
153
166
|
case 0 /* ReadState.PREFIX */:
|
|
154
167
|
case 2 /* ReadState.SUFFIX */:
|
|
@@ -162,14 +175,16 @@ class FileReadStream extends stream.Readable {
|
|
|
162
175
|
}
|
|
163
176
|
}
|
|
164
177
|
/**
|
|
165
|
-
* @
|
|
166
|
-
* @method
|
|
178
|
+
* @private
|
|
179
|
+
* @method dispose
|
|
167
180
|
* @param error The error.
|
|
168
181
|
* @param callback The callback.
|
|
169
182
|
*/
|
|
170
|
-
|
|
183
|
+
dispose(error, callback) {
|
|
171
184
|
const { fd } = this;
|
|
172
185
|
if (fd != null) {
|
|
186
|
+
this.fd = null;
|
|
187
|
+
// Close the fd.
|
|
173
188
|
this.fs.close(fd, closeError => {
|
|
174
189
|
callback(error !== null && error !== void 0 ? error : closeError);
|
|
175
190
|
});
|
|
@@ -177,6 +192,22 @@ class FileReadStream extends stream.Readable {
|
|
|
177
192
|
callback(error);
|
|
178
193
|
}
|
|
179
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* @override
|
|
197
|
+
* @method _destroy
|
|
198
|
+
* @param error The error.
|
|
199
|
+
* @param callback The callback.
|
|
200
|
+
*/
|
|
201
|
+
_destroy(error, callback) {
|
|
202
|
+
// Wait I/O completion.
|
|
203
|
+
if (this.reading) {
|
|
204
|
+
this.once(DISPOSE_EVENT, disposeError => {
|
|
205
|
+
this.dispose(error !== null && error !== void 0 ? error : disposeError, callback);
|
|
206
|
+
});
|
|
207
|
+
} else {
|
|
208
|
+
this.dispose(error, callback);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
180
211
|
}
|
|
181
212
|
|
|
182
213
|
exports.FileReadStream = FileReadStream;
|
package/esm/Service.js
CHANGED
package/esm/index.js
CHANGED
package/esm/utils/fs.js
CHANGED
package/esm/utils/hash.js
CHANGED
package/esm/utils/http.js
CHANGED
package/esm/utils/path.js
CHANGED
package/esm/utils/stream.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package koa-files
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 3.1.
|
|
4
|
+
* @version 3.1.6
|
|
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
|
|
@@ -13,6 +13,7 @@ import { Readable } from 'stream';
|
|
|
13
13
|
/**
|
|
14
14
|
* @module stream
|
|
15
15
|
*/
|
|
16
|
+
const DISPOSE_EVENT = Symbol('dispose');
|
|
16
17
|
class FileReadStream extends Readable {
|
|
17
18
|
/**
|
|
18
19
|
* @constructor
|
|
@@ -21,9 +22,10 @@ class FileReadStream extends Readable {
|
|
|
21
22
|
* @param options The stream options.
|
|
22
23
|
*/
|
|
23
24
|
constructor(path, ranges, options) {
|
|
24
|
-
const { fs, encoding, highWaterMark } = options;
|
|
25
|
+
const { fs, encoding, highWaterMark = 65536 } = options;
|
|
25
26
|
super({ encoding, highWaterMark });
|
|
26
27
|
this.bytesRead = 0;
|
|
28
|
+
this.fd = null;
|
|
27
29
|
this.reading = false;
|
|
28
30
|
this.currentRangeIndex = 0;
|
|
29
31
|
this.readState = 0 /* ReadState.PREFIX */;
|
|
@@ -75,6 +77,7 @@ class FileReadStream extends Readable {
|
|
|
75
77
|
let bytesRead = 0;
|
|
76
78
|
const padding = this.getPadding(range);
|
|
77
79
|
const hasRangePadding = padding != null;
|
|
80
|
+
// If padding exists.
|
|
78
81
|
if (hasRangePadding) {
|
|
79
82
|
const { length } = padding;
|
|
80
83
|
const begin = this.bytesRead;
|
|
@@ -85,9 +88,11 @@ class FileReadStream extends Readable {
|
|
|
85
88
|
this.bytesRead = end;
|
|
86
89
|
}
|
|
87
90
|
}
|
|
91
|
+
// If no padding or read completed.
|
|
88
92
|
if (bytesRead <= 0) {
|
|
89
93
|
this.bytesRead = 0;
|
|
90
94
|
const { readState } = this;
|
|
95
|
+
// Change read state.
|
|
91
96
|
switch (readState) {
|
|
92
97
|
case 0 /* ReadState.PREFIX */:
|
|
93
98
|
this.readState = 1 /* ReadState.RANGE */;
|
|
@@ -117,21 +122,27 @@ class FileReadStream extends Readable {
|
|
|
117
122
|
this.reading = true;
|
|
118
123
|
const { bytesRead } = this;
|
|
119
124
|
const position = range.offset + bytesRead;
|
|
120
|
-
const buffer = Buffer.
|
|
125
|
+
const buffer = Buffer.allocUnsafeSlow(Math.min(size, range.length - bytesRead));
|
|
126
|
+
// Read file range.
|
|
121
127
|
this.fs.read(fd, buffer, 0, buffer.length, position, (readError, bytesRead, buffer) => {
|
|
122
|
-
|
|
123
|
-
|
|
128
|
+
this.reading = false;
|
|
129
|
+
// Tell ._destroy() that it's safe to close the fd now.
|
|
130
|
+
if (this.destroyed) {
|
|
131
|
+
this.emit(DISPOSE_EVENT, readError);
|
|
124
132
|
} else {
|
|
125
|
-
if (
|
|
126
|
-
this.
|
|
127
|
-
this.bytesRead += bytesRead;
|
|
133
|
+
if (readError != null) {
|
|
134
|
+
this.destroy(readError);
|
|
128
135
|
} else {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
136
|
+
if (bytesRead > 0) {
|
|
137
|
+
this.push(buffer.subarray(0, bytesRead));
|
|
138
|
+
this.bytesRead += bytesRead;
|
|
139
|
+
} else {
|
|
140
|
+
this.bytesRead = 0;
|
|
141
|
+
this.readState = 2 /* ReadState.SUFFIX */;
|
|
142
|
+
this.readFilePadding(fd, range, size);
|
|
143
|
+
}
|
|
132
144
|
}
|
|
133
145
|
}
|
|
134
|
-
this.reading = false;
|
|
135
146
|
});
|
|
136
147
|
}
|
|
137
148
|
/**
|
|
@@ -143,10 +154,12 @@ class FileReadStream extends Readable {
|
|
|
143
154
|
if (!this.reading) {
|
|
144
155
|
const { fd } = this;
|
|
145
156
|
const range = this.getRange();
|
|
157
|
+
// If fd or range is null, finish stream.
|
|
146
158
|
if (fd == null || range == null) {
|
|
147
159
|
this.push(null);
|
|
148
160
|
} else {
|
|
149
161
|
const { readState } = this;
|
|
162
|
+
// Read bytes from range.
|
|
150
163
|
switch (readState) {
|
|
151
164
|
case 0 /* ReadState.PREFIX */:
|
|
152
165
|
case 2 /* ReadState.SUFFIX */:
|
|
@@ -160,14 +173,16 @@ class FileReadStream extends Readable {
|
|
|
160
173
|
}
|
|
161
174
|
}
|
|
162
175
|
/**
|
|
163
|
-
* @
|
|
164
|
-
* @method
|
|
176
|
+
* @private
|
|
177
|
+
* @method dispose
|
|
165
178
|
* @param error The error.
|
|
166
179
|
* @param callback The callback.
|
|
167
180
|
*/
|
|
168
|
-
|
|
181
|
+
dispose(error, callback) {
|
|
169
182
|
const { fd } = this;
|
|
170
183
|
if (fd != null) {
|
|
184
|
+
this.fd = null;
|
|
185
|
+
// Close the fd.
|
|
171
186
|
this.fs.close(fd, closeError => {
|
|
172
187
|
callback(error !== null && error !== void 0 ? error : closeError);
|
|
173
188
|
});
|
|
@@ -175,6 +190,22 @@ class FileReadStream extends Readable {
|
|
|
175
190
|
callback(error);
|
|
176
191
|
}
|
|
177
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* @override
|
|
195
|
+
* @method _destroy
|
|
196
|
+
* @param error The error.
|
|
197
|
+
* @param callback The callback.
|
|
198
|
+
*/
|
|
199
|
+
_destroy(error, callback) {
|
|
200
|
+
// Wait I/O completion.
|
|
201
|
+
if (this.reading) {
|
|
202
|
+
this.once(DISPOSE_EVENT, disposeError => {
|
|
203
|
+
this.dispose(error !== null && error !== void 0 ? error : disposeError, callback);
|
|
204
|
+
});
|
|
205
|
+
} else {
|
|
206
|
+
this.dispose(error, callback);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
178
209
|
}
|
|
179
210
|
|
|
180
211
|
export { FileReadStream };
|
package/package.json
CHANGED
package/types/utils/stream.d.ts
CHANGED
|
@@ -18,11 +18,11 @@ interface Callback {
|
|
|
18
18
|
(error?: Error | null): void;
|
|
19
19
|
}
|
|
20
20
|
export declare class FileReadStream extends Readable {
|
|
21
|
-
private fd?;
|
|
22
21
|
private fs;
|
|
23
22
|
private path;
|
|
24
23
|
private ranges;
|
|
25
24
|
private bytesRead;
|
|
25
|
+
private fd;
|
|
26
26
|
private reading;
|
|
27
27
|
private currentRangeIndex;
|
|
28
28
|
private readState;
|
|
@@ -72,6 +72,13 @@ export declare class FileReadStream extends Readable {
|
|
|
72
72
|
* @param size The number of bytes to read.
|
|
73
73
|
*/
|
|
74
74
|
_read(size: number): void;
|
|
75
|
+
/**
|
|
76
|
+
* @private
|
|
77
|
+
* @method dispose
|
|
78
|
+
* @param error The error.
|
|
79
|
+
* @param callback The callback.
|
|
80
|
+
*/
|
|
81
|
+
private dispose;
|
|
75
82
|
/**
|
|
76
83
|
* @override
|
|
77
84
|
* @method _destroy
|