Skip to content

Commit 23657c7

Browse files
committed
fix(runtime/) use 'URL', don't clobber config when given in 'createWindow'
1 parent 863b4b2 commit 23657c7

File tree

12 files changed

+134
-104
lines changed

12 files changed

+134
-104
lines changed

api/application.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ export async function getScreenSize () {
386386
}
387387

388388
function throwOnInvalidIndex (index) {
389-
if (index === undefined || typeof index !== 'number' || !Number.isInteger(index) || index < 0) {
389+
if (index === undefined || typeof index !== 'number' || !Number.isInteger(index) || index < -1) {
390390
throw new Error(`Invalid window index: ${index} (must be a positive integer number)`)
391391
}
392392
}

api/service-worker/container.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,14 +376,14 @@ export class ServiceWorkerContainer extends EventTarget {
376376
return new ServiceWorkerRegistration(info, serviceWorker)
377377
}
378378

379-
async getRegistrations () {
379+
async getRegistrations (options) {
380380
if (globalThis.top && globalThis.window && globalThis.top !== globalThis.window) {
381381
try {
382-
return await globalThis.top.navigator.serviceWorker.getRegistrations()
382+
return await globalThis.top.navigator.serviceWorker.getRegistrations(options)
383383
} catch (err) {}
384384
}
385385

386-
const result = await ipc.request('serviceWorker.getRegistrations')
386+
const result = await ipc.request('serviceWorker.getRegistrations', options)
387387

388388
if (result.err) {
389389
throw result.err

api/service-worker/init.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,12 @@ export class ServiceWorkerInstance extends Worker {
4747
options.args = JSON.parse(decodeURIComponent(decodeURIComponent(info.serializedWorkerArgs)))
4848
}
4949
}
50+
51+
if (options?.args?.index) {
52+
options.args.index = globalThis.__args.index
53+
}
5054
}
55+
5156
super(filename, {
5257
name: `ServiceWorker (${options?.info?.pathname ?? filename})`,
5358
...options,

bin/functions.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,8 @@ function determine_cxx () {
513513
read_env_data
514514

515515
if [ ! "$CXX" ]; then
516-
# TODO(@mribbons): yum support
517-
if [ -n "$dpkg" ]; then
516+
# TODO(@jwerle): yum support
517+
if [[ "$(host_os)" == "Linux" ]] && [ -n "$dpkg" ]; then
518518
tmp="$(mktemp)"
519519
{
520520
dpkg -S clang 2>&1| grep "clang++" | cut -d" " -f 2 | while read clang; do

src/runtime/bridge/bridge.cc

Lines changed: 77 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -597,13 +597,12 @@ export * from '{{url}}'
597597
});
598598

599599
if (fetched) {
600-
// FIXME(@jwerle): revisit timeout
601-
//this->core->setTimeout(32000, [request] () mutable {
602-
//if (request->isActive()) {
603-
//auto response = SchemeHandlers::Response(request, 408);
604-
//response.fail("ServiceWorker request timed out.");
605-
//}
606-
//});
600+
this->getRuntime()->services.timers.setTimeout(32000, [request] () mutable {
601+
if (request->isActive()) {
602+
auto response = SchemeHandlers::Response(request, 408);
603+
response.fail("ServiceWorker request timed out.");
604+
}
605+
});
607606
return;
608607
}
609608
}
@@ -739,13 +738,12 @@ export * from '{{url}}'
739738
});
740739

741740
if (fetched) {
742-
// FIXME(@jwerle): revisit timeout
743-
//this->core->setTimeout(32000, [request] () mutable {
744-
//if (request->isActive()) {
745-
//auto response = SchemeHandlers::Response(request, 408);
746-
//response.fail("ServiceWorker request timed out.");
747-
//}
748-
//});
741+
this->getRuntime()->services.timers.setTimeout(32000, [request] () mutable {
742+
if (request->isActive()) {
743+
auto response = SchemeHandlers::Response(request, 408);
744+
response.fail("ServiceWorker request timed out.");
745+
}
746+
});
749747
return;
750748
}
751749
}
@@ -779,23 +777,23 @@ export * from '{{url}}'
779777
auto resource = filesystem::Resource(resourcePath, { .cache = true });
780778

781779
if (resource.exists()) {
782-
const auto url = (
783-
#if SOCKET_RUNTIME_PLATFORM_ANDROID
784-
"https://" +
785-
#else
786-
"socket://" +
787-
#endif
788-
toLowerCase(bundleIdentifier) +
789-
contentLocation +
790-
(request->query.size() > 0 ? "?" + request->query : "")
791-
);
780+
auto url = URL();
781+
#if SOCKET_RUNTIME_PLATFORM_ANDROID
782+
url.scheme = "https";
783+
#else
784+
url.scheme = "socket";
785+
#endif
786+
url.hostname = toLowerCase(bundleIdentifier);
787+
url.pathname = contentLocation;
788+
url.search = request->query;
789+
debug("URL1: %s", url.str().c_str());
792790

793791
const auto moduleImportProxy = tmpl(
794792
String(reinterpret_cast<const char*>(resource.read())).find("export default") != String::npos
795793
? ESM_IMPORT_PROXY_TEMPLATE_WITH_DEFAULT_EXPORT
796794
: ESM_IMPORT_PROXY_TEMPLATE_WITHOUT_DEFAULT_EXPORT,
797795
Map<String, String> {
798-
{"url", url},
796+
{"url", url.str()},
799797
{"commit", version::VERSION_HASH_STRING},
800798
{"protocol", "socket"},
801799
{"pathname", pathname},
@@ -902,22 +900,22 @@ export * from '{{url}}'
902900
}
903901

904902
if (resource.exists()) {
905-
const auto url = (
906-
#if SOCKET_RUNTIME_PLATFORM_ANDROID
907-
"https://" +
908-
#else
909-
"socket://" +
910-
#endif
911-
toLowerCase(bundleIdentifier) +
912-
"/socket" +
913-
pathname
914-
);
903+
auto url = URL();
904+
#if SOCKET_RUNTIME_PLATFORM_ANDROID
905+
url.scheme = "https";
906+
#else
907+
url.scheme = "socket";
908+
#endif
909+
url.hostname = toLowerCase(bundleIdentifier);
910+
url.pathname = "/socket" + pathname;
911+
url.search = request->query;
912+
debug("URL2: %s", url.str().c_str());
915913
const auto moduleImportProxy = tmpl(
916914
String(reinterpret_cast<const char*>(resource.read())).find("export default") != String::npos
917915
? ESM_IMPORT_PROXY_TEMPLATE_WITH_DEFAULT_EXPORT
918916
: ESM_IMPORT_PROXY_TEMPLATE_WITHOUT_DEFAULT_EXPORT,
919917
Map<String, String> {
920-
{"url", url},
918+
{"url", url.str()},
921919
{"commit", version::VERSION_HASH_STRING},
922920
{"protocol", "node"},
923921
{"pathname", pathname},
@@ -949,10 +947,29 @@ export * from '{{url}}'
949947
callback(response);
950948
});
951949

950+
Set<String> globalProtocolHandlers = { "npm" };
952951
Map<String, String> protocolHandlers = {};
953952
auto globalUserConfig = getUserConfig();
954-
if (globalUserConfig["meta_bundle_identifier"] == this->userConfig["meta_bundle_identifier"]) {
955-
protocolHandlers.insert({"npm", "/socket/npm/service-worker.js"});
953+
protocolHandlers.insert({"npm", "/socket/npm/service-worker.js"});
954+
955+
for (const auto& entry : split(globalUserConfig["webview_protocol-handlers"], " ")) {
956+
const auto scheme = replace(trim(entry), ":", "");
957+
if (this->navigator.serviceWorkerServer->container.protocols.registerHandler(scheme)) {
958+
protocolHandlers.insert_or_assign(scheme, "");
959+
globalProtocolHandlers.insert(scheme);
960+
}
961+
}
962+
963+
for (const auto& entry : globalUserConfig) {
964+
const auto& key = entry.first;
965+
if (key.starts_with("webview_protocol-handlers_")) {
966+
const auto scheme = replace(replace(trim(key), "webview_protocol-handlers_", ""), ":", "");;
967+
const auto data = entry.second;
968+
if (this->navigator.serviceWorkerServer->container.protocols.registerHandler(scheme, { data })) {
969+
protocolHandlers.insert_or_assign(scheme, data);
970+
globalProtocolHandlers.insert(scheme);
971+
}
972+
}
956973
}
957974

958975
for (const auto& entry : split(this->userConfig["webview_protocol-handlers"], " ")) {
@@ -968,7 +985,6 @@ export * from '{{url}}'
968985
const auto scheme = replace(replace(trim(key), "webview_protocol-handlers_", ""), ":", "");;
969986
const auto data = entry.second;
970987
if (this->navigator.serviceWorkerServer->container.protocols.registerHandler(scheme, { data })) {
971-
debug("protocol: %s %s", scheme.c_str(), data.c_str());
972988
protocolHandlers.insert_or_assign(scheme, data);
973989
}
974990
}
@@ -978,6 +994,12 @@ export * from '{{url}}'
978994
const auto& scheme = entry.first;
979995
const auto id = rand64();
980996

997+
if (globalUserConfig["meta_bundle_identifier"] != this->userConfig["meta_bundle_identifier"]) {
998+
if (globalProtocolHandlers.contains(scheme)) {
999+
continue;
1000+
}
1001+
}
1002+
9811003
auto scriptURL = trim(entry.second);
9821004

9831005
if (scriptURL.size() == 0) {
@@ -1010,6 +1032,8 @@ export * from '{{url}}'
10101032
scriptURL
10111033
);
10121034

1035+
debug("scriptURL: %s", scriptURL.c_str());
1036+
10131037
auto env = JSON::Object::Entries {};
10141038
for (const auto& entry : this->userConfig) {
10151039
if (entry.first.starts_with("env_")) {
@@ -1023,14 +1047,16 @@ export * from '{{url}}'
10231047
}
10241048

10251049
if (scheme == "npm") {
1026-
this->navigator.serviceWorkerServer->container.registerServiceWorker({
1027-
.type = serviceworker::Registration::Options::Type::Module,
1028-
.scriptURL = scriptURL,
1029-
.scope = scope,
1030-
.scheme = scheme,
1031-
.serializedWorkerArgs = "",
1032-
.id = id
1033-
});
1050+
if (globalUserConfig["meta_bundle_identifier"] == this->userConfig["meta_bundle_identifier"]) {
1051+
this->navigator.serviceWorkerServer->container.registerServiceWorker({
1052+
.type = serviceworker::Registration::Options::Type::Module,
1053+
.scriptURL = scriptURL,
1054+
.scope = scope,
1055+
.scheme = scheme,
1056+
.serializedWorkerArgs = "",
1057+
.id = id
1058+
});
1059+
}
10341060
} else {
10351061
this->navigator.serviceWorkerServer->container.registerServiceWorker({
10361062
.type = serviceworker::Registration::Options::Type::Module,
@@ -1045,9 +1071,9 @@ export * from '{{url}}'
10451071
{"headless", this->userConfig["build_headless"] == "true"},
10461072
{"config", this->userConfig},
10471073
{"conduit", JSON::Object::Entries {
1048-
{"port", this->context.getRuntime()->services.conduit.port},
1049-
{"hostname", this->context.getRuntime()->services.conduit.hostname},
1050-
{"sharedKey", this->context.getRuntime()->services.conduit.sharedKey}
1074+
{"port", this->getRuntime()->services.conduit.port},
1075+
{"hostname", this->getRuntime()->services.conduit.hostname},
1076+
{"sharedKey", this->getRuntime()->services.conduit.sharedKey}
10511077
}}
10521078
}).str()),
10531079
.id = id
@@ -1248,7 +1274,7 @@ extern "C" {
12481274
return false;
12491275
}
12501276

1251-
const auto window = app->windowManager.getWindow(index);
1277+
const auto window = app->runtime.windowManager.getWindow(index);
12521278

12531279
if (!window) {
12541280
ANDROID_THROW(env, "Invalid window requested");

src/runtime/ipc/routes.cc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2560,6 +2560,7 @@ static void mapIPCRoutes (Router *router) {
25602560

25612561
auto serviceWorkerServer = app->runtime.serviceWorkerManager.get(origin.name());
25622562
if (!serviceWorkerServer) {
2563+
debug("no server for: %s", origin.name().c_str());
25632564
serviceWorkerServer = dynamic_cast<Bridge&>(router->bridge).navigator.serviceWorkerServer;
25642565
}
25652566

@@ -2634,8 +2635,15 @@ static void mapIPCRoutes (Router *router) {
26342635
* Gets all service worker scope registrations.
26352636
*/
26362637
router->map("serviceWorker.getRegistrations", [=](auto message, auto router, auto reply) {
2638+
const auto origin = webview::Origin(message.get("origin"));
2639+
auto serviceWorkerServer = dynamic_cast<Bridge&>(router->bridge).getRuntime()->serviceWorkerManager.get(origin.name());
2640+
2641+
if (!serviceWorkerServer) {
2642+
serviceWorkerServer = dynamic_cast<Bridge&>(router->bridge).navigator.serviceWorkerServer;
2643+
}
2644+
26372645
auto json = JSON::Array::Entries {};
2638-
for (const auto& entry : dynamic_cast<Bridge&>(router->bridge).navigator.serviceWorkerServer->container.registrations) {
2646+
for (const auto& entry : serviceWorkerServer->container.registrations) {
26392647
const auto& registration = entry.second;
26402648
json.push_back(registration.json());
26412649
}

src/runtime/serviceworker/container.cc

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,22 @@ namespace ssc::runtime::serviceworker {
6262
if (bridge->userConfig["webview_service-workers"].size() > 0) {
6363
const auto scripts = split(bridge->userConfig["webview_service-workers"], " ");
6464
for (const auto& value : scripts) {
65-
auto parts = split(value, "/");
66-
parts = Vector<String>(parts.begin(), parts.end() - 1);
65+
auto url = URL(
66+
value,
67+
"socket://" + bridge->userConfig["meta_bundle_identifier"]
68+
);
6769

6870
#if SOCKET_RUNTIME_PLATFORM_ANDROID
69-
auto scriptURL = String("https://");
71+
url.scheme = "https";
7072
#else
71-
auto scriptURL = String("socket://");
73+
url.scheme = "socket";
7274
#endif
73-
scriptURL += bridge->userConfig["meta_bundle_identifier"];
7475

75-
if (!value.starts_with("/")) {
76-
scriptURL += "/";
77-
}
78-
79-
scriptURL += value;
80-
81-
const auto scope = normalizeScope(join(parts, "/"));
76+
const auto scriptURL = url.str();
77+
const auto parts = split(url.pathname, "/");
78+
const auto scope = parts.size() > 2
79+
? join(Vector<String>(parts.begin(), parts.end() - 1), "/")
80+
: "/";
8281
const auto id = rand64();
8382
this->registrations.insert_or_assign(scope, Registration(
8483
id,
@@ -425,24 +424,23 @@ namespace ssc::runtime::serviceworker {
425424
: getUserConfig();
426425

427426
if (scope.size() == 0) {
428-
auto tmp = trim(options.scriptURL);
429-
tmp = replace(tmp, "https://", "");
430-
tmp = replace(tmp, "socket://", "");
431-
tmp = replace(tmp, userConfig["meta_bundle_identifier"], "");
432-
433-
auto parts = split(tmp, "/");
434-
parts = Vector<String>(parts.begin(), parts.end() - 1);
427+
auto url = URL(
428+
scriptURL,
429+
"socket://" + userConfig["meta_bundle_identifier"]
430+
);
435431

436432
#if SOCKET_RUNTIME_PLATFORM_ANDROID
437-
scriptURL = String("https://");
433+
url.scheme = "https";
438434
#else
439-
scriptURL = String("socket://");
435+
url.scheme = "socket";
440436
#endif
441437

442-
scriptURL += userConfig["meta_bundle_identifier"];
443-
scriptURL += tmp;
438+
scriptURL = url.str();
444439

445-
scope = join(parts, "/");
440+
const auto parts = split(url.pathname, "/");
441+
scope = parts.size() > 2
442+
? join(Vector<String>(parts.begin(), parts.end() - 1), "/")
443+
: "/";
446444
}
447445

448446
scope = normalizeScope(scope);

src/runtime/serviceworker/fetch.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,11 @@ namespace ssc::runtime::serviceworker {
118118
auto json = registration.json();
119119
json.set("fetch", fetch);
120120

121+
debug("dispatch fetch: %s", json.str().c_str());
121122
return this->container.bridge->emit("serviceWorker.fetch", json);
122123
}
123124

125+
debug("failed to dispatch fetch: %s %s", pathname.c_str(), this->request.str().c_str());
124126
return false;
125127
}
126128

src/runtime/url.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ namespace ssc::runtime::url {
187187
const char* c_str () const;
188188
const JSON::Object json () const;
189189
const size_t size () const;
190+
bool empty () const;
190191
};
191192

192193
size_t url_encode_uri_component (

src/runtime/url/url.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,4 +422,8 @@ namespace ssc::runtime::url {
422422
const size_t URL::size () const {
423423
return this->str().size();
424424
}
425+
426+
bool URL::empty () const {
427+
return this->str().empty();
428+
}
425429
}

0 commit comments

Comments
 (0)