153 lines
3.8 KiB
D
153 lines
3.8 KiB
D
module util;
|
|
import asdf;
|
|
|
|
__gshared Config cfg;
|
|
struct Config {
|
|
string token, homeserver;
|
|
string database_path;
|
|
bool accept_invitations;
|
|
}
|
|
|
|
string intToStr(T)(T num) {
|
|
if (num == 0) return "0";
|
|
|
|
char[] buf;
|
|
bool minus = num < 0;
|
|
if (minus) num /= -1;
|
|
for(short i; num > 0; ++i) {
|
|
buf = (num % 10 + '0')~buf;
|
|
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;
|
|
}
|
|
|
|
struct JsonObject {
|
|
import mir.conv: to;
|
|
string raw;
|
|
|
|
SerdeException deserializeFromAsdf(Asdf data) {
|
|
this.raw = data.to!string;
|
|
return null;
|
|
}
|
|
|
|
// void serialize(S)(ref S serializer) {
|
|
// try serializer.sink.putSmallEscaped(data.parseJson.to!string);
|
|
// catch (Exception) serializer.sink.putSmallEscaped("{}");
|
|
// }
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
size_t wrt(ubyte[]* outptt, size_t size, size_t nmemb, ubyte* inptt) {
|
|
auto len = size * nmemb;
|
|
*outptt ~= inptt[0..len];
|
|
return len;
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
}
|
|
}
|
|
return len;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
curl_slist* authhdr;
|
|
if (authorized) {
|
|
authhdr = curl_slist_append(null, cast(char*)cfg.token);
|
|
curl_easy_setopt(hndl, CURLOPT_HTTPHEADER, authhdr);
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
curl_easy_getinfo(hndl, CURLINFO_RESPONSE_CODE, &rsp.status);
|
|
if (authorized) curl_slist_free_all(authhdr);
|
|
curl_easy_cleanup(hndl);
|
|
return rsp;
|
|
}
|
|
|
|
RqRsp mkhsrq(string uri, string method = "GET", string content = null) {
|
|
return mkrqst(cfg.homeserver ~ uri, method, content, true);
|
|
} |