@hono/node-server 1.7.0 → 1.8.1

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
  };
@@ -108,7 +117,8 @@ var requestPrototype = {
108
117
  "redirect",
109
118
  "referrer",
110
119
  "referrerPolicy",
111
- "signal"
120
+ "signal",
121
+ "keepalive"
112
122
  ].forEach((k) => {
113
123
  Object.defineProperty(requestPrototype, k, {
114
124
  get() {
@@ -186,18 +196,19 @@ var buildOutgoingHttpHeaders = (headers) => {
186
196
  if (cookies.length > 0) {
187
197
  res["set-cookie"] = cookies;
188
198
  }
189
- res["content-type"] ??= "text/plain;charset=UTF-8";
199
+ res["content-type"] ??= "text/plain; charset=UTF-8";
190
200
  return res;
191
201
  };
192
202
 
193
203
  // src/response.ts
194
204
  var responseCache = Symbol("responseCache");
205
+ var getResponseCache = Symbol("getResponseCache");
195
206
  var cacheKey = Symbol("cache");
196
207
  var GlobalResponse = global.Response;
197
208
  var Response2 = class _Response {
198
209
  #body;
199
210
  #init;
200
- get cache() {
211
+ [getResponseCache]() {
201
212
  delete this[cacheKey];
202
213
  return this[responseCache] ||= new GlobalResponse(this.#body, this.#init);
203
214
  }
@@ -207,7 +218,7 @@ var Response2 = class _Response {
207
218
  const cachedGlobalResponse = init[responseCache];
208
219
  if (cachedGlobalResponse) {
209
220
  this.#init = cachedGlobalResponse;
210
- this.cache;
221
+ this[getResponseCache]();
211
222
  return;
212
223
  } else {
213
224
  this.#init = init.#init;
@@ -216,7 +227,7 @@ var Response2 = class _Response {
216
227
  this.#init = init;
217
228
  }
218
229
  if (typeof body === "string" || body instanceof ReadableStream) {
219
- let headers = init?.headers || { "content-type": "text/plain;charset=UTF-8" };
230
+ let headers = init?.headers || { "content-type": "text/plain; charset=UTF-8" };
220
231
  if (headers instanceof Headers) {
221
232
  headers = buildOutgoingHttpHeaders(headers);
222
233
  }
@@ -239,14 +250,14 @@ var Response2 = class _Response {
239
250
  ].forEach((k) => {
240
251
  Object.defineProperty(Response2.prototype, k, {
241
252
  get() {
242
- return this.cache[k];
253
+ return this[getResponseCache]()[k];
243
254
  }
244
255
  });
245
256
  });
246
257
  ["arrayBuffer", "blob", "clone", "formData", "json", "text"].forEach((k) => {
247
258
  Object.defineProperty(Response2.prototype, k, {
248
259
  value: function() {
249
- return this.cache[k]();
260
+ return this[getResponseCache]()[k]();
250
261
  }
251
262
  });
252
263
  });
@@ -255,6 +266,22 @@ Object.setPrototypeOf(Response2.prototype, GlobalResponse.prototype);
255
266
  Object.defineProperty(global, "Response", {
256
267
  value: Response2
257
268
  });
269
+ var stateKey = Reflect.ownKeys(new GlobalResponse()).find(
270
+ (k) => typeof k === "symbol" && k.toString() === "Symbol(state)"
271
+ );
272
+ if (!stateKey) {
273
+ console.warn("Failed to find Response internal state key");
274
+ }
275
+ function getInternalBody(response) {
276
+ if (!stateKey) {
277
+ return;
278
+ }
279
+ if (response instanceof Response2) {
280
+ response = response[getResponseCache]();
281
+ }
282
+ const state = response[stateKey];
283
+ return state && state.body || void 0;
284
+ }
258
285
 
259
286
  // src/globals.ts
260
287
  var import_node_crypto = __toESM(require("crypto"));
@@ -320,36 +347,40 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
320
347
  res = await res.catch(handleFetchError);
321
348
  }
322
349
  }
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);
350
+ if (cacheKey in res) {
351
+ return responseViaCache(res, outgoing);
330
352
  }
331
353
  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);
354
+ const internalBody = getInternalBody(res);
355
+ if (internalBody) {
356
+ if (internalBody.length) {
357
+ resHeaderRecord["content-length"] = internalBody.length;
358
+ }
359
+ outgoing.writeHead(res.status, resHeaderRecord);
360
+ if (typeof internalBody.source === "string" || internalBody.source instanceof Uint8Array) {
361
+ outgoing.end(internalBody.source);
362
+ } else if (internalBody.source instanceof Blob) {
363
+ outgoing.end(new Uint8Array(await internalBody.source.arrayBuffer()));
364
+ } else {
365
+ await writeFromReadableStream(internalBody.stream, outgoing);
366
+ }
367
+ } else if (res.body) {
368
+ const {
369
+ "transfer-encoding": transferEncoding,
370
+ "content-encoding": contentEncoding,
371
+ "content-length": contentLength,
372
+ "x-accel-buffering": accelBuffering,
373
+ "content-type": contentType
374
+ } = resHeaderRecord;
375
+ if (transferEncoding || contentEncoding || contentLength || // nginx buffering variant
376
+ accelBuffering && regBuffer.test(accelBuffering) || !regContentType.test(contentType)) {
377
+ outgoing.writeHead(res.status, resHeaderRecord);
378
+ await writeFromReadableStream(res.body, outgoing);
379
+ } else {
380
+ const buffer = await res.arrayBuffer();
381
+ resHeaderRecord["content-length"] = buffer.byteLength;
382
+ outgoing.writeHead(res.status, resHeaderRecord);
383
+ outgoing.end(new Uint8Array(buffer));
353
384
  }
354
385
  } else {
355
386
  outgoing.writeHead(res.status, resHeaderRecord);
@@ -360,6 +391,11 @@ var getRequestListener = (fetchCallback, options = {}) => {
360
391
  return async (incoming, outgoing) => {
361
392
  let res;
362
393
  const req = newRequest(incoming);
394
+ outgoing.on("close", () => {
395
+ if (incoming.destroyed) {
396
+ req[getAbortController]().abort();
397
+ }
398
+ });
363
399
  try {
364
400
  res = fetchCallback(req, { incoming, outgoing });
365
401
  if (cacheKey in res) {
@@ -379,7 +415,11 @@ var getRequestListener = (fetchCallback, options = {}) => {
379
415
  return handleResponseError(e, outgoing);
380
416
  }
381
417
  }
382
- return responseViaResponseObject(res, outgoing, options);
418
+ try {
419
+ return responseViaResponseObject(res, outgoing, options);
420
+ } catch (e) {
421
+ return handleResponseError(e, outgoing);
422
+ }
383
423
  };
384
424
  };
385
425
 
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
  };
@@ -70,7 +79,8 @@ var requestPrototype = {
70
79
  "redirect",
71
80
  "referrer",
72
81
  "referrerPolicy",
73
- "signal"
82
+ "signal",
83
+ "keepalive"
74
84
  ].forEach((k) => {
75
85
  Object.defineProperty(requestPrototype, k, {
76
86
  get() {
@@ -148,18 +158,19 @@ var buildOutgoingHttpHeaders = (headers) => {
148
158
  if (cookies.length > 0) {
149
159
  res["set-cookie"] = cookies;
150
160
  }
151
- res["content-type"] ??= "text/plain;charset=UTF-8";
161
+ res["content-type"] ??= "text/plain; charset=UTF-8";
152
162
  return res;
153
163
  };
154
164
 
155
165
  // src/response.ts
156
166
  var responseCache = Symbol("responseCache");
167
+ var getResponseCache = Symbol("getResponseCache");
157
168
  var cacheKey = Symbol("cache");
158
169
  var GlobalResponse = global.Response;
159
170
  var Response2 = class _Response {
160
171
  #body;
161
172
  #init;
162
- get cache() {
173
+ [getResponseCache]() {
163
174
  delete this[cacheKey];
164
175
  return this[responseCache] ||= new GlobalResponse(this.#body, this.#init);
165
176
  }
@@ -169,7 +180,7 @@ var Response2 = class _Response {
169
180
  const cachedGlobalResponse = init[responseCache];
170
181
  if (cachedGlobalResponse) {
171
182
  this.#init = cachedGlobalResponse;
172
- this.cache;
183
+ this[getResponseCache]();
173
184
  return;
174
185
  } else {
175
186
  this.#init = init.#init;
@@ -178,7 +189,7 @@ var Response2 = class _Response {
178
189
  this.#init = init;
179
190
  }
180
191
  if (typeof body === "string" || body instanceof ReadableStream) {
181
- let headers = init?.headers || { "content-type": "text/plain;charset=UTF-8" };
192
+ let headers = init?.headers || { "content-type": "text/plain; charset=UTF-8" };
182
193
  if (headers instanceof Headers) {
183
194
  headers = buildOutgoingHttpHeaders(headers);
184
195
  }
@@ -201,14 +212,14 @@ var Response2 = class _Response {
201
212
  ].forEach((k) => {
202
213
  Object.defineProperty(Response2.prototype, k, {
203
214
  get() {
204
- return this.cache[k];
215
+ return this[getResponseCache]()[k];
205
216
  }
206
217
  });
207
218
  });
208
219
  ["arrayBuffer", "blob", "clone", "formData", "json", "text"].forEach((k) => {
209
220
  Object.defineProperty(Response2.prototype, k, {
210
221
  value: function() {
211
- return this.cache[k]();
222
+ return this[getResponseCache]()[k]();
212
223
  }
213
224
  });
214
225
  });
@@ -217,6 +228,22 @@ Object.setPrototypeOf(Response2.prototype, GlobalResponse.prototype);
217
228
  Object.defineProperty(global, "Response", {
218
229
  value: Response2
219
230
  });
231
+ var stateKey = Reflect.ownKeys(new GlobalResponse()).find(
232
+ (k) => typeof k === "symbol" && k.toString() === "Symbol(state)"
233
+ );
234
+ if (!stateKey) {
235
+ console.warn("Failed to find Response internal state key");
236
+ }
237
+ function getInternalBody(response) {
238
+ if (!stateKey) {
239
+ return;
240
+ }
241
+ if (response instanceof Response2) {
242
+ response = response[getResponseCache]();
243
+ }
244
+ const state = response[stateKey];
245
+ return state && state.body || void 0;
246
+ }
220
247
 
221
248
  // src/globals.ts
222
249
  import crypto from "crypto";
@@ -282,36 +309,40 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
282
309
  res = await res.catch(handleFetchError);
283
310
  }
284
311
  }
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);
312
+ if (cacheKey in res) {
313
+ return responseViaCache(res, outgoing);
292
314
  }
293
315
  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);
316
+ const internalBody = getInternalBody(res);
317
+ if (internalBody) {
318
+ if (internalBody.length) {
319
+ resHeaderRecord["content-length"] = internalBody.length;
320
+ }
321
+ outgoing.writeHead(res.status, resHeaderRecord);
322
+ if (typeof internalBody.source === "string" || internalBody.source instanceof Uint8Array) {
323
+ outgoing.end(internalBody.source);
324
+ } else if (internalBody.source instanceof Blob) {
325
+ outgoing.end(new Uint8Array(await internalBody.source.arrayBuffer()));
326
+ } else {
327
+ await writeFromReadableStream(internalBody.stream, outgoing);
328
+ }
329
+ } else if (res.body) {
330
+ const {
331
+ "transfer-encoding": transferEncoding,
332
+ "content-encoding": contentEncoding,
333
+ "content-length": contentLength,
334
+ "x-accel-buffering": accelBuffering,
335
+ "content-type": contentType
336
+ } = resHeaderRecord;
337
+ if (transferEncoding || contentEncoding || contentLength || // nginx buffering variant
338
+ accelBuffering && regBuffer.test(accelBuffering) || !regContentType.test(contentType)) {
339
+ outgoing.writeHead(res.status, resHeaderRecord);
340
+ await writeFromReadableStream(res.body, outgoing);
341
+ } else {
342
+ const buffer = await res.arrayBuffer();
343
+ resHeaderRecord["content-length"] = buffer.byteLength;
344
+ outgoing.writeHead(res.status, resHeaderRecord);
345
+ outgoing.end(new Uint8Array(buffer));
315
346
  }
316
347
  } else {
317
348
  outgoing.writeHead(res.status, resHeaderRecord);
@@ -322,6 +353,11 @@ var getRequestListener = (fetchCallback, options = {}) => {
322
353
  return async (incoming, outgoing) => {
323
354
  let res;
324
355
  const req = newRequest(incoming);
356
+ outgoing.on("close", () => {
357
+ if (incoming.destroyed) {
358
+ req[getAbortController]().abort();
359
+ }
360
+ });
325
361
  try {
326
362
  res = fetchCallback(req, { incoming, outgoing });
327
363
  if (cacheKey in res) {
@@ -341,7 +377,11 @@ var getRequestListener = (fetchCallback, options = {}) => {
341
377
  return handleResponseError(e, outgoing);
342
378
  }
343
379
  }
344
- return responseViaResponseObject(res, outgoing, options);
380
+ try {
381
+ return responseViaResponseObject(res, outgoing, options);
382
+ } catch (e) {
383
+ return handleResponseError(e, outgoing);
384
+ }
345
385
  };
346
386
  };
347
387
 
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
  };
@@ -103,7 +112,8 @@ var requestPrototype = {
103
112
  "redirect",
104
113
  "referrer",
105
114
  "referrerPolicy",
106
- "signal"
115
+ "signal",
116
+ "keepalive"
107
117
  ].forEach((k) => {
108
118
  Object.defineProperty(requestPrototype, k, {
109
119
  get() {
@@ -181,18 +191,19 @@ var buildOutgoingHttpHeaders = (headers) => {
181
191
  if (cookies.length > 0) {
182
192
  res["set-cookie"] = cookies;
183
193
  }
184
- res["content-type"] ??= "text/plain;charset=UTF-8";
194
+ res["content-type"] ??= "text/plain; charset=UTF-8";
185
195
  return res;
186
196
  };
187
197
 
188
198
  // src/response.ts
189
199
  var responseCache = Symbol("responseCache");
200
+ var getResponseCache = Symbol("getResponseCache");
190
201
  var cacheKey = Symbol("cache");
191
202
  var GlobalResponse = global.Response;
192
203
  var Response2 = class _Response {
193
204
  #body;
194
205
  #init;
195
- get cache() {
206
+ [getResponseCache]() {
196
207
  delete this[cacheKey];
197
208
  return this[responseCache] ||= new GlobalResponse(this.#body, this.#init);
198
209
  }
@@ -202,7 +213,7 @@ var Response2 = class _Response {
202
213
  const cachedGlobalResponse = init[responseCache];
203
214
  if (cachedGlobalResponse) {
204
215
  this.#init = cachedGlobalResponse;
205
- this.cache;
216
+ this[getResponseCache]();
206
217
  return;
207
218
  } else {
208
219
  this.#init = init.#init;
@@ -211,7 +222,7 @@ var Response2 = class _Response {
211
222
  this.#init = init;
212
223
  }
213
224
  if (typeof body === "string" || body instanceof ReadableStream) {
214
- let headers = init?.headers || { "content-type": "text/plain;charset=UTF-8" };
225
+ let headers = init?.headers || { "content-type": "text/plain; charset=UTF-8" };
215
226
  if (headers instanceof Headers) {
216
227
  headers = buildOutgoingHttpHeaders(headers);
217
228
  }
@@ -234,14 +245,14 @@ var Response2 = class _Response {
234
245
  ].forEach((k) => {
235
246
  Object.defineProperty(Response2.prototype, k, {
236
247
  get() {
237
- return this.cache[k];
248
+ return this[getResponseCache]()[k];
238
249
  }
239
250
  });
240
251
  });
241
252
  ["arrayBuffer", "blob", "clone", "formData", "json", "text"].forEach((k) => {
242
253
  Object.defineProperty(Response2.prototype, k, {
243
254
  value: function() {
244
- return this.cache[k]();
255
+ return this[getResponseCache]()[k]();
245
256
  }
246
257
  });
247
258
  });
@@ -250,6 +261,22 @@ Object.setPrototypeOf(Response2.prototype, GlobalResponse.prototype);
250
261
  Object.defineProperty(global, "Response", {
251
262
  value: Response2
252
263
  });
264
+ var stateKey = Reflect.ownKeys(new GlobalResponse()).find(
265
+ (k) => typeof k === "symbol" && k.toString() === "Symbol(state)"
266
+ );
267
+ if (!stateKey) {
268
+ console.warn("Failed to find Response internal state key");
269
+ }
270
+ function getInternalBody(response) {
271
+ if (!stateKey) {
272
+ return;
273
+ }
274
+ if (response instanceof Response2) {
275
+ response = response[getResponseCache]();
276
+ }
277
+ const state = response[stateKey];
278
+ return state && state.body || void 0;
279
+ }
253
280
 
254
281
  // src/globals.ts
255
282
  var import_node_crypto = __toESM(require("crypto"));
@@ -315,36 +342,40 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
315
342
  res = await res.catch(handleFetchError);
316
343
  }
317
344
  }
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);
345
+ if (cacheKey in res) {
346
+ return responseViaCache(res, outgoing);
325
347
  }
326
348
  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);
349
+ const internalBody = getInternalBody(res);
350
+ if (internalBody) {
351
+ if (internalBody.length) {
352
+ resHeaderRecord["content-length"] = internalBody.length;
353
+ }
354
+ outgoing.writeHead(res.status, resHeaderRecord);
355
+ if (typeof internalBody.source === "string" || internalBody.source instanceof Uint8Array) {
356
+ outgoing.end(internalBody.source);
357
+ } else if (internalBody.source instanceof Blob) {
358
+ outgoing.end(new Uint8Array(await internalBody.source.arrayBuffer()));
359
+ } else {
360
+ await writeFromReadableStream(internalBody.stream, outgoing);
361
+ }
362
+ } else if (res.body) {
363
+ const {
364
+ "transfer-encoding": transferEncoding,
365
+ "content-encoding": contentEncoding,
366
+ "content-length": contentLength,
367
+ "x-accel-buffering": accelBuffering,
368
+ "content-type": contentType
369
+ } = resHeaderRecord;
370
+ if (transferEncoding || contentEncoding || contentLength || // nginx buffering variant
371
+ accelBuffering && regBuffer.test(accelBuffering) || !regContentType.test(contentType)) {
372
+ outgoing.writeHead(res.status, resHeaderRecord);
373
+ await writeFromReadableStream(res.body, outgoing);
374
+ } else {
375
+ const buffer = await res.arrayBuffer();
376
+ resHeaderRecord["content-length"] = buffer.byteLength;
377
+ outgoing.writeHead(res.status, resHeaderRecord);
378
+ outgoing.end(new Uint8Array(buffer));
348
379
  }
349
380
  } else {
350
381
  outgoing.writeHead(res.status, resHeaderRecord);
@@ -355,6 +386,11 @@ var getRequestListener = (fetchCallback, options = {}) => {
355
386
  return async (incoming, outgoing) => {
356
387
  let res;
357
388
  const req = newRequest(incoming);
389
+ outgoing.on("close", () => {
390
+ if (incoming.destroyed) {
391
+ req[getAbortController]().abort();
392
+ }
393
+ });
358
394
  try {
359
395
  res = fetchCallback(req, { incoming, outgoing });
360
396
  if (cacheKey in res) {
@@ -374,7 +410,11 @@ var getRequestListener = (fetchCallback, options = {}) => {
374
410
  return handleResponseError(e, outgoing);
375
411
  }
376
412
  }
377
- return responseViaResponseObject(res, outgoing, options);
413
+ try {
414
+ return responseViaResponseObject(res, outgoing, options);
415
+ } catch (e) {
416
+ return handleResponseError(e, outgoing);
417
+ }
378
418
  };
379
419
  };
380
420
  // Annotate the CommonJS export names for ESM import in node: