Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 153 additions & 37 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9997,6 +9997,9 @@ var require_form_data = __commonJS({
var setToStringTag = require_es_set_tostringtag();
var hasOwn = require_hasown();
var populate = require_populate();
function escapeHeaderParam(str) {
return String(str).replace(/\r/g, "%0D").replace(/\n/g, "%0A").replace(/"/g, "%22");
}
function FormData3(options) {
if (!(this instanceof FormData3)) {
return new FormData3(options);
Expand Down Expand Up @@ -10086,7 +10089,7 @@ var require_form_data = __commonJS({
var contents = "";
var headers = {
// add custom disposition as third element or keep it two elements if not
"Content-Disposition": ["form-data", 'name="' + field + '"'].concat(contentDisposition || []),
"Content-Disposition": ["form-data", 'name="' + escapeHeaderParam(field) + '"'].concat(contentDisposition || []),
// if no content type. allow it to be empty array
"Content-Type": [].concat(contentType || [])
};
Expand Down Expand Up @@ -10120,7 +10123,7 @@ var require_form_data = __commonJS({
filename = path.basename(value.client._httpMessage.path || "");
}
if (filename) {
return 'filename="' + filename + '"';
return 'filename="' + escapeHeaderParam(filename) + '"';
}
};
FormData3.prototype._getContentType = function(value, options) {
Expand Down Expand Up @@ -13505,6 +13508,7 @@ var require_dispatcher_base = __commonJS({
}
get webSocketOptions() {
return {
maxFragments: this[kWebSocketOptions].maxFragments ?? 131072,
maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024
};
}
Expand Down Expand Up @@ -17159,6 +17163,9 @@ var require_client_h1 = __commonJS({
var FastBuffer = Buffer[Symbol.species];
var addListener = util3.addListener;
var removeAllListeners = util3.removeAllListeners;
var kIdleSocketValidation = Symbol("kIdleSocketValidation");
var kIdleSocketValidationTimeout = Symbol("kIdleSocketValidationTimeout");
var kSocketUsed = Symbol("kSocketUsed");
var extractBody;
async function lazyllhttp() {
const llhttpWasmData = process.env.JEST_WORKER_ID ? require_llhttp_wasm() : void 0;
Expand Down Expand Up @@ -17321,24 +17328,55 @@ var require_client_h1 = __commonJS({
currentBufferRef = null;
}
const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr;
if (ret === constants3.ERROR.PAUSED_UPGRADE) {
this.onUpgrade(data.slice(offset));
} else if (ret === constants3.ERROR.PAUSED) {
this.paused = true;
socket.unshift(data.slice(offset));
} else if (ret !== constants3.ERROR.OK) {
const ptr = llhttp.llhttp_get_error_reason(this.ptr);
let message = "";
if (ptr) {
const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0);
message = "Response does not match the HTTP/1.1 protocol (" + Buffer.from(llhttp.memory.buffer, ptr, len).toString() + ")";
if (ret !== constants3.ERROR.OK) {
const body = data.subarray(offset);
if (ret === constants3.ERROR.PAUSED_UPGRADE) {
this.onUpgrade(body);
} else if (ret === constants3.ERROR.PAUSED) {
this.paused = true;
socket.unshift(body);
} else {
throw this.createError(ret, body);
}
throw new HTTPParserError(message, constants3.ERROR[ret], data.slice(offset));
}
} catch (err) {
util3.destroy(socket, err);
}
}
finish() {
assert(currentParser === null);
assert(this.ptr != null);
assert(!this.paused);
const { llhttp } = this;
let ret;
try {
currentParser = this;
ret = llhttp.llhttp_finish(this.ptr);
} finally {
currentParser = null;
}
if (ret === constants3.ERROR.OK) {
return null;
}
if (ret === constants3.ERROR.PAUSED || ret === constants3.ERROR.PAUSED_UPGRADE) {
this.paused = true;
return null;
}
return this.createError(ret, EMPTY_BUF);
}
createError(ret, data) {
const { llhttp, contentLength, bytesRead } = this;
if (contentLength && bytesRead !== parseInt(contentLength, 10)) {
return new ResponseContentLengthMismatchError();
}
const ptr = llhttp.llhttp_get_error_reason(this.ptr);
let message = "";
if (ptr) {
const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0);
message = "Response does not match the HTTP/1.1 protocol (" + Buffer.from(llhttp.memory.buffer, ptr, len).toString() + ")";
}
return new HTTPParserError(message, constants3.ERROR[ret], data);
}
destroy() {
assert(this.ptr != null);
assert(currentParser == null);
Expand All @@ -17358,6 +17396,10 @@ var require_client_h1 = __commonJS({
if (socket.destroyed) {
return -1;
}
if (client[kRunning] === 0) {
util3.destroy(socket, new SocketError("bad response", util3.getSocketInfo(socket)));
return -1;
}
const request2 = client[kQueue][client[kRunningIdx]];
if (!request2) {
return -1;
Expand Down Expand Up @@ -17437,6 +17479,10 @@ var require_client_h1 = __commonJS({
if (socket.destroyed) {
return -1;
}
if (client[kRunning] === 0) {
util3.destroy(socket, new SocketError("bad response", util3.getSocketInfo(socket)));
return -1;
}
const request2 = client[kQueue][client[kRunningIdx]];
if (!request2) {
return -1;
Expand Down Expand Up @@ -17562,6 +17608,7 @@ var require_client_h1 = __commonJS({
}
request2.onComplete(headers);
client[kQueue][client[kRunningIdx]++] = null;
socket[kSocketUsed] = true;
if (socket[kWriting]) {
assert(client[kRunning] === 0);
util3.destroy(socket, new InformationalError("reset"));
Expand Down Expand Up @@ -17605,12 +17652,19 @@ var require_client_h1 = __commonJS({
socket[kWriting] = false;
socket[kReset] = false;
socket[kBlocking] = false;
socket[kIdleSocketValidation] = 0;
socket[kIdleSocketValidationTimeout] = null;
socket[kSocketUsed] = false;
socket[kParser] = new Parser(client, socket, llhttpInstance);
addListener(socket, "error", function(err) {
assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID");
const parser = this[kParser];
if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) {
parser.onMessageComplete();
const parserErr = parser.finish();
if (parserErr) {
this[kError] = parserErr;
this[kClient][kOnError](parserErr);
}
return;
}
this[kError] = err;
Expand All @@ -17625,17 +17679,21 @@ var require_client_h1 = __commonJS({
addListener(socket, "end", function() {
const parser = this[kParser];
if (parser.statusCode && !parser.shouldKeepAlive) {
parser.onMessageComplete();
const parserErr = parser.finish();
if (parserErr) {
util3.destroy(this, parserErr);
}
return;
}
util3.destroy(this, new SocketError("other side closed", util3.getSocketInfo(this)));
});
addListener(socket, "close", function() {
const client2 = this[kClient];
const parser = this[kParser];
clearIdleSocketValidation(this);
if (parser) {
if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) {
parser.onMessageComplete();
this[kError] = parser.finish() || this[kError];
}
this[kParser].destroy();
this[kParser] = null;
Expand Down Expand Up @@ -17684,7 +17742,7 @@ var require_client_h1 = __commonJS({
return socket.destroyed;
},
busy(request2) {
if (socket[kWriting] || socket[kReset] || socket[kBlocking]) {
if (socket[kWriting] || socket[kReset] || socket[kBlocking] || socket[kIdleSocketValidation] === 1) {
return true;
}
if (request2) {
Expand All @@ -17702,6 +17760,24 @@ var require_client_h1 = __commonJS({
}
};
}
function clearIdleSocketValidation(socket) {
if (socket[kIdleSocketValidationTimeout]) {
clearTimeout(socket[kIdleSocketValidationTimeout]);
socket[kIdleSocketValidationTimeout] = null;
}
socket[kIdleSocketValidation] = 0;
}
function scheduleIdleSocketValidation(client, socket) {
socket[kIdleSocketValidation] = 1;
socket[kIdleSocketValidationTimeout] = setTimeout(() => {
socket[kIdleSocketValidationTimeout] = null;
socket[kIdleSocketValidation] = 2;
if (client[kSocket] === socket && !socket.destroyed) {
client[kResume]();
}
}, 0);
socket[kIdleSocketValidationTimeout].unref?.();
}
function resumeH1(client) {
const socket = client[kSocket];
if (socket && !socket.destroyed) {
Expand All @@ -17714,6 +17790,29 @@ var require_client_h1 = __commonJS({
socket.ref();
socket[kNoRef] = false;
}
if (client[kRunning] === 0 && client[kPending] > 0 && socket[kSocketUsed]) {
if (socket[kIdleSocketValidation] === 0) {
scheduleIdleSocketValidation(client, socket);
socket[kParser].readMore();
if (socket.destroyed) {
return;
}
return;
}
if (socket[kIdleSocketValidation] === 1) {
socket[kParser].readMore();
if (socket.destroyed) {
return;
}
return;
}
}
if (client[kRunning] === 0) {
socket[kParser].readMore();
if (socket.destroyed) {
return;
}
}
if (client[kSize] === 0) {
if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) {
socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE);
Expand Down Expand Up @@ -17766,6 +17865,7 @@ var require_client_h1 = __commonJS({
process.emitWarning(new RequestContentLengthMismatchError());
}
const socket = client[kSocket];
clearIdleSocketValidation(socket);
const abort = (err) => {
if (request2.aborted || request2.completed) {
return;
Expand Down Expand Up @@ -27550,18 +27650,14 @@ var require_parse = __commonJS({
} else if (attributeNameLowercase === "httponly") {
cookieAttributeList.httpOnly = true;
} else if (attributeNameLowercase === "samesite") {
let enforcement = "Default";
const attributeValueLowercase = attributeValue.toLowerCase();
if (attributeValueLowercase.includes("none")) {
enforcement = "None";
}
if (attributeValueLowercase.includes("strict")) {
enforcement = "Strict";
}
if (attributeValueLowercase.includes("lax")) {
enforcement = "Lax";
if (attributeValueLowercase === "none") {
cookieAttributeList.sameSite = "None";
} else if (attributeValueLowercase === "strict") {
cookieAttributeList.sameSite = "Strict";
} else if (attributeValueLowercase === "lax") {
cookieAttributeList.sameSite = "Lax";
}
cookieAttributeList.sameSite = enforcement;
} else {
cookieAttributeList.unparsed ??= [];
cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`);
Expand Down Expand Up @@ -28583,6 +28679,10 @@ var require_receiver = __commonJS({
var { closeWebSocketConnection } = require_connection();
var { PerMessageDeflate } = require_permessage_deflate();
var { MessageSizeExceededError } = require_errors();
function failWebsocketConnectionWithCode(ws, code, reason) {
closeWebSocketConnection(ws, code, reason, Buffer.byteLength(reason));
failWebsocketConnection(ws, reason);
}
var ByteParser = class extends Writable {
#buffers = [];
#fragmentsBytes = 0;
Expand All @@ -28594,16 +28694,19 @@ var require_receiver = __commonJS({
/** @type {Map<string, PerMessageDeflate>} */
#extensions;
/** @type {number} */
#maxFragments;
/** @type {number} */
#maxPayloadSize;
/**
* @param {import('./websocket').WebSocket} ws
* @param {Map<string, string>|null} extensions
* @param {{ maxPayloadSize?: number }} [options]
* @param {{ maxFragments?: number, maxPayloadSize?: number }} [options]
*/
constructor(ws, extensions, options = {}) {
super();
this.ws = ws;
this.#extensions = extensions == null ? /* @__PURE__ */ new Map() : extensions;
this.#maxFragments = options.maxFragments ?? 0;
this.#maxPayloadSize = options.maxPayloadSize ?? 0;
if (this.#extensions.has("permessage-deflate")) {
this.#extensions.set("permessage-deflate", new PerMessageDeflate(extensions, options));
Expand All @@ -28620,8 +28723,8 @@ var require_receiver = __commonJS({
this.run(callback);
}
#validatePayloadLength() {
if (this.#maxPayloadSize > 0 && !isControlFrame(this.#info.opcode) && this.#info.payloadLength > this.#maxPayloadSize) {
failWebsocketConnection(this.ws, "Payload size exceeds maximum allowed size");
if (this.#maxPayloadSize > 0 && !isControlFrame(this.#info.opcode) && this.#info.payloadLength + this.#fragmentsBytes > this.#maxPayloadSize) {
failWebsocketConnectionWithCode(this.ws, 1009, "Payload size exceeds maximum allowed size");
return false;
}
return true;
Expand Down Expand Up @@ -28737,9 +28840,11 @@ var require_receiver = __commonJS({
this.#state = parserStates.INFO;
} else {
if (!this.#info.compressed) {
this.writeFragments(body);
if (!this.writeFragments(body)) {
return;
}
if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
failWebsocketConnection(this.ws, new MessageSizeExceededError().message);
failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message);
return;
}
if (!this.#info.fragmented && this.#info.fin) {
Expand All @@ -28752,12 +28857,15 @@ var require_receiver = __commonJS({
this.#info.fin,
(error2, data) => {
if (error2) {
failWebsocketConnection(this.ws, error2.message);
const code = error2 instanceof MessageSizeExceededError ? 1009 : 1007;
failWebsocketConnectionWithCode(this.ws, code, error2.message);
return;
}
if (!this.writeFragments(data)) {
return;
}
this.writeFragments(data);
if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
failWebsocketConnection(this.ws, new MessageSizeExceededError().message);
failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message);
return;
}
if (!this.#info.fin) {
Expand Down Expand Up @@ -28815,8 +28923,13 @@ var require_receiver = __commonJS({
return buffer;
}
writeFragments(fragment) {
if (this.#maxFragments > 0 && this.#fragments.length === this.#maxFragments) {
failWebsocketConnectionWithCode(this.ws, 1008, "Too many message fragments");
return false;
}
this.#fragmentsBytes += fragment.length;
this.#fragments.push(fragment);
return true;
}
consumeFragments() {
const fragments = this.#fragments;
Expand Down Expand Up @@ -29266,8 +29379,11 @@ var require_websocket = __commonJS({
*/
#onConnectionEstablished(response, parsedExtensions) {
this[kResponse] = response;
const maxPayloadSize = this[kController]?.dispatcher?.webSocketOptions?.maxPayloadSize;
const webSocketOptions = this[kController]?.dispatcher?.webSocketOptions;
const maxFragments = webSocketOptions?.maxFragments;
const maxPayloadSize = webSocketOptions?.maxPayloadSize;
const parser = new ByteParser(this, parsedExtensions, {
maxFragments,
maxPayloadSize
});
parser.on("drain", onParserDrain);
Expand Down
Loading
Loading