@c9up/ream 0.2.18 → 0.2.19

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.
Files changed (45) hide show
  1. package/README.md +4 -0
  2. package/dist/Application.d.ts +15 -0
  3. package/dist/Application.d.ts.map +1 -1
  4. package/dist/Application.js +15 -0
  5. package/dist/Application.js.map +1 -1
  6. package/dist/Provider.d.ts +15 -0
  7. package/dist/Provider.d.ts.map +1 -1
  8. package/dist/Provider.js.map +1 -1
  9. package/dist/http/Request.d.ts +13 -3
  10. package/dist/http/Request.d.ts.map +1 -1
  11. package/dist/http/Request.js.map +1 -1
  12. package/dist/index.d.ts +3 -3
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +2 -2
  15. package/dist/index.js.map +1 -1
  16. package/dist/router/Router.d.ts +1 -1
  17. package/dist/router/Router.js +1 -1
  18. package/dist/security/CookieSigner.d.ts +3 -2
  19. package/dist/security/CookieSigner.d.ts.map +1 -1
  20. package/dist/security/CookieSigner.js +3 -2
  21. package/dist/security/CookieSigner.js.map +1 -1
  22. package/dist/storage/StaticMiddleware.d.ts +75 -7
  23. package/dist/storage/StaticMiddleware.d.ts.map +1 -1
  24. package/dist/storage/StaticMiddleware.js +257 -85
  25. package/dist/storage/StaticMiddleware.js.map +1 -1
  26. package/dist/storage/StaticProvider.d.ts.map +1 -1
  27. package/dist/storage/StaticProvider.js +12 -3
  28. package/dist/storage/StaticProvider.js.map +1 -1
  29. package/events.win32-x64-msvc.node +0 -0
  30. package/index.darwin-arm64.node +0 -0
  31. package/index.darwin-x64.node +0 -0
  32. package/index.linux-arm64-gnu.node +0 -0
  33. package/index.linux-x64-gnu.node +0 -0
  34. package/index.win32-x64-msvc.node +0 -0
  35. package/package.json +8 -8
  36. package/scheduler.win32-x64-msvc.node +0 -0
  37. package/scripts/copy-napi.mjs +11 -3
  38. package/src/Application.ts +15 -0
  39. package/src/Provider.ts +15 -0
  40. package/src/http/Request.ts +13 -3
  41. package/src/index.ts +3 -3
  42. package/src/router/Router.ts +1 -1
  43. package/src/security/CookieSigner.ts +3 -2
  44. package/src/storage/StaticMiddleware.ts +338 -97
  45. package/src/storage/StaticProvider.ts +14 -3
@@ -1,27 +1,95 @@
1
1
  /**
2
2
  * Static file serving middleware.
3
3
  *
4
- * Serves files from a directory with cache headers and ETag support.
4
+ * The shape is `@adonisjs/static`'s, whose own work is done by `serve-static`:
5
+ * the same option names, the same defaults, the same response headers. Ream
6
+ * cannot delegate to `serve-static` itself —
7
+ *
8
+ * NAMED DEVIATION (NAPI): `serve-static` writes to a Node `ServerResponse`, and
9
+ * Ream's response crosses the NAPI boundary as a complete object; there is no
10
+ * such object to hand it. So the BEHAVIOUR is reproduced here rather than the
11
+ * code, and every deviation from it below is deliberate and marked.
12
+ *
13
+ * One deviation is a deliberate improvement, kept per the rule that we do not
14
+ * give up safety for parity: the file is opened with `O_NOFOLLOW` and its
15
+ * metadata read from the descriptor, so the bytes served are the ones that
16
+ * passed the containment checks. `serve-static` re-reads by path.
5
17
  *
6
18
  * Usage:
7
- * server.use(new StaticMiddleware({ root: 'public' }))
19
+ * server.use(new StaticMiddleware({ root: app.publicPath() }))
8
20
  *
9
21
  * @implements MISS-25
10
22
  */
23
+ import * as fs from 'node:fs';
11
24
  import type { HttpContext } from '../http/HttpContext.js';
25
+ /** How a request for a dotfile is answered (`send`'s `dotfiles`). */
26
+ export type DotFilesPolicy = 'allow' | 'deny' | 'ignore';
12
27
  export interface StaticConfig {
13
28
  /** Root directory to serve files from. */
14
29
  root: string;
15
- /** URL prefix (default: /static). */
16
- prefix?: string;
17
- /** Max-age for Cache-Control header in seconds (default: 86400 = 1 day). */
30
+ /** Serve at all. `false` makes every request fall through. Default `true`. */
31
+ enabled?: boolean;
32
+ /**
33
+ * Answer `Range` requests with `206`, and advertise `Accept-Ranges: bytes`.
34
+ * Default `true` — without it a browser cannot seek in audio or video, and
35
+ * an interrupted download restarts from zero.
36
+ */
37
+ acceptRanges?: boolean;
38
+ /**
39
+ * Emit `Cache-Control`. Default `true`. When `false`, `maxAge` and
40
+ * `immutable` are ignored, as upstream documents.
41
+ */
42
+ cacheControl?: boolean;
43
+ /**
44
+ * Dotfiles: `'ignore'` (fall through, the default), `'deny'` (403), or
45
+ * `'allow'` (serve). The default is why `.env` in the served root is not
46
+ * an accident waiting to happen.
47
+ */
48
+ dotFiles?: DotFilesPolicy;
49
+ /** Emit `ETag` and honour `If-None-Match`. Default `true`. */
50
+ etag?: boolean;
51
+ /**
52
+ * FALLBACK extensions, NOT an allowlist: when the requested path has no
53
+ * file, try appending each of these. `['html']` makes `/about` serve
54
+ * `about.html`. Default: none.
55
+ *
56
+ * The name and meaning are upstream's. An earlier version of this file used
57
+ * the same option as an allowlist — the opposite meaning — which silently
58
+ * restricted the server for anyone porting an AdonisJS config across, and
59
+ * refused formats the framework itself produces (`.avif`, from prism).
60
+ */
61
+ extensions?: string[] | false;
62
+ /** Add `immutable` to `Cache-Control`. Needs `maxAge`. Default `false`. */
63
+ immutable?: boolean;
64
+ /** Index file for a directory request. Default `'index.html'`; `false` disables. */
65
+ index?: string | string[] | false;
66
+ /** Emit `Last-Modified` and honour `If-Modified-Since`. Default `true`. */
67
+ lastModified?: boolean;
68
+ /** `Cache-Control: max-age`, in MILLISECONDS as upstream. Default `0`. */
18
69
  maxAge?: number;
19
- /** File extensions to serve (default: common web assets). */
20
- extensions?: string[];
70
+ /** Extra headers, per file. Runs last, so it can override the above. */
71
+ headers?: (filePath: string, stat: fs.Stats) => Record<string, string>;
72
+ /**
73
+ * Serve only under this URL prefix.
74
+ *
75
+ * NAMED DEVIATION: AdonisJS has no such option — its middleware is mounted at
76
+ * the URL root and falls through. Ream keeps it because the router is the
77
+ * same object the application writes to, and narrowing is occasionally what
78
+ * an application wants. The default is upstream's behaviour: no prefix.
79
+ */
80
+ prefix?: string;
21
81
  }
22
82
  export declare class StaticMiddleware {
23
83
  #private;
24
84
  constructor(config: StaticConfig);
25
85
  handle(ctx: HttpContext, next: () => Promise<void>): Promise<void>;
26
86
  }
87
+ /**
88
+ * Static config with the defaults filled in — `@adonisjs/static`'s
89
+ * `defineConfig`, value for value.
90
+ *
91
+ * // config/static.ts
92
+ * export default defineStaticConfig({ maxAge: 86_400_000 })
93
+ */
94
+ export declare function defineStaticConfig(config?: Partial<StaticConfig>): Partial<StaticConfig>;
27
95
  //# sourceMappingURL=StaticMiddleware.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"StaticMiddleware.d.ts","sourceRoot":"","sources":["../../src/storage/StaticMiddleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAGzD,MAAM,WAAW,YAAY;IAC3B,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAA;IACZ,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACtB;AA4BD,qBAAa,gBAAgB;;gBAMf,MAAM,EAAE,YAAY;IAO1B,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CA+HzE"}
1
+ {"version":3,"file":"StaticMiddleware.d.ts","sourceRoot":"","sources":["../../src/storage/StaticMiddleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAK7B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAGzD,qEAAqE;AACrE,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAA;AAExD,MAAM,WAAW,YAAY;IAC3B,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAA;IAEZ,8EAA8E;IAC9E,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IAEtB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IAEtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAA;IAEzB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,OAAO,CAAA;IAEd;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;IAE7B,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,KAAK,CAAA;IAEjC,2EAA2E;IAC3E,YAAY,CAAC,EAAE,OAAO,CAAA;IAEtB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf,wEAAwE;IACxE,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEtE;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAQD,qBAAa,gBAAgB;;gBAef,MAAM,EAAE,YAAY;IAqB1B,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CA0RzE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAE5F"}
@@ -1,10 +1,22 @@
1
1
  /**
2
2
  * Static file serving middleware.
3
3
  *
4
- * Serves files from a directory with cache headers and ETag support.
4
+ * The shape is `@adonisjs/static`'s, whose own work is done by `serve-static`:
5
+ * the same option names, the same defaults, the same response headers. Ream
6
+ * cannot delegate to `serve-static` itself —
7
+ *
8
+ * NAMED DEVIATION (NAPI): `serve-static` writes to a Node `ServerResponse`, and
9
+ * Ream's response crosses the NAPI boundary as a complete object; there is no
10
+ * such object to hand it. So the BEHAVIOUR is reproduced here rather than the
11
+ * code, and every deviation from it below is deliberate and marked.
12
+ *
13
+ * One deviation is a deliberate improvement, kept per the rule that we do not
14
+ * give up safety for parity: the file is opened with `O_NOFOLLOW` and its
15
+ * metadata read from the descriptor, so the bytes served are the ones that
16
+ * passed the containment checks. `serve-static` re-reads by path.
5
17
  *
6
18
  * Usage:
7
- * server.use(new StaticMiddleware({ root: 'public' }))
19
+ * server.use(new StaticMiddleware({ root: app.publicPath() }))
8
20
  *
9
21
  * @implements MISS-25
10
22
  */
@@ -13,122 +25,273 @@ import * as fsp from 'node:fs/promises';
13
25
  import * as path from 'node:path';
14
26
  import { matchesIfNoneMatch, statTag } from '../http/etag.js';
15
27
  import { contentType } from '../http/mime.js';
16
- const DEFAULT_EXTENSIONS = [
17
- '.html',
18
- '.css',
19
- '.js',
20
- '.json',
21
- '.xml',
22
- '.txt',
23
- '.png',
24
- '.jpg',
25
- '.jpeg',
26
- '.gif',
27
- '.svg',
28
- '.ico',
29
- '.webp',
30
- '.woff',
31
- '.woff2',
32
- '.ttf',
33
- '.eot',
34
- '.mp4',
35
- '.webm',
36
- '.mp3',
37
- '.ogg',
38
- '.pdf',
39
- '.zip',
40
- ];
41
28
  export class StaticMiddleware {
42
29
  #root;
43
- #prefix;
44
- #maxAge;
30
+ #enabled;
31
+ #acceptRanges;
32
+ #cacheControl;
33
+ #dotFiles;
34
+ #etag;
45
35
  #extensions;
36
+ #immutable;
37
+ #index;
38
+ #lastModified;
39
+ #maxAge;
40
+ #headers;
41
+ #prefix;
46
42
  constructor(config) {
47
43
  this.#root = path.resolve(config.root);
48
- this.#prefix = config.prefix ?? '/static';
49
- this.#maxAge = config.maxAge ?? 86400;
50
- this.#extensions = new Set(config.extensions ?? DEFAULT_EXTENSIONS);
44
+ this.#enabled = config.enabled ?? true;
45
+ this.#acceptRanges = config.acceptRanges ?? true;
46
+ this.#cacheControl = config.cacheControl ?? true;
47
+ this.#dotFiles = config.dotFiles ?? 'ignore';
48
+ this.#etag = config.etag ?? true;
49
+ this.#extensions = config.extensions === false ? [] : (config.extensions ?? []);
50
+ this.#immutable = config.immutable ?? false;
51
+ this.#index =
52
+ config.index === false
53
+ ? []
54
+ : typeof config.index === 'string'
55
+ ? [config.index]
56
+ : (config.index ?? ['index.html']);
57
+ this.#lastModified = config.lastModified ?? true;
58
+ this.#maxAge = config.maxAge ?? 0;
59
+ this.#headers = config.headers;
60
+ this.#prefix = config.prefix ?? '';
51
61
  }
52
62
  async handle(ctx, next) {
53
- if (ctx.request.method() !== 'GET' && ctx.request.method() !== 'HEAD') {
63
+ if (!this.#enabled)
54
64
  return next();
65
+ const method = ctx.request.method();
66
+ if (method !== 'GET' && method !== 'HEAD')
67
+ return next();
68
+ const reqPath = ctx.request.path();
69
+ // A dotfile under `deny` is answered, not passed on: falling through would
70
+ // leak its existence through whatever the router answers next.
71
+ if (this.#dotFiles === 'deny' && this.#hasDotSegment(reqPath)) {
72
+ ctx.response.status(403).send('Forbidden');
73
+ return;
55
74
  }
56
- const resolved = await this.#openServableFile(ctx.request.path());
75
+ const resolved = await this.#openServableFile(reqPath);
57
76
  if (!resolved)
58
77
  return next();
59
- const { handle, ext, stat } = resolved;
60
- // The handle is ours until the read stream takes it; every path that does
61
- // not hand it over closes it, or the process leaks a descriptor per 304.
78
+ const { handle, filePath, stat } = resolved;
79
+ // The handle is ours until a read stream takes it; every path that does not
80
+ // hand it over closes it, or the process leaks a descriptor per 304.
62
81
  let owned = true;
63
82
  try {
64
- const etag = statTag(stat);
65
- if (matchesIfNoneMatch(ctx.request.header('if-none-match'), etag)) {
83
+ const etag = this.#etag ? statTag(stat) : undefined;
84
+ const lastModified = this.#lastModified ? stat.mtime.toUTCString() : undefined;
85
+ // One table for the whole package (`src/http/mime.ts`), generated from
86
+ // mime-db. A second hand-written one here is how `.js` came to be served
87
+ // as `application/javascript` from one path and `text/javascript` from
88
+ // the other.
89
+ ctx.response.header('Content-Type', contentType(path.extname(filePath).toLowerCase()) || 'application/octet-stream');
90
+ if (etag)
91
+ ctx.response.header('ETag', etag);
92
+ if (lastModified)
93
+ ctx.response.header('Last-Modified', lastModified);
94
+ if (this.#cacheControl)
95
+ ctx.response.header('Cache-Control', this.#cacheControlValue());
96
+ if (this.#acceptRanges)
97
+ ctx.response.header('Accept-Ranges', 'bytes');
98
+ if (this.#headers) {
99
+ for (const [name, value] of Object.entries(this.#headers(filePath, stat))) {
100
+ ctx.response.header(name, value);
101
+ }
102
+ }
103
+ if (this.#isFresh(ctx, etag, stat)) {
104
+ // A 304 carries no body and no Content-Length: the client reuses the
105
+ // copy it already has.
66
106
  ctx.response.status(304);
67
107
  return;
68
108
  }
69
- // One table for the whole package (`src/http/mime.ts`), generated from
70
- // mime-db. A second hand-written one here is how `.js` came to be
71
- // served as `application/javascript` from one code path and
72
- // `text/javascript` from the other.
73
- ctx.response.header('Content-Type', contentType(ext) || 'application/octet-stream');
74
- ctx.response.header('Content-Length', String(stat.size));
75
- ctx.response.header('Cache-Control', `public, max-age=${this.#maxAge}`);
76
- ctx.response.header('ETag', etag);
77
- if (ctx.request.method() === 'HEAD') {
78
- ctx.response.status(200);
109
+ const range = this.#acceptRanges ? this.#resolveRange(ctx, stat, etag) : undefined;
110
+ if (range === 'unsatisfiable') {
111
+ ctx.response.header('Content-Range', `bytes */${stat.size}`);
112
+ ctx.response.status(416).send('');
113
+ return;
114
+ }
115
+ const length = range ? range.end - range.start + 1 : stat.size;
116
+ ctx.response.header('Content-Length', String(length));
117
+ if (range) {
118
+ ctx.response.header('Content-Range', `bytes ${range.start}-${range.end}/${stat.size}`);
119
+ }
120
+ if (method === 'HEAD') {
121
+ // HEAD carries the headers a GET would, and no body.
122
+ ctx.response.status(range ? 206 : 200);
79
123
  return;
80
124
  }
81
- // Streamed, not read whole.
82
- //
83
- // `readFileSync` stalled the event loop for EVERY concurrent request
84
- // while one client asked for a file, and the allowed extensions include
85
- // `.mp4`, `.zip` and `.pdf` — so one large asset became every other
86
- // request's latency, and each request allocated the file again. The
87
- // stream applies backpressure and holds one chunk at a time.
88
- //
89
- // The read stream owns the handle from here and closes it at end.
90
- ctx.response.status(200);
125
+ // Streamed, not read whole. `readFileSync` stalled the event loop for
126
+ // every concurrent request while one client asked for a file, and one
127
+ // large asset became every other request's latency. The read stream owns
128
+ // the handle from here and closes it at end.
129
+ ctx.response.status(range ? 206 : 200);
91
130
  owned = false;
92
- await ctx.response.stream(handle.createReadStream());
131
+ await ctx.response.stream(range
132
+ ? handle.createReadStream({ start: range.start, end: range.end })
133
+ : handle.createReadStream());
93
134
  }
94
135
  finally {
95
136
  if (owned)
96
137
  await handle.close().catch(() => { });
97
138
  }
98
139
  }
140
+ /** `Cache-Control`, built the way `send` builds it. */
141
+ #cacheControlValue() {
142
+ const seconds = Math.floor(this.#maxAge / 1000);
143
+ let value = `public, max-age=${seconds}`;
144
+ // Upstream only honours `immutable` alongside a max-age: `immutable` on a
145
+ // response that expires immediately tells a cache two opposite things.
146
+ if (this.#immutable && seconds > 0)
147
+ value += ', immutable';
148
+ return value;
149
+ }
150
+ /**
151
+ * Is the client's copy still good? `If-None-Match` wins outright when
152
+ * present, and `If-Modified-Since` is only consulted in its absence — the
153
+ * order RFC 9110 §13.1.3 requires, and the reason a weak ETag plus a
154
+ * second-resolution mtime do not contradict each other.
155
+ */
156
+ #isFresh(ctx, etag, stat) {
157
+ const ifNoneMatch = ctx.request.header('if-none-match');
158
+ if (ifNoneMatch !== undefined && ifNoneMatch !== null) {
159
+ return etag !== undefined && matchesIfNoneMatch(ifNoneMatch, etag);
160
+ }
161
+ if (!this.#lastModified)
162
+ return false;
163
+ const since = ctx.request.header('if-modified-since');
164
+ if (since === undefined || since === null)
165
+ return false;
166
+ const sinceMs = Date.parse(Array.isArray(since) ? since[0] : String(since));
167
+ if (Number.isNaN(sinceMs))
168
+ return false;
169
+ // HTTP dates have one-second resolution; the file's mtime does not. Compare
170
+ // at the coarser one, or a file written mid-second looks modified forever.
171
+ return Math.floor(stat.mtimeMs / 1000) * 1000 <= sinceMs;
172
+ }
173
+ /**
174
+ * The range to serve, `undefined` for the whole file, or `'unsatisfiable'`
175
+ * for a 416.
176
+ *
177
+ * Only a single range is honoured. Multiple ranges require a
178
+ * `multipart/byteranges` body, which upstream supports and this does not —
179
+ * a request for several is served whole, which is a response every client
180
+ * accepts.
181
+ */
182
+ #resolveRange(ctx, stat, etag) {
183
+ const raw = ctx.request.header('range');
184
+ if (raw === undefined || raw === null)
185
+ return undefined;
186
+ const header = Array.isArray(raw) ? raw[0] : String(raw);
187
+ // `If-Range` guards against a resumed download stitching bytes from two
188
+ // different versions of the file: if the validator does not match, the
189
+ // whole current file is the honest answer.
190
+ const ifRange = ctx.request.header('if-range');
191
+ if (ifRange !== undefined && ifRange !== null) {
192
+ const value = Array.isArray(ifRange) ? ifRange[0] : String(ifRange);
193
+ const matchesEtag = etag !== undefined && value.trim() === etag;
194
+ const asDate = Date.parse(value);
195
+ const matchesDate = !Number.isNaN(asDate) && Math.floor(stat.mtimeMs / 1000) * 1000 <= asDate;
196
+ if (!matchesEtag && !matchesDate)
197
+ return undefined;
198
+ }
199
+ const match = /^bytes=(\d*)-(\d*)$/.exec(header.trim());
200
+ if (!match)
201
+ return undefined; // not a form we serve: send the whole file
202
+ const [, rawStart, rawEnd] = match;
203
+ if (rawStart === '' && rawEnd === '')
204
+ return undefined;
205
+ let start;
206
+ let end;
207
+ if (rawStart === '') {
208
+ // `bytes=-500`: the LAST 500 bytes, not the first.
209
+ const suffix = Number(rawEnd);
210
+ if (suffix === 0)
211
+ return 'unsatisfiable';
212
+ start = Math.max(stat.size - suffix, 0);
213
+ end = stat.size - 1;
214
+ }
215
+ else {
216
+ start = Number(rawStart);
217
+ end = rawEnd === '' ? stat.size - 1 : Math.min(Number(rawEnd), stat.size - 1);
218
+ }
219
+ if (!Number.isFinite(start) || !Number.isFinite(end) || start > end || start >= stat.size) {
220
+ return 'unsatisfiable';
221
+ }
222
+ return { start, end };
223
+ }
224
+ #hasDotSegment(reqPath) {
225
+ return reqPath.split('/').some((segment) => segment.length > 1 && segment.startsWith('.'));
226
+ }
99
227
  /**
100
- * Open a request path as a real, in-root, regular file, or answer `null`
101
- * when it is not servable (wrong prefix/extension, outside the root,
102
- * missing, or a symlink escaping the root). `null` tells `handle` to call
103
- * `next()`.
228
+ * Open a request path as a real, in-root, regular file, or answer `null` when
229
+ * it is not servable. `null` tells `handle` to call `next()`.
104
230
  *
105
231
  * The file is OPENED here rather than merely checked, and its metadata read
106
- * from the descriptor: what gets served is then the same file that passed
107
- * the checks, which a path re-read after the fact cannot promise.
232
+ * from the descriptor: what gets served is then the same file that passed the
233
+ * checks, which a path re-read after the fact cannot promise.
108
234
  */
109
235
  async #openServableFile(reqPath) {
110
- // Match only when the prefix is followed by `/` or end-of-path —
111
- // otherwise `/staticx/foo.js` would be intercepted when the configured
112
- // prefix is `/static`, hijacking unrelated routes.
113
- if (!(reqPath === this.#prefix || reqPath.startsWith(`${this.#prefix}/`))) {
236
+ if (this.#prefix !== '') {
237
+ // Match only when the prefix is followed by `/` or end-of-path —
238
+ // otherwise `/staticx/foo.js` would be intercepted when the configured
239
+ // prefix is `/static`, hijacking unrelated routes.
240
+ if (!(reqPath === this.#prefix || reqPath.startsWith(`${this.#prefix}/`)))
241
+ return null;
242
+ reqPath = reqPath.slice(this.#prefix.length) || '/';
243
+ }
244
+ if (this.#dotFiles === 'ignore' && this.#hasDotSegment(reqPath))
245
+ return null;
246
+ // The candidates, in upstream's order: the path itself, then the path with
247
+ // each fallback extension, then the index files for a directory request.
248
+ //
249
+ // Percent-decoding happens BEFORE resolution on purpose: `%2e%2e%2f` is
250
+ // `../` and has to be normalised away by `path.resolve` like any other
251
+ // traversal, not carried through as an opaque segment. `decodeURIComponent`
252
+ // THROWS on a malformed sequence (a lone `%`), which would otherwise become
253
+ // a 500 on a request anyone can send.
254
+ let decoded;
255
+ try {
256
+ decoded = decodeURIComponent(reqPath);
257
+ }
258
+ catch {
114
259
  return null;
115
260
  }
116
- // Strip prefix and resolve file path
117
- const relativePath = reqPath.slice(this.#prefix.length) || '/index.html';
118
- const ext = path.extname(relativePath).toLowerCase();
119
- if (!this.#extensions.has(ext))
261
+ // A NUL truncates the path in the syscall layer of some runtimes; Node
262
+ // rejects it, but refusing here keeps the decision in one place.
263
+ if (decoded.includes('\0'))
120
264
  return null;
121
- const filePath = path.resolve(this.#root, relativePath.replace(/^\//, ''));
265
+ const relative = decoded.replace(/^\/+/, '');
266
+ const candidates = [];
267
+ if (relative !== '') {
268
+ candidates.push(relative);
269
+ for (const ext of this.#extensions) {
270
+ candidates.push(`${relative}.${ext.replace(/^\./, '')}`);
271
+ }
272
+ }
273
+ for (const index of this.#index) {
274
+ candidates.push(relative === '' ? index : `${relative}/${index}`);
275
+ }
276
+ for (const candidate of candidates) {
277
+ const opened = await this.#openInRoot(candidate);
278
+ if (opened)
279
+ return opened;
280
+ }
281
+ return null;
282
+ }
283
+ /** One candidate, fully contained and opened, or `null`. */
284
+ async #openInRoot(relative) {
285
+ const filePath = path.resolve(this.#root, relative);
122
286
  // Two containment checks. The first uses `path.sep` to reject sibling
123
- // directories with a shared prefix (`/var/www-static-secret` slipping
124
- // past a guard for `/var/www-static`). The second resolves symlinks
125
- // via realpath so a symlink planted inside the root cannot point
126
- // outside it. We do realpath AFTER the lexical check so a non-existent
127
- // path returns `next()` rather than throwing.
287
+ // directories with a shared prefix (`/var/www-static-secret` slipping past
288
+ // a guard for `/var/www-static`). The second resolves symlinks via realpath
289
+ // so a symlink planted inside the root cannot point outside it. Realpath
290
+ // runs AFTER the lexical check so a non-existent path returns null rather
291
+ // than throwing.
128
292
  const rootWithSep = this.#root.endsWith(path.sep) ? this.#root : this.#root + path.sep;
129
- if (filePath !== this.#root && !filePath.startsWith(rootWithSep)) {
293
+ if (filePath !== this.#root && !filePath.startsWith(rootWithSep))
130
294
  return null;
131
- }
132
295
  let realFilePath;
133
296
  let realRoot;
134
297
  try {
@@ -139,9 +302,8 @@ export class StaticMiddleware {
139
302
  return null;
140
303
  }
141
304
  const realRootWithSep = realRoot.endsWith(path.sep) ? realRoot : realRoot + path.sep;
142
- if (realFilePath !== realRoot && !realFilePath.startsWith(realRootWithSep)) {
305
+ if (realFilePath !== realRoot && !realFilePath.startsWith(realRootWithSep))
143
306
  return null;
144
- }
145
307
  // O_NOFOLLOW closes the window the checks above leave open: between
146
308
  // `realpath` and the read, the last path component can be replaced by a
147
309
  // symlink pointing anywhere, and a read by name follows it. Refusing to
@@ -161,7 +323,7 @@ export class StaticMiddleware {
161
323
  await handle.close();
162
324
  return null;
163
325
  }
164
- return { handle, ext, stat };
326
+ return { handle, filePath: realFilePath, stat };
165
327
  }
166
328
  catch {
167
329
  await handle.close().catch(() => { });
@@ -169,4 +331,14 @@ export class StaticMiddleware {
169
331
  }
170
332
  }
171
333
  }
334
+ /**
335
+ * Static config with the defaults filled in — `@adonisjs/static`'s
336
+ * `defineConfig`, value for value.
337
+ *
338
+ * // config/static.ts
339
+ * export default defineStaticConfig({ maxAge: 86_400_000 })
340
+ */
341
+ export function defineStaticConfig(config = {}) {
342
+ return { enabled: true, dotFiles: 'ignore', etag: true, lastModified: true, ...config };
343
+ }
172
344
  //# sourceMappingURL=StaticMiddleware.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"StaticMiddleware.js","sourceRoot":"","sources":["../../src/storage/StaticMiddleware.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"StaticMiddleware.js","sourceRoot":"","sources":["../../src/storage/StaticMiddleware.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"StaticProvider.d.ts","sourceRoot":"","sources":["../../src/storage/StaticProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAqB,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAE3E,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,UAAU,CAAC,EAAE,gBAAgB,CAAA;CAC9B;AAED,qBAAa,cAAe,SAAQ,QAAQ;;gBAG9B,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,qBAA0B;IAKhE;;;;;;;;;OASG;IACY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAOtC;AAGD,eAAe,cAAc,CAAA"}
1
+ {"version":3,"file":"StaticProvider.d.ts","sourceRoot":"","sources":["../../src/storage/StaticProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAqB,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAE3E,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,UAAU,CAAC,EAAE,gBAAgB,CAAA;CAC9B;AAED,qBAAa,cAAe,SAAQ,QAAQ;;gBAG9B,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,qBAA0B;IAKhE;;;;;;;;;OASG;IACY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAkBtC;AAGD,eAAe,cAAc,CAAA"}
@@ -30,10 +30,19 @@ export class StaticProvider extends Provider {
30
30
  * the app that meant to override it.
31
31
  */
32
32
  async start() {
33
- const config = this.app.config.get('static');
34
- const middleware = this.#override ?? (config?.root ? new StaticMiddleware(config) : undefined);
33
+ // `?? {}` rather than a default argument: a host may supply its own
34
+ // ConfigReader, and not every implementation honours the second parameter.
35
+ const config = this.app.config.get('static') ?? {};
36
+ // Registering the provider is the whole opt-in, as it is upstream: there,
37
+ // `node ace configure @adonisjs/static` adds the provider AND the
38
+ // middleware, and the middleware serves `public/` with no `root` named
39
+ // anywhere. Requiring a `root` before doing anything meant a provider
40
+ // could be registered and silently serve nothing.
41
+ const root = config.root ?? this.app.publicPath?.() ?? 'public';
42
+ const middleware = this.#override ??
43
+ (config.enabled === false ? undefined : new StaticMiddleware({ ...config, root }));
35
44
  if (!middleware)
36
- return; // not configured — opt-out
45
+ return;
37
46
  const server = await this.app.container.make('server');
38
47
  server.use([(ctx, next) => middleware.handle(ctx, next)]);
39
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"StaticProvider.js","sourceRoot":"","sources":["../../src/storage/StaticProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAqB,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAO3E,MAAM,OAAO,cAAe,SAAQ,QAAQ;IACjC,SAAS,CAAmB;IAErC,YAAY,GAAe,EAAE,UAAiC,EAAE;QAC9D,KAAK,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,UAAU,CAAA;IACrC,CAAC;IAED;;;;;;;;;OASG;IACM,KAAK,CAAC,KAAK;QAClB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAe,QAAQ,CAAC,CAAA;QAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QAC9F,IAAI,CAAC,UAAU;YAAE,OAAM,CAAC,2BAA2B;QACnD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAS,QAAQ,CAAC,CAAA;QAC9D,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;IAC3D,CAAC;CACF;AAED,yKAAyK;AACzK,eAAe,cAAc,CAAA"}
1
+ {"version":3,"file":"StaticProvider.js","sourceRoot":"","sources":["../../src/storage/StaticProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAqB,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAO3E,MAAM,OAAO,cAAe,SAAQ,QAAQ;IACjC,SAAS,CAAmB;IAErC,YAAY,GAAe,EAAE,UAAiC,EAAE;QAC9D,KAAK,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,UAAU,CAAA;IACrC,CAAC;IAED;;;;;;;;;OASG;IACM,KAAK,CAAC,KAAK;QAClB,oEAAoE;QACpE,2EAA2E;QAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAe,QAAQ,CAAC,IAAK,EAAmB,CAAA;QAElF,0EAA0E;QAC1E,kEAAkE;QAClE,uEAAuE;QACvE,sEAAsE;QACtE,kDAAkD;QAClD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,IAAI,QAAQ,CAAA;QAC/D,MAAM,UAAU,GACd,IAAI,CAAC,SAAS;YACd,CAAC,MAAM,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,gBAAgB,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QACpF,IAAI,CAAC,UAAU;YAAE,OAAM;QACvB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAS,QAAQ,CAAC,CAAA;QAC9D,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;IAC3D,CAAC;CACF;AAED,yKAAyK;AACzK,eAAe,cAAc,CAAA"}
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file