webpack-dev-service 0.12.12 → 0.13.0
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/cjs/client/client.cjs +1 -1
- package/cjs/client/events.cjs +1 -1
- package/cjs/client/hot.cjs +1 -1
- package/cjs/client/index.cjs +1 -1
- package/cjs/client/main.cjs +1 -1
- package/cjs/client/ui/Overlay.cjs +1 -1
- package/cjs/client/ui/Progress.cjs +1 -1
- package/cjs/client/ui/utils.cjs +1 -1
- package/cjs/server/compose.cjs +1 -1
- package/cjs/server/dev/{utils/stream.cjs → ReadStream.cjs} +6 -6
- package/cjs/server/dev/Service.cjs +41 -43
- package/cjs/server/dev/index.cjs +1 -1
- package/cjs/server/dev/middleware.cjs +6 -3
- package/cjs/server/dev/utils/fs.cjs +1 -1
- package/cjs/server/dev/utils/hash.cjs +1 -1
- package/cjs/server/dev/utils/http.cjs +68 -73
- package/cjs/server/dev/utils/path.cjs +1 -1
- package/cjs/server/dev/utils/paths.cjs +1 -1
- package/cjs/server/dev/utils/ready.cjs +1 -1
- package/cjs/server/dev/utils/setupHooks.cjs +1 -1
- package/cjs/server/dev/utils/setupOutputFileSystem.cjs +1 -1
- package/cjs/server/dev/utils/setupWatching.cjs +1 -1
- package/cjs/server/dev/utils/setupWriteToDisk.cjs +1 -1
- package/cjs/server/hot/Socket.cjs +1 -1
- package/cjs/server/hot/index.cjs +1 -1
- package/cjs/server/hot/utils.cjs +6 -4
- package/cjs/server/index.cjs +1 -1
- package/cjs/server/schema.cjs +1 -1
- package/cjs/server/utils.cjs +1 -1
- package/esm/client/client.js +1 -1
- package/esm/client/events.js +1 -1
- package/esm/client/hot.js +1 -1
- package/esm/client/index.js +1 -1
- package/esm/client/main.js +1 -1
- package/esm/client/ui/Overlay.js +1 -1
- package/esm/client/ui/Progress.js +1 -1
- package/esm/client/ui/utils.js +1 -1
- package/esm/server/compose.js +1 -1
- package/esm/server/dev/{utils/stream.js → ReadStream.js} +6 -6
- package/esm/server/dev/Service.js +42 -44
- package/esm/server/dev/index.js +1 -1
- package/esm/server/dev/middleware.js +6 -3
- package/esm/server/dev/utils/fs.js +1 -1
- package/esm/server/dev/utils/hash.js +1 -1
- package/esm/server/dev/utils/http.js +68 -73
- package/esm/server/dev/utils/path.js +1 -1
- package/esm/server/dev/utils/paths.js +1 -1
- package/esm/server/dev/utils/ready.js +1 -1
- package/esm/server/dev/utils/setupHooks.js +1 -1
- package/esm/server/dev/utils/setupOutputFileSystem.js +1 -1
- package/esm/server/dev/utils/setupWatching.js +1 -1
- package/esm/server/dev/utils/setupWriteToDisk.js +1 -1
- package/esm/server/hot/Socket.js +1 -1
- package/esm/server/hot/index.js +1 -1
- package/esm/server/hot/utils.js +6 -4
- package/esm/server/index.js +1 -1
- package/esm/server/schema.js +1 -1
- package/esm/server/utils.js +1 -1
- package/package.json +5 -5
- package/types/server/dev/{utils/stream.d.ts → ReadStream.d.ts} +5 -11
- package/types/server/dev/Service.d.ts +3 -3
- package/types/server/dev/utils/http.d.ts +12 -8
- package/types/server/hot/utils.d.ts +1 -1
package/cjs/client/client.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
package/cjs/client/events.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
package/cjs/client/hot.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
package/cjs/client/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
package/cjs/client/main.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
package/cjs/client/ui/utils.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
package/cjs/server/compose.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -13,10 +13,10 @@ const node_buffer = require('node:buffer');
|
|
|
13
13
|
const node_stream = require('node:stream');
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* @module
|
|
16
|
+
* @module ReadStream
|
|
17
17
|
*/
|
|
18
18
|
const DISPOSE_EVENT = Symbol('dispose');
|
|
19
|
-
class
|
|
19
|
+
class ReadStream extends node_stream.Readable {
|
|
20
20
|
#fs;
|
|
21
21
|
#path;
|
|
22
22
|
#ranges;
|
|
@@ -32,8 +32,8 @@ class FileReadStream extends node_stream.Readable {
|
|
|
32
32
|
* @param options The stream options.
|
|
33
33
|
*/
|
|
34
34
|
constructor(path, ranges, options) {
|
|
35
|
-
const { fs,
|
|
36
|
-
super({
|
|
35
|
+
const { fs, highWaterMark } = options;
|
|
36
|
+
super({ highWaterMark });
|
|
37
37
|
this.#fs = fs;
|
|
38
38
|
this.#path = path;
|
|
39
39
|
this.#ranges = ranges;
|
|
@@ -221,4 +221,4 @@ class FileReadStream extends node_stream.Readable {
|
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
exports.
|
|
224
|
+
exports.ReadStream = ReadStream;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
'use strict';
|
|
11
11
|
|
|
12
12
|
const createETag = require('etag');
|
|
13
|
+
const ReadStream = require('./ReadStream.cjs');
|
|
13
14
|
const utils = require('../utils.cjs');
|
|
14
15
|
const fs = require('./utils/fs.cjs');
|
|
15
|
-
const stream = require('./utils/stream.cjs');
|
|
16
16
|
const node_path = require('node:path');
|
|
17
17
|
const path = require('./utils/path.cjs');
|
|
18
18
|
const http = require('./utils/http.cjs');
|
|
@@ -60,47 +60,47 @@ class Service {
|
|
|
60
60
|
* @param path The file path.
|
|
61
61
|
* @param stats The file stats.
|
|
62
62
|
*/
|
|
63
|
-
#setupHeaders(
|
|
63
|
+
async #setupHeaders({ response }, path, stats) {
|
|
64
64
|
const options = this.#options;
|
|
65
|
-
const { headers
|
|
65
|
+
const { headers } = options;
|
|
66
66
|
// Set status.
|
|
67
|
-
|
|
67
|
+
response.status = 200;
|
|
68
68
|
// Set Content-Type.
|
|
69
|
-
|
|
69
|
+
response.type = node_path.extname(path);
|
|
70
|
+
// Set headers.
|
|
71
|
+
if (headers) {
|
|
72
|
+
if (utils.isFunction(headers)) {
|
|
73
|
+
const fields = await headers(path, stats);
|
|
74
|
+
if (fields) {
|
|
75
|
+
response.set(fields);
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
response.set(headers);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
70
81
|
// Accept-Ranges.
|
|
71
82
|
if (options.acceptRanges === false) {
|
|
72
83
|
// Set Accept-Ranges to none tell client not support.
|
|
73
|
-
|
|
84
|
+
response.set('Accept-Ranges', 'none');
|
|
74
85
|
} else {
|
|
75
86
|
// Set Accept-Ranges.
|
|
76
|
-
|
|
87
|
+
response.set('Accept-Ranges', 'bytes');
|
|
77
88
|
}
|
|
78
89
|
// ETag.
|
|
79
|
-
if (etag === false) {
|
|
90
|
+
if (options.etag === false) {
|
|
80
91
|
// Remove ETag.
|
|
81
|
-
|
|
82
|
-
} else {
|
|
83
|
-
// Set ETag.
|
|
84
|
-
|
|
92
|
+
response.remove('ETag');
|
|
93
|
+
} else if (!response.get('ETag')) {
|
|
94
|
+
// Set weak ETag.
|
|
95
|
+
response.set('ETag', createETag__default.default(stats));
|
|
85
96
|
}
|
|
86
97
|
// Last-Modified.
|
|
87
98
|
if (options.lastModified === false) {
|
|
88
99
|
// Remove Last-Modified.
|
|
89
|
-
|
|
90
|
-
} else {
|
|
91
|
-
// Set
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
// Set headers.
|
|
95
|
-
if (headers) {
|
|
96
|
-
if (utils.isFunction(headers)) {
|
|
97
|
-
const fields = headers(path, stats);
|
|
98
|
-
if (fields) {
|
|
99
|
-
context.set(fields);
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
context.set(headers);
|
|
103
|
-
}
|
|
100
|
+
response.remove('Last-Modified');
|
|
101
|
+
} else if (!response.get('Last-Modified')) {
|
|
102
|
+
// Set last modified from mtime.
|
|
103
|
+
response.set('Last-Modified', stats.mtime.toUTCString());
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
/**
|
|
@@ -134,10 +134,8 @@ class Service {
|
|
|
134
134
|
}
|
|
135
135
|
// Get options.
|
|
136
136
|
const options = this.#options;
|
|
137
|
-
// Get file system.
|
|
138
|
-
const { fs: fs$1 } = options;
|
|
139
137
|
// File stats.
|
|
140
|
-
const stats = await fs.stat(fs
|
|
138
|
+
const stats = await fs.stat(options.fs, path$1);
|
|
141
139
|
// Check file stats.
|
|
142
140
|
if (
|
|
143
141
|
// File not exist (404 | 500).
|
|
@@ -149,30 +147,32 @@ class Service {
|
|
|
149
147
|
) {
|
|
150
148
|
return false;
|
|
151
149
|
}
|
|
150
|
+
// Koa request and response.
|
|
151
|
+
const { request, response } = context;
|
|
152
152
|
// Setup headers.
|
|
153
|
-
this.#setupHeaders(context, path$1, stats);
|
|
153
|
+
await this.#setupHeaders(context, path$1, stats);
|
|
154
154
|
// Conditional get support.
|
|
155
155
|
if (http.isConditionalGET(context)) {
|
|
156
156
|
// Request precondition failure.
|
|
157
|
-
if (http.
|
|
157
|
+
if (http.isPreconditionFailed(context)) {
|
|
158
158
|
return context.throw(412);
|
|
159
159
|
}
|
|
160
160
|
// Request fresh (304).
|
|
161
|
-
if (
|
|
161
|
+
if (request.fresh) {
|
|
162
162
|
// Set status.
|
|
163
|
-
|
|
163
|
+
response.status = 304;
|
|
164
164
|
// Set body null.
|
|
165
|
-
|
|
165
|
+
response.body = null;
|
|
166
166
|
// File found.
|
|
167
167
|
return true;
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
// Head request.
|
|
171
|
-
if (
|
|
171
|
+
if (request.method === 'HEAD') {
|
|
172
172
|
// Set Content-Length.
|
|
173
|
-
|
|
173
|
+
response.length = stats.size;
|
|
174
174
|
// Set body null
|
|
175
|
-
|
|
175
|
+
response.body = null;
|
|
176
176
|
// File found.
|
|
177
177
|
return true;
|
|
178
178
|
}
|
|
@@ -181,7 +181,7 @@ class Service {
|
|
|
181
181
|
// 416
|
|
182
182
|
if (ranges === -1) {
|
|
183
183
|
// Set Content-Range.
|
|
184
|
-
|
|
184
|
+
response.set('Content-Range', `bytes */${stats.size}`);
|
|
185
185
|
// Unsatisfiable 416.
|
|
186
186
|
return context.throw(416);
|
|
187
187
|
}
|
|
@@ -189,10 +189,8 @@ class Service {
|
|
|
189
189
|
if (ranges === -2) {
|
|
190
190
|
return context.throw(400);
|
|
191
191
|
}
|
|
192
|
-
// Get stream options.
|
|
193
|
-
const { highWaterMark } = options;
|
|
194
192
|
// Set response body.
|
|
195
|
-
|
|
193
|
+
response.body = new ReadStream.ReadStream(path$1, ranges, options);
|
|
196
194
|
// File found.
|
|
197
195
|
return true;
|
|
198
196
|
}
|
package/cjs/server/dev/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -52,13 +52,16 @@ function getFileServicesAsync(context) {
|
|
|
52
52
|
function middleware(context) {
|
|
53
53
|
// Middleware.
|
|
54
54
|
return async (ctx, next) => {
|
|
55
|
-
const
|
|
55
|
+
const { request } = ctx;
|
|
56
|
+
const pathname = http.decodeURI(request.path);
|
|
56
57
|
// Pathname decode failed or includes null byte(s).
|
|
57
58
|
if (pathname === -1 || pathname.includes('\0')) {
|
|
58
59
|
return ctx.throw(400);
|
|
59
60
|
}
|
|
61
|
+
// Get request method.
|
|
62
|
+
const { method } = request;
|
|
60
63
|
// Only support GET and HEAD (405).
|
|
61
|
-
if (
|
|
64
|
+
if (method === 'GET' || method === 'HEAD') {
|
|
62
65
|
// Get the file services.
|
|
63
66
|
const services = await getFileServicesAsync(context);
|
|
64
67
|
// Try to respond.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -22,23 +22,8 @@ const parseRange__default = /*#__PURE__*/ _interopDefault(parseRange);
|
|
|
22
22
|
/**
|
|
23
23
|
* @module http
|
|
24
24
|
*/
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
* @function isETag
|
|
28
|
-
* @description Check if etag is valid.
|
|
29
|
-
* @param value The value to check.
|
|
30
|
-
*/
|
|
31
|
-
function isETag(value) {
|
|
32
|
-
return /^(?:W\/)?"[\s\S]+"$/.test(value);
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* @function parseTokens
|
|
36
|
-
* @description Parse HTTP tokens.
|
|
37
|
-
* @param value The tokens value string.
|
|
38
|
-
*/
|
|
39
|
-
function parseTokens(value) {
|
|
40
|
-
return value.trim().split(TOKEN_SPLIT_REGEX);
|
|
41
|
-
}
|
|
25
|
+
const SPLIT_ETAG_RE = /\s*,\s*/;
|
|
26
|
+
const SINGLE_ETAG_RE = /^(?:W\/)?"[ !#-\x7E\x80-\xFF]+"$/;
|
|
42
27
|
/**
|
|
43
28
|
* @function decodeURI
|
|
44
29
|
* @description Decode URI component.
|
|
@@ -51,45 +36,12 @@ function decodeURI(URI) {
|
|
|
51
36
|
return -1;
|
|
52
37
|
}
|
|
53
38
|
}
|
|
54
|
-
/**
|
|
55
|
-
* @function isRangeFresh
|
|
56
|
-
* @description Check if request range fresh.
|
|
57
|
-
* @param context Koa context.
|
|
58
|
-
*/
|
|
59
|
-
function isRangeFresh(context) {
|
|
60
|
-
const { request, response } = context;
|
|
61
|
-
const ifRange = request.get('If-Range');
|
|
62
|
-
// No If-Range.
|
|
63
|
-
if (!ifRange) {
|
|
64
|
-
return true;
|
|
65
|
-
}
|
|
66
|
-
// If-Range as etag.
|
|
67
|
-
if (isETag(ifRange)) {
|
|
68
|
-
const etag = response.get('ETag');
|
|
69
|
-
return !!(etag && isETagFresh(ifRange, etag));
|
|
70
|
-
}
|
|
71
|
-
// If-Range as modified date.
|
|
72
|
-
const lastModified = response.get('Last-Modified');
|
|
73
|
-
return Date.parse(lastModified) <= Date.parse(ifRange);
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* @function isETagFresh
|
|
77
|
-
* @description Check if etag is fresh.
|
|
78
|
-
* @param match The match value.
|
|
79
|
-
* @param etag The etag value.
|
|
80
|
-
*/
|
|
81
|
-
function isETagFresh(match, etag) {
|
|
82
|
-
return parseTokens(match).some(match => {
|
|
83
|
-
return match === etag || match === 'W/' + etag || 'W/' + match === etag;
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
39
|
/**
|
|
87
40
|
* @function isConditionalGET
|
|
88
41
|
* @description Check if request is conditional GET.
|
|
89
42
|
* @param context The koa context.
|
|
90
43
|
*/
|
|
91
|
-
function isConditionalGET(
|
|
92
|
-
const { request } = context;
|
|
44
|
+
function isConditionalGET({ request }) {
|
|
93
45
|
return !!(
|
|
94
46
|
request.get('If-Match') ||
|
|
95
47
|
request.get('If-None-Match') ||
|
|
@@ -98,30 +50,72 @@ function isConditionalGET(context) {
|
|
|
98
50
|
);
|
|
99
51
|
}
|
|
100
52
|
/**
|
|
101
|
-
* @function
|
|
102
|
-
* @
|
|
53
|
+
* @function isETagMatch
|
|
54
|
+
* @see https://httpwg.org/specs/rfc9110.html
|
|
55
|
+
* @param match The match value.
|
|
56
|
+
* @param etag The etag value.
|
|
57
|
+
* @param isIfMatch The flag of if-match.
|
|
58
|
+
*/
|
|
59
|
+
function isETagMatch(match, etag, isIfMatch) {
|
|
60
|
+
// Trim etag.
|
|
61
|
+
etag = etag.trim();
|
|
62
|
+
// Weak tags cannot be matched and return false.
|
|
63
|
+
if (!etag || etag.startsWith('W/')) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
// Trim match.
|
|
67
|
+
match = match.trim();
|
|
68
|
+
// Check If-Match.
|
|
69
|
+
if (isIfMatch) {
|
|
70
|
+
if (match === '*') {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
// If-Match maybe a list of etag.
|
|
74
|
+
return match.split(SPLIT_ETAG_RE).includes(etag);
|
|
75
|
+
}
|
|
76
|
+
// Check If-Range.
|
|
77
|
+
return match === etag;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* @function isPreconditionFailed
|
|
81
|
+
* @description Check if request precondition failed.
|
|
103
82
|
* @param context The koa context.
|
|
104
83
|
*/
|
|
105
|
-
function
|
|
84
|
+
function isPreconditionFailed({ request, response }) {
|
|
106
85
|
// If-Match.
|
|
107
|
-
const
|
|
108
|
-
// Check
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
const etag = response.get('ETag');
|
|
112
|
-
return !etag || match === '*' || !isETagFresh(match, etag);
|
|
86
|
+
const ifMatch = request.get('If-Match');
|
|
87
|
+
// Check If-Match.
|
|
88
|
+
if (ifMatch) {
|
|
89
|
+
return !isETagMatch(ifMatch, response.get('ETag'), true);
|
|
113
90
|
}
|
|
114
91
|
// If-Unmodified-Since.
|
|
115
92
|
const unmodifiedSince = Date.parse(request.get('If-Unmodified-Since'));
|
|
116
|
-
// Check
|
|
93
|
+
// Check If-Unmodified-Since.
|
|
117
94
|
if (!Number.isNaN(unmodifiedSince)) {
|
|
118
|
-
// Last-Modified.
|
|
119
95
|
const lastModified = Date.parse(response.get('Last-Modified'));
|
|
120
96
|
return Number.isNaN(lastModified) || lastModified > unmodifiedSince;
|
|
121
97
|
}
|
|
122
98
|
// Check precondition passed.
|
|
123
99
|
return false;
|
|
124
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* @function isRangeFresh
|
|
103
|
+
* @description Check if request range fresh.
|
|
104
|
+
* @param context Koa context.
|
|
105
|
+
*/
|
|
106
|
+
function isRangeFresh({ request, response }) {
|
|
107
|
+
const ifRange = request.get('If-Range');
|
|
108
|
+
// No If-Range.
|
|
109
|
+
if (!ifRange) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
// If-Range as modified date failed.
|
|
113
|
+
if (SINGLE_ETAG_RE.test(ifRange)) {
|
|
114
|
+
return isETagMatch(ifRange, response.get('ETag'));
|
|
115
|
+
}
|
|
116
|
+
// Check if Last-Modified is valid and equal to If-Range date
|
|
117
|
+
return Date.parse(response.get('Last-Modified')) <= Date.parse(ifRange);
|
|
118
|
+
}
|
|
125
119
|
/**
|
|
126
120
|
* @function parseRanges
|
|
127
121
|
* @description Parse ranges.
|
|
@@ -130,9 +124,10 @@ function isPreconditionFailure({ request, response }) {
|
|
|
130
124
|
*/
|
|
131
125
|
function parseRanges(context, stats) {
|
|
132
126
|
const { size } = stats;
|
|
127
|
+
const { request, response } = context;
|
|
133
128
|
// Range support.
|
|
134
|
-
if (/^bytes$/i.test(
|
|
135
|
-
const range =
|
|
129
|
+
if (/^bytes$/i.test(response.get('Accept-Ranges'))) {
|
|
130
|
+
const range = request.get('Range');
|
|
136
131
|
// Range fresh.
|
|
137
132
|
if (range && isRangeFresh(context)) {
|
|
138
133
|
// Parse range -1 -2 or [].
|
|
@@ -145,7 +140,7 @@ function parseRanges(context, stats) {
|
|
|
145
140
|
// Ranges ok, support multiple ranges.
|
|
146
141
|
if (parsed.type === 'bytes') {
|
|
147
142
|
// Set 206 status.
|
|
148
|
-
|
|
143
|
+
response.status = 206;
|
|
149
144
|
const { length } = parsed;
|
|
150
145
|
// Multiple ranges.
|
|
151
146
|
if (length > 1) {
|
|
@@ -158,11 +153,11 @@ function parseRanges(context, stats) {
|
|
|
158
153
|
// Range boundary.
|
|
159
154
|
const boundary = `${hash.generate(32)}`;
|
|
160
155
|
// Multipart Content-Type.
|
|
161
|
-
const contentType = `Content-Type: ${
|
|
156
|
+
const contentType = `Content-Type: ${response.type}`;
|
|
162
157
|
// Range suffix.
|
|
163
158
|
const suffix = node_buffer.Buffer.from(`\r\n--${boundary}--\r\n`);
|
|
164
159
|
// Override Content-Type.
|
|
165
|
-
|
|
160
|
+
response.type = `multipart/byteranges; boundary="${boundary}"`;
|
|
166
161
|
// Map ranges.
|
|
167
162
|
for (const [index, { start, end }] of entries) {
|
|
168
163
|
const length = end - start + 1;
|
|
@@ -177,7 +172,7 @@ function parseRanges(context, stats) {
|
|
|
177
172
|
// Compute Content-Length.
|
|
178
173
|
contentLength += suffix.length;
|
|
179
174
|
// Set Content-Length.
|
|
180
|
-
|
|
175
|
+
response.length = contentLength;
|
|
181
176
|
// The last add suffix boundary.
|
|
182
177
|
ranges[length - 1].suffix = suffix;
|
|
183
178
|
// Return ranges.
|
|
@@ -186,9 +181,9 @@ function parseRanges(context, stats) {
|
|
|
186
181
|
const [{ start, end }] = parsed;
|
|
187
182
|
const length = end - start + 1;
|
|
188
183
|
// Set Content-Length.
|
|
189
|
-
|
|
184
|
+
response.length = length;
|
|
190
185
|
// Set Content-Range.
|
|
191
|
-
|
|
186
|
+
response.set('Content-Range', `bytes ${start}-${end}/${size}`);
|
|
192
187
|
// Return ranges.
|
|
193
188
|
return [{ offset: start, length }];
|
|
194
189
|
}
|
|
@@ -196,12 +191,12 @@ function parseRanges(context, stats) {
|
|
|
196
191
|
}
|
|
197
192
|
}
|
|
198
193
|
// Set Content-Length.
|
|
199
|
-
|
|
194
|
+
response.length = size;
|
|
200
195
|
// Return ranges.
|
|
201
196
|
return [{ offset: 0, length: size }];
|
|
202
197
|
}
|
|
203
198
|
|
|
204
199
|
exports.decodeURI = decodeURI;
|
|
205
200
|
exports.isConditionalGET = isConditionalGET;
|
|
206
|
-
exports.
|
|
201
|
+
exports.isPreconditionFailed = isPreconditionFailed;
|
|
207
202
|
exports.parseRanges = parseRanges;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @package webpack-dev-service
|
|
3
3
|
* @license MIT
|
|
4
|
-
* @version 0.
|
|
4
|
+
* @version 0.13.0
|
|
5
5
|
* @author nuintun <nuintun@qq.com>
|
|
6
6
|
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
7
|
* @see https://github.com/nuintun/webpack-dev-service#readme
|