Skip to content

Commit 7c3f6d6

Browse files
committed
refactor(runtime/{serviceworker,core,ipc,http}): introduce SW priorities, improve conduit, clean up
1 parent 19963a3 commit 7c3f6d6

File tree

19 files changed

+252
-100
lines changed

19 files changed

+252
-100
lines changed

src/runtime/bridge/bridge.cc

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -455,13 +455,6 @@ export * from '{{url}}'
455455
auto origin = webview::Origin(request->scheme + "://" + request->hostname);
456456
auto serviceWorker = app->runtime.serviceWorkerManager.get(origin.name());
457457

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-
465458
if (
466459
serviceWorker != nullptr &&
467460
request->hostname != globalBundleIdentifier &&
@@ -486,7 +479,6 @@ export * from '{{url}}'
486479

487480
const auto app = App::sharedApplication();
488481
const auto options = serviceworker::Fetch::Options { request->client };
489-
debug("FETCH PLZ: %s", fetch.str().c_str());
490482
const auto fetched = serviceWorker->fetch(fetch, options, [
491483
this,
492484
applicationResources,
@@ -551,7 +543,6 @@ export * from '{{url}}'
551543
contentLocation = resourcePath.substr(applicationResources.size(), resourcePath.size());
552544
}
553545

554-
debug("RESOURCE PATH: %s", resourcePath.c_str());
555546
auto resource = filesystem::Resource(resourcePath);
556547

557548
if (!resource.exists()) {
@@ -723,6 +714,7 @@ export * from '{{url}}'
723714
auto fetch = serviceworker::Request();
724715
fetch.method = request->method;
725716
fetch.scheme = request->scheme;
717+
fetch.url.scheme = request->scheme;
726718
fetch.url.hostname = request->hostname;
727719
fetch.url.pathname = request->pathname;
728720
fetch.url.searchParams.set(request->query);
@@ -1067,7 +1059,6 @@ export * from '{{url}}'
10671059
});
10681060
}
10691061
} else {
1070-
debug("BEFORE REGISTER: %s %s", scheme.c_str(), scope.c_str());
10711062
this->navigator.serviceWorkerServer->container.registerServiceWorker({
10721063
.type = serviceworker::Registration::Options::Type::Module,
10731064
.scriptURL = scriptURL,
@@ -1091,7 +1082,6 @@ export * from '{{url}}'
10911082
}
10921083
}
10931084

1094-
debug("REGISTER SCHEME: %s", scheme.c_str());
10951085
this->schemeHandlers.registerSchemeHandler(scheme, [this](
10961086
auto request,
10971087
auto bridge,
@@ -1156,10 +1146,8 @@ export * from '{{url}}'
11561146

11571147
auto origin = webview::Origin(fetch.url.str());
11581148
origin.scheme = "socket";
1159-
debug("origin: %s", origin.name().c_str());
11601149
serviceWorkerServer = app->runtime.serviceWorkerManager.get(origin.name());
11611150
if (!serviceWorkerServer) {
1162-
debug("fall back to navigator serviceWorkerServer");
11631151
serviceWorkerServer = this->navigator.serviceWorkerServer;
11641152
}
11651153

@@ -1168,7 +1156,6 @@ export * from '{{url}}'
11681156
if (scope.size() > 0) {
11691157
fetch.url.pathname = scope + fetch.url.pathname;
11701158
}
1171-
debug("fetch: %s", fetch.str().c_str());
11721159

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

src/runtime/bytes.hh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ namespace ssc::runtime::bytes {
135135
Buffer& operator = (Buffer&&);
136136
Buffer& operator = (const String&);
137137

138+
unsigned char operator [] (size_t) const;
139+
unsigned char& operator [] (size_t);
140+
138141
size_t size () const;
139142

140143
template <size_t size>
@@ -146,7 +149,8 @@ namespace ssc::runtime::bytes {
146149
bool set (const unsigned char*, size_t, size_t);
147150
bool set (const char*, size_t, size_t);
148151

149-
unsigned char at (size_t) const;
152+
unsigned char at (ssize_t);
153+
unsigned char at (ssize_t) const;
150154
const unsigned char* data () const;
151155
unsigned char* data ();
152156
const Buffer slice (size_t, size_t = -1, bool = false) const;

src/runtime/bytes/buffer.cc

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,22 @@ namespace ssc::runtime::bytes {
295295
return *this;
296296
}
297297

298+
unsigned char Buffer::operator [] (size_t byteOffset) const {
299+
if (byteOffset >= this->byteLength) {
300+
throw Error("Buffer::operator[]: RangeError: 'byteOffset' exceeds 'byteLength'");
301+
}
302+
303+
return this->at(byteOffset);
304+
}
305+
306+
unsigned char& Buffer::operator [] (size_t byteOffset) {
307+
if (byteOffset >= this->byteLength) {
308+
throw Error("Buffer::operator[]: RangeError: 'byteOffset' exceeds 'byteLength'");
309+
}
310+
311+
return (this->buffer.bytes.get() + this->byteOffset)[byteOffset];
312+
}
313+
298314
size_t Buffer::size () const {
299315
return this->byteLength.load(std::memory_order_relaxed);
300316
}
@@ -357,12 +373,25 @@ namespace ssc::runtime::bytes {
357373
return true;
358374
}
359375

360-
unsigned char Buffer::at (size_t size) const {
376+
unsigned char Buffer::at (ssize_t size) {
377+
if (size >= this->byteLength) {
378+
throw Error("Buffer::at: RangeError: 'size' exceeds 'byteLength'");
379+
}
380+
381+
const auto data = this->data();
382+
if (data == nullptr) {
383+
return 0;
384+
}
385+
386+
return data[size];
387+
}
388+
389+
unsigned char Buffer::at (ssize_t size) const {
361390
if (size >= this->byteLength) {
362391
throw Error("Buffer::at: RangeError: 'size' exceeds 'byteLength'");
363392
}
364393

365-
const auto data = this->buffer.data();
394+
const auto data = this->data();
366395
if (data == nullptr) {
367396
return 0;
368397
}

src/runtime/core/services/ai.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ namespace ssc::runtime::core::services {
228228

229229
LLM::LLM (LLMOptions options) {
230230
llama_log_set([](ggml_log_level level, const char* message, void* llm) {
231-
debug("LLMSTATUS: %s", message);
231+
// debug("LLMSTATUS: %s", message);
232232
// llm.log(message);
233233
}, this);
234234

src/runtime/core/services/conduit.cc

Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
1-
#include <iostream>
2-
31
#include "../../runtime.hh"
42
#include "../../crypto.hh"
53
#include "../../config.hh"
64
#include "../../string.hh"
7-
#include "../../bytes.hh"
85
#include "../../http.hh"
96
#include "../../env.hh"
107
#include "../../ipc.hh"
118
#include "../../url.hh"
129

1310
#include "conduit.hh"
1411

15-
#define SHA_DIGEST_LENGTH 20
16-
1712
using ssc::runtime::config::getUserConfig;
1813
using ssc::runtime::string::toUpperCase;
1914
using ssc::runtime::crypto::rand64;
@@ -261,17 +256,34 @@ namespace ssc::runtime::core::services {
261256
Conduit::Client* client,
262257
const char* buffer
263258
) {
264-
const auto request = http::Request(buffer);
259+
auto request = http::Request(buffer);
260+
request.url.hostname = "127.0.0.1";
261+
request.url.scheme = "ws";
262+
request.scheme = "ws";
265263

266264
if (!request.valid()) {
267-
// TODO(@jwerle); handle malformed handshake request
265+
client->close();
268266
return;
269267
}
270268

271269
const auto webSocketKey = request.headers.get("sec-websocket-key");
272270

273271
if (webSocketKey.empty()) {
274272
// debug("Sec-WebSocket-Key is required but missing.");
273+
const auto buffer = bytes::Buffer(http::Response(400).str());
274+
client->write(buffer, [client]() {
275+
client->close();
276+
});
277+
return;
278+
}
279+
280+
const auto sharedKey = request.url.searchParams.get("key").str();
281+
if (sharedKey != this->sharedKey) {
282+
// debug("Conduit::Client failed auth");
283+
const auto buffer = bytes::Buffer(http::Response(403).str());
284+
client->write(buffer, [client]() {
285+
client->close();
286+
});
275287
return;
276288
}
277289

@@ -283,7 +295,7 @@ namespace ssc::runtime::core::services {
283295
}
284296

285297
try {
286-
client->clientId = request.url.pathComponents.get<int>(1);
298+
client->client.id = request.url.pathComponents.get<int>(1);
287299
} catch (...) {
288300
// debug("Unable to parse client id");
289301
}
@@ -306,45 +318,16 @@ namespace ssc::runtime::core::services {
306318
// std::cout << "added client " << this->clients.size() << std::endl;
307319
} while (0);
308320

309-
if (sharedKey != this->sharedKey) {
310-
debug("Conduit::Client failed auth");
311-
client->close();
312-
return;
313-
}
314-
315321
const auto response = http::Response(101)
316322
.setHeader("upgrade", "websocket")
317323
.setHeader("connection", "upgrade")
318324
.setHeader(
319325
"sec-websocket-accept",
320-
bytes::base64::encode(sha1(webSocketKey + WS_GUID))
321-
);
322-
323-
const auto output = response.str();
324-
const auto size = output.size();
325-
const auto data = new char[size]{0};
326-
memcpy(data, output.c_str(), size);
327-
328-
const auto buf = uv_buf_init(data, size);
329-
330-
auto req = new uv_write_t;
331-
auto handle = reinterpret_cast<uv_handle_t*>(req);
332-
auto stream = reinterpret_cast<uv_stream_t*>(&client->handle);
333-
334-
uv_handle_set_data(handle, data);
335-
uv_write(req, stream, &buf, 1, [](uv_write_t *req, int status) {
336-
const auto data = reinterpret_cast<char*>(
337-
uv_handle_get_data(reinterpret_cast<uv_handle_t*>(req))
326+
bytes::base64::encode(crypto::SHA1(webSocketKey + WS_GUID).finalize())
338327
);
339328

340-
if (data != nullptr) {
341-
delete [] data;
342-
}
343-
344-
delete req;
345-
});
346-
347-
client->isHandshakeDone = 1;
329+
client->write(response.str());
330+
client->isHandshakeDone = true;
348331
}
349332

350333
void Conduit::processFrame (
@@ -488,8 +471,8 @@ namespace ssc::runtime::core::services {
488471
const auto bytes = vectorToSharedPointer(buffer);
489472
const auto message = ipc::Message(uri);
490473

491-
auto window = client && client->clientId > 0
492-
? this->context.getRuntime()->windowManager.getWindowForClient({ client->clientId })
474+
auto window = client && client->client.id > 0
475+
? this->context.getRuntime()->windowManager.getWindowForClient({ client->client.id })
493476
: nullptr;
494477

495478
// prevent external usage of internal routes
@@ -649,6 +632,41 @@ namespace ssc::runtime::core::services {
649632
return true;
650633
}
651634

635+
bool Conduit::Client::write (const bytes::Buffer& buffer, const WriteCallback callback) {
636+
auto buf = uv_buf_init(reinterpret_cast<char*>(const_cast<unsigned char*>(buffer.data())), buffer.size());
637+
auto req = new uv_write_t;
638+
auto handle = reinterpret_cast<uv_handle_t*>(req);
639+
auto stream = reinterpret_cast<uv_stream_t*>(&this->handle);
640+
641+
if (callback != nullptr) {
642+
uv_handle_set_data(
643+
reinterpret_cast<uv_handle_t*>(req),
644+
new ClientWriteContext { this, callback }
645+
);
646+
} else {
647+
uv_handle_set_data(
648+
reinterpret_cast<uv_handle_t*>(req),
649+
nullptr
650+
);
651+
}
652+
653+
uv_write(req, stream, &buf, 1, [](uv_write_t *req, int status) {
654+
const auto data = uv_handle_get_data(reinterpret_cast<uv_handle_t*>(req));
655+
const auto context = static_cast<ClientWriteContext*>(data);
656+
657+
delete req;
658+
659+
if (context != nullptr) {
660+
context->client->conduit->loop.dispatch([=]() mutable {
661+
context->callback();
662+
delete context;
663+
});
664+
}
665+
});
666+
667+
return true;
668+
}
669+
652670
struct ClientCloseContext {
653671
Conduit::Client* client = nullptr;
654672
Conduit::Client::CloseCallback callback = nullptr;

src/runtime/core/services/conduit.hh

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#ifndef SOCKET_RUNTIME_CORE_SERVICES_CONDUIT_H
22
#define SOCKET_RUNTIME_CORE_SERVICES_CONDUIT_H
33

4-
#include "../../core.hh"
54
#include "../../ipc.hh"
5+
#include "../../core.hh"
6+
#include "../../bytes.hh"
67

78
namespace ssc::runtime::core::services {
89
class Conduit : public core::Service {
@@ -39,13 +40,13 @@ namespace ssc::runtime::core::services {
3940

4041
class Client {
4142
public:
42-
using CloseCallback = Function<void()>;
4343
using SendCallback = Function<void()>;
44+
using WriteCallback = Function<void()>;
45+
using CloseCallback = Function<void()>;
4446
using ID = uint64_t;
4547

4648
ID id = 0;
47-
// client state
48-
ID clientId = 0;
49+
ipc::Client client;
4950
Atomic<bool> isHandshakeDone = false;
5051
Atomic<bool> isClosing = false;
5152
Atomic<bool> isClosed = false;
@@ -64,13 +65,20 @@ namespace ssc::runtime::core::services {
6465
Client (Conduit* conduit)
6566
: conduit(conduit),
6667
id(0),
67-
clientId(0),
6868
isHandshakeDone(0)
6969
{}
7070

7171
~Client ();
7272

73-
bool send ( const Message::Options&, SharedPointer<unsigned char[]>, size_t, int opcode = 2, const SendCallback = nullptr);
73+
bool send (
74+
const Message::Options&,
75+
SharedPointer<unsigned char[]>,
76+
size_t,
77+
int opcode = 2,
78+
const SendCallback = nullptr
79+
);
80+
81+
bool write (const bytes::Buffer&, const WriteCallback = nullptr);
7482
void close (const CloseCallback callback = nullptr);
7583
};
7684

src/runtime/crypto/sha1.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,5 +214,4 @@ namespace ssc::runtime::crypto {
214214
const String sha1 (const unsigned char * input, size_t size) {
215215
return SHA1(input, size).str();
216216
}
217-
218217
}

src/runtime/http/headers.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,11 @@ namespace ssc::runtime::http {
144144

145145
headers << name << ": " << entry.value.str();
146146
if (--remaining > 0) {
147-
headers << "\n";
147+
headers << "\r\n";
148148
}
149149
}
150150

151-
return headers.str() + "\r\n";
151+
return headers.str() + "\r\n\r\n";
152152
}
153153

154154
const Headers::Iterator Headers::begin () const noexcept {

0 commit comments

Comments
 (0)