module webfinger; import std.algorithm; import std.array; import std.format; import std.json; import std.typecons; import requests; import net.request_pool; import singletons; enum AcceptedWebfingerContentType = "application/jrd+json, application/json"; private bool checkValidWebfingerResponse(Response rs) { return AcceptedWebfingerContentType.canFind(rs.responseHeaders()["content-type"].split(";")[0]); } 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("%s://%s/.well-known/webfinger", schema, uri); rq.headers["Accept"] = AcceptedWebfingerContentType; QueryParam[] p; foreach (k, v; params) p ~= tuple!("key", "value")(k, v); rq.params = p; return rq; } PRequest buildAcctRequest(string uri, string acct) { string[string] params = ["resource": format("acct:%s@%s", acct, uri)]; return buildRequest(uri, params); } JSONValue wfRequestAccount(string uri, string acct) { Response rs = RP.request(buildAcctRequest(uri, acct), true); if (checkValidWebfingerResponse(rs) == false) throw new Exception("Invalid webfinger response"); return parseJSON(rs.responseBody().toString()); } JSONValue wfRequestAccount(string handle) { string[] uriAcct = handle.split("@")[$ - 2 .. $]; return wfRequestAccount(uriAcct[1], uriAcct[0]); }