aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-08-22 09:51:33 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-08-22 09:51:33 -0700
commit633bef7ef11ff204fba4afd06cde1b532be3d591 (patch)
tree4f878b9774504327d535cad0f46e493aeea522ba /src/bun.js
parentfcd09abec6d4b0ff4560e847644674afb02ee248 (diff)
downloadbun-633bef7ef11ff204fba4afd06cde1b532be3d591.tar.gz
bun-633bef7ef11ff204fba4afd06cde1b532be3d591.tar.zst
bun-633bef7ef11ff204fba4afd06cde1b532be3d591.zip
[node:http] speed up assigning headers
Diffstat (limited to 'src/bun.js')
-rw-r--r--src/bun.js/bindings/webcore/JSFetchHeaders.cpp34
-rw-r--r--src/bun.js/http.exports.js96
-rw-r--r--src/bun.js/webcore/streams.zig3
3 files changed, 58 insertions, 75 deletions
diff --git a/src/bun.js/bindings/webcore/JSFetchHeaders.cpp b/src/bun.js/bindings/webcore/JSFetchHeaders.cpp
index ef9474a1b..78ba9f2fc 100644
--- a/src/bun.js/bindings/webcore/JSFetchHeaders.cpp
+++ b/src/bun.js/bindings/webcore/JSFetchHeaders.cpp
@@ -73,7 +73,7 @@ static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_forEach);
// Non-standard functions
static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_toJSON);
-static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_size);
+static JSC_DECLARE_CUSTOM_GETTER(jsFetchHeadersPrototypeFunction_size);
// Attributes
@@ -166,6 +166,19 @@ template<> void JSFetchHeadersDOMConstructor::initializeProperties(VM& vm, JSDOM
putDirect(vm, vm.propertyNames->prototype, JSFetchHeaders::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete);
}
+/**
+ * Non standard function.
+ **/
+JSC_DEFINE_CUSTOM_GETTER(jsFetchHeadersGetterCount, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
+{
+ auto& vm = JSC::getVM(globalObject);
+ JSFetchHeaders* castedThis = jsCast<JSFetchHeaders*>(JSValue::decode(thisValue));
+
+ auto& impl = castedThis->wrapped();
+ auto count = impl.size();
+ return JSValue::encode(jsNumber(count));
+}
+
/* Hash table for prototype */
static const HashTableValue JSFetchHeadersPrototypeTableValues[] = {
@@ -180,7 +193,7 @@ static const HashTableValue JSFetchHeadersPrototypeTableValues[] = {
{ "values"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsFetchHeadersPrototypeFunction_values), (intptr_t)(0) } },
{ "forEach"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsFetchHeadersPrototypeFunction_forEach), (intptr_t)(1) } },
{ "toJSON"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsFetchHeadersPrototypeFunction_toJSON), (intptr_t)(0) } },
- { "size"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsFetchHeadersPrototypeFunction_size), (intptr_t)(0) } },
+ { "count"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsFetchHeadersGetterCount), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
};
const ClassInfo JSFetchHeadersPrototype::s_info = { "Headers"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSFetchHeadersPrototype) };
@@ -305,23 +318,6 @@ JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_toJSON, (JSGlobalObject
return IDLOperation<JSFetchHeaders>::call<jsFetchHeadersPrototypeFunction_toJSONBody>(*lexicalGlobalObject, *callFrame, "toJSON");
}
-/**
- * Non standard function.
- **/
-static inline JSC::EncodedJSValue jsFetchHeadersPrototypeFunction_sizeBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSFetchHeaders>::ClassParameter castedThis)
-{
- auto& vm = JSC::getVM(lexicalGlobalObject);
-
- auto& impl = castedThis->wrapped();
- auto size = impl.size();
- return JSValue::encode(jsNumber(size));
-}
-
-JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_size, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
-{
- return IDLOperation<JSFetchHeaders>::call<jsFetchHeadersPrototypeFunction_sizeBody>(*lexicalGlobalObject, *callFrame, "size");
-}
-
JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_append, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
{
return IDLOperation<JSFetchHeaders>::call<jsFetchHeadersPrototypeFunction_appendBody>(*lexicalGlobalObject, *callFrame, "append");
diff --git a/src/bun.js/http.exports.js b/src/bun.js/http.exports.js
index cbaf937b7..01fdab696 100644
--- a/src/bun.js/http.exports.js
+++ b/src/bun.js/http.exports.js
@@ -91,6 +91,18 @@ export class Server extends EventEmitter {
}
}
+function assignHeaders(object, req) {
+ var headers = req.headers.toJSON();
+ const rawHeaders = new Array(req.headers.count * 2);
+ var i = 0;
+ for (const key in headers) {
+ rawHeaders[i++] = key;
+ rawHeaders[i++] = headers[key];
+ }
+ object.headers = headers;
+ object.rawHeaders = rawHeaders;
+}
+
export class IncomingMessage extends Readable {
constructor(req) {
const method = req.method;
@@ -116,62 +128,35 @@ export class IncomingMessage extends Readable {
this._socket = undefined;
this.url = url.pathname;
- this.#inputRequest = req;
+ assignHeaders(this, req);
}
- #inputRequest;
- #headers;
- #rawHeaders;
+
+ headers;
+ rawHeaders;
_consuming = false;
_dumped = false;
-
- #constructHeaders() {
- const rawHeaders = [];
- const headers = Object.create(null);
- var req = this.#inputRequest;
- this.#inputRequest = undefined;
- for (const [key, value] of req.headers.entries()) {
- headers[key] = value;
- rawHeaders.push(key, value);
- }
- this.#headers = headers;
- this.#rawHeaders = rawHeaders;
- }
-
- get headers() {
- var _headers = this.#headers;
- if (_headers) return _headers;
- this.#constructHeaders();
- return this.#headers;
- }
-
- set headers(val) {
- this.#headers = val;
- return true;
- }
-
- get rawHeaders() {
- var _rawHeaders = this.#rawHeaders;
- if (_rawHeaders) return _rawHeaders;
- this.#constructHeaders();
- return this.#rawHeaders;
- }
-
- set rawHeaders(val) {
- this.#rawHeaders = val;
- return true;
- }
+ _body;
+ _body_offset;
+ _socket;
+ _no_body;
+ _req;
+ url;
_construct(callback) {
// TODO: streaming
+ if (this._no_body) {
+ callback();
+ return;
+ }
+
(async () => {
- if (!this._no_body)
- try {
- this._body = Buffer.from(await this._req.arrayBuffer());
+ try {
+ this._body = Buffer.from(await this._req.arrayBuffer());
- callback();
- } catch (err) {
- callback(err);
- }
+ callback();
+ } catch (err) {
+ callback(err);
+ }
})();
}
@@ -254,7 +239,7 @@ export class ServerResponse extends Writable {
this._reply = reply;
this.sendDate = true;
this.statusCode = 200;
- this.#headers = undefined;
+ this.#headers = new Headers();
this.headersSent = false;
this.statusMessage = undefined;
this.#controller = undefined;
@@ -290,6 +275,7 @@ export class ServerResponse extends Writable {
}
_writev(chunks, callback) {
+ console.trace("typeof chunk " + chunks[0].chunk);
if (chunks.length === 1 && !this.headersSent && !this.#firstWrite) {
this.#firstWrite = chunks[0].chunk;
callback();
@@ -411,27 +397,27 @@ export class ServerResponse extends Writable {
flushHeaders() {}
removeHeader(name) {
- var headers = (this.#headers ||= new Headers());
+ var headers = this.#headers;
headers.delete(name);
}
getHeader(name) {
- var headers = (this.#headers ||= new Headers());
+ var headers = this.#headers;
return headers.get(name);
}
hasHeader(name) {
- var headers = (this.#headers ||= new Headers());
+ var headers = this.#headers;
return headers.has(name);
}
getHeaderNames() {
- var headers = (this.#headers ||= new Headers());
+ var headers = this.#headers;
return Array.from(headers.keys());
}
setHeader(name, value) {
- var headers = (this.#headers ||= new Headers());
+ var headers = this.#headers;
headers.set(name, value);
@@ -446,7 +432,7 @@ export class ServerResponse extends Writable {
getHeaders() {
if (!this.#headers) return {};
- return Object.fromEntries(this.#headers.entries());
+ return this.#headers.toJSON();
}
}
diff --git a/src/bun.js/webcore/streams.zig b/src/bun.js/webcore/streams.zig
index 7851f93fe..32e6d9f19 100644
--- a/src/bun.js/webcore/streams.zig
+++ b/src/bun.js/webcore/streams.zig
@@ -1460,7 +1460,7 @@ pub fn HTTPServerWritable(comptime ssl: bool) type {
std.debug.assert(!this.done);
const success = if (!this.requested_end) this.res.write(buf) else this.res.tryEnd(buf, this.end_len);
this.has_backpressure = !success;
- log("send: {d} bytes ({d})", .{ buf.len, this.has_backpressure });
+ log("send: {d} bytes (backpressure: {d})", .{ buf.len, this.has_backpressure });
return success;
}
@@ -1681,6 +1681,7 @@ pub fn HTTPServerWritable(comptime ssl: bool) type {
this.res.onWritable(*@This(), onWritable, this);
} else {
+ log("has backpressure", .{});
_ = this.buffer.write(this.allocator, bytes) catch {
return .{ .err = Syscall.Error.fromCode(.NOMEM, .write) };
};