@telorun/http-server 0.20.0 → 0.26.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.
|
@@ -164,8 +164,35 @@ class HttpServer {
|
|
|
164
164
|
}, { eventName: "http.server.request" });
|
|
165
165
|
});
|
|
166
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* Accept a multipart body out of the box.
|
|
169
|
+
*
|
|
170
|
+
* Fastify ships parsers for JSON and urlencoded and nothing else, so a route
|
|
171
|
+
* receiving a file upload answered 415 before any handler ran — a failure that
|
|
172
|
+
* names a media type the author DID send and points at no fix. Every server
|
|
173
|
+
* taking an upload had to discover `contentTypeParsers` first.
|
|
174
|
+
*
|
|
175
|
+
* Registered as RAW BYTES rather than a string, because that is what a
|
|
176
|
+
* multipart body is: decoding it as text corrupts every binary part, and the
|
|
177
|
+
* parts are the point. The handler receives the undrained request stream, which
|
|
178
|
+
* `Multipart.Decoder` consumes.
|
|
179
|
+
*
|
|
180
|
+
* Registered UNCONDITIONALLY, as a regex. Fastify keys a duplicate on the exact
|
|
181
|
+
* string (or the regex's `toString()`) and consults its string parsers before
|
|
182
|
+
* its regex ones, so a declared `multipart/form-data` neither collides with this
|
|
183
|
+
* nor is shadowed by it — it simply wins for its own type. Skipping the default
|
|
184
|
+
* whenever any multipart parser was declared would instead disable it for the
|
|
185
|
+
* SIBLING subtypes the author did not customize, so declaring a parser for
|
|
186
|
+
* `form-data` would silently restore the 415 for `related` and `mixed`.
|
|
187
|
+
*/
|
|
188
|
+
installDefaultMultipartParser() {
|
|
189
|
+
this.app.addContentTypeParser(/^multipart\//, (_req, payload, done) => {
|
|
190
|
+
done(null, payload);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
167
193
|
async setupPlugins() {
|
|
168
194
|
this.installRequestLogging();
|
|
195
|
+
this.installDefaultMultipartParser();
|
|
169
196
|
for (const { contentType, parser, stream } of this.resource.contentTypeParsers ?? []) {
|
|
170
197
|
if (stream) {
|
|
171
198
|
// Raw passthrough: omit `parseAs` so Fastify hands the handler the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telorun/http-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Telo HTTP Server module - HTTP server and API resource kinds for Telo manifests.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"telo",
|
|
@@ -49,13 +49,13 @@
|
|
|
49
49
|
"ajv": "^8.17.1",
|
|
50
50
|
"ajv-formats": "^3.0.1",
|
|
51
51
|
"fastify": "^5.7.2",
|
|
52
|
-
"@telorun/http-dispatch": "0.
|
|
52
|
+
"@telorun/http-dispatch": "0.11.1"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@types/node": "^20.0.0",
|
|
56
56
|
"typescript": "^5.0.0",
|
|
57
57
|
"vitest": "^2.1.8",
|
|
58
|
-
"@telorun/sdk": "0.
|
|
58
|
+
"@telorun/sdk": "0.75.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@telorun/sdk": "*"
|
|
@@ -261,8 +261,36 @@ class HttpServer implements ResourceInstance {
|
|
|
261
261
|
});
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Accept a multipart body out of the box.
|
|
266
|
+
*
|
|
267
|
+
* Fastify ships parsers for JSON and urlencoded and nothing else, so a route
|
|
268
|
+
* receiving a file upload answered 415 before any handler ran — a failure that
|
|
269
|
+
* names a media type the author DID send and points at no fix. Every server
|
|
270
|
+
* taking an upload had to discover `contentTypeParsers` first.
|
|
271
|
+
*
|
|
272
|
+
* Registered as RAW BYTES rather than a string, because that is what a
|
|
273
|
+
* multipart body is: decoding it as text corrupts every binary part, and the
|
|
274
|
+
* parts are the point. The handler receives the undrained request stream, which
|
|
275
|
+
* `Multipart.Decoder` consumes.
|
|
276
|
+
*
|
|
277
|
+
* Registered UNCONDITIONALLY, as a regex. Fastify keys a duplicate on the exact
|
|
278
|
+
* string (or the regex's `toString()`) and consults its string parsers before
|
|
279
|
+
* its regex ones, so a declared `multipart/form-data` neither collides with this
|
|
280
|
+
* nor is shadowed by it — it simply wins for its own type. Skipping the default
|
|
281
|
+
* whenever any multipart parser was declared would instead disable it for the
|
|
282
|
+
* SIBLING subtypes the author did not customize, so declaring a parser for
|
|
283
|
+
* `form-data` would silently restore the 415 for `related` and `mixed`.
|
|
284
|
+
*/
|
|
285
|
+
private installDefaultMultipartParser(): void {
|
|
286
|
+
this.app.addContentTypeParser(/^multipart\//, (_req, payload, done) => {
|
|
287
|
+
done(null, payload);
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
|
|
264
291
|
private async setupPlugins() {
|
|
265
292
|
this.installRequestLogging();
|
|
293
|
+
this.installDefaultMultipartParser();
|
|
266
294
|
for (const { contentType, parser, stream } of this.resource.contentTypeParsers ?? []) {
|
|
267
295
|
if (stream) {
|
|
268
296
|
// Raw passthrough: omit `parseAs` so Fastify hands the handler the
|