dx-server 0.11.0 → 0.11.2

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/esm/static.js CHANGED
@@ -1,6 +1,8 @@
1
- import { getReq, getRes } from './dx.js';
2
- import { sendFile } from './staticHelpers.js';
1
+ import { getReq, getRes, setHtml } from './dx.js';
2
+ import { sendFileTrusted } from './staticHelpers.js';
3
3
  import { urlFromReq } from './bodyHelpers.js';
4
+ import path from 'node:path';
5
+ const UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
4
6
  export function chainStatic(pattern, { getPathname, ...options }) {
5
7
  const urlPattern = new URLPattern({ pathname: pattern });
6
8
  return async (next) => {
@@ -20,4 +22,47 @@ export function chainStatic(pattern, { getPathname, ...options }) {
20
22
  }
21
23
  };
22
24
  }
23
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3N0YXRpYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWlCLE1BQU0sRUFBRSxNQUFNLEVBQUMsTUFBTSxTQUFTLENBQUE7QUFFdEQsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLG9CQUFvQixDQUFBO0FBQzNDLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUUzQyxNQUFNLFVBQVUsV0FBVyxDQUMxQixPQUFlLEVBQ2YsRUFBQyxXQUFXLEVBQUUsR0FBRyxPQUFPLEVBSXZCO0lBRUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxVQUFVLENBQUMsRUFBQyxRQUFRLEVBQUUsT0FBTyxFQUFDLENBQUMsQ0FBQTtJQUN0RCxPQUFPLEtBQUssRUFBQyxJQUFJLEVBQUMsRUFBRTtRQUNuQixNQUFNLEdBQUcsR0FBRyxNQUFNLEVBQUUsQ0FBQTtRQUNwQixJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssS0FBSyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssTUFBTTtZQUFFLE9BQU8sSUFBSSxFQUFFLENBQUE7UUFFaEUsTUFBTSxFQUFDLFFBQVEsRUFBQyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNsQyxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUMsUUFBUSxFQUFDLENBQUMsQ0FBQTtRQUMzQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sSUFBSSxFQUFFLENBQUE7UUFFM0IsSUFBSSxDQUFDO1lBQ0osTUFBTSxRQUFRLENBQ2IsR0FBRyxFQUNILE1BQU0sRUFBRSxFQUNQLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQzttQkFDcEIsa0JBQWtCLENBQUMsUUFBUSxDQUFDLEVBQy9CLE9BQU8sQ0FDUCxDQUFBO1FBQ0YsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDWixPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQSxDQUFDLGlHQUFpRztRQUNqSCxDQUFDO0lBQ0YsQ0FBQyxDQUFBO0FBQ0YsQ0FBQyJ9
25
+ async function sendFile(req, res, pathname, // plain path, not URI-encoded
26
+ options) {
27
+ const { root, dotfiles, ...trustedSendOptions } = options ?? {};
28
+ // null byte(s)
29
+ if (pathname.includes('\0'))
30
+ return setHtml('Invalid request', { status: 400 });
31
+ let parts;
32
+ if (root) {
33
+ // normalize
34
+ pathname = path.normalize(`.${path.sep}${pathname}`);
35
+ // malicious path
36
+ if (UP_PATH_REGEXP.test(pathname))
37
+ return setHtml('Forbidden', { status: 403 });
38
+ // explode path parts
39
+ parts = pathname.split(path.sep);
40
+ // join / normalize from optional root dir
41
+ pathname = path.normalize(path.join(root, pathname));
42
+ }
43
+ else {
44
+ // malicious path
45
+ if (UP_PATH_REGEXP.test(pathname))
46
+ return setHtml('Forbidden', { status: 403 });
47
+ // explode path parts
48
+ parts = path.normalize(pathname).split(path.sep);
49
+ // join / normalize from optional root dir
50
+ pathname = path.resolve(pathname);
51
+ }
52
+ // dotfile handling
53
+ if (parts.some(part => part.length > 1 && part[0] === '.'))
54
+ switch (dotfiles) {
55
+ case 'allow':
56
+ break;
57
+ case 'deny':
58
+ return setHtml('Forbidden', { status: 403 });
59
+ case 'ignore':
60
+ default:
61
+ throw new Error('Forbidden: dotfiles are not allowed');
62
+ }
63
+ // pathEndsWithSep
64
+ if (pathname[pathname.length - 1] === path.sep)
65
+ return setHtml('Forbidden: directory access is not allowed', { status: 403 });
66
+ return sendFileTrusted(req, res, pathname, trustedSendOptions);
67
+ }
68
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3N0YXRpYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWlCLE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFDLE1BQU0sU0FBUyxDQUFBO0FBQy9ELE9BQU8sRUFBQyxlQUFlLEVBQTBCLE1BQU0sb0JBQW9CLENBQUE7QUFDM0UsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLGtCQUFrQixDQUFBO0FBRTNDLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQTtBQUU1QixNQUFNLGNBQWMsR0FBRyw0QkFBNEIsQ0FBQTtBQUVuRCxNQUFNLFVBQVUsV0FBVyxDQUMxQixPQUFlLEVBQ2YsRUFBQyxXQUFXLEVBQUUsR0FBRyxPQUFPLEVBUXZCO0lBRUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxVQUFVLENBQUMsRUFBQyxRQUFRLEVBQUUsT0FBTyxFQUFDLENBQUMsQ0FBQTtJQUN0RCxPQUFPLEtBQUssRUFBQyxJQUFJLEVBQUMsRUFBRTtRQUNuQixNQUFNLEdBQUcsR0FBRyxNQUFNLEVBQUUsQ0FBQTtRQUNwQixJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssS0FBSyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssTUFBTTtZQUFFLE9BQU8sSUFBSSxFQUFFLENBQUE7UUFFaEUsTUFBTSxFQUFDLFFBQVEsRUFBQyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNsQyxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUMsUUFBUSxFQUFDLENBQUMsQ0FBQTtRQUMzQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sSUFBSSxFQUFFLENBQUE7UUFFM0IsSUFBSSxDQUFDO1lBQ0osTUFBTSxRQUFRLENBQ2IsR0FBRyxFQUNILE1BQU0sRUFBRSxFQUNQLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQzttQkFDcEIsa0JBQWtCLENBQUMsUUFBUSxDQUFDLEVB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
@@ -1,21 +1,16 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
2
  import { IncomingMessage, ServerResponse } from 'node:http';
3
3
  import './polyfillWithResolvers.js';
4
- export interface SendOptions {
4
+ export interface TrustedSendOptions {
5
5
  disableAcceptRanges?: boolean;
6
6
  disableLastModified?: boolean;
7
- disableEtag?: boolean;
7
+ etag?: 'disabled' | 'strong' | 'weak';
8
8
  disableCacheControl?: boolean;
9
9
  maxAge?: number;
10
- dotfiles?: 'allow' | 'deny' | 'ignore';
11
10
  immutable?: boolean;
12
- weakEtag?: boolean;
13
11
  end?: number;
14
- root?: string;
15
12
  start?: number;
16
13
  }
17
- export declare function sendFile(req: IncomingMessage, res: ServerResponse, pathname: string, // plain path, not URI-encoded
18
- options?: SendOptions): Promise<void>;
19
14
  export declare function sendFileTrusted(req: IncomingMessage, res: ServerResponse, pathname: string, // plain path, not URI-encoded
20
- { root, dotfiles, start, end, disableAcceptRanges, disableLastModified, disableEtag, disableCacheControl, maxAge, // 1 year
21
- immutable, weakEtag, }?: SendOptions | undefined): Promise<void>;
15
+ { start, end, disableAcceptRanges, disableLastModified, etag, disableCacheControl, maxAge, // 1 year
16
+ immutable, }?: TrustedSendOptions | undefined): Promise<void>;
@@ -1,62 +1,17 @@
1
1
  import './polyfillWithResolvers.js';
2
- import { setEmpty, setHtml } from './dx.js';
3
2
  import path from 'node:path';
4
- import { readFile, stat } from 'node:fs/promises';
5
- import { entityTag, statTag } from './vendors/etag.js';
3
+ import { stat } from 'node:fs/promises';
4
+ import { entityTagPath, statTag } from './vendors/etag.js';
6
5
  import { contentTypeForExtension } from './vendors/mime.js';
7
6
  import { fresh, parseHttpDate, parseTokenList } from './vendors/fresh.js';
8
7
  import { parseRange } from './vendors/rangeParser.js';
9
8
  import { createReadStream } from 'node:fs';
10
9
  import { onFinished } from './vendors/onFinished.js';
11
- const UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
10
+ import { promisify } from 'node:util';
12
11
  const BYTES_RANGE_REGEXP = /^ *bytes=/;
13
- export async function sendFile(req, res, pathname, // plain path, not URI-encoded
14
- options) {
15
- const { root, dotfiles, start = 0, end, disableAcceptRanges, disableLastModified, disableEtag, disableCacheControl, maxAge = 60 * 60 * 24 * 365 * 1000, // 1 year
16
- immutable, } = options ?? {};
17
- // null byte(s)
18
- if (pathname.includes('\0'))
19
- return setHtml('Invalid request', { status: 400 });
20
- let parts;
21
- if (root) {
22
- // normalize
23
- pathname = path.normalize(`.${path.sep}${pathname}`);
24
- // malicious path
25
- if (UP_PATH_REGEXP.test(pathname))
26
- return setHtml('Forbidden', { status: 403 });
27
- // explode path parts
28
- parts = pathname.split(path.sep);
29
- // join / normalize from optional root dir
30
- pathname = path.normalize(path.join(root, pathname));
31
- }
32
- else {
33
- // malicious path
34
- if (UP_PATH_REGEXP.test(pathname))
35
- return setHtml('Forbidden', { status: 403 });
36
- // explode path parts
37
- parts = path.normalize(pathname).split(path.sep);
38
- // join / normalize from optional root dir
39
- pathname = path.resolve(pathname);
40
- }
41
- // dotfile handling
42
- if (parts.some(part => part.length > 1 && part[0] === '.'))
43
- switch (dotfiles) {
44
- case 'allow':
45
- break;
46
- case 'deny':
47
- return setHtml('Forbidden', { status: 403 });
48
- case 'ignore':
49
- default:
50
- throw new Error('Forbidden: dotfiles are not allowed');
51
- }
52
- // pathEndsWithSep
53
- if (pathname[pathname.length - 1] === path.sep)
54
- return setHtml('Forbidden: directory access is not allowed', { status: 403 });
55
- return sendFileTrusted(req, res, pathname, options);
56
- }
57
12
  export async function sendFileTrusted(req, res, pathname, // plain path, not URI-encoded
58
- { root, dotfiles, start = 0, end, disableAcceptRanges, disableLastModified, disableEtag, disableCacheControl, maxAge = 60 * 60 * 24 * 365 * 1000, // 1 year
59
- immutable, weakEtag, } = {}) {
13
+ { start = 0, end, disableAcceptRanges, disableLastModified, etag = 'strong', disableCacheControl, maxAge = 60 * 60 * 24 * 365 * 1000, // 1 year
14
+ immutable, } = {}) {
60
15
  const fileStat = await stat(pathname);
61
16
  // not found, check extensions
62
17
  // if (err.code === 'ENOENT' && !path.extname(pathname) && !pathEndsWithSep) throw err
@@ -70,21 +25,18 @@ immutable, weakEtag, } = {}) {
70
25
  throw new Error('Forbidden: directory access is not allowed');
71
26
  if (res.headersSent)
72
27
  return;
73
- // Load file into buffer for strong ETag calculation
74
- let fileBuffer;
75
- if (!weakEtag)
76
- fileBuffer = await readFile(pathname);
77
28
  //region set header fields
78
- if (!disableAcceptRanges && weakEtag && !res.getHeader('Accept-Ranges'))
29
+ if (!disableAcceptRanges && !res.getHeader('Accept-Ranges'))
79
30
  res.setHeader('Accept-Ranges', 'bytes');
80
31
  if (!disableCacheControl && !res.getHeader('Cache-Control'))
81
- res.setHeader('Cache-Control', [`public, max-age=${Math.floor(maxAge / 1000)}`,
32
+ res.setHeader('Cache-Control', [
33
+ `public, max-age=${Math.floor(maxAge / 1000)}`,
82
34
  immutable && 'immutable',
83
35
  ].filter(Boolean).join(', '));
84
36
  if (!disableLastModified && !res.getHeader('Last-Modified'))
85
37
  res.setHeader('Last-Modified', fileStat.mtime.toUTCString());
86
- if (!disableEtag && !res.getHeader('ETag'))
87
- res.setHeader('ETag', weakEtag ? statTag(fileStat) : entityTag(fileBuffer, false));
38
+ if (etag !== 'disabled' && !res.getHeader('ETag'))
39
+ res.setHeader('ETag', etag === 'weak' ? statTag(fileStat) : await entityTagPath(fileStat, pathname, false));
88
40
  //endregion set header fields
89
41
  // content-type
90
42
  if (!res.getHeader('Content-Type'))
@@ -102,7 +54,7 @@ immutable, weakEtag, } = {}) {
102
54
  throw new Error('Precondition Failed: request headers do not match the response');
103
55
  }
104
56
  // if-unmodified-since (ignore when using strong etag since mtime may be unreliable)
105
- if (weakEtag) {
57
+ if (etag === 'weak') {
106
58
  const unmodifiedSince = parseHttpDate(req.headers['if-unmodified-since']);
107
59
  if (!isNaN(unmodifiedSince)) {
108
60
  const lastModified = parseHttpDate(res.getHeader('Last-Modified'));
@@ -112,12 +64,11 @@ immutable, weakEtag, } = {}) {
112
64
  }
113
65
  //endregion isPreconditionFailure
114
66
  // isCachable
115
- if (((res.statusCode >= 200 && res.statusCode < 300) ||
116
- res.statusCode === 304)
67
+ if ((res.statusCode >= 200 && res.statusCode < 300 || res.statusCode === 304)
117
68
  && fresh(req.headers, {
118
69
  etag: res.getHeader('ETag'),
119
- // Only use last-modified for freshness check when using weakEtag
120
- 'last-modified': weakEtag ? res.getHeader('Last-Modified') : undefined
70
+ // Only use last-modified for freshness check when using weak Etag
71
+ 'last-modified': etag === 'weak' ? res.getHeader('Last-Modified') : undefined
121
72
  })) {
122
73
  // removeContentHeaderFields
123
74
  res.removeHeader('Content-Encoding');
@@ -126,7 +77,7 @@ immutable, weakEtag, } = {}) {
126
77
  res.removeHeader('Content-Range');
127
78
  res.removeHeader('Content-Type');
128
79
  res.statusCode = 304;
129
- res.end();
80
+ return void await promisify(res.end.bind(res))();
130
81
  }
131
82
  }
132
83
  // adjust len to start/end options
@@ -137,34 +88,32 @@ immutable, weakEtag, } = {}) {
137
88
  if (len > bytes)
138
89
  len = bytes;
139
90
  }
140
- // Range support (only available when using weakEtag)
141
- if (weakEtag) {
142
- let ranges = req.headers.range;
143
- if (!disableAcceptRanges && BYTES_RANGE_REGEXP.test(ranges)) {
144
- // parse
145
- ranges = parseRange(len, ranges, { combine: true });
146
- // If-Range support
147
- if (!isRangeFresh(req, res))
148
- ranges = -2;
149
- // unsatisfiable
150
- if (ranges === -1) {
151
- // Content-Range
152
- res.setHeader('Content-Range', contentRange('bytes', len));
153
- // 416 Requested Range Not Satisfiable
154
- throw new Error('Requested Range Not Satisfiable: requested range is not satisfiable');
155
- // return this.error(416, {
156
- // headers: {'Content-Range': res.getHeader('Content-Range')}
157
- // })
158
- }
159
- // valid (syntactically invalid/multiple ranges are treated as a regular response)
160
- if (ranges !== -2 && ranges.length === 1) {
161
- // Content-Range
162
- res.statusCode = 206;
163
- res.setHeader('Content-Range', contentRange('bytes', len, ranges[0]));
164
- // adjust for requested range
165
- start += ranges[0].start;
166
- len = ranges[0].end - ranges[0].start + 1;
167
- }
91
+ // Range support
92
+ let ranges = req.headers.range;
93
+ if (!disableAcceptRanges && BYTES_RANGE_REGEXP.test(ranges ?? '')) {
94
+ // parse
95
+ let rangesNum = parseRange(len, ranges, { combine: true });
96
+ // If-Range support
97
+ if (!isRangeFresh(req, res))
98
+ rangesNum = -2;
99
+ // unsatisfiable
100
+ if (rangesNum === -1) {
101
+ // Content-Range
102
+ res.setHeader('Content-Range', contentRange('bytes', len));
103
+ // 416 Requested Range Not Satisfiable
104
+ throw new Error('Requested Range Not Satisfiable: requested range is not satisfiable');
105
+ // return this.error(416, {
106
+ // headers: {'Content-Range': res.getHeader('Content-Range')}
107
+ // })
108
+ }
109
+ // valid (syntactically invalid/multiple ranges are treated as a regular response)
110
+ if (rangesNum !== -2 && rangesNum.length === 1) {
111
+ // Content-Range
112
+ res.statusCode = 206;
113
+ res.setHeader('Content-Range', contentRange('bytes', len, rangesNum[0]));
114
+ // adjust for requested range
115
+ start += rangesNum[0].start;
116
+ len = rangesNum[0].end - rangesNum[0].start + 1;
168
117
  }
169
118
  }
170
119
  // set read options
@@ -173,13 +122,7 @@ immutable, weakEtag, } = {}) {
173
122
  res.setHeader('Content-Length', len);
174
123
  // HEAD support
175
124
  if (req.method === 'HEAD')
176
- return setEmpty();
177
- // Strong ETag path (default): send buffer directly
178
- if (!weakEtag && fileBuffer) {
179
- res.write(fileBuffer);
180
- res.end();
181
- return;
182
- }
125
+ return void await promisify(res.end.bind(res))();
183
126
  // Weak ETag path: stream file
184
127
  const stream = createReadStream(pathname, { start, end });
185
128
  stream.pipe(res);
@@ -211,4 +154,4 @@ function isRangeFresh(req, res) {
211
154
  function contentRange(type, size, range) {
212
155
  return `${type} ${range ? range.start + '-' + range.end : '*'}/${size}`;
213
156
  }
214
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljSGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zdGF0aWNIZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sNEJBQTRCLENBQUE7QUFDbkMsT0FBTyxFQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUMsTUFBTSxTQUFTLENBQUE7QUFDekMsT0FBTyxJQUFJLE1BQU0sV0FBVyxDQUFBO0FBQzVCLE9BQU8sRUFBQyxRQUFRLEVBQUUsSUFBSSxFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDL0MsT0FBTyxFQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQTtBQUNwRCxPQUFPLEVBQUMsdUJBQXVCLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQTtBQUN6RCxPQUFPLEVBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQTtBQUN2RSxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sMEJBQTBCLENBQUE7QUFDbkQsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sU0FBUyxDQUFBO0FBQ3hDLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUVsRCxNQUFNLGNBQWMsR0FBRyw0QkFBNEIsQ0FBQTtBQUNuRCxNQUFNLGtCQUFrQixHQUFHLFdBQVcsQ0FBQTtBQXdCdEMsTUFBTSxDQUFDLEtBQUssVUFBVSxRQUFRLENBQzdCLEdBQW9CLEVBQ3BCLEdBQW1CLEVBQ25CLFFBQWdCLEVBQUUsOEJBQThCO0FBQ2hELE9BQXFCO0lBRXJCLE1BQU0sRUFDTCxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUM5QixtQkFBbUIsRUFBRSxtQkFBbUIsRUFBRSxXQUFXLEVBQ3JELG1CQUFtQixFQUFFLE1BQU0sR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsSUFBSSxFQUFFLFNBQVM7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
157
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljSGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zdGF0aWNIZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sNEJBQTRCLENBQUE7QUFDbkMsT0FBTyxJQUFJLE1BQU0sV0FBVyxDQUFBO0FBQzVCLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUNyQyxPQUFPLEVBQUMsYUFBYSxFQUFFLE9BQU8sRUFBQyxNQUFNLG1CQUFtQixDQUFBO0FBQ3hELE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLG1CQUFtQixDQUFBO0FBQ3pELE9BQU8sRUFBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLGNBQWMsRUFBQyxNQUFNLG9CQUFvQixDQUFBO0FBQ3ZFLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQTtBQUNuRCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxTQUFTLENBQUE7QUFDeEMsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLHlCQUF5QixDQUFBO0FBQ2xELE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFFbkMsTUFBTSxrQkFBa0IsR0FBRyxXQUFXLENBQUE7QUFpQnRDLE1BQU0sQ0FBQyxLQUFLLFVBQVUsZUFBZSxDQUNwQyxHQUFvQixFQUNwQixHQUFtQixFQUNuQixRQUFnQixFQUFFLDhCQUE4QjtBQUNoRCxFQUNDLEtBQUssR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUNkLG1CQUFtQixFQUNuQixtQkFBbUIsRUFDbkIsSUFBSSxHQUFHLFFBQVEsRUFDZixtQkFBbUIsRUFDbkIsTUFBTSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxJQUFJLEVBQUUsU0FBUztBQUM3QyxTQUFTLE1BQzBCLEVBQUU7SUFFdEMsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDckMs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
@@ -2,8 +2,9 @@
2
2
  /// <reference types="node" resolution-mode="require"/>
3
3
  /// <reference types="node" resolution-mode="require"/>
4
4
  import type { IncomingMessage } from 'node:http';
5
- import type { Stats } from 'node:fs';
5
+ import { type Stats } from 'node:fs';
6
6
  export declare function entityTag(buf: Buffer, weak?: boolean): string;
7
+ export declare function entityTagPath(fileStat: Stats, filePath: string, weak?: boolean): Promise<string>;
7
8
  export declare function statTag(stat: Stats): string;
8
9
  export declare function isFreshETag(req: IncomingMessage, etag: string): true | undefined;
9
10
  export declare function isFreshModifiedSince(req: IncomingMessage, lastModified: string): boolean | undefined;
@@ -1,5 +1,6 @@
1
1
  // etag: https://github.com/jshttp/etag/blob/b9f0642256e63654287299d205bc6ced71b1a228/index.js#L39
2
- import crypto from 'node:crypto';
2
+ import crypto, { createHash } from 'node:crypto';
3
+ import { createReadStream } from 'node:fs';
3
4
  export function entityTag(buf, weak) {
4
5
  // pre-computed empty
5
6
  return buf.length
@@ -13,6 +14,20 @@ export function entityTag(buf, weak) {
13
14
  // weak W/ vs strong eTag
14
15
  // same weak eTag: 2 resources might be semantically equivalent, but not byte-for-byte identical
15
16
  }
17
+ export async function entityTagPath(fileStat, filePath, weak) {
18
+ const hash = createHash('sha1');
19
+ const defer = Promise.withResolvers();
20
+ createReadStream(filePath).pipe(hash)
21
+ .on('finish', defer.resolve)
22
+ .on('error', defer.reject);
23
+ await defer.promise;
24
+ return `${fileStat.size.toString(16)}-${hash
25
+ .digest('base64')
26
+ .substring(0, 27)}`;
27
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag#directives
28
+ // weak W/ vs strong eTag
29
+ // same weak eTag: 2 resources might be semantically equivalent, but not byte-for-byte identical
30
+ }
16
31
  const CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/;
17
32
  export function statTag(stat) {
18
33
  const mtime = stat.mtime.getTime().toString(16);
@@ -87,4 +102,4 @@ function parseTokenList(str) {
87
102
  list.push(str.substring(start, end));
88
103
  return list;
89
104
  }
90
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRhZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZW5kb3JzL2V0YWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsa0dBQWtHO0FBQ2xHLE9BQU8sTUFBTSxNQUFNLGFBQWEsQ0FBQTtBQUloQyxNQUFNLFVBQVUsU0FBUyxDQUFDLEdBQVcsRUFBRSxJQUFjO0lBQ3BELHFCQUFxQjtJQUNyQixPQUFPLEdBQUcsQ0FBQyxNQUFNO1FBQ2hCLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxJQUFJLE1BQU07YUFDcEMsVUFBVSxDQUFDLE1BQU0sQ0FBQzthQUNsQixNQUFNLENBQUMsR0FBRyxDQUFDO2FBQ1gsTUFBTSxDQUFDLFFBQVEsQ0FBQzthQUNoQixTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHO1FBQ3JCLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLGlDQUFpQyxDQUFBO0lBQ3ZELDRFQUE0RTtJQUM1RSx5QkFBeUI7SUFDekIsZ0dBQWdHO0FBQ2pHLENBQUM7QUFFRCxNQUFNLDZCQUE2QixHQUFHLGdDQUFnQyxDQUFBO0FBQ3RFLE1BQU0sVUFBVSxPQUFPLENBQUMsSUFBVztJQUNsQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUMvQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUVuQyxPQUFPLElBQUksSUFBSSxJQUFJLEtBQUssR0FBRyxDQUFBO0FBQzVCLENBQUM7QUFDRCw2RkFBNkY7QUFDN0YsTUFBTSxVQUFVLFdBQVcsQ0FBQyxHQUFvQixFQUFFLElBQVk7SUFDN0QsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLE9B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
105
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRhZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZW5kb3JzL2V0YWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsa0dBQWtHO0FBQ2xHLE9BQU8sTUFBTSxFQUFFLEVBQUMsVUFBVSxFQUFDLE1BQU0sYUFBYSxDQUFBO0FBRTlDLE9BQU8sRUFBQyxnQkFBZ0IsRUFBYSxNQUFNLFNBQVMsQ0FBQTtBQUVwRCxNQUFNLFVBQVUsU0FBUyxDQUFDLEdBQVcsRUFBRSxJQUFjO0lBQ3BELHFCQUFxQjtJQUNyQixPQUFPLEdBQUcsQ0FBQyxNQUFNO1FBQ2hCLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxJQUFJLE1BQU07YUFDcEMsVUFBVSxDQUFDLE1BQU0sQ0FBQzthQUNsQixNQUFNLENBQUMsR0FBRyxDQUFDO2FBQ1gsTUFBTSxDQUFDLFFBQVEsQ0FBQzthQUNoQixTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHO1FBQ3JCLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLGlDQUFpQyxDQUFBO0lBQ3ZELDRFQUE0RTtJQUM1RSx5QkFBeUI7SUFDekIsZ0dBQWdHO0FBQ2pHLENBQUM7QUFFRCxNQUFNLENBQUMsS0FBSyxVQUFVLGFBQWEsQ0FBQyxRQUFlLEVBQUUsUUFBZ0IsRUFBRSxJQUFjO0lBQ3BGLE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUMvQixNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsYUFBYSxFQUFVLENBQUE7SUFDN0MsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztTQUNuQyxFQUFFLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUM7U0FDM0IsRUFBRSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMs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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dx-server",
3
- "version": "0.11.0",
3
+ "version": "0.11.2",
4
4
  "main": "./cjs/index.js",
5
5
  "homepage": "https://github.com/tranvansang/dx-server",
6
6
  "repository": "https://github.com/tranvansang/dx-server",