Skip to content

Commit

Permalink
speed up url.c++ scheme and port detection
Browse files Browse the repository at this point in the history
  • Loading branch information
anonrig committed Sep 10, 2024
1 parent 1ab6829 commit cf73291
Showing 1 changed file with 31 additions and 19 deletions.
50 changes: 31 additions & 19 deletions src/workerd/api/url.c++
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,38 @@ namespace {

// Helper functions for the origin, pathname, and search getters and setters.

bool isSpecialScheme(kj::StringPtr scheme) {
// TODO(cleanup): Move this to kj::Url.
static const std::set<kj::StringPtr> specialSchemes{
"ftp", "file", "gopher", "http", "https", "ws", "wss"};
return specialSchemes.count(scheme);
}

kj::Maybe<kj::StringPtr> defaultPortForScheme(kj::StringPtr scheme) {
static const std::map<kj::StringPtr, kj::StringPtr> defaultPorts{
{"ftp", "21"},
{"gopher", "70"},
{"http", "80"},
{"https", "443"},
{"ws", "80"},
{"wss", "443"},
};
auto port = defaultPorts.find(scheme);
if (port != defaultPorts.end()) {
return port->second;
constexpr kj::StringPtr is_special_list[] = {
"http"_kj, " "_kj, "https"_kj, "ws"_kj, "ftp"_kj, "wss"_kj, "file"_kj, " "_kj};
constexpr kj::StringPtr special_ports[] = {
"80"_kj, ""_kj, "443"_kj, "80"_kj, "21"_kj, "443"_kj, ""_kj, ""_kj};

// Taken from Ada URL library.
// Ref: https://github.com/ada-url/ada/blob/b431670699cf4f3ebb2e2c394c23a89850bb6f3f/include/ada/scheme-inl.h#L49
bool isSpecialScheme(kj::StringPtr scheme) noexcept {
if (scheme.size() == 0) {
return false;
}
int hash_value = (2 * scheme.size() + (unsigned)(scheme[0])) & 7;
const auto target = is_special_list[hash_value];
return (target[0] == scheme[0]) && (target.slice(1) == scheme.slice(1));
}

// Taken from Ada URL library.
// Ref: https://github.com/ada-url/ada/blob/b431670699cf4f3ebb2e2c394c23a89850bb6f3f/include/ada/scheme-inl.h#L57
kj::Maybe<kj::StringPtr> defaultPortForScheme(kj::StringPtr scheme) noexcept {
if (scheme.size() == 0) {
return kj::none;
}
int hash_value = (2 * scheme.size() + (unsigned)(scheme[0])) & 7;
const auto target = is_special_list[hash_value];
if ((target[0] == scheme[0]) && (target.slice(1) == scheme.slice(1))) {
auto port = special_ports[hash_value];
if (port.size() == 0) {
return kj::none;
}
return port;
}

return kj::none;
}

Expand Down

0 comments on commit cf73291

Please sign in to comment.