From 7c3f6d69f58ff746d690c676d740c3f7449a555b Mon Sep 17 00:00:00 2001 From: jwerle Date: Wed, 8 Jan 2025 22:05:55 -0500 Subject: [PATCH] refactor(runtime/{serviceworker,core,ipc,http}): introduce SW priorities, improve conduit, clean up --- src/runtime/bridge/bridge.cc | 15 +--- src/runtime/bytes.hh | 6 +- src/runtime/bytes/buffer.cc | 33 ++++++- src/runtime/core/services/ai.cc | 2 +- src/runtime/core/services/conduit.cc | 102 +++++++++++++--------- src/runtime/core/services/conduit.hh | 20 +++-- src/runtime/crypto/sha1.cc | 1 - src/runtime/http/headers.cc | 4 +- src/runtime/http/request.cc | 72 ++++++++++++--- src/runtime/http/response.cc | 2 +- src/runtime/ipc/router.cc | 2 +- src/runtime/ipc/routes.cc | 42 +++++++-- src/runtime/platform/system.hh | 5 ++ src/runtime/serviceworker.hh | 7 ++ src/runtime/serviceworker/container.cc | 19 ++-- src/runtime/serviceworker/fetch.cc | 1 - src/runtime/serviceworker/registration.cc | 15 +++- src/runtime/url.hh | 1 - src/runtime/window/linux.cc | 3 + 19 files changed, 252 insertions(+), 100 deletions(-) diff --git a/src/runtime/bridge/bridge.cc b/src/runtime/bridge/bridge.cc index 3a1538d0c..fe819b8ba 100644 --- a/src/runtime/bridge/bridge.cc +++ b/src/runtime/bridge/bridge.cc @@ -455,13 +455,6 @@ export * from '{{url}}' auto origin = webview::Origin(request->scheme + "://" + request->hostname); auto serviceWorker = app->runtime.serviceWorkerManager.get(origin.name()); - debug(">> %d %d %d %d", - serviceWorker != nullptr, - request->hostname != globalBundleIdentifier, - window->options.shouldPreferServiceWorker, - serviceWorker->container.registrations.size() > 0 - ); - if ( serviceWorker != nullptr && request->hostname != globalBundleIdentifier && @@ -486,7 +479,6 @@ export * from '{{url}}' const auto app = App::sharedApplication(); const auto options = serviceworker::Fetch::Options { request->client }; - debug("FETCH PLZ: %s", fetch.str().c_str()); const auto fetched = serviceWorker->fetch(fetch, options, [ this, applicationResources, @@ -551,7 +543,6 @@ export * from '{{url}}' contentLocation = resourcePath.substr(applicationResources.size(), resourcePath.size()); } - debug("RESOURCE PATH: %s", resourcePath.c_str()); auto resource = filesystem::Resource(resourcePath); if (!resource.exists()) { @@ -723,6 +714,7 @@ export * from '{{url}}' auto fetch = serviceworker::Request(); fetch.method = request->method; fetch.scheme = request->scheme; + fetch.url.scheme = request->scheme; fetch.url.hostname = request->hostname; fetch.url.pathname = request->pathname; fetch.url.searchParams.set(request->query); @@ -1067,7 +1059,6 @@ export * from '{{url}}' }); } } else { - debug("BEFORE REGISTER: %s %s", scheme.c_str(), scope.c_str()); this->navigator.serviceWorkerServer->container.registerServiceWorker({ .type = serviceworker::Registration::Options::Type::Module, .scriptURL = scriptURL, @@ -1091,7 +1082,6 @@ export * from '{{url}}' } } - debug("REGISTER SCHEME: %s", scheme.c_str()); this->schemeHandlers.registerSchemeHandler(scheme, [this]( auto request, auto bridge, @@ -1156,10 +1146,8 @@ export * from '{{url}}' auto origin = webview::Origin(fetch.url.str()); origin.scheme = "socket"; - debug("origin: %s", origin.name().c_str()); serviceWorkerServer = app->runtime.serviceWorkerManager.get(origin.name()); if (!serviceWorkerServer) { - debug("fall back to navigator serviceWorkerServer"); serviceWorkerServer = this->navigator.serviceWorkerServer; } @@ -1168,7 +1156,6 @@ export * from '{{url}}' if (scope.size() > 0) { fetch.url.pathname = scope + fetch.url.pathname; } - debug("fetch: %s", fetch.str().c_str()); const auto fetched = serviceWorkerServer->fetch(fetch, options, [request, callback] (auto res) mutable { if (!request->isActive()) { diff --git a/src/runtime/bytes.hh b/src/runtime/bytes.hh index d9885911e..3af244ac7 100644 --- a/src/runtime/bytes.hh +++ b/src/runtime/bytes.hh @@ -135,6 +135,9 @@ namespace ssc::runtime::bytes { Buffer& operator = (Buffer&&); Buffer& operator = (const String&); + unsigned char operator [] (size_t) const; + unsigned char& operator [] (size_t); + size_t size () const; template @@ -146,7 +149,8 @@ namespace ssc::runtime::bytes { bool set (const unsigned char*, size_t, size_t); bool set (const char*, size_t, size_t); - unsigned char at (size_t) const; + unsigned char at (ssize_t); + unsigned char at (ssize_t) const; const unsigned char* data () const; unsigned char* data (); const Buffer slice (size_t, size_t = -1, bool = false) const; diff --git a/src/runtime/bytes/buffer.cc b/src/runtime/bytes/buffer.cc index 1b48631e3..b25acc5cc 100644 --- a/src/runtime/bytes/buffer.cc +++ b/src/runtime/bytes/buffer.cc @@ -295,6 +295,22 @@ namespace ssc::runtime::bytes { return *this; } + unsigned char Buffer::operator [] (size_t byteOffset) const { + if (byteOffset >= this->byteLength) { + throw Error("Buffer::operator[]: RangeError: 'byteOffset' exceeds 'byteLength'"); + } + + return this->at(byteOffset); + } + + unsigned char& Buffer::operator [] (size_t byteOffset) { + if (byteOffset >= this->byteLength) { + throw Error("Buffer::operator[]: RangeError: 'byteOffset' exceeds 'byteLength'"); + } + + return (this->buffer.bytes.get() + this->byteOffset)[byteOffset]; + } + size_t Buffer::size () const { return this->byteLength.load(std::memory_order_relaxed); } @@ -357,12 +373,25 @@ namespace ssc::runtime::bytes { return true; } - unsigned char Buffer::at (size_t size) const { + unsigned char Buffer::at (ssize_t size) { + if (size >= this->byteLength) { + throw Error("Buffer::at: RangeError: 'size' exceeds 'byteLength'"); + } + + const auto data = this->data(); + if (data == nullptr) { + return 0; + } + + return data[size]; + } + + unsigned char Buffer::at (ssize_t size) const { if (size >= this->byteLength) { throw Error("Buffer::at: RangeError: 'size' exceeds 'byteLength'"); } - const auto data = this->buffer.data(); + const auto data = this->data(); if (data == nullptr) { return 0; } diff --git a/src/runtime/core/services/ai.cc b/src/runtime/core/services/ai.cc index 81fddf7f1..549e2c32c 100644 --- a/src/runtime/core/services/ai.cc +++ b/src/runtime/core/services/ai.cc @@ -228,7 +228,7 @@ namespace ssc::runtime::core::services { LLM::LLM (LLMOptions options) { llama_log_set([](ggml_log_level level, const char* message, void* llm) { - debug("LLMSTATUS: %s", message); + // debug("LLMSTATUS: %s", message); // llm.log(message); }, this); diff --git a/src/runtime/core/services/conduit.cc b/src/runtime/core/services/conduit.cc index cf915bffb..602e48cc7 100644 --- a/src/runtime/core/services/conduit.cc +++ b/src/runtime/core/services/conduit.cc @@ -1,10 +1,7 @@ -#include - #include "../../runtime.hh" #include "../../crypto.hh" #include "../../config.hh" #include "../../string.hh" -#include "../../bytes.hh" #include "../../http.hh" #include "../../env.hh" #include "../../ipc.hh" @@ -12,8 +9,6 @@ #include "conduit.hh" -#define SHA_DIGEST_LENGTH 20 - using ssc::runtime::config::getUserConfig; using ssc::runtime::string::toUpperCase; using ssc::runtime::crypto::rand64; @@ -261,10 +256,13 @@ namespace ssc::runtime::core::services { Conduit::Client* client, const char* buffer ) { - const auto request = http::Request(buffer); + auto request = http::Request(buffer); + request.url.hostname = "127.0.0.1"; + request.url.scheme = "ws"; + request.scheme = "ws"; if (!request.valid()) { - // TODO(@jwerle); handle malformed handshake request + client->close(); return; } @@ -272,6 +270,20 @@ namespace ssc::runtime::core::services { if (webSocketKey.empty()) { // debug("Sec-WebSocket-Key is required but missing."); + const auto buffer = bytes::Buffer(http::Response(400).str()); + client->write(buffer, [client]() { + client->close(); + }); + return; + } + + const auto sharedKey = request.url.searchParams.get("key").str(); + if (sharedKey != this->sharedKey) { + // debug("Conduit::Client failed auth"); + const auto buffer = bytes::Buffer(http::Response(403).str()); + client->write(buffer, [client]() { + client->close(); + }); return; } @@ -283,7 +295,7 @@ namespace ssc::runtime::core::services { } try { - client->clientId = request.url.pathComponents.get(1); + client->client.id = request.url.pathComponents.get(1); } catch (...) { // debug("Unable to parse client id"); } @@ -306,45 +318,16 @@ namespace ssc::runtime::core::services { // std::cout << "added client " << this->clients.size() << std::endl; } while (0); - if (sharedKey != this->sharedKey) { - debug("Conduit::Client failed auth"); - client->close(); - return; - } - const auto response = http::Response(101) .setHeader("upgrade", "websocket") .setHeader("connection", "upgrade") .setHeader( "sec-websocket-accept", - bytes::base64::encode(sha1(webSocketKey + WS_GUID)) - ); - - const auto output = response.str(); - const auto size = output.size(); - const auto data = new char[size]{0}; - memcpy(data, output.c_str(), size); - - const auto buf = uv_buf_init(data, size); - - auto req = new uv_write_t; - auto handle = reinterpret_cast(req); - auto stream = reinterpret_cast(&client->handle); - - uv_handle_set_data(handle, data); - uv_write(req, stream, &buf, 1, [](uv_write_t *req, int status) { - const auto data = reinterpret_cast( - uv_handle_get_data(reinterpret_cast(req)) + bytes::base64::encode(crypto::SHA1(webSocketKey + WS_GUID).finalize()) ); - if (data != nullptr) { - delete [] data; - } - - delete req; - }); - - client->isHandshakeDone = 1; + client->write(response.str()); + client->isHandshakeDone = true; } void Conduit::processFrame ( @@ -488,8 +471,8 @@ namespace ssc::runtime::core::services { const auto bytes = vectorToSharedPointer(buffer); const auto message = ipc::Message(uri); - auto window = client && client->clientId > 0 - ? this->context.getRuntime()->windowManager.getWindowForClient({ client->clientId }) + auto window = client && client->client.id > 0 + ? this->context.getRuntime()->windowManager.getWindowForClient({ client->client.id }) : nullptr; // prevent external usage of internal routes @@ -649,6 +632,41 @@ namespace ssc::runtime::core::services { return true; } + bool Conduit::Client::write (const bytes::Buffer& buffer, const WriteCallback callback) { + auto buf = uv_buf_init(reinterpret_cast(const_cast(buffer.data())), buffer.size()); + auto req = new uv_write_t; + auto handle = reinterpret_cast(req); + auto stream = reinterpret_cast(&this->handle); + + if (callback != nullptr) { + uv_handle_set_data( + reinterpret_cast(req), + new ClientWriteContext { this, callback } + ); + } else { + uv_handle_set_data( + reinterpret_cast(req), + nullptr + ); + } + + uv_write(req, stream, &buf, 1, [](uv_write_t *req, int status) { + const auto data = uv_handle_get_data(reinterpret_cast(req)); + const auto context = static_cast(data); + + delete req; + + if (context != nullptr) { + context->client->conduit->loop.dispatch([=]() mutable { + context->callback(); + delete context; + }); + } + }); + + return true; + } + struct ClientCloseContext { Conduit::Client* client = nullptr; Conduit::Client::CloseCallback callback = nullptr; diff --git a/src/runtime/core/services/conduit.hh b/src/runtime/core/services/conduit.hh index 0087a9c29..88c539a3c 100644 --- a/src/runtime/core/services/conduit.hh +++ b/src/runtime/core/services/conduit.hh @@ -1,8 +1,9 @@ #ifndef SOCKET_RUNTIME_CORE_SERVICES_CONDUIT_H #define SOCKET_RUNTIME_CORE_SERVICES_CONDUIT_H -#include "../../core.hh" #include "../../ipc.hh" +#include "../../core.hh" +#include "../../bytes.hh" namespace ssc::runtime::core::services { class Conduit : public core::Service { @@ -39,13 +40,13 @@ namespace ssc::runtime::core::services { class Client { public: - using CloseCallback = Function; using SendCallback = Function; + using WriteCallback = Function; + using CloseCallback = Function; using ID = uint64_t; ID id = 0; - // client state - ID clientId = 0; + ipc::Client client; Atomic isHandshakeDone = false; Atomic isClosing = false; Atomic isClosed = false; @@ -64,13 +65,20 @@ namespace ssc::runtime::core::services { Client (Conduit* conduit) : conduit(conduit), id(0), - clientId(0), isHandshakeDone(0) {} ~Client (); - bool send ( const Message::Options&, SharedPointer, size_t, int opcode = 2, const SendCallback = nullptr); + bool send ( + const Message::Options&, + SharedPointer, + size_t, + int opcode = 2, + const SendCallback = nullptr + ); + + bool write (const bytes::Buffer&, const WriteCallback = nullptr); void close (const CloseCallback callback = nullptr); }; diff --git a/src/runtime/crypto/sha1.cc b/src/runtime/crypto/sha1.cc index 63fae5c02..e4a07ba43 100644 --- a/src/runtime/crypto/sha1.cc +++ b/src/runtime/crypto/sha1.cc @@ -214,5 +214,4 @@ namespace ssc::runtime::crypto { const String sha1 (const unsigned char * input, size_t size) { return SHA1(input, size).str(); } - } diff --git a/src/runtime/http/headers.cc b/src/runtime/http/headers.cc index 89cd67a64..7b3ebbb27 100644 --- a/src/runtime/http/headers.cc +++ b/src/runtime/http/headers.cc @@ -144,11 +144,11 @@ namespace ssc::runtime::http { headers << name << ": " << entry.value.str(); if (--remaining > 0) { - headers << "\n"; + headers << "\r\n"; } } - return headers.str() + "\r\n"; + return headers.str() + "\r\n\r\n"; } const Headers::Iterator Headers::begin () const noexcept { diff --git a/src/runtime/http/request.cc b/src/runtime/http/request.cc index bd66fb694..50f6d17a9 100644 --- a/src/runtime/http/request.cc +++ b/src/runtime/http/request.cc @@ -1,22 +1,48 @@ -#include "../http.hh" #include "../string.hh" +#include "../http.hh" -using namespace ssc::runtime::string; +using ssc::runtime::string::split; namespace ssc::runtime::http { Request::Request (const String& input) { const auto crlf = input.find("\r\n"); if (crlf != String::npos) { auto stream = std::istringstream(input.substr(0, crlf)); - String uri; + String pathname; + String version; stream >> this->method - >> uri - >> this->version; + >> pathname + >> version; + + const auto versionParts = split(version, '/'); + const auto pathParts = split(pathname, '?'); + + if (versionParts.size() == 2) { + this->version = versionParts[1]; + } + + if (pathParts.size() == 2) { + this->url.pathname = pathParts[0]; + this->url.search = "?" + pathParts[1]; + this->url.searchParams.set(pathParts[1]); + } else { + this->url.pathname = pathname; + } - this->url = uri; this->headers = input.substr(crlf, input.find("\r\n\r\n")); this->body = input.substr(input.find("\r\n\r\n")); + + const auto host = this->headers.get("host"); + if (!host.empty()) { + const auto parts = split(host.value.str(), ':'); + if (parts.size() == 2) { + this->url.hostname = parts[0]; + this->url.port = parts[0]; + } else { + this->url.hostname = host.value.str(); + } + } } } @@ -29,19 +55,45 @@ namespace ssc::runtime::http { if (crlf != String::npos) { auto stream = std::istringstream(string.substr(0, crlf)); - String uri; + String pathname; + String version; stream >> this->method - >> uri - >> this->version; + >> pathname + >> version; + + const auto versionParts = split(version, '/'); + const auto pathParts = split(pathname, '?'); + + if (versionParts.size() == 2) { + this->version = versionParts[1]; + } + + if (pathParts.size() == 2) { + this->url.pathname = pathParts[0]; + this->url.search = "?" + pathParts[1]; + this->url.searchParams.set(pathParts[1]); + } else { + this->url.pathname = pathname; + } - this->url = uri; this->headers = string.substr(crlf, string.find("\r\n\r\n")); this->body.set( input + string.find("\r\n\r\n") + 4, 0, size - string.find("\r\n\r\n") - 4 ); + + const auto host = this->headers.get("host"); + if (!host.empty()) { + const auto parts = split(host.value.str(), ':'); + if (parts.size() == 2) { + this->url.hostname = parts[0]; + this->url.port = parts[0]; + } else { + this->url.hostname = host.value.str(); + } + } } } diff --git a/src/runtime/http/response.cc b/src/runtime/http/response.cc index 49db111dc..42bdad3cc 100644 --- a/src/runtime/http/response.cc +++ b/src/runtime/http/response.cc @@ -51,6 +51,6 @@ namespace ssc::runtime::http { } String Response::str () const { - return this->status.str() + "\r\n" + this->headers.str(); + return "HTTP/" + this->version + " " + this->status.str() + "\r\n" + this->headers.str(); } } diff --git a/src/runtime/ipc/router.cc b/src/runtime/ipc/router.cc index 036a79e30..48b079e3d 100644 --- a/src/runtime/ipc/router.cc +++ b/src/runtime/ipc/router.cc @@ -82,7 +82,7 @@ namespace ssc::runtime::ipc { size_t size ) { return this->invoke(uri, bytes, size, [this](auto result) { - this->dispatcher.dispatch([=, this] () { + this->dispatcher.dispatch([this, result] () { this->bridge.send(result.seq, result.str(), result.queuedResponse); }); }); diff --git a/src/runtime/ipc/routes.cc b/src/runtime/ipc/routes.cc index 7d7222108..df9974488 100644 --- a/src/runtime/ipc/routes.cc +++ b/src/runtime/ipc/routes.cc @@ -2548,7 +2548,7 @@ static void mapIPCRoutes (Router *router) { return reply(Result { message.seq, message, err }); } - const auto options = serviceworker::Registration::Options { + auto options = serviceworker::Registration::Options { .type = serviceworker::Registration::Options::Type::Module, .scriptURL = message.get("scriptURL"), .scope = message.get("scope"), @@ -2556,13 +2556,29 @@ static void mapIPCRoutes (Router *router) { .serializedWorkerArgs = encodeURIComponent(message.get("__runtime_worker_args", message.get("serializedWorkerArgs"))) }; + if (message.get("priority") == "high") { + options.priority = serviceworker::Registration::Priority::High; + } else if (message.get("priority") == "low") { + options.priority = serviceworker::Registration::Priority::Low; + } + const auto url = URL(options.scriptURL); const auto origin = webview::Origin(url.str()); - debug("register: (%s) %s", origin.name().c_str(), url.str().c_str()); auto serviceWorkerServer = app->runtime.serviceWorkerManager.get(origin.name()); if (!serviceWorkerServer) { - serviceWorkerServer = dynamic_cast(router->bridge).navigator.serviceWorkerServer; + if (message.has("__runtime_user_config")) { + auto userConfig = INI::parse(message.get("__runtime_user_config")); + serviceWorkerServer = static_cast(router->bridge).getRuntime()->serviceWorkerManager.init( + origin.name(), + serviceworker::Server::Options { + origin.name(), + userConfig + } + ); + } else { + serviceWorkerServer = dynamic_cast(router->bridge).navigator.serviceWorkerServer; + } } const auto registration = serviceWorkerServer->container.registerServiceWorker(options); @@ -2663,11 +2679,14 @@ static void mapIPCRoutes (Router *router) { auto fetch = serviceworker::Request(); fetch.method = message.get("method", "GET"); fetch.scheme = message.get("scheme", "socket"); + fetch.url.scheme = message.get("scheme", "socket"); fetch.url.hostname = message.get("hostname"); fetch.url.pathname = message.get("pathname", "/"); + fetch.url.search = "?" + message.get("query", ""); fetch.url.searchParams.set(message.get("query", "")); fetch.headers = message.get("headers", ""); fetch.body = message.buffer; + fetch.client = router->bridge.client; if (fetch.scheme == "socket" && fetch.url.hostname.size() == 0) { fetch.url.hostname = router->bridge.userConfig["meta_bundle_identifier"]; @@ -2690,11 +2709,17 @@ static void mapIPCRoutes (Router *router) { } if (fetch.scheme == "npm") { + static auto userConfig = ssc::runtime::config::getUserConfig(); + const auto bundleIdentifier = userConfig["meta_bundle_identifier"]; if (fetch.url.hostname.size() > 0) { fetch.url.pathname = "/" + fetch.url.hostname; } - fetch.url.hostname = dynamic_cast(router->bridge).userConfig["meta_bundle_identifier"]; + fetch.url.hostname = bundleIdentifier; + } + + if (!fetch.headers.has("origin")) { + fetch.headers.set("origin", dynamic_cast(router->bridge).navigator.location.origin); } const auto scope = dynamic_cast(router->bridge).navigator.serviceWorkerServer->container.protocols.getServiceWorkerScope(fetch.scheme); @@ -2707,7 +2732,14 @@ static void mapIPCRoutes (Router *router) { router->bridge.client }; - const auto fetched = app->runtime.serviceWorkerManager.fetch(fetch, options, [=] (auto res) mutable { + auto origin = webview::Origin(fetch.url.str()); + origin.scheme = "socket"; + auto serviceWorkerServer = app->runtime.serviceWorkerManager.get(origin.name()); + if (!serviceWorkerServer) { + serviceWorkerServer = dynamic_cast(router->bridge).navigator.serviceWorkerServer; + } + + const auto fetched = serviceWorkerServer->fetch(fetch, options, [=] (auto res) mutable { if (res.statusCode == 0) { return reply(Result::Err { message, diff --git a/src/runtime/platform/system.hh b/src/runtime/platform/system.hh index 64e054678..86feeafff 100644 --- a/src/runtime/platform/system.hh +++ b/src/runtime/platform/system.hh @@ -133,4 +133,9 @@ #if SOCKET_RUNTIME_PLATFORM_ANDROID #include "android.hh" #endif + +#ifdef _WIN32 +typedef __int64 ssize_t; +#endif + #endif diff --git a/src/runtime/serviceworker.hh b/src/runtime/serviceworker.hh index ee74f6614..65cbfd5f5 100644 --- a/src/runtime/serviceworker.hh +++ b/src/runtime/serviceworker.hh @@ -71,6 +71,12 @@ namespace ssc::runtime::serviceworker { class Registration { public: static String key (const String&, const URL&, const String& = "socket"); + enum class Priority { + High, + Default, + Low + }; + struct Options { enum class Type { Classic, Module }; @@ -79,6 +85,7 @@ namespace ssc::runtime::serviceworker { String scope; String scheme = "*"; String serializedWorkerArgs = ""; + Priority priority = Priority::Default; ID id = 0; }; diff --git a/src/runtime/serviceworker/container.cc b/src/runtime/serviceworker/container.cc index d16ce4a62..5d9d8d60b 100644 --- a/src/runtime/serviceworker/container.cc +++ b/src/runtime/serviceworker/container.cc @@ -2,18 +2,12 @@ #include "../config.hh" #include "../crypto.hh" #include "../string.hh" -#include "../env.hh" #include "../serviceworker.hh" -using ssc::runtime::url::encodeURIComponent; using ssc::runtime::crypto::rand64; -using ssc::runtime::config::isDebugEnabled; using ssc::runtime::config::getUserConfig; -using ssc::runtime::string::parseStringList; -using ssc::runtime::string::replace; using ssc::runtime::string::split; -using ssc::runtime::string::trim; using ssc::runtime::string::join; namespace ssc::runtime::serviceworker { @@ -127,10 +121,12 @@ namespace ssc::runtime::serviceworker { do { Lock lock(fetch->mutex); + fetch->response.client.id = clientId; + fetch->response.status = statusCode; + fetch->response.statusCode = statusCode; + if (fetch->response.headers.size() == 0 && message.has("headers")) { fetch->response.headers = http::Headers(message.get("headers")); - fetch->response.client.id = clientId; - fetch->response.status = statusCode; } if (message.buffer.size() > 0) { @@ -188,11 +184,12 @@ namespace ssc::runtime::serviceworker { do { Lock lock(fetch->mutex); + fetch->response.client.id = clientId; + fetch->response.status = statusCode; + fetch->response.statusCode = statusCode; if (fetch->response.headers.size() == 0 && message.has("headers")) { fetch->response.headers = http::Headers(message.get("headers")); - fetch->response.client.id = clientId; - fetch->response.status = statusCode; } if (message.buffer.size() > 0) { @@ -282,7 +279,6 @@ namespace ssc::runtime::serviceworker { scope = normalizeScope(scope); const auto key = Registration::key(scope, this->origin, options.scheme); - debug("KEY: (scope=%s, scheme=%s) %s", scope.c_str(), options.scheme.c_str(), key.c_str()); if (this->registrations.contains(key)) { const auto& registration = this->registrations.at(key); @@ -304,6 +300,7 @@ namespace ssc::runtime::serviceworker { scope, options.scheme, options.serializedWorkerArgs, + Registration::Priority::Default, id } )); diff --git a/src/runtime/serviceworker/fetch.cc b/src/runtime/serviceworker/fetch.cc index 0442b784c..7bb9fc406 100644 --- a/src/runtime/serviceworker/fetch.cc +++ b/src/runtime/serviceworker/fetch.cc @@ -125,7 +125,6 @@ namespace ssc::runtime::serviceworker { return this->container.bridge->emit("serviceWorker.fetch", json); } - debug("failed to dispatch fetch: %s %s", pathname.c_str(), this->request.str().c_str()); return false; } diff --git a/src/runtime/serviceworker/registration.cc b/src/runtime/serviceworker/registration.cc index 380d04636..a010a40da 100644 --- a/src/runtime/serviceworker/registration.cc +++ b/src/runtime/serviceworker/registration.cc @@ -5,6 +5,16 @@ using ssc::runtime::url::encodeURIComponent; namespace ssc::runtime::serviceworker { + static String getPriorityString (const Registration::Priority& priority) { + if (priority == Registration::Priority::High) { + return "high"; + } else if (priority == Registration::Priority::Low) { + return "low"; + } + + return "default"; + } + String Registration::key ( const String& scope, const URL& origin, @@ -14,6 +24,7 @@ namespace ssc::runtime::serviceworker { url.scheme = scheme; return url.str(); } + Registration::Registration ( const ID id, const State state, @@ -35,6 +46,7 @@ namespace ssc::runtime::serviceworker { Registration::Registration (Registration&& registration) { this->id = registration.id; this->state = registration.state.load(); + this->origin = registration.origin; this->options = registration.options; registration.id = 0; @@ -74,7 +86,8 @@ namespace ssc::runtime::serviceworker { {"state", this->getStateString()}, {"scheme", this->options.scheme}, {"origin", this->origin.name()}, - {"serializedWorkerArgs", includeSerializedWorkerArgs ? encodeURIComponent(this->options.serializedWorkerArgs) : ""} + {"serializedWorkerArgs", includeSerializedWorkerArgs ? encodeURIComponent(this->options.serializedWorkerArgs) : ""}, + {"priority", getPriorityString(this->options.priority)} }; } diff --git a/src/runtime/url.hh b/src/runtime/url.hh index 4f846a58d..91d90440b 100644 --- a/src/runtime/url.hh +++ b/src/runtime/url.hh @@ -184,7 +184,6 @@ namespace ssc::runtime::url { void set (const JSON::Object&); const String href () const; const String str () const; - const char* c_str () const; const JSON::Object json () const; const size_t size () const; bool empty () const; diff --git a/src/runtime/window/linux.cc b/src/runtime/window/linux.cc index f443dee61..5e5bef21f 100644 --- a/src/runtime/window/linux.cc +++ b/src/runtime/window/linux.cc @@ -417,8 +417,11 @@ namespace ssc::runtime::window { gpointer ptr ) { auto window = static_cast(ptr); + if (!window) return; auto value = webkit_javascript_result_get_js_value(result); + if (!value) return; auto valueString = jsc_value_to_string(value); + if (!valueString) return; auto str = String(valueString); if (!window->bridge->route(str, nullptr, 0)) {