fulmine.js 5.18.0 → 5.18.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fulmine.js",
3
- "version": "5.18.0",
3
+ "version": "5.18.2",
4
4
  "description": "Drop-in Express 5 replacement on uWebSockets.js. Your existing middleware keeps working.",
5
5
  "main": "src/index.js",
6
6
  "exports": {
package/src/node-shim.js CHANGED
@@ -222,7 +222,9 @@ class NodeHttpResponse {
222
222
  */
223
223
  writeHeader(key, value) {
224
224
  if (!this._nodeRes.headersSent) {
225
- this._nodeRes.appendHeader(key, String(value));
225
+ // String() because writeHeaders hands the recurring names and values over as
226
+ // Buffers for the uWS crossing, and node's appendHeader wants strings
227
+ this._nodeRes.appendHeader(String(key), String(value));
226
228
  }
227
229
  return this;
228
230
  }
package/src/request.js CHANGED
@@ -914,9 +914,11 @@ module.exports = class Request extends LazyReadable {
914
914
  if (this.#responseEnded) {
915
915
  return;
916
916
  }
917
- // ab.slice(0) copies the ArrayBuffer; uWS neuters `ab` after this callback,
918
- // so a Buffer.from(ab) view would corrupt data left in the Readable queue.
919
- const chunk = Buffer.from(ab.slice(0));
917
+ // The bytes are copied because uWS neuters `ab` when this callback returns, and a
918
+ // view of it would corrupt whatever is still queued. Buffer.from over a view rather
919
+ // than ab.slice(0): the slice allocates an ArrayBuffer of its own for every chunk,
920
+ // which on a small body costs several times the copying it is there to do.
921
+ const chunk = Buffer.from(new Uint8Array(ab));
920
922
  const accepted = this.push(chunk);
921
923
  // push() may synchronously end the response via a flowing-mode listener.
922
924
  if (!accepted && !isLast && !this.#responseEnded) {
package/src/response.js CHANGED
@@ -83,6 +83,32 @@ const kShapeMode =
83
83
  // request are one Map hit. Insert-only after validation, bounded; only setHeader may insert,
84
84
  // the never-throwing readers keep their plain toLowerCase
85
85
  const VALIDATED_HEADER_NAMES = new Map();
86
+ // The names and values that recur on every response, kept as Buffers for the uWS crossing: a
87
+ // Buffer is memcpy'd as it is, a string pays a UTF-8 scan and copy per call. A header that is
88
+ // not here just misses the lookup and crosses as the string it was. Names must stay lowercase,
89
+ // which is how writeHeaders receives them.
90
+ const HEADER_NAME_BUF = { __proto__: null };
91
+ const HEADER_VALUE_BUF = { __proto__: null };
92
+ for (const s of ["connection", "keep-alive", "content-type", "vary", "x-powered-by", "content-encoding"]) {
93
+ HEADER_NAME_BUF[s] = Buffer.from(s);
94
+ }
95
+ for (const s of [
96
+ "keep-alive",
97
+ "timeout=10",
98
+ "close",
99
+ "Fulmine",
100
+ "Accept-Encoding",
101
+ "text/html; charset=utf-8",
102
+ "text/plain; charset=utf-8",
103
+ "application/json; charset=utf-8",
104
+ "application/octet-stream",
105
+ "gzip",
106
+ "br",
107
+ "deflate",
108
+ "zstd"
109
+ ]) {
110
+ HEADER_VALUE_BUF[s] = Buffer.from(s);
111
+ }
86
112
  const HIGH_WATERMARK = 128 * 1024;
87
113
  // the exact string json() writes, so send() can skip recomputing the charset on it
88
114
  const JSON_UTF8 = "application/json; charset=utf-8";
@@ -714,12 +740,15 @@ module.exports = class Response extends LazyWritable {
714
740
  this.totalSize = parseInt(value);
715
741
  continue;
716
742
  }
743
+ // the recurring names and values cross as cached Buffers, see HEADER_NAME_BUF; a
744
+ // miss is two failed lookups and the string goes as it came
745
+ const name = HEADER_NAME_BUF[header] || header;
717
746
  if (Array.isArray(value)) {
718
747
  for (const val of value) {
719
- res.writeHeader(header, val);
748
+ res.writeHeader(name, HEADER_VALUE_BUF[val] || val);
720
749
  }
721
750
  } else {
722
- res.writeHeader(header, value);
751
+ res.writeHeader(name, HEADER_VALUE_BUF[value] || value);
723
752
  }
724
753
  }
725
754
  this.headersSent = true;