aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-08-22 07:49:58 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-08-22 07:49:58 -0700
commit5273415ce578d27b9e65161ca1bee4016de7f641 (patch)
tree9deaa66136acca83f176654c764dcb865356e7bf
parent47a91e745781bd97b1747e2b11234244cd46b29d (diff)
downloadbun-5273415ce578d27b9e65161ca1bee4016de7f641.tar.gz
bun-5273415ce578d27b9e65161ca1bee4016de7f641.tar.zst
bun-5273415ce578d27b9e65161ca1bee4016de7f641.zip
Add some optimizations to FetchHeaders
Diffstat (limited to '')
-rw-r--r--src/bun.js/bindings/webcore/FetchHeaders.cpp14
-rw-r--r--src/bun.js/bindings/webcore/HTTPHeaderNames.h102
-rw-r--r--src/bun.js/bindings/webcore/JSFetchHeaders.cpp88
3 files changed, 188 insertions, 16 deletions
diff --git a/src/bun.js/bindings/webcore/FetchHeaders.cpp b/src/bun.js/bindings/webcore/FetchHeaders.cpp
index d4ecba216..e852a74d1 100644
--- a/src/bun.js/bindings/webcore/FetchHeaders.cpp
+++ b/src/bun.js/bindings/webcore/FetchHeaders.cpp
@@ -76,20 +76,6 @@ static ExceptionOr<void> appendToHeaderMap(const String& name, const String& val
return {};
}
-static void appendToHeaderMapFast(const String& name, const String& value, HTTPHeaderMap& headers, FetchHeaders::Guard guard)
-{
- String combinedValue;
- if (headers.contains(name)) {
- combinedValue = makeString(headers.get(name), ", ", value);
- } else {
- combinedValue = value.isolatedCopy();
- }
-
- headers.append(name.isolatedCopy(), WTFMove(combinedValue));
- // if (guard == FetchHeaders::Guard::RequestNoCors)
- // removePrivilegedNoCORSRequestHeaders(headers);
-}
-
static ExceptionOr<void> appendToHeaderMap(const HTTPHeaderMap::HTTPHeaderMapConstIterator::KeyValue& header, HTTPHeaderMap& headers, FetchHeaders::Guard guard)
{
String normalizedValue = stripLeadingAndTrailingHTTPSpaces(header.value);
diff --git a/src/bun.js/bindings/webcore/HTTPHeaderNames.h b/src/bun.js/bindings/webcore/HTTPHeaderNames.h
index 92dff5c19..246afeefa 100644
--- a/src/bun.js/bindings/webcore/HTTPHeaderNames.h
+++ b/src/bun.js/bindings/webcore/HTTPHeaderNames.h
@@ -238,6 +238,108 @@ template<> struct EnumTraits<WebCore::HTTPHeaderName> {
WebCore::HTTPHeaderName::XXSSProtection>;
};
+static StaticStringImpl* staticHeaderNames[] = {
+ MAKE_STATIC_STRING_IMPL("accept"),
+ MAKE_STATIC_STRING_IMPL("accept-charset"),
+ MAKE_STATIC_STRING_IMPL("accept-encoding"),
+ MAKE_STATIC_STRING_IMPL("accept-language"),
+ MAKE_STATIC_STRING_IMPL("accept-ranges"),
+ MAKE_STATIC_STRING_IMPL("access-control-allow-credentials"),
+ MAKE_STATIC_STRING_IMPL("access-control-allow-headers"),
+ MAKE_STATIC_STRING_IMPL("access-control-allow-methods"),
+ MAKE_STATIC_STRING_IMPL("access-control-allow-origin"),
+ MAKE_STATIC_STRING_IMPL("access-control-expose-headers"),
+ MAKE_STATIC_STRING_IMPL("access-control-max-age"),
+ MAKE_STATIC_STRING_IMPL("access-control-request-headers"),
+ MAKE_STATIC_STRING_IMPL("access-control-request-method"),
+ MAKE_STATIC_STRING_IMPL("age"),
+ MAKE_STATIC_STRING_IMPL("authorization"),
+ MAKE_STATIC_STRING_IMPL("cache-control"),
+ MAKE_STATIC_STRING_IMPL("connection"),
+ MAKE_STATIC_STRING_IMPL("content-disposition"),
+ MAKE_STATIC_STRING_IMPL("content-encoding"),
+ MAKE_STATIC_STRING_IMPL("content-language"),
+ MAKE_STATIC_STRING_IMPL("content-length"),
+ MAKE_STATIC_STRING_IMPL("content-location"),
+ MAKE_STATIC_STRING_IMPL("content-range"),
+ MAKE_STATIC_STRING_IMPL("content-security-policy"),
+ MAKE_STATIC_STRING_IMPL("content-security-policy-report-only"),
+ MAKE_STATIC_STRING_IMPL("content-type"),
+ MAKE_STATIC_STRING_IMPL("cookie"),
+ MAKE_STATIC_STRING_IMPL("cookie2"),
+ MAKE_STATIC_STRING_IMPL("cross-origin-embedder-policy"),
+ MAKE_STATIC_STRING_IMPL("cross-origin-embedder-policy-report-only"),
+ MAKE_STATIC_STRING_IMPL("cross-origin-opener-policy"),
+ MAKE_STATIC_STRING_IMPL("cross-origin-opener-policy-report-only"),
+ MAKE_STATIC_STRING_IMPL("cross-origin-resource-policy"),
+ MAKE_STATIC_STRING_IMPL("dnt"),
+ MAKE_STATIC_STRING_IMPL("date"),
+ MAKE_STATIC_STRING_IMPL("default-style"),
+ MAKE_STATIC_STRING_IMPL("etag"),
+ MAKE_STATIC_STRING_IMPL("expect"),
+ MAKE_STATIC_STRING_IMPL("expires"),
+ MAKE_STATIC_STRING_IMPL("host"),
+ MAKE_STATIC_STRING_IMPL("icy-metaint"),
+ MAKE_STATIC_STRING_IMPL("icy-metadata"),
+ MAKE_STATIC_STRING_IMPL("if-match"),
+ MAKE_STATIC_STRING_IMPL("if-modified-since"),
+ MAKE_STATIC_STRING_IMPL("if-none-match"),
+ MAKE_STATIC_STRING_IMPL("if-range"),
+ MAKE_STATIC_STRING_IMPL("if-unmodified-since"),
+ MAKE_STATIC_STRING_IMPL("keep-alive"),
+ MAKE_STATIC_STRING_IMPL("last-event-id"),
+ MAKE_STATIC_STRING_IMPL("last-modified"),
+ MAKE_STATIC_STRING_IMPL("link"),
+ MAKE_STATIC_STRING_IMPL("location"),
+ MAKE_STATIC_STRING_IMPL("origin"),
+ MAKE_STATIC_STRING_IMPL("ping-from"),
+ MAKE_STATIC_STRING_IMPL("ping-to"),
+ MAKE_STATIC_STRING_IMPL("pragma"),
+ MAKE_STATIC_STRING_IMPL("proxy-authorization"),
+ MAKE_STATIC_STRING_IMPL("purpose"),
+ MAKE_STATIC_STRING_IMPL("range"),
+ MAKE_STATIC_STRING_IMPL("referer"),
+ MAKE_STATIC_STRING_IMPL("referrer-policy"),
+ MAKE_STATIC_STRING_IMPL("refresh"),
+ MAKE_STATIC_STRING_IMPL("report-to"),
+ MAKE_STATIC_STRING_IMPL("sec-fetch-dest"),
+ MAKE_STATIC_STRING_IMPL("sec-fetch-mode"),
+ MAKE_STATIC_STRING_IMPL("sec-websocket-accept"),
+ MAKE_STATIC_STRING_IMPL("sec-websocket-extensions"),
+ MAKE_STATIC_STRING_IMPL("sec-websocket-key"),
+ MAKE_STATIC_STRING_IMPL("sec-websocket-protocol"),
+ MAKE_STATIC_STRING_IMPL("sec-websocket-version"),
+ MAKE_STATIC_STRING_IMPL("server-timing"),
+ MAKE_STATIC_STRING_IMPL("service-worker"),
+ MAKE_STATIC_STRING_IMPL("service-worker-allowed"),
+ MAKE_STATIC_STRING_IMPL("service-worker-navigation-preload"),
+ MAKE_STATIC_STRING_IMPL("set-cookie"),
+ MAKE_STATIC_STRING_IMPL("set-cookie2"),
+ MAKE_STATIC_STRING_IMPL("sourcemap"),
+ MAKE_STATIC_STRING_IMPL("strict-transport-security"),
+ MAKE_STATIC_STRING_IMPL("te"),
+ MAKE_STATIC_STRING_IMPL("timing-allow-origin"),
+ MAKE_STATIC_STRING_IMPL("trailer"),
+ MAKE_STATIC_STRING_IMPL("transfer-encoding"),
+ MAKE_STATIC_STRING_IMPL("upgrade"),
+ MAKE_STATIC_STRING_IMPL("upgrade-insecure-requests"),
+ MAKE_STATIC_STRING_IMPL("user-agent"),
+ MAKE_STATIC_STRING_IMPL("vary"),
+ MAKE_STATIC_STRING_IMPL("via"),
+ MAKE_STATIC_STRING_IMPL("x-content-type-options"),
+ MAKE_STATIC_STRING_IMPL("x-dns-prefetch-control"),
+ MAKE_STATIC_STRING_IMPL("x-frame-options"),
+ MAKE_STATIC_STRING_IMPL("x-sourcemap"),
+ MAKE_STATIC_STRING_IMPL("x-temp-tablet"),
+ MAKE_STATIC_STRING_IMPL("x-xss-protection"),
+};
+
+static WTF::StaticStringImpl* httpHeaderNameStringImpl(WebCore::HTTPHeaderName headerName) {
+ return staticHeaderNames[static_cast<size_t>(headerName)];
+}
+
+
} // namespace WTF
+
#endif // HTTPHeaderNames_h
diff --git a/src/bun.js/bindings/webcore/JSFetchHeaders.cpp b/src/bun.js/bindings/webcore/JSFetchHeaders.cpp
index 8ea72b567..ef9474a1b 100644
--- a/src/bun.js/bindings/webcore/JSFetchHeaders.cpp
+++ b/src/bun.js/bindings/webcore/JSFetchHeaders.cpp
@@ -71,6 +71,10 @@ static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_keys);
static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_values);
static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_forEach);
+// Non-standard functions
+static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_toJSON);
+static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_size);
+
// Attributes
static JSC_DECLARE_CUSTOM_GETTER(jsFetchHeadersConstructor);
@@ -116,7 +120,21 @@ template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSFetchHeadersDOMConstructor:
auto* castedThis = jsCast<JSFetchHeadersDOMConstructor*>(callFrame->jsCallee());
ASSERT(castedThis);
EnsureStillAliveScope argument0 = callFrame->argument(0);
- auto init = argument0.value().isUndefined() ? std::optional<Converter<IDLUnion<IDLSequence<IDLSequence<IDLByteString>>, IDLRecord<IDLByteString, IDLByteString>>>::ReturnType>() : std::optional<Converter<IDLUnion<IDLSequence<IDLSequence<IDLByteString>>, IDLRecord<IDLByteString, IDLByteString>>>::ReturnType>(convert<IDLUnion<IDLSequence<IDLSequence<IDLByteString>>, IDLRecord<IDLByteString, IDLByteString>>>(*lexicalGlobalObject, argument0.value()));
+
+ auto init = std::optional<Converter<IDLUnion<IDLSequence<IDLSequence<IDLByteString>>, IDLRecord<IDLByteString, IDLByteString>>>::ReturnType>();
+
+ if (argument0.value() && !argument0.value().isUndefined()) {
+ if (auto* existingJsFetchHeaders = jsDynamicCast<JSFetchHeaders*>(argument0.value())) {
+ auto newHeaders = FetchHeaders::create(existingJsFetchHeaders->wrapped());
+ auto jsValue = toJSNewlyCreated<IDLInterface<FetchHeaders>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(newHeaders));
+ if constexpr (IsExceptionOr<decltype(jsValue)>)
+ RETURN_IF_EXCEPTION(throwScope, {});
+ setSubclassStructureIfNeeded<FetchHeaders>(lexicalGlobalObject, callFrame, asObject(jsValue));
+ RETURN_IF_EXCEPTION(throwScope, {});
+ }
+ init = std::optional<Converter<IDLUnion<IDLSequence<IDLSequence<IDLByteString>>, IDLRecord<IDLByteString, IDLByteString>>>::ReturnType>(convert<IDLUnion<IDLSequence<IDLSequence<IDLByteString>>, IDLRecord<IDLByteString, IDLByteString>>>(*lexicalGlobalObject, argument0.value()));
+ }
+
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
auto object = FetchHeaders::create(WTFMove(init));
if constexpr (IsExceptionOr<decltype(object)>)
@@ -161,6 +179,8 @@ static const HashTableValue JSFetchHeadersPrototypeTableValues[] = {
{ "keys"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsFetchHeadersPrototypeFunction_keys), (intptr_t)(0) } },
{ "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) } },
};
const ClassInfo JSFetchHeadersPrototype::s_info = { "Headers"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSFetchHeadersPrototype) };
@@ -237,6 +257,71 @@ static inline JSC::EncodedJSValue jsFetchHeadersPrototypeFunction_appendBody(JSC
RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.append(WTFMove(name), WTFMove(value)); })));
}
+/**
+ * Non standard function.
+ **/
+static inline JSC::EncodedJSValue jsFetchHeadersPrototypeFunction_toJSONBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSFetchHeaders>::ClassParameter castedThis)
+{
+ auto& vm = JSC::getVM(lexicalGlobalObject);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ auto& impl = castedThis->wrapped();
+ size_t size = impl.size();
+ JSObject* obj;
+ if (size == 0) {
+ obj = constructEmptyObject(lexicalGlobalObject);
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(obj));
+ } else if (size < 64) {
+ obj = constructEmptyObject(lexicalGlobalObject, lexicalGlobalObject->objectPrototype(), size);
+ } else {
+ obj = constructEmptyObject(lexicalGlobalObject);
+ }
+
+ auto& internal = impl.internalHeaders();
+ {
+ auto& vec = internal.commonHeaders();
+ for (auto it = vec.begin(); it != vec.end(); ++it) {
+ auto& name = it->key;
+ auto& value = it->value;
+ obj->putDirect(vm, Identifier::fromString(vm, String(WTF::httpHeaderNameStringImpl(name))), jsString(vm, value), 0);
+ }
+ }
+
+ {
+ auto& vec = internal.uncommonHeaders();
+ for (auto it = vec.begin(); it != vec.end(); ++it) {
+ auto& name = it->key;
+ auto& value = it->value;
+ obj->putDirect(vm, Identifier::fromString(vm, name), jsString(vm, value), 0);
+ }
+ }
+
+ RELEASE_AND_RETURN(throwScope, JSValue::encode(obj));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_toJSON, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
+{
+ 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");
@@ -498,5 +583,4 @@ FetchHeaders* JSFetchHeaders::toWrapped(JSC::VM& vm, JSC::JSValue value)
return &wrapper->wrapped();
return nullptr;
}
-
}