neptune/source/util.d

153 lines
3.8 KiB
D
Raw Normal View History

2025-01-08 17:24:48 +03:00
module util;
import asdf;
2025-03-11 01:01:54 +03:00
__gshared Config cfg;
struct Config {
string token, homeserver;
string database_path;
bool accept_invitations;
}
2025-01-19 00:55:34 +03:00
string intToStr(T)(T num) {
2025-03-11 01:01:54 +03:00
if (num == 0) return "0";
char[] buf;
2025-03-11 01:01:54 +03:00
bool minus = num < 0;
if (minus) num /= -1;
for(short i; num > 0; ++i) {
buf = (num % 10 + '0')~buf;
2025-03-11 01:01:54 +03:00
num /= 10;
}
return cast(string)(minus ? '-'~buf : buf);
}
int strToInt(T)(T str) @nogc {
int num;
bool minus;
for (short i; str.length > i; ++i) {
if (str[i] == '-') minus = true;
else if (str[i] >= '0' || str[i] <= '9')
num = num * 10 + (str[i] - 48);
else break;
}
return minus ? num / -1 : num;
}
2025-01-08 17:24:48 +03:00
struct JsonObject {
import mir.conv: to;
2025-01-19 00:55:34 +03:00
string raw;
2025-01-08 17:24:48 +03:00
SerdeException deserializeFromAsdf(Asdf data) {
2025-01-19 00:55:34 +03:00
this.raw = data.to!string;
2025-01-08 17:24:48 +03:00
return null;
}
2025-03-11 01:01:54 +03:00
// void serialize(S)(ref S serializer) {
// try serializer.sink.putSmallEscaped(data.parseJson.to!string);
// catch (Exception) serializer.sink.putSmallEscaped("{}");
// }
2025-01-08 17:24:48 +03:00
}
2025-03-11 01:01:54 +03:00
struct RqRsp {
short status;
char[] body;
char[] headers;
string getHeader(string header) @nogc {
int prev, splt;
for (int i; i < headers.length; ++i) {
if (headers[i] == '\0') splt = i;
else if (headers[i] == '\1') {
if (header == headers[prev..splt])
return cast(string)headers[splt+2..i];
prev = i + 1;
}
}
return null;
}
2025-01-19 00:55:34 +03:00
}
2025-03-11 01:01:54 +03:00
size_t wrt(ubyte[]* outptt, size_t size, size_t nmemb, ubyte* inptt) {
auto len = size * nmemb;
*outptt ~= inptt[0..len];
return len;
}
2025-01-08 17:24:48 +03:00
2025-03-11 01:01:54 +03:00
// struct MM {
// char* rsp;
// size_t len;
// }
// size_t wrt(MM* outptt, size_t size, size_t nmemb, char* inptt) @nogc {
// import core.stdc.stdlib;
// import core.stdc.string;
// size_t rs = size * nmemb;
// outptt.rsp = cast(char*)realloc(outptt.rsp, outptt.len+rs+1);
// memcpy(&(outptt.rsp[outptt.len]), inptt, rs);
// outptt.len += rs;
// outptt.rsp[outptt.len] = '\0';
// return rs;
// }
size_t hddrz(ubyte[]* outptt, size_t size, size_t nmemb, ubyte* inptt) {
auto len = size * nmemb;
auto headers = inptt[0..len];
int prev;
for (int i; i < len; ++i) {
if (headers[i] == '\r' && headers[i + 1] == '\n') {
auto line = headers[prev..i];
prev = i + 1;
for (int x; x < line.length; ++x)
if (line[x] == ':') {
*outptt ~= line[0..x] ~ '\0' ~ line[x + 1..$] ~ '\1';
break;
}
}
2025-01-08 17:24:48 +03:00
}
2025-03-11 01:01:54 +03:00
return len;
}
2025-01-08 17:24:48 +03:00
2025-03-11 01:01:54 +03:00
import bindings.curl;
const char* UA = "Neptune/1.0 (https://code.lost-skunk.cc/neptune)";
// FIXME: memory corruption
RqRsp mkrqst(string url, string method = "GET", string content = null, bool authorized = false) {
RqRsp rsp;
auto hndl = curl_easy_init();
curl_easy_setopt(hndl, CURLOPT_URL, cast(char*)url);
curl_easy_setopt(hndl, CURLOPT_WRITEFUNCTION, &wrt);
curl_easy_setopt(hndl, CURLOPT_WRITEDATA, &rsp.body);
curl_easy_setopt(hndl, CURLOPT_USERAGENT, UA);
curl_easy_setopt(hndl, CURLOPT_HEADERFUNCTION, &hddrz);
curl_easy_setopt(hndl, CURLOPT_HEADERDATA, &rsp.headers);
if (method) curl_easy_setopt(hndl, CURLOPT_CUSTOMREQUEST, cast(char*)method);
if (content) {
curl_easy_setopt(hndl, CURLOPT_POST, 1);
curl_easy_setopt(hndl, CURLOPT_POSTFIELDS, cast(void*)content);
curl_easy_setopt(hndl, CURLOPT_POSTFIELDSIZE, content.length);
}
2025-01-08 17:24:48 +03:00
2025-03-11 01:01:54 +03:00
curl_slist* authhdr;
if (authorized) {
authhdr = curl_slist_append(null, cast(char*)cfg.token);
curl_easy_setopt(hndl, CURLOPT_HTTPHEADER, authhdr);
}
2025-01-08 17:24:48 +03:00
2025-03-11 01:01:54 +03:00
int rs = curl_easy_perform(hndl);
if (rs != 0) {
static foreach (err; __traits(allMembers, CURLcode)) {
if (rs == __traits(getMember, CURLcode, err))
throw new Exception(err);
2025-01-08 17:24:48 +03:00
}
}
2025-03-11 01:01:54 +03:00
curl_easy_getinfo(hndl, CURLINFO_RESPONSE_CODE, &rsp.status);
if (authorized) curl_slist_free_all(authhdr);
curl_easy_cleanup(hndl);
return rsp;
2025-01-19 00:55:34 +03:00
}
2025-03-11 01:01:54 +03:00
RqRsp mkhsrq(string uri, string method = "GET", string content = null) {
return mkrqst(cfg.homeserver ~ uri, method, content, true);
2025-01-08 17:24:48 +03:00
}