From 7fbdd031ff0e8520b7088de81b366ada0ac29155 Mon Sep 17 00:00:00 2001 From: marisa Date: Wed, 21 Feb 2024 15:39:41 -0300 Subject: [PATCH] Minor improvements - WebFinger: detect when to use http or https, better function naming - RequestPool: add user agent --- source/main.d | 49 ++++++++++++++++++++++++++++++++++----- source/net/request_pool.d | 4 +--- source/singletons.d | 2 +- source/util.d | 20 ++++++++++++++++ source/webfinger.d | 21 +++++++++-------- 5 files changed, 76 insertions(+), 20 deletions(-) diff --git a/source/main.d b/source/main.d index 07284a9..82c767e 100644 --- a/source/main.d +++ b/source/main.d @@ -11,24 +11,61 @@ import singletons; import db.db; import net.request_pool; import webfinger; +import ap.actor; +import ap.util; +import std.math.remainder; +import util; void commonInit() { auto provider = new DefaultProvider(true, Levels.DEBUG); configureLoggingProvider(provider); - RP = new RequestPool(); - RP.startBackground(); + Config cfg = loadConfig(); + initRequestPool(cfg); + initDatabase(cfg); +} + +Config loadConfig() { + Config cfg = new Config(); + cfg.load(); + return cfg; +} + +void initRequestPool(Config cfg) { + Rp = new RequestPool(); + Rp.startBackground(); +} + +void initDatabase(Config cfg) { + Db = new DB(DBSettings.fromJson(cfg.v["db"])); + Db.connect(); } void main() { commonInit(); - scope (exit) - RP.stop(); + scope (exit) { + Db.close(); + Rp.stop(); + } - JSONValue js = requestAcct("localhost:8080", "admin"); + generateRSA(); + return; - infoF!"Response body: %s"(js.toJSON(true)); + Actor marisa = apResolveRemoteUsername("@admin@localhost:8080"); + infoF!"Actor type: %s"(marisa.type); + infoF!"Actor preferredUsername: %s"(marisa.preferredUsername); + infoF!"Actor sharedInbox: %s"(marisa.endpoints.sharedInbox); + + PRequest followers = PRequest(); + + with (followers) { + url = marisa.followers; + headers["Accept"] = "application/activity+json"; + } + + Response rs = Rp.request(followers, true); + infoF!"followers: %s"(rs.responseBody); } //int main() { diff --git a/source/net/request_pool.d b/source/net/request_pool.d index fd1aea5..5570a69 100644 --- a/source/net/request_pool.d +++ b/source/net/request_pool.d @@ -1,8 +1,5 @@ module net.request_pool; -import core.thread; -import core.sync.semaphore; - import std.container; import std.parallelism; @@ -32,6 +29,7 @@ class RequestPool { for (int i = 0; i < totalWorkers + 1; i++) { Request rq = Request(); // TODO: add custom fields (such as user agent) + rq.addHeaders(["User-Agent": "apd (development)"]); this.m_requests ~= rq; } } diff --git a/source/singletons.d b/source/singletons.d index 7fdaf29..b20d380 100644 --- a/source/singletons.d +++ b/source/singletons.d @@ -4,4 +4,4 @@ import db.db; import net.request_pool; DB Db; -RequestPool RP; +RequestPool Rp; diff --git a/source/util.d b/source/util.d index 2aef033..b02c2d9 100644 --- a/source/util.d +++ b/source/util.d @@ -3,6 +3,11 @@ module util; import std.format; import std.json; +import slf4d; + +import deimos.openssl.rsa; +import deimos.openssl.pem; + void optional(T)(ref JSONValue val, string key, ref T receiver) { const(JSONValue)* p = key in val; @@ -24,3 +29,18 @@ T optional(T)(ref JSONValue val, string key) { void required(T)(ref JSONValue val, string key, ref T receiver) { receiver = val[key].get!T; } + +void generateRSA() { + RSA* rsa = RSA_generate_key(2048, 3, null, null); + BIO* bio = BIO_new(BIO_s_mem()); + PEM_write_bio_RSAPrivateKey(bio, rsa, null, null, 0, null, null); + + int keyLen = BIO_pending(bio); + char[] pemKey = new char[keyLen + 1]; + BIO_read(bio, pemKey.ptr, keyLen); + + BIO_free_all(bio); + RSA_free(rsa); + + infoF!"private key: %s"(pemKey); +} diff --git a/source/webfinger.d b/source/webfinger.d index 998bd14..0e2b6cf 100644 --- a/source/webfinger.d +++ b/source/webfinger.d @@ -18,11 +18,15 @@ private bool checkValidWebfingerResponse(Response rs) { return AcceptedWebfingerContentType.canFind(rs.responseHeaders()["content-type"].split(";")[0]); } -PRequest buildRequest(string uri, string[string] params) { +private PRequest buildRequest(string uri, string[string] params) { PRequest rq = PRequest(); + string schema = "https"; + + if (uri.startsWith("localhost")) + schema = "http"; rq.method = "GET"; - rq.url = format("https://%s/.well-known/webfinger", uri); + rq.url = format("%s://%s/.well-known/webfinger", schema, uri); rq.headers["Accept"] = AcceptedWebfingerContentType; QueryParam[] p; @@ -41,8 +45,8 @@ PRequest buildAcctRequest(string uri, string acct) { return buildRequest(uri, params); } -JSONValue requestAcct(string uri, string acct) { - Response rs = RP.request(buildAcctRequest(uri, acct), true); +JSONValue wfRequestAccount(string uri, string acct) { + Response rs = Rp.request(buildAcctRequest(uri, acct), true); if (checkValidWebfingerResponse(rs) == false) throw new Exception("Invalid webfinger response"); @@ -50,11 +54,8 @@ JSONValue requestAcct(string uri, string acct) { return parseJSON(rs.responseBody().toString()); } -JSONValue requestAcct(string handle) { - string uri, acct; +JSONValue wfRequestAccount(string handle) { + string[] uriAcct = handle.split("@")[$ - 2 .. $]; - uri = handle.split("@")[$ - 1]; - acct = handle.split("@")[$ - 2]; - - return requestAcct(uri, acct); + return wfRequestAccount(uriAcct[1], uriAcct[0]); }