@hono/node-server 1.7.0 → 1.8.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/dist/index.js CHANGED
@@ -58,7 +58,7 @@ var Request = class extends GlobalRequest {
58
58
  Object.defineProperty(global, "Request", {
59
59
  value: Request
60
60
  });
61
- var newRequestFromIncoming = (method, url, incoming) => {
61
+ var newRequestFromIncoming = (method, url, incoming, abortController) => {
62
62
  const headerRecord = [];
63
63
  const rawHeaders = incoming.rawHeaders;
64
64
  for (let i = 0; i < rawHeaders.length; i += 2) {
@@ -70,7 +70,8 @@ var newRequestFromIncoming = (method, url, incoming) => {
70
70
  }
71
71
  const init = {
72
72
  method,
73
- headers: headerRecord
73
+ headers: headerRecord,
74
+ signal: abortController.signal
74
75
  };
75
76
  if (!(method === "GET" || method === "HEAD")) {
76
77
  init.body = import_node_stream.Readable.toWeb(incoming);
@@ -81,6 +82,8 @@ var getRequestCache = Symbol("getRequestCache");
81
82
  var requestCache = Symbol("requestCache");
82
83
  var incomingKey = Symbol("incomingKey");
83
84
  var urlKey = Symbol("urlKey");
85
+ var abortControllerKey = Symbol("abortControllerKey");
86
+ var getAbortController = Symbol("getAbortController");
84
87
  var requestPrototype = {
85
88
  get method() {
86
89
  return this[incomingKey].method || "GET";
@@ -88,11 +91,17 @@ var requestPrototype = {
88
91
  get url() {
89
92
  return this[urlKey];
90
93
  },
94
+ [getAbortController]() {
95
+ this[getRequestCache]();
96
+ return this[abortControllerKey];
97
+ },
91
98
  [getRequestCache]() {
99
+ this[abortControllerKey] ||= new AbortController();
92
100
  return this[requestCache] ||= newRequestFromIncoming(
93
101
  this.method,
94
102
  this[urlKey],
95
- this[incomingKey]
103
+ this[incomingKey],
104
+ this[abortControllerKey]
96
105
  );
97
106
  }
98
107
  };
@@ -186,18 +195,19 @@ var buildOutgoingHttpHeaders = (headers) => {
186
195
  if (cookies.length > 0) {
187
196
  res["set-cookie"] = cookies;
188
197
  }
189
- res["content-type"] ??= "text/plain;charset=UTF-8";
198
+ res["content-type"] ??= "text/plain; charset=UTF-8";
190
199
  return res;
191
200
  };
192
201
 
193
202
  // src/response.ts
194
203
  var responseCache = Symbol("responseCache");
204
+ var getResponseCache = Symbol("getResponseCache");
195
205
  var cacheKey = Symbol("cache");
196
206
  var GlobalResponse = global.Response;
197
207
  var Response2 = class _Response {
198
208
  #body;
199
209
  #init;
200
- get cache() {
210
+ [getResponseCache]() {
201
211
  delete this[cacheKey];
202
212
  return this[responseCache] ||= new GlobalResponse(this.#body, this.#init);
203
213
  }
@@ -207,7 +217,7 @@ var Response2 = class _Response {
207
217
  const cachedGlobalResponse = init[responseCache];
208
218
  if (cachedGlobalResponse) {
209
219
  this.#init = cachedGlobalResponse;
210
- this.cache;
220
+ this[getResponseCache]();
211
221
  return;
212
222
  } else {
213
223
  this.#init = init.#init;
@@ -216,7 +226,7 @@ var Response2 = class _Response {
216
226
  this.#init = init;
217
227
  }
218
228
  if (typeof body === "string" || body instanceof ReadableStream) {
219
- let headers = init?.headers || { "content-type": "text/plain;charset=UTF-8" };
229
+ let headers = init?.headers || { "content-type": "text/plain; charset=UTF-8" };
220
230
  if (headers instanceof Headers) {
221
231
  headers = buildOutgoingHttpHeaders(headers);
222
232
  }
@@ -239,14 +249,14 @@ var Response2 = class _Response {
239
249
  ].forEach((k) => {
240
250
  Object.defineProperty(Response2.prototype, k, {
241
251
  get() {
242
- return this.cache[k];
252
+ return this[getResponseCache]()[k];
243
253
  }
244
254
  });
245
255
  });
246
256
  ["arrayBuffer", "blob", "clone", "formData", "json", "text"].forEach((k) => {
247
257
  Object.defineProperty(Response2.prototype, k, {
248
258
  value: function() {
249
- return this.cache[k]();
259
+ return this[getResponseCache]()[k]();
250
260
  }
251
261
  });
252
262
  });
@@ -255,6 +265,22 @@ Object.setPrototypeOf(Response2.prototype, GlobalResponse.prototype);
255
265
  Object.defineProperty(global, "Response", {
256
266
  value: Response2
257
267
  });
268
+ var stateKey = Reflect.ownKeys(new GlobalResponse()).find(
269
+ (k) => typeof k === "symbol" && k.toString() === "Symbol(state)"
270
+ );
271
+ if (!stateKey) {
272
+ console.warn("Failed to find Response internal state key");
273
+ }
274
+ function getInternalBody(response) {
275
+ if (!stateKey) {
276
+ return;
277
+ }
278
+ if (response instanceof Response2) {
279
+ response = response[getResponseCache]();
280
+ }
281
+ const state = response[stateKey];
282
+ return state && state.body || void 0;
283
+ }
258
284
 
259
285
  // src/globals.ts
260
286
  var import_node_crypto = __toESM(require("crypto"));
@@ -320,36 +346,40 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
320
346
  res = await res.catch(handleFetchError);
321
347
  }
322
348
  }
323
- try {
324
- const isCached = cacheKey in res;
325
- if (isCached) {
326
- return responseViaCache(res, outgoing);
327
- }
328
- } catch (e) {
329
- return handleResponseError(e, outgoing);
349
+ if (cacheKey in res) {
350
+ return responseViaCache(res, outgoing);
330
351
  }
331
352
  const resHeaderRecord = buildOutgoingHttpHeaders(res.headers);
332
- if (res.body) {
333
- try {
334
- const {
335
- "transfer-encoding": transferEncoding,
336
- "content-encoding": contentEncoding,
337
- "content-length": contentLength,
338
- "x-accel-buffering": accelBuffering,
339
- "content-type": contentType
340
- } = resHeaderRecord;
341
- if (transferEncoding || contentEncoding || contentLength || // nginx buffering variant
342
- accelBuffering && regBuffer.test(accelBuffering) || !regContentType.test(contentType)) {
343
- outgoing.writeHead(res.status, resHeaderRecord);
344
- await writeFromReadableStream(res.body, outgoing);
345
- } else {
346
- const buffer = await res.arrayBuffer();
347
- resHeaderRecord["content-length"] = buffer.byteLength;
348
- outgoing.writeHead(res.status, resHeaderRecord);
349
- outgoing.end(new Uint8Array(buffer));
350
- }
351
- } catch (e) {
352
- handleResponseError(e, outgoing);
353
+ const internalBody = getInternalBody(res);
354
+ if (internalBody) {
355
+ if (internalBody.length) {
356
+ resHeaderRecord["content-length"] = internalBody.length;
357
+ }
358
+ outgoing.writeHead(res.status, resHeaderRecord);
359
+ if (typeof internalBody.source === "string" || internalBody.source instanceof Uint8Array) {
360
+ outgoing.end(internalBody.source);
361
+ } else if (internalBody.source instanceof Blob) {
362
+ outgoing.end(new Uint8Array(await internalBody.source.arrayBuffer()));
363
+ } else {
364
+ await writeFromReadableStream(internalBody.stream, outgoing);
365
+ }
366
+ } else if (res.body) {
367
+ const {
368
+ "transfer-encoding": transferEncoding,
369
+ "content-encoding": contentEncoding,
370
+ "content-length": contentLength,
371
+ "x-accel-buffering": accelBuffering,
372
+ "content-type": contentType
373
+ } = resHeaderRecord;
374
+ if (transferEncoding || contentEncoding || contentLength || // nginx buffering variant
375
+ accelBuffering && regBuffer.test(accelBuffering) || !regContentType.test(contentType)) {
376
+ outgoing.writeHead(res.status, resHeaderRecord);
377
+ await writeFromReadableStream(res.body, outgoing);
378
+ } else {
379
+ const buffer = await res.arrayBuffer();
380
+ resHeaderRecord["content-length"] = buffer.byteLength;
381
+ outgoing.writeHead(res.status, resHeaderRecord);
382
+ outgoing.end(new Uint8Array(buffer));
353
383
  }
354
384
  } else {
355
385
  outgoing.writeHead(res.status, resHeaderRecord);
@@ -360,6 +390,11 @@ var getRequestListener = (fetchCallback, options = {}) => {
360
390
  return async (incoming, outgoing) => {
361
391
  let res;
362
392
  const req = newRequest(incoming);
393
+ outgoing.on("close", () => {
394
+ if (incoming.destroyed) {
395
+ req[getAbortController]().abort();
396
+ }
397
+ });
363
398
  try {
364
399
  res = fetchCallback(req, { incoming, outgoing });
365
400
  if (cacheKey in res) {
@@ -379,7 +414,11 @@ var getRequestListener = (fetchCallback, options = {}) => {
379
414
  return handleResponseError(e, outgoing);
380
415
  }
381
416
  }
382
- return responseViaResponseObject(res, outgoing, options);
417
+ try {
418
+ return responseViaResponseObject(res, outgoing, options);
419
+ } catch (e) {
420
+ return handleResponseError(e, outgoing);
421
+ }
383
422
  };
384
423
  };
385
424
 
package/dist/index.mjs CHANGED
@@ -20,7 +20,7 @@ var Request = class extends GlobalRequest {
20
20
  Object.defineProperty(global, "Request", {
21
21
  value: Request
22
22
  });
23
- var newRequestFromIncoming = (method, url, incoming) => {
23
+ var newRequestFromIncoming = (method, url, incoming, abortController) => {
24
24
  const headerRecord = [];
25
25
  const rawHeaders = incoming.rawHeaders;
26
26
  for (let i = 0; i < rawHeaders.length; i += 2) {
@@ -32,7 +32,8 @@ var newRequestFromIncoming = (method, url, incoming) => {
32
32
  }
33
33
  const init = {
34
34
  method,
35
- headers: headerRecord
35
+ headers: headerRecord,
36
+ signal: abortController.signal
36
37
  };
37
38
  if (!(method === "GET" || method === "HEAD")) {
38
39
  init.body = Readable.toWeb(incoming);
@@ -43,6 +44,8 @@ var getRequestCache = Symbol("getRequestCache");
43
44
  var requestCache = Symbol("requestCache");
44
45
  var incomingKey = Symbol("incomingKey");
45
46
  var urlKey = Symbol("urlKey");
47
+ var abortControllerKey = Symbol("abortControllerKey");
48
+ var getAbortController = Symbol("getAbortController");
46
49
  var requestPrototype = {
47
50
  get method() {
48
51
  return this[incomingKey].method || "GET";
@@ -50,11 +53,17 @@ var requestPrototype = {
50
53
  get url() {
51
54
  return this[urlKey];
52
55
  },
56
+ [getAbortController]() {
57
+ this[getRequestCache]();
58
+ return this[abortControllerKey];
59
+ },
53
60
  [getRequestCache]() {
61
+ this[abortControllerKey] ||= new AbortController();
54
62
  return this[requestCache] ||= newRequestFromIncoming(
55
63
  this.method,
56
64
  this[urlKey],
57
- this[incomingKey]
65
+ this[incomingKey],
66
+ this[abortControllerKey]
58
67
  );
59
68
  }
60
69
  };
@@ -148,18 +157,19 @@ var buildOutgoingHttpHeaders = (headers) => {
148
157
  if (cookies.length > 0) {
149
158
  res["set-cookie"] = cookies;
150
159
  }
151
- res["content-type"] ??= "text/plain;charset=UTF-8";
160
+ res["content-type"] ??= "text/plain; charset=UTF-8";
152
161
  return res;
153
162
  };
154
163
 
155
164
  // src/response.ts
156
165
  var responseCache = Symbol("responseCache");
166
+ var getResponseCache = Symbol("getResponseCache");
157
167
  var cacheKey = Symbol("cache");
158
168
  var GlobalResponse = global.Response;
159
169
  var Response2 = class _Response {
160
170
  #body;
161
171
  #init;
162
- get cache() {
172
+ [getResponseCache]() {
163
173
  delete this[cacheKey];
164
174
  return this[responseCache] ||= new GlobalResponse(this.#body, this.#init);
165
175
  }
@@ -169,7 +179,7 @@ var Response2 = class _Response {
169
179
  const cachedGlobalResponse = init[responseCache];
170
180
  if (cachedGlobalResponse) {
171
181
  this.#init = cachedGlobalResponse;
172
- this.cache;
182
+ this[getResponseCache]();
173
183
  return;
174
184
  } else {
175
185
  this.#init = init.#init;
@@ -178,7 +188,7 @@ var Response2 = class _Response {
178
188
  this.#init = init;
179
189
  }
180
190
  if (typeof body === "string" || body instanceof ReadableStream) {
181
- let headers = init?.headers || { "content-type": "text/plain;charset=UTF-8" };
191
+ let headers = init?.headers || { "content-type": "text/plain; charset=UTF-8" };
182
192
  if (headers instanceof Headers) {
183
193
  headers = buildOutgoingHttpHeaders(headers);
184
194
  }
@@ -201,14 +211,14 @@ var Response2 = class _Response {
201
211
  ].forEach((k) => {
202
212
  Object.defineProperty(Response2.prototype, k, {
203
213
  get() {
204
- return this.cache[k];
214
+ return this[getResponseCache]()[k];
205
215
  }
206
216
  });
207
217
  });
208
218
  ["arrayBuffer", "blob", "clone", "formData", "json", "text"].forEach((k) => {
209
219
  Object.defineProperty(Response2.prototype, k, {
210
220
  value: function() {
211
- return this.cache[k]();
221
+ return this[getResponseCache]()[k]();
212
222
  }
213
223
  });
214
224
  });
@@ -217,6 +227,22 @@ Object.setPrototypeOf(Response2.prototype, GlobalResponse.prototype);
217
227
  Object.defineProperty(global, "Response", {
218
228
  value: Response2
219
229
  });
230
+ var stateKey = Reflect.ownKeys(new GlobalResponse()).find(
231
+ (k) => typeof k === "symbol" && k.toString() === "Symbol(state)"
232
+ );
233
+ if (!stateKey) {
234
+ console.warn("Failed to find Response internal state key");
235
+ }
236
+ function getInternalBody(response) {
237
+ if (!stateKey) {
238
+ return;
239
+ }
240
+ if (response instanceof Response2) {
241
+ response = response[getResponseCache]();
242
+ }
243
+ const state = response[stateKey];
244
+ return state && state.body || void 0;
245
+ }
220
246
 
221
247
  // src/globals.ts
222
248
  import crypto from "crypto";
@@ -282,36 +308,40 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
282
308
  res = await res.catch(handleFetchError);
283
309
  }
284
310
  }
285
- try {
286
- const isCached = cacheKey in res;
287
- if (isCached) {
288
- return responseViaCache(res, outgoing);
289
- }
290
- } catch (e) {
291
- return handleResponseError(e, outgoing);
311
+ if (cacheKey in res) {
312
+ return responseViaCache(res, outgoing);
292
313
  }
293
314
  const resHeaderRecord = buildOutgoingHttpHeaders(res.headers);
294
- if (res.body) {
295
- try {
296
- const {
297
- "transfer-encoding": transferEncoding,
298
- "content-encoding": contentEncoding,
299
- "content-length": contentLength,
300
- "x-accel-buffering": accelBuffering,
301
- "content-type": contentType
302
- } = resHeaderRecord;
303
- if (transferEncoding || contentEncoding || contentLength || // nginx buffering variant
304
- accelBuffering && regBuffer.test(accelBuffering) || !regContentType.test(contentType)) {
305
- outgoing.writeHead(res.status, resHeaderRecord);
306
- await writeFromReadableStream(res.body, outgoing);
307
- } else {
308
- const buffer = await res.arrayBuffer();
309
- resHeaderRecord["content-length"] = buffer.byteLength;
310
- outgoing.writeHead(res.status, resHeaderRecord);
311
- outgoing.end(new Uint8Array(buffer));
312
- }
313
- } catch (e) {
314
- handleResponseError(e, outgoing);
315
+ const internalBody = getInternalBody(res);
316
+ if (internalBody) {
317
+ if (internalBody.length) {
318
+ resHeaderRecord["content-length"] = internalBody.length;
319
+ }
320
+ outgoing.writeHead(res.status, resHeaderRecord);
321
+ if (typeof internalBody.source === "string" || internalBody.source instanceof Uint8Array) {
322
+ outgoing.end(internalBody.source);
323
+ } else if (internalBody.source instanceof Blob) {
324
+ outgoing.end(new Uint8Array(await internalBody.source.arrayBuffer()));
325
+ } else {
326
+ await writeFromReadableStream(internalBody.stream, outgoing);
327
+ }
328
+ } else if (res.body) {
329
+ const {
330
+ "transfer-encoding": transferEncoding,
331
+ "content-encoding": contentEncoding,
332
+ "content-length": contentLength,
333
+ "x-accel-buffering": accelBuffering,
334
+ "content-type": contentType
335
+ } = resHeaderRecord;
336
+ if (transferEncoding || contentEncoding || contentLength || // nginx buffering variant
337
+ accelBuffering && regBuffer.test(accelBuffering) || !regContentType.test(contentType)) {
338
+ outgoing.writeHead(res.status, resHeaderRecord);
339
+ await writeFromReadableStream(res.body, outgoing);
340
+ } else {
341
+ const buffer = await res.arrayBuffer();
342
+ resHeaderRecord["content-length"] = buffer.byteLength;
343
+ outgoing.writeHead(res.status, resHeaderRecord);
344
+ outgoing.end(new Uint8Array(buffer));
315
345
  }
316
346
  } else {
317
347
  outgoing.writeHead(res.status, resHeaderRecord);
@@ -322,6 +352,11 @@ var getRequestListener = (fetchCallback, options = {}) => {
322
352
  return async (incoming, outgoing) => {
323
353
  let res;
324
354
  const req = newRequest(incoming);
355
+ outgoing.on("close", () => {
356
+ if (incoming.destroyed) {
357
+ req[getAbortController]().abort();
358
+ }
359
+ });
325
360
  try {
326
361
  res = fetchCallback(req, { incoming, outgoing });
327
362
  if (cacheKey in res) {
@@ -341,7 +376,11 @@ var getRequestListener = (fetchCallback, options = {}) => {
341
376
  return handleResponseError(e, outgoing);
342
377
  }
343
378
  }
344
- return responseViaResponseObject(res, outgoing, options);
379
+ try {
380
+ return responseViaResponseObject(res, outgoing, options);
381
+ } catch (e) {
382
+ return handleResponseError(e, outgoing);
383
+ }
345
384
  };
346
385
  };
347
386
 
package/dist/listener.js CHANGED
@@ -53,7 +53,7 @@ var Request = class extends GlobalRequest {
53
53
  Object.defineProperty(global, "Request", {
54
54
  value: Request
55
55
  });
56
- var newRequestFromIncoming = (method, url, incoming) => {
56
+ var newRequestFromIncoming = (method, url, incoming, abortController) => {
57
57
  const headerRecord = [];
58
58
  const rawHeaders = incoming.rawHeaders;
59
59
  for (let i = 0; i < rawHeaders.length; i += 2) {
@@ -65,7 +65,8 @@ var newRequestFromIncoming = (method, url, incoming) => {
65
65
  }
66
66
  const init = {
67
67
  method,
68
- headers: headerRecord
68
+ headers: headerRecord,
69
+ signal: abortController.signal
69
70
  };
70
71
  if (!(method === "GET" || method === "HEAD")) {
71
72
  init.body = import_node_stream.Readable.toWeb(incoming);
@@ -76,6 +77,8 @@ var getRequestCache = Symbol("getRequestCache");
76
77
  var requestCache = Symbol("requestCache");
77
78
  var incomingKey = Symbol("incomingKey");
78
79
  var urlKey = Symbol("urlKey");
80
+ var abortControllerKey = Symbol("abortControllerKey");
81
+ var getAbortController = Symbol("getAbortController");
79
82
  var requestPrototype = {
80
83
  get method() {
81
84
  return this[incomingKey].method || "GET";
@@ -83,11 +86,17 @@ var requestPrototype = {
83
86
  get url() {
84
87
  return this[urlKey];
85
88
  },
89
+ [getAbortController]() {
90
+ this[getRequestCache]();
91
+ return this[abortControllerKey];
92
+ },
86
93
  [getRequestCache]() {
94
+ this[abortControllerKey] ||= new AbortController();
87
95
  return this[requestCache] ||= newRequestFromIncoming(
88
96
  this.method,
89
97
  this[urlKey],
90
- this[incomingKey]
98
+ this[incomingKey],
99
+ this[abortControllerKey]
91
100
  );
92
101
  }
93
102
  };
@@ -181,18 +190,19 @@ var buildOutgoingHttpHeaders = (headers) => {
181
190
  if (cookies.length > 0) {
182
191
  res["set-cookie"] = cookies;
183
192
  }
184
- res["content-type"] ??= "text/plain;charset=UTF-8";
193
+ res["content-type"] ??= "text/plain; charset=UTF-8";
185
194
  return res;
186
195
  };
187
196
 
188
197
  // src/response.ts
189
198
  var responseCache = Symbol("responseCache");
199
+ var getResponseCache = Symbol("getResponseCache");
190
200
  var cacheKey = Symbol("cache");
191
201
  var GlobalResponse = global.Response;
192
202
  var Response2 = class _Response {
193
203
  #body;
194
204
  #init;
195
- get cache() {
205
+ [getResponseCache]() {
196
206
  delete this[cacheKey];
197
207
  return this[responseCache] ||= new GlobalResponse(this.#body, this.#init);
198
208
  }
@@ -202,7 +212,7 @@ var Response2 = class _Response {
202
212
  const cachedGlobalResponse = init[responseCache];
203
213
  if (cachedGlobalResponse) {
204
214
  this.#init = cachedGlobalResponse;
205
- this.cache;
215
+ this[getResponseCache]();
206
216
  return;
207
217
  } else {
208
218
  this.#init = init.#init;
@@ -211,7 +221,7 @@ var Response2 = class _Response {
211
221
  this.#init = init;
212
222
  }
213
223
  if (typeof body === "string" || body instanceof ReadableStream) {
214
- let headers = init?.headers || { "content-type": "text/plain;charset=UTF-8" };
224
+ let headers = init?.headers || { "content-type": "text/plain; charset=UTF-8" };
215
225
  if (headers instanceof Headers) {
216
226
  headers = buildOutgoingHttpHeaders(headers);
217
227
  }
@@ -234,14 +244,14 @@ var Response2 = class _Response {
234
244
  ].forEach((k) => {
235
245
  Object.defineProperty(Response2.prototype, k, {
236
246
  get() {
237
- return this.cache[k];
247
+ return this[getResponseCache]()[k];
238
248
  }
239
249
  });
240
250
  });
241
251
  ["arrayBuffer", "blob", "clone", "formData", "json", "text"].forEach((k) => {
242
252
  Object.defineProperty(Response2.prototype, k, {
243
253
  value: function() {
244
- return this.cache[k]();
254
+ return this[getResponseCache]()[k]();
245
255
  }
246
256
  });
247
257
  });
@@ -250,6 +260,22 @@ Object.setPrototypeOf(Response2.prototype, GlobalResponse.prototype);
250
260
  Object.defineProperty(global, "Response", {
251
261
  value: Response2
252
262
  });
263
+ var stateKey = Reflect.ownKeys(new GlobalResponse()).find(
264
+ (k) => typeof k === "symbol" && k.toString() === "Symbol(state)"
265
+ );
266
+ if (!stateKey) {
267
+ console.warn("Failed to find Response internal state key");
268
+ }
269
+ function getInternalBody(response) {
270
+ if (!stateKey) {
271
+ return;
272
+ }
273
+ if (response instanceof Response2) {
274
+ response = response[getResponseCache]();
275
+ }
276
+ const state = response[stateKey];
277
+ return state && state.body || void 0;
278
+ }
253
279
 
254
280
  // src/globals.ts
255
281
  var import_node_crypto = __toESM(require("crypto"));
@@ -315,36 +341,40 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
315
341
  res = await res.catch(handleFetchError);
316
342
  }
317
343
  }
318
- try {
319
- const isCached = cacheKey in res;
320
- if (isCached) {
321
- return responseViaCache(res, outgoing);
322
- }
323
- } catch (e) {
324
- return handleResponseError(e, outgoing);
344
+ if (cacheKey in res) {
345
+ return responseViaCache(res, outgoing);
325
346
  }
326
347
  const resHeaderRecord = buildOutgoingHttpHeaders(res.headers);
327
- if (res.body) {
328
- try {
329
- const {
330
- "transfer-encoding": transferEncoding,
331
- "content-encoding": contentEncoding,
332
- "content-length": contentLength,
333
- "x-accel-buffering": accelBuffering,
334
- "content-type": contentType
335
- } = resHeaderRecord;
336
- if (transferEncoding || contentEncoding || contentLength || // nginx buffering variant
337
- accelBuffering && regBuffer.test(accelBuffering) || !regContentType.test(contentType)) {
338
- outgoing.writeHead(res.status, resHeaderRecord);
339
- await writeFromReadableStream(res.body, outgoing);
340
- } else {
341
- const buffer = await res.arrayBuffer();
342
- resHeaderRecord["content-length"] = buffer.byteLength;
343
- outgoing.writeHead(res.status, resHeaderRecord);
344
- outgoing.end(new Uint8Array(buffer));
345
- }
346
- } catch (e) {
347
- handleResponseError(e, outgoing);
348
+ const internalBody = getInternalBody(res);
349
+ if (internalBody) {
350
+ if (internalBody.length) {
351
+ resHeaderRecord["content-length"] = internalBody.length;
352
+ }
353
+ outgoing.writeHead(res.status, resHeaderRecord);
354
+ if (typeof internalBody.source === "string" || internalBody.source instanceof Uint8Array) {
355
+ outgoing.end(internalBody.source);
356
+ } else if (internalBody.source instanceof Blob) {
357
+ outgoing.end(new Uint8Array(await internalBody.source.arrayBuffer()));
358
+ } else {
359
+ await writeFromReadableStream(internalBody.stream, outgoing);
360
+ }
361
+ } else if (res.body) {
362
+ const {
363
+ "transfer-encoding": transferEncoding,
364
+ "content-encoding": contentEncoding,
365
+ "content-length": contentLength,
366
+ "x-accel-buffering": accelBuffering,
367
+ "content-type": contentType
368
+ } = resHeaderRecord;
369
+ if (transferEncoding || contentEncoding || contentLength || // nginx buffering variant
370
+ accelBuffering && regBuffer.test(accelBuffering) || !regContentType.test(contentType)) {
371
+ outgoing.writeHead(res.status, resHeaderRecord);
372
+ await writeFromReadableStream(res.body, outgoing);
373
+ } else {
374
+ const buffer = await res.arrayBuffer();
375
+ resHeaderRecord["content-length"] = buffer.byteLength;
376
+ outgoing.writeHead(res.status, resHeaderRecord);
377
+ outgoing.end(new Uint8Array(buffer));
348
378
  }
349
379
  } else {
350
380
  outgoing.writeHead(res.status, resHeaderRecord);
@@ -355,6 +385,11 @@ var getRequestListener = (fetchCallback, options = {}) => {
355
385
  return async (incoming, outgoing) => {
356
386
  let res;
357
387
  const req = newRequest(incoming);
388
+ outgoing.on("close", () => {
389
+ if (incoming.destroyed) {
390
+ req[getAbortController]().abort();
391
+ }
392
+ });
358
393
  try {
359
394
  res = fetchCallback(req, { incoming, outgoing });
360
395
  if (cacheKey in res) {
@@ -374,7 +409,11 @@ var getRequestListener = (fetchCallback, options = {}) => {
374
409
  return handleResponseError(e, outgoing);
375
410
  }
376
411
  }
377
- return responseViaResponseObject(res, outgoing, options);
412
+ try {
413
+ return responseViaResponseObject(res, outgoing, options);
414
+ } catch (e) {
415
+ return handleResponseError(e, outgoing);
416
+ }
378
417
  };
379
418
  };
380
419
  // Annotate the CommonJS export names for ESM import in node: