Skip to content

Commit 19963a3

Browse files
committed
refactor(runtime/serviceworker): use better service worker registration keys, fix registrations
1 parent 23657c7 commit 19963a3

File tree

9 files changed

+119
-254
lines changed

9 files changed

+119
-254
lines changed

api/service-worker/init.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ export async function onActivate (event) {
198198
export async function onFetch (event) {
199199
const info = new ServiceWorkerInfo(event.detail)
200200
const exists = workers.has(info.hash)
201+
console.log(exists, event.detail)
201202

202203
// this may be an early fetch, just try waiting at most
203204
// 32*16 milliseconds for the worker to be available or
@@ -377,7 +378,7 @@ hooks.onReady(async () => {
377378
const result = await ipc.request('serviceWorker.getRegistrations')
378379
if (Array.isArray(result.data)) {
379380
for (const info of result.data) {
380-
await navigator.serviceWorker.register(info.scriptURL, info)
381+
//await navigator.serviceWorker.register(info.scriptURL, info)
381382
}
382383
}
383384
})

api/service-worker/worker.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ export async function onMessage (event) {
410410
}
411411

412412
const url = new URL(data.fetch.request.url)
413+
console.log('FetchEvent: %s', url.href)
413414
const fetchEvent = new FetchEvent('fetch', {
414415
clientId: data.fetch.client.id,
415416
fetchId: data.fetch.request.id,

src/runtime/bridge/bridge.cc

Lines changed: 83 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,14 @@ export * from '{{url}}'
454454
if (request->hostname.size() > 0) {
455455
auto origin = webview::Origin(request->scheme + "://" + request->hostname);
456456
auto serviceWorker = app->runtime.serviceWorkerManager.get(origin.name());
457+
458+
debug(">> %d %d %d %d",
459+
serviceWorker != nullptr,
460+
request->hostname != globalBundleIdentifier,
461+
window->options.shouldPreferServiceWorker,
462+
serviceWorker->container.registrations.size() > 0
463+
);
464+
457465
if (
458466
serviceWorker != nullptr &&
459467
request->hostname != globalBundleIdentifier &&
@@ -463,6 +471,7 @@ export * from '{{url}}'
463471
auto fetch = serviceworker::Request();
464472
fetch.method = request->method;
465473
fetch.scheme = request->scheme;
474+
fetch.url.scheme = request->scheme;
466475
fetch.url.hostname = request->hostname;
467476
fetch.url.pathname = request->pathname;
468477
fetch.url.searchParams.set(request->query);
@@ -477,6 +486,7 @@ export * from '{{url}}'
477486

478487
const auto app = App::sharedApplication();
479488
const auto options = serviceworker::Fetch::Options { request->client };
489+
debug("FETCH PLZ: %s", fetch.str().c_str());
480490
const auto fetched = serviceWorker->fetch(fetch, options, [
481491
this,
482492
applicationResources,
@@ -541,6 +551,7 @@ export * from '{{url}}'
541551
contentLocation = resourcePath.substr(applicationResources.size(), resourcePath.size());
542552
}
543553

554+
debug("RESOURCE PATH: %s", resourcePath.c_str());
544555
auto resource = filesystem::Resource(resourcePath);
545556

546557
if (!resource.exists()) {
@@ -607,7 +618,10 @@ export * from '{{url}}'
607618
}
608619
}
609620

610-
if (request->hostname == userConfig["meta_bundle_identifier"]) {
621+
if (
622+
request->hostname == userConfig["meta_bundle_identifier"] ||
623+
request->hostname == globalConfig["meta_bundle_identifier"]
624+
) {
611625
const auto resolved = this->navigator.location.resolve(request->pathname, applicationResources);
612626

613627
if (resolved.redirect) {
@@ -786,7 +800,6 @@ export * from '{{url}}'
786800
url.hostname = toLowerCase(bundleIdentifier);
787801
url.pathname = contentLocation;
788802
url.search = request->query;
789-
debug("URL1: %s", url.str().c_str());
790803

791804
const auto moduleImportProxy = tmpl(
792805
String(reinterpret_cast<const char*>(resource.read())).find("export default") != String::npos
@@ -909,7 +922,6 @@ export * from '{{url}}'
909922
url.hostname = toLowerCase(bundleIdentifier);
910923
url.pathname = "/socket" + pathname;
911924
url.search = request->query;
912-
debug("URL2: %s", url.str().c_str());
913925
const auto moduleImportProxy = tmpl(
914926
String(reinterpret_cast<const char*>(resource.read())).find("export default") != String::npos
915927
? ESM_IMPORT_PROXY_TEMPLATE_WITH_DEFAULT_EXPORT
@@ -994,92 +1006,92 @@ export * from '{{url}}'
9941006
const auto& scheme = entry.first;
9951007
const auto id = rand64();
9961008

997-
if (globalUserConfig["meta_bundle_identifier"] != this->userConfig["meta_bundle_identifier"]) {
998-
if (globalProtocolHandlers.contains(scheme)) {
999-
continue;
1000-
}
1001-
}
1002-
1003-
auto scriptURL = trim(entry.second);
1009+
if (
1010+
globalUserConfig["meta_bundle_identifier"] == this->userConfig["meta_bundle_identifier"] ||
1011+
!globalProtocolHandlers.contains(scheme)
1012+
) {
10041013

1005-
if (scriptURL.size() == 0) {
1006-
continue;
1007-
}
1014+
auto scriptURL = trim(entry.second);
10081015

1009-
if (!scriptURL.starts_with(".") && !scriptURL.starts_with("/")) {
1010-
continue;
1011-
}
1016+
if (scriptURL.size() == 0) {
1017+
continue;
1018+
}
10121019

1013-
if (scriptURL.starts_with(".")) {
1014-
scriptURL = scriptURL.substr(1, scriptURL.size());
1015-
}
1020+
if (!scriptURL.starts_with(".") && !scriptURL.starts_with("/")) {
1021+
continue;
1022+
}
10161023

1017-
String scope = "/";
1024+
if (scriptURL.starts_with(".")) {
1025+
scriptURL = scriptURL.substr(1, scriptURL.size());
1026+
}
10181027

1019-
auto scopeParts = split(scriptURL, "/");
1020-
if (scopeParts.size() > 0) {
1021-
scopeParts = Vector<String>(scopeParts.begin(), scopeParts.end() - 1);
1022-
scope = join(scopeParts, "/");
1023-
}
1028+
String scope = "/";
10241029

1025-
scriptURL = (
1026-
#if SOCKET_RUNTIME_PLATFORM_ANDROID
1027-
"https://" +
1028-
#else
1029-
"socket://" +
1030-
#endif
1031-
this->userConfig["meta_bundle_identifier"] +
1032-
scriptURL
1033-
);
1030+
auto scopeParts = split(scriptURL, "/");
1031+
if (scopeParts.size() > 0) {
1032+
scopeParts = Vector<String>(scopeParts.begin(), scopeParts.end() - 1);
1033+
scope = join(scopeParts, "/");
1034+
}
10341035

1035-
debug("scriptURL: %s", scriptURL.c_str());
1036+
scriptURL = (
1037+
#if SOCKET_RUNTIME_PLATFORM_ANDROID
1038+
"https://" +
1039+
#else
1040+
"socket://" +
1041+
#endif
1042+
this->userConfig["meta_bundle_identifier"] +
1043+
scriptURL
1044+
);
10361045

1037-
auto env = JSON::Object::Entries {};
1038-
for (const auto& entry : this->userConfig) {
1039-
if (entry.first.starts_with("env_")) {
1040-
env[entry.first.substr(4)] = entry.second;
1041-
} else if (entry.first == "build_env") {
1042-
const auto keys = parseStringList(entry.second, { ',', ' ' });
1043-
for (const auto& key : keys) {
1044-
env[key] = env::get(key);
1046+
auto env = JSON::Object::Entries {};
1047+
for (const auto& entry : this->userConfig) {
1048+
if (entry.first.starts_with("env_")) {
1049+
env[entry.first.substr(4)] = entry.second;
1050+
} else if (entry.first == "build_env") {
1051+
const auto keys = parseStringList(entry.second, { ',', ' ' });
1052+
for (const auto& key : keys) {
1053+
env[key] = env::get(key);
1054+
}
10451055
}
10461056
}
1047-
}
10481057

1049-
if (scheme == "npm") {
1050-
if (globalUserConfig["meta_bundle_identifier"] == this->userConfig["meta_bundle_identifier"]) {
1058+
if (scheme == "npm") {
1059+
if (globalUserConfig["meta_bundle_identifier"] == this->userConfig["meta_bundle_identifier"]) {
1060+
this->navigator.serviceWorkerServer->container.registerServiceWorker({
1061+
.type = serviceworker::Registration::Options::Type::Module,
1062+
.scriptURL = scriptURL,
1063+
.scope = scope,
1064+
.scheme = scheme,
1065+
.serializedWorkerArgs = "",
1066+
.id = id
1067+
});
1068+
}
1069+
} else {
1070+
debug("BEFORE REGISTER: %s %s", scheme.c_str(), scope.c_str());
10511071
this->navigator.serviceWorkerServer->container.registerServiceWorker({
10521072
.type = serviceworker::Registration::Options::Type::Module,
10531073
.scriptURL = scriptURL,
10541074
.scope = scope,
10551075
.scheme = scheme,
1056-
.serializedWorkerArgs = "",
1057-
.id = id
1058-
});
1059-
}
1060-
} else {
1061-
this->navigator.serviceWorkerServer->container.registerServiceWorker({
1062-
.type = serviceworker::Registration::Options::Type::Module,
1063-
.scriptURL = scriptURL,
1064-
.scope = scope,
1065-
.scheme = scheme,
1066-
.serializedWorkerArgs = encodeURIComponent(JSON::Object(JSON::Object::Entries {
1067-
{"index", this->client.index},
1068-
{"argv", JSON::Array {}},
1069-
{"env", env},
1070-
{"debug", isDebugEnabled()},
1071-
{"headless", this->userConfig["build_headless"] == "true"},
1072-
{"config", this->userConfig},
1073-
{"conduit", JSON::Object::Entries {
1076+
.serializedWorkerArgs = encodeURIComponent(JSON::Object(JSON::Object::Entries {
1077+
{"index", this->client.index},
1078+
{"argv", JSON::Array {}},
1079+
{"env", env},
1080+
{"debug", isDebugEnabled()},
1081+
{"headless", this->userConfig["build_headless"] == "true"},
1082+
{"config", this->userConfig},
1083+
{"conduit", JSON::Object::Entries {
10741084
{"port", this->getRuntime()->services.conduit.port},
10751085
{"hostname", this->getRuntime()->services.conduit.hostname},
10761086
{"sharedKey", this->getRuntime()->services.conduit.sharedKey}
1077-
}}
1078-
}).str()),
1079-
.id = id
1080-
});
1087+
}}
1088+
}).str()),
1089+
.id = id
1090+
});
1091+
}
10811092
}
10821093

1094+
debug("REGISTER SCHEME: %s", scheme.c_str());
10831095
this->schemeHandlers.registerSchemeHandler(scheme, [this](
10841096
auto request,
10851097
auto bridge,
@@ -1094,8 +1106,6 @@ export * from '{{url}}'
10941106
auto fetch = serviceworker::Request();
10951107
SharedPointer<serviceworker::Server> serviceWorkerServer = nullptr;
10961108

1097-
debug("request: %s", request->str().c_str());
1098-
10991109
if (window == nullptr) {
11001110
auto response = SchemeHandlers::Response(request);
11011111
response.writeHead(400);
@@ -1144,8 +1154,8 @@ export * from '{{url}}'
11441154
.waitForRegistrationToFinish = request->scheme != "npm"
11451155
};
11461156

1147-
debug("fetch: %s", fetch.str().c_str());
1148-
const auto origin = webview::Origin(request->str());
1157+
auto origin = webview::Origin(fetch.url.str());
1158+
origin.scheme = "socket";
11491159
debug("origin: %s", origin.name().c_str());
11501160
serviceWorkerServer = app->runtime.serviceWorkerManager.get(origin.name());
11511161
if (!serviceWorkerServer) {
@@ -1158,6 +1168,7 @@ export * from '{{url}}'
11581168
if (scope.size() > 0) {
11591169
fetch.url.pathname = scope + fetch.url.pathname;
11601170
}
1171+
debug("fetch: %s", fetch.str().c_str());
11611172

11621173
const auto fetched = serviceWorkerServer->fetch(fetch, options, [request, callback] (auto res) mutable {
11631174
if (!request->isActive()) {

src/runtime/ipc/routes.cc

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2406,14 +2406,14 @@ static void mapIPCRoutes (Router *router) {
24062406
const auto scheme = message.get("scheme");
24072407

24082408
for (const auto& entry : dynamic_cast<Bridge&>(router->bridge).navigator.serviceWorkerServer->container.registrations) {
2409-
const auto& scope = entry.first;
24102409
const auto& registration = entry.second;
24112410
if (registration.options.scheme == scheme) {
24122411
auto json = JSON::Object::Entries {
24132412
{"source", message.name},
24142413
{"data", JSON::Object::Entries {
24152414
{"id", registration.id},
2416-
{"scope", scope},
2415+
{"scope", registration.options.scope},
2416+
{"origin", registration.origin.name()},
24172417
{"scheme", scheme},
24182418
{"scriptURL", registration.options.scriptURL}
24192419
}}
@@ -2552,15 +2552,16 @@ static void mapIPCRoutes (Router *router) {
25522552
.type = serviceworker::Registration::Options::Type::Module,
25532553
.scriptURL = message.get("scriptURL"),
25542554
.scope = message.get("scope"),
2555-
.serializedWorkerArgs = encodeURIComponent(message.get("__runtime_worker_args"))
2555+
.scheme = message.get("scheme", "socket"),
2556+
.serializedWorkerArgs = encodeURIComponent(message.get("__runtime_worker_args", message.get("serializedWorkerArgs")))
25562557
};
25572558

25582559
const auto url = URL(options.scriptURL);
25592560
const auto origin = webview::Origin(url.str());
2561+
debug("register: (%s) %s", origin.name().c_str(), url.str().c_str());
25602562

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

@@ -2611,10 +2612,10 @@ static void mapIPCRoutes (Router *router) {
26112612
}
26122613

26132614
const auto scope = message.get("scope");
2614-
2615+
const auto origin = webview::Origin(dynamic_cast<Bridge&>(router->bridge).navigator.location.str());
26152616
for (const auto& entry : dynamic_cast<Bridge&>(router->bridge).navigator.serviceWorkerServer->container.registrations) {
26162617
const auto& registration = entry.second;
2617-
if (scope.starts_with(registration.options.scope)) {
2618+
if (registration.options.scheme == "socket" && registration.origin.name() == origin.name() && scope.starts_with(registration.options.scope)) {
26182619
auto json = JSON::Object {
26192620
JSON::Object::Entries {
26202621
{"registration", registration.json()},

src/runtime/serviceworker.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ namespace ssc::runtime::serviceworker {
7070

7171
class Registration {
7272
public:
73+
static String key (const String&, const URL&, const String& = "socket");
7374
struct Options {
7475
enum class Type { Classic, Module };
7576

0 commit comments

Comments
 (0)