diff --git a/.gitignore b/.gitignore index 932cb35..569477f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,15 +2,17 @@ docs.json __dummy.html docs/ -/skunkybot-d -skunkybot-d.so -skunkybot-d.dylib -skunkybot-d.dll -skunkybot-d.a -skunkybot-d.lib -skunkybot-d-test-* +/neptune +neptune.so +neptune.dylib +neptune.dll +neptune.a +neptune.lib +neptune-test-* *.exe *.pdb *.o +*.db *.obj *.lst +config.json diff --git a/README.md b/README.md index 756a99f..1fddd59 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,13 @@ # TODO - [ ] get rid of indian code +- [x] make function listener asynchronious +- [x] make all as replies +- [x] APOD (https://api.nasa.gov/) +- [ ] implement encrypting +- [ ] implement admin tools (i.e. ban, mute, kick, etc) - [ ] implement shared-library modules - [ ] implement config -- [ ] implement forgejo/gitea webhooks +- [ ] implement MSC2448 +- [ ] implement rss feeds # INFO -говнобот \ No newline at end of file +Deps: sqlite3, libolm, libcurl \ No newline at end of file diff --git a/config.example.json b/config.example.json new file mode 100644 index 0000000..8959813 --- /dev/null +++ b/config.example.json @@ -0,0 +1,7 @@ +{ + "homeserver": "http://192.168.1.132:8008", + "token": "zfPqqre33zFgLECg71cQxNHdNByDAsvh", + "status": "https://code.lost-skunk.cc/neptune", + "database_path": "matrix.db", + "accept_invitations": true +} \ No newline at end of file diff --git a/dub.sdl b/dub.sdl index b6dc7a0..def4eba 100644 --- a/dub.sdl +++ b/dub.sdl @@ -1,6 +1,12 @@ -name "skunkybot-d" +name "neptune" description "Matrix bot" -authors "skunk" -copyright "Copyright © 2025, skunk" +authors "lost+skunk" +copyright "Copyright © 2025, lost+skunk" license "AGPL-3.0-only" +dependency "gamut" version="~>3.2.0" +dependency "database:sqlite" version="~>1.2.1" +dependency "database" version="~>1.2.1" dependency "asdf" version="~>0.7.17" +dflags "-L-s" +dflags "-mcpu=native" platform="ldc" +libs "curl" diff --git a/dub.selections.json b/dub.selections.json index 9d35756..eaf0b24 100644 --- a/dub.selections.json +++ b/dub.selections.json @@ -2,8 +2,19 @@ "fileVersion": 1, "versions": { "asdf": "0.7.17", + "automem": "0.6.11", + "cachetools": "0.4.1", + "database": "1.2.1", + "gamut": "3.2.0", + "intel-intrinsics": "1.11.25", + "miniz": "0.0.1", "mir-algorithm": "3.22.3", "mir-core": "1.7.1", - "silly": "1.1.1" + "mir-cpuid": "1.2.11", + "mir-ion": "2.3.3", + "requests": "2.1.3", + "silly": "1.1.1", + "test_allocator": "0.3.4", + "unit-threaded": "0.10.8" } } diff --git a/source/api.d b/source/api.d new file mode 100644 index 0000000..0e4ddae --- /dev/null +++ b/source/api.d @@ -0,0 +1,35 @@ +module api; +import util, asdf, api_data; + +void send(T)(T content, string roomid, string type = "m.room.message") { + import std.random: uniform; + mkhsrq("/_matrix/client/v3/rooms/" ~ roomid ~ "/send/" ~ type ~ + "/skunky-" ~ intToStr(uniform(1111_1111, 9999_9999)), "PUT", content.serializeToJson); +} + +void rawState(string room, string name, string content) { + mkhsrq ( + "/_matrix/client/v3/rooms/" ~ room ~ "/state/" ~ name, + "PUT", + content + ); +} + +void state(T)(string room, string name, T content) { + rawState(room, name, content.serializeToJson); +} + +T getState(T)(string room, string name) { + return mkhsrq("/_matrix/client/v3/rooms/" ~ room ~ "/state/" ~ name).body.deserialize!T; +} + +MSG event(string id, string room) { + struct Evt { MSG content; } + return (mkhsrq("/_matrix/client/v3/rooms/" ~ room ~ "/event/" ~ id).body.deserialize!Evt).content; +} + +string upload(T)(T file) { + struct Upload { string content_uri; } + return (mkhsrq("/_matrix/media/v3/upload", "POST", cast(string)file) + .body.deserialize!Upload).content_uri; +} \ No newline at end of file diff --git a/source/api_data.d b/source/api_data.d new file mode 100644 index 0000000..eacdd35 --- /dev/null +++ b/source/api_data.d @@ -0,0 +1,110 @@ +module api_data; +import mir.serde, util: JsonObject; + +struct Moderate { + string user_id; + @serdeOptional string reason; +} + +struct State { + struct PowerLevels { + short[string] users; + } + + struct ACL { + @serdeOptional: + bool allow_ip_literals; + string[] allow = ["*"]; + string[] deny; + } + + JsonObject content; + string event_id; + string sender; + string type; +} + +struct Encrypted { + char[] algorithm; + char[] ciphertext; + char[] device_id; + char[] sender_key; + char[] session_id; +} + +struct MSG { + struct Meta { + int h, w; + ulong size; + string mimetype; + } + + struct Relates { + struct EvtBase { + string event_id; + } + + @serdeOptional @serdeKeys("m.in_reply_to") EvtBase reply; + } + + string body; + @serdeOptional @serdeIgnoreDefault string formatted_body; + string msgtype = "m.notice"; + @serdeOptional string format = "org.matrix.custom.html"; + + @serdeOptional @serdeIgnoreDefault: + @serdeKeys("m.relates_to") Relates relates; + string rel_type; + string url; + string filename; + Meta info; +} + +struct Sync { + struct StrippedStateEvent { + JsonObject content; + string sender, state_key, type; + } + + struct Unsigned { + int age; + string membership, transaction_id; + } + + struct Rooms { + struct Invited { + struct IS { StrippedStateEvent[] events; } + IS invite_state; + } + struct Joined { + struct Timeline { + EventWithoutRoomID[] events; + @serdeOptional bool limited; + string prev_batch; + } + + struct UNC { + int highlight_count; + int notification_count; + } + + @serdeOptional Timeline timeline; + @serdeOptional UNC unread_notifications; + } + + @serdeOptional Invited[string] invite; + @serdeOptional Joined[string] join; + } + + @serdeOptional Rooms rooms; + string next_batch; +} + +struct EventWithoutRoomID { + JsonObject content; + string event_id; + ulong origin_server_ts; + @serdeOptional string sender, state_key, type; + @serdeIgnore string room; + // Unsigned unsigned; +} \ No newline at end of file diff --git a/source/app.d b/source/app.d index 0540ee0..a19280c 100644 --- a/source/app.d +++ b/source/app.d @@ -1,101 +1,104 @@ +module main; + import std.stdio: writeln; -import std.net.curl; import asdf: deserialize, serializeToJson; import util; +import listener; -void main() { - import std.process: environment; - alias env = environment.get; - homeserver = env("SKUNKYBOT_HOMESERVER"); - init(env("SKUNKYBOT_TOKEN")); - sync; -} +import database.sqlite.db; +__gshared SQLite3DB db; -HTTP http; -string syncUrl; -string initialBatch; -void init(string token) { - http = HTTP(); - http.addRequestHeader("Authorization", "Bearer " ~ token); - http.tcpNoDelay = true; +int main(string[] args) { + import core.stdc.stdio; - // initial sync - writeln("starting initial sync.."); - syncUrl = homeserver ~ "/_matrix/client/v3/sync?set_presence=online"; - initialBatch = (get(syncUrl, http).deserialize!Sync).next_batch; syncUrl ~= "&since="; - writeln("done!"); -} + char buf; + char[] fileStr; + auto file = fopen("config.json", "r"); + if (file is null) return 1; + while ((buf = cast(char)fgetc(file)) != 255) + fileStr ~= buf; + fclose(file); -void send(T)(T content, string roomid, string type = "m.room.message") { - import std.random: uniform; - put(homeserver~"/_matrix/client/v3/rooms/" ~ roomid ~ "/send/" ~ type ~ - "/skunky-" ~ intToStr(uniform(1111_1111, 9999_9999)), content.serializeToJson, http); -} + cfg = fileStr.deserialize!Config; + cfg.token = "Authorization: Bearer " ~ cfg.token; -// void join(string roomid) { -// post(homeserver~"/_matrix/client/v3/rooms/"~roomid~"/join", http); -// } + if (args.length == 5 && args[1] == "get-token") { + auto rq = mkrqst( + args[2]~"/_matrix/client/v3/login", "POST", + `{ + "identifier": { + "type": "m.id.user", + "user": "`~args[3]~`" + }, + "initial_device_display_name": "Neptune Bot", + "password": "`~args[4]~`", + "type": "m.login.password" + }`, + true + ); -import commands; -static MSG helpgen() { - string buf; - static foreach (member; __traits(allMembers, commands)) { - static foreach (attr; __traits(getAttributes, __traits(getMember, commands, member))) { - static if (is(typeof(attr) == Command)) buf ~= member ~ ": " ~ attr.description ~ '\n'; + if (rq.status != 200) { + writeln("Something went wrong :(\n", rq.body); + return 1; } + + struct Login { + string access_token; + } + + writeln("Your access token: \033[0;32m", (rq.body.deserialize!Login).access_token, "\033[0m.\n", + "Save it!"); + return 0; } - return MSG(buf); -} -void sync() { - auto content = Sync(); - content.next_batch = initialBatch; - for (;;) { - string bthUrl = syncUrl ~ content.next_batch; - try content = get(bthUrl, http).deserialize!Sync; - catch (Exception e) { writeln("ERR: ", e.msg); continue; } + init; - foreach (room, _; content.rooms.invite) { - writeln("Joining to room: ", room); - post(homeserver~"/_matrix/client/v3/rooms/"~room~"/join", null, http); - send(MSG("Йа криведко"), room); - } - foreach (room, roomContent; content.rooms.join) { - foreach(event; roomContent.timeline.events) { - if (event.type == "m.room.message") { - try { - auto evt = deserialize!MSG(event.content.raw); - if (!evt.body.length) break; - auto argz = parseMsg(evt.body); - - if (argz.command == "hlp") { - send(helpgen, room); - break; - } - - foreach (member; __traits(allMembers, commands)) { - if (argz.command == member) { - alias command = __traits(getMember, commands, member); - foreach (attr; __traits(getAttributes, command)) { - static if (is(typeof(attr) == Command)) { - static if (is(typeof(command) == function)) - auto content = command(argz, &event); - else static if (__traits(isStaticArray, command)) - auto content = MSG(command[0], command[1]); - else - auto content = MSG(command); - send(content, room); - } - } - } - } - } catch (Exception e) { - writeln(e.msg); - send(MSG(e.msg), room); - } - } + import core.thread; + import commands.slaves; + alias sl = commands.slaves; + static foreach (member; __traits(allMembers, sl)) { + static foreach (attr; __traits(getAttributes, __traits(getMember, sl, member))) { + static if (is(attr == Parallel)) { + new Thread(&__traits(getMember, sl, member)).start; } } } + + import commands.apod, + commands.misc, + commands.mozhi, + commands.moderation; + + listen!( + commands.apod, + commands.misc, + commands.mozhi, + commands.moderation, + ); + + return 0; +} + +// https://m.lost-skunk.cc/_matrix/client/v3/presence/@me:lost-skunk.cc/status +void init() { + db = SQLite3DB(cfg.database_path); + syncUrl = "/_matrix/client/v3/sync?set_presence=online"; + db.exec("create table if not exists client (latest_batch string)"); + db.exec("create table if not exists room_pls (room string, user string, pl integer)"); + auto q = db.query("select latest_batch from client"); + + if (q.step) initialBatch = q.get!string; + else { + import api_data: Sync; + writeln("starting initial sync.."); + Sync snk = mkhsrq(syncUrl).body.deserialize!Sync; + initialBatch = snk.next_batch; + db.exec("insert into client (latest_batch) values (?)", initialBatch); + writeln("done!"); + + foreach(room; snk.rooms.join.keys) fetchMembers(room); + } + + syncUrl ~= "&since="; } \ No newline at end of file diff --git a/source/bindings/curl.d b/source/bindings/curl.d new file mode 100644 index 0000000..0a57ab9 --- /dev/null +++ b/source/bindings/curl.d @@ -0,0 +1,2223 @@ +module bindings.curl; + +import core.stdc.config; +import core.sys.posix.sys.select; +import core.sys.posix.sys.socket; + +extern (C): + +alias curl_off_t = long; +alias CURL = void; +alias CURLSH = void; + +alias curl_socket_t = int; +enum CURL_SOCKET_BAD = -1; + +enum curl_sslbackend +{ + CURLSSLBACKEND_NONE = 0, + CURLSSLBACKEND_OPENSSL = 1, + CURLSSLBACKEND_GNUTLS = 2, + CURLSSLBACKEND_NSS = 3, + CURLSSLBACKEND_OBSOLETE4 = 4, + CURLSSLBACKEND_GSKIT = 5, + CURLSSLBACKEND_POLARSSL = 6, + CURLSSLBACKEND_WOLFSSL = 7, + CURLSSLBACKEND_SCHANNEL = 8, + CURLSSLBACKEND_SECURETRANSPORT = 9, + CURLSSLBACKEND_AXTLS = 10, + CURLSSLBACKEND_MBEDTLS = 11, + CURLSSLBACKEND_MESALINK = 12, + CURLSSLBACKEND_BEARSSL = 13, + CURLSSLBACKEND_RUSTLS = 14 +} + +alias CURLSSLBACKEND_NONE = curl_sslbackend.CURLSSLBACKEND_NONE; +alias CURLSSLBACKEND_OPENSSL = curl_sslbackend.CURLSSLBACKEND_OPENSSL; +alias CURLSSLBACKEND_GNUTLS = curl_sslbackend.CURLSSLBACKEND_GNUTLS; +alias CURLSSLBACKEND_NSS = curl_sslbackend.CURLSSLBACKEND_NSS; +alias CURLSSLBACKEND_OBSOLETE4 = curl_sslbackend.CURLSSLBACKEND_OBSOLETE4; +alias CURLSSLBACKEND_GSKIT = curl_sslbackend.CURLSSLBACKEND_GSKIT; +alias CURLSSLBACKEND_POLARSSL = curl_sslbackend.CURLSSLBACKEND_POLARSSL; +alias CURLSSLBACKEND_WOLFSSL = curl_sslbackend.CURLSSLBACKEND_WOLFSSL; +alias CURLSSLBACKEND_SCHANNEL = curl_sslbackend.CURLSSLBACKEND_SCHANNEL; +alias CURLSSLBACKEND_SECURETRANSPORT = curl_sslbackend.CURLSSLBACKEND_SECURETRANSPORT; +alias CURLSSLBACKEND_AXTLS = curl_sslbackend.CURLSSLBACKEND_AXTLS; +alias CURLSSLBACKEND_MBEDTLS = curl_sslbackend.CURLSSLBACKEND_MBEDTLS; +alias CURLSSLBACKEND_MESALINK = curl_sslbackend.CURLSSLBACKEND_MESALINK; +alias CURLSSLBACKEND_BEARSSL = curl_sslbackend.CURLSSLBACKEND_BEARSSL; +alias CURLSSLBACKEND_RUSTLS = curl_sslbackend.CURLSSLBACKEND_RUSTLS; + +enum CURLSSLBACKEND_AWSLC = curl_sslbackend.CURLSSLBACKEND_OPENSSL; +enum CURLSSLBACKEND_BORINGSSL = curl_sslbackend.CURLSSLBACKEND_OPENSSL; +enum CURLSSLBACKEND_LIBRESSL = curl_sslbackend.CURLSSLBACKEND_OPENSSL; + +enum CURLSSLBACKEND_CYASSL = curl_sslbackend.CURLSSLBACKEND_WOLFSSL; +enum CURLSSLBACKEND_DARWINSSL = curl_sslbackend.CURLSSLBACKEND_SECURETRANSPORT; + +struct curl_httppost +{ + curl_httppost* next; + char* name; + c_long namelength; + char* contents; + c_long contentslength; + + char* buffer; + c_long bufferlength; + char* contenttype; + + struct curl_slist + { + char* data; + curl_slist* next; + } + + curl_slist* contentheader; + curl_httppost* more; + c_long flags; + char* showfilename; + void* userp; + alias curl_off_t = c_long; + curl_off_t contentlen; +} + +enum CURL_HTTPPOST_FILENAME = 1 << 0; +enum CURL_HTTPPOST_READFILE = 1 << 1; +enum CURL_HTTPPOST_PTRNAME = 1 << 2; +enum CURL_HTTPPOST_PTRCONTENTS = 1 << 3; +enum CURL_HTTPPOST_BUFFER = 1 << 4; +enum CURL_HTTPPOST_PTRBUFFER = 1 << 5; +enum CURL_HTTPPOST_CALLBACK = 1 << 6; +enum CURL_HTTPPOST_LARGE = 1 << 7; +enum CURL_PROGRESSFUNC_CONTINUE = 0x10000001; +alias curl_progress_callback = int function (void* clientp, double dltotal, double dlnow, double ultotal, double ulnow); +alias curl_xferinfo_callback = int function (void* clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow); +enum CURL_MAX_READ_SIZE = 10 * 1024 * 1024; +enum CURL_MAX_WRITE_SIZE = 16384; +enum CURL_MAX_HTTP_HEADER = 100 * 1024; +enum CURL_WRITEFUNC_PAUSE = 0x10000001; +enum CURL_WRITEFUNC_ERROR = 0xFFFFFFFF; +alias curl_write_callback = c_ulong function (char* buffer, size_t size, size_t nitems, void* outstream); +alias curl_resolver_start_callback = int function (void* resolver_state, void* reserved, void* userdata); + +enum curlfiletype +{ + CURLFILETYPE_FILE = 0, + CURLFILETYPE_DIRECTORY = 1, + CURLFILETYPE_SYMLINK = 2, + CURLFILETYPE_DEVICE_BLOCK = 3, + CURLFILETYPE_DEVICE_CHAR = 4, + CURLFILETYPE_NAMEDPIPE = 5, + CURLFILETYPE_SOCKET = 6, + CURLFILETYPE_DOOR = 7, + CURLFILETYPE_UNKNOWN = 8 +} + +alias CURLFILETYPE_FILE = curlfiletype.CURLFILETYPE_FILE; +alias CURLFILETYPE_DIRECTORY = curlfiletype.CURLFILETYPE_DIRECTORY; +alias CURLFILETYPE_SYMLINK = curlfiletype.CURLFILETYPE_SYMLINK; +alias CURLFILETYPE_DEVICE_BLOCK = curlfiletype.CURLFILETYPE_DEVICE_BLOCK; +alias CURLFILETYPE_DEVICE_CHAR = curlfiletype.CURLFILETYPE_DEVICE_CHAR; +alias CURLFILETYPE_NAMEDPIPE = curlfiletype.CURLFILETYPE_NAMEDPIPE; +alias CURLFILETYPE_SOCKET = curlfiletype.CURLFILETYPE_SOCKET; +alias CURLFILETYPE_DOOR = curlfiletype.CURLFILETYPE_DOOR; +alias CURLFILETYPE_UNKNOWN = curlfiletype.CURLFILETYPE_UNKNOWN; + +enum CURLFINFOFLAG_KNOWN_FILENAME = 1 << 0; +enum CURLFINFOFLAG_KNOWN_FILETYPE = 1 << 1; +enum CURLFINFOFLAG_KNOWN_TIME = 1 << 2; +enum CURLFINFOFLAG_KNOWN_PERM = 1 << 3; +enum CURLFINFOFLAG_KNOWN_UID = 1 << 4; +enum CURLFINFOFLAG_KNOWN_GID = 1 << 5; +enum CURLFINFOFLAG_KNOWN_SIZE = 1 << 6; +enum CURLFINFOFLAG_KNOWN_HLINKCOUNT = 1 << 7; + +struct curl_fileinfo +{ + char* filename; + curlfiletype filetype; + alias time_t = c_long; + time_t time; + uint perm; + int uid; + int gid; + curl_off_t size; + c_long hardlinks; + + struct idk + { + char* time; + char* perm; + char* user; + char* group; + char* target; + } + + idk strings; + uint flags; + char* b_data; + alias size_t = c_ulong; + size_t b_size; + size_t b_used; +} + +enum CURL_CHUNK_BGN_FUNC_OK = 0; +enum CURL_CHUNK_BGN_FUNC_FAIL = 1; +enum CURL_CHUNK_BGN_FUNC_SKIP = 2; +alias curl_chunk_bgn_callback = c_long function (const(void)* transfer_info, void* ptr, int remains); +enum CURL_CHUNK_END_FUNC_OK = 0; +enum CURL_CHUNK_END_FUNC_FAIL = 1; +alias curl_chunk_end_callback = c_long function (void* ptr); +enum CURL_FNMATCHFUNC_MATCH = 0; +enum CURL_FNMATCHFUNC_NOMATCH = 1; +enum CURL_FNMATCHFUNC_FAIL = 2; +alias curl_fnmatch_callback = int function (void* ptr, const(char)* pattern, const(char)* string); +enum CURL_SEEKFUNC_OK = 0; +enum CURL_SEEKFUNC_FAIL = 1; +enum CURL_SEEKFUNC_CANTSEEK = 2; +alias curl_seek_callback = int function (void* instream, curl_off_t offset, int origin); +enum CURL_READFUNC_ABORT = 0x10000000; +enum CURL_READFUNC_PAUSE = 0x10000001; +enum CURL_TRAILERFUNC_OK = 0; +enum CURL_TRAILERFUNC_ABORT = 1; +alias curl_read_callback = c_ulong function (char* buffer, size_t size, size_t nitems, void* instream); +alias curl_trailer_callback = int function (curl_slist** list, void* userdata); + +enum curlsocktype +{ + CURLSOCKTYPE_IPCXN = 0, + CURLSOCKTYPE_ACCEPT = 1, + CURLSOCKTYPE_LAST = 2 +} + +alias CURLSOCKTYPE_IPCXN = curlsocktype.CURLSOCKTYPE_IPCXN; +alias CURLSOCKTYPE_ACCEPT = curlsocktype.CURLSOCKTYPE_ACCEPT; +alias CURLSOCKTYPE_LAST = curlsocktype.CURLSOCKTYPE_LAST; + +enum CURL_SOCKOPT_OK = 0; +enum CURL_SOCKOPT_ERROR = 1; +enum CURL_SOCKOPT_ALREADY_CONNECTED = 2; +alias curl_sockopt_callback = int function (void* clientp, curl_socket_t curlfd, curlsocktype purpose); + +struct curl_sockaddr +{ + int family; + int socktype; + int protocol; + uint addrlen; + + struct sockaddr + { + alias sa_family_t = ushort; + sa_family_t sa_family; + char[14] sa_data; + } + + sockaddr addr; +} + +alias curl_opensocket_callback = int function (void* clientp, curlsocktype purpose, curl_sockaddr* address); +alias curl_closesocket_callback = int function (void* clientp, curl_socket_t item); + +enum curlioerr +{ + CURLIOE_OK = 0, + CURLIOE_UNKNOWNCMD = 1, + CURLIOE_FAILRESTART = 2, + CURLIOE_LAST = 3 +} + +alias CURLIOE_OK = curlioerr.CURLIOE_OK; +alias CURLIOE_UNKNOWNCMD = curlioerr.CURLIOE_UNKNOWNCMD; +alias CURLIOE_FAILRESTART = curlioerr.CURLIOE_FAILRESTART; +alias CURLIOE_LAST = curlioerr.CURLIOE_LAST; + +enum curliocmd +{ + CURLIOCMD_NOP = 0, + CURLIOCMD_RESTARTREAD = 1, + CURLIOCMD_LAST = 2 +} + +alias CURLIOCMD_NOP = curliocmd.CURLIOCMD_NOP; +alias CURLIOCMD_RESTARTREAD = curliocmd.CURLIOCMD_RESTARTREAD; +alias CURLIOCMD_LAST = curliocmd.CURLIOCMD_LAST; + +alias curl_ioctl_callback = curlioerr function (CURL* handle, int cmd, void* clientp); +alias curl_malloc_callback = void* function (size_t size); +alias curl_free_callback = void function (void* ptr); +alias curl_realloc_callback = void* function (void* ptr, size_t size); +alias curl_strdup_callback = char* function (const(char)* str); +alias curl_calloc_callback = void* function (size_t nmemb, size_t size); + +enum curl_infotype +{ + CURLINFO_TEXT = 0, + CURLINFO_HEADER_IN = 1, + CURLINFO_HEADER_OUT = 2, + CURLINFO_DATA_IN = 3, + CURLINFO_DATA_OUT = 4, + CURLINFO_SSL_DATA_IN = 5, + CURLINFO_SSL_DATA_OUT = 6, + CURLINFO_END = 7 +} + +alias CURLINFO_TEXT = curl_infotype.CURLINFO_TEXT; +alias CURLINFO_HEADER_IN = curl_infotype.CURLINFO_HEADER_IN; +alias CURLINFO_HEADER_OUT = curl_infotype.CURLINFO_HEADER_OUT; +alias CURLINFO_DATA_IN = curl_infotype.CURLINFO_DATA_IN; +alias CURLINFO_DATA_OUT = curl_infotype.CURLINFO_DATA_OUT; +alias CURLINFO_SSL_DATA_IN = curl_infotype.CURLINFO_SSL_DATA_IN; +alias CURLINFO_SSL_DATA_OUT = curl_infotype.CURLINFO_SSL_DATA_OUT; +alias CURLINFO_END = curl_infotype.CURLINFO_END; + +alias curl_debug_callback = int function (CURL* handle, curl_infotype type, char* data, size_t size, void* userptr); +alias curl_prereq_callback = int function (void* clientp, char* conn_primary_ip, char* conn_local_ip, int conn_primary_port, int conn_local_port); +enum CURL_PREREQFUNC_OK = 0; +enum CURL_PREREQFUNC_ABORT = 1; + +enum CURLcode +{ + CURLE_OK = 0, + CURLE_UNSUPPORTED_PROTOCOL = 1, + CURLE_FAILED_INIT = 2, + CURLE_URL_MALFORMAT = 3, + CURLE_NOT_BUILT_IN = 4, + CURLE_COULDNT_RESOLVE_PROXY = 5, + CURLE_COULDNT_RESOLVE_HOST = 6, + CURLE_COULDNT_CONNECT = 7, + CURLE_WEIRD_SERVER_REPLY = 8, + CURLE_REMOTE_ACCESS_DENIED = 9, + CURLE_FTP_ACCEPT_FAILED = 10, + CURLE_FTP_WEIRD_PASS_REPLY = 11, + CURLE_FTP_ACCEPT_TIMEOUT = 12, + CURLE_FTP_WEIRD_PASV_REPLY = 13, + CURLE_FTP_WEIRD_227_FORMAT = 14, + CURLE_FTP_CANT_GET_HOST = 15, + CURLE_HTTP2 = 16, + CURLE_FTP_COULDNT_SET_TYPE = 17, + CURLE_PARTIAL_FILE = 18, + CURLE_FTP_COULDNT_RETR_FILE = 19, + CURLE_OBSOLETE20 = 20, + CURLE_QUOTE_ERROR = 21, + CURLE_HTTP_RETURNED_ERROR = 22, + CURLE_WRITE_ERROR = 23, + CURLE_OBSOLETE24 = 24, + CURLE_UPLOAD_FAILED = 25, + CURLE_READ_ERROR = 26, + CURLE_OUT_OF_MEMORY = 27, + CURLE_OPERATION_TIMEDOUT = 28, + CURLE_OBSOLETE29 = 29, + CURLE_FTP_PORT_FAILED = 30, + CURLE_FTP_COULDNT_USE_REST = 31, + CURLE_OBSOLETE32 = 32, + CURLE_RANGE_ERROR = 33, + CURLE_OBSOLETE34 = 34, + CURLE_SSL_CONNECT_ERROR = 35, + CURLE_BAD_DOWNLOAD_RESUME = 36, + CURLE_FILE_COULDNT_READ_FILE = 37, + CURLE_LDAP_CANNOT_BIND = 38, + CURLE_LDAP_SEARCH_FAILED = 39, + CURLE_OBSOLETE40 = 40, + CURLE_OBSOLETE41 = 41, + CURLE_ABORTED_BY_CALLBACK = 42, + CURLE_BAD_FUNCTION_ARGUMENT = 43, + CURLE_OBSOLETE44 = 44, + CURLE_INTERFACE_FAILED = 45, + CURLE_OBSOLETE46 = 46, + CURLE_TOO_MANY_REDIRECTS = 47, + CURLE_UNKNOWN_OPTION = 48, + CURLE_SETOPT_OPTION_SYNTAX = 49, + CURLE_OBSOLETE50 = 50, + CURLE_OBSOLETE51 = 51, + CURLE_GOT_NOTHING = 52, + CURLE_SSL_ENGINE_NOTFOUND = 53, + CURLE_SSL_ENGINE_SETFAILED = 54, + CURLE_SEND_ERROR = 55, + CURLE_RECV_ERROR = 56, + CURLE_OBSOLETE57 = 57, + CURLE_SSL_CERTPROBLEM = 58, + CURLE_SSL_CIPHER = 59, + CURLE_PEER_FAILED_VERIFICATION = 60, + CURLE_BAD_CONTENT_ENCODING = 61, + CURLE_OBSOLETE62 = 62, + CURLE_FILESIZE_EXCEEDED = 63, + CURLE_USE_SSL_FAILED = 64, + CURLE_SEND_FAIL_REWIND = 65, + CURLE_SSL_ENGINE_INITFAILED = 66, + CURLE_LOGIN_DENIED = 67, + CURLE_TFTP_NOTFOUND = 68, + CURLE_TFTP_PERM = 69, + CURLE_REMOTE_DISK_FULL = 70, + CURLE_TFTP_ILLEGAL = 71, + CURLE_TFTP_UNKNOWNID = 72, + CURLE_REMOTE_FILE_EXISTS = 73, + CURLE_TFTP_NOSUCHUSER = 74, + CURLE_OBSOLETE75 = 75, + CURLE_OBSOLETE76 = 76, + CURLE_SSL_CACERT_BADFILE = 77, + CURLE_REMOTE_FILE_NOT_FOUND = 78, + CURLE_SSH = 79, + CURLE_SSL_SHUTDOWN_FAILED = 80, + CURLE_AGAIN = 81, + CURLE_SSL_CRL_BADFILE = 82, + CURLE_SSL_ISSUER_ERROR = 83, + CURLE_FTP_PRET_FAILED = 84, + CURLE_RTSP_CSEQ_ERROR = 85, + CURLE_RTSP_SESSION_ERROR = 86, + CURLE_FTP_BAD_FILE_LIST = 87, + CURLE_CHUNK_FAILED = 88, + CURLE_NO_CONNECTION_AVAILABLE = 89, + CURLE_SSL_PINNEDPUBKEYNOTMATCH = 90, + CURLE_SSL_INVALIDCERTSTATUS = 91, + CURLE_HTTP2_STREAM = 92, + CURLE_RECURSIVE_API_CALL = 93, + CURLE_AUTH_ERROR = 94, + CURLE_HTTP3 = 95, + CURLE_QUIC_CONNECT_ERROR = 96, + CURLE_PROXY = 97, + CURLE_SSL_CLIENTCERT = 98, + CURLE_UNRECOVERABLE_POLL = 99, + CURLE_TOO_LARGE = 100, + CURLE_ECH_REQUIRED = 101, + CURL_LAST = 102 +} + +alias CURLE_OK = CURLcode.CURLE_OK; +alias CURLE_UNSUPPORTED_PROTOCOL = CURLcode.CURLE_UNSUPPORTED_PROTOCOL; +alias CURLE_FAILED_INIT = CURLcode.CURLE_FAILED_INIT; +alias CURLE_URL_MALFORMAT = CURLcode.CURLE_URL_MALFORMAT; +alias CURLE_NOT_BUILT_IN = CURLcode.CURLE_NOT_BUILT_IN; +alias CURLE_COULDNT_RESOLVE_PROXY = CURLcode.CURLE_COULDNT_RESOLVE_PROXY; +alias CURLE_COULDNT_RESOLVE_HOST = CURLcode.CURLE_COULDNT_RESOLVE_HOST; +alias CURLE_COULDNT_CONNECT = CURLcode.CURLE_COULDNT_CONNECT; +alias CURLE_WEIRD_SERVER_REPLY = CURLcode.CURLE_WEIRD_SERVER_REPLY; +alias CURLE_REMOTE_ACCESS_DENIED = CURLcode.CURLE_REMOTE_ACCESS_DENIED; +alias CURLE_FTP_ACCEPT_FAILED = CURLcode.CURLE_FTP_ACCEPT_FAILED; +alias CURLE_FTP_WEIRD_PASS_REPLY = CURLcode.CURLE_FTP_WEIRD_PASS_REPLY; +alias CURLE_FTP_ACCEPT_TIMEOUT = CURLcode.CURLE_FTP_ACCEPT_TIMEOUT; +alias CURLE_FTP_WEIRD_PASV_REPLY = CURLcode.CURLE_FTP_WEIRD_PASV_REPLY; +alias CURLE_FTP_WEIRD_227_FORMAT = CURLcode.CURLE_FTP_WEIRD_227_FORMAT; +alias CURLE_FTP_CANT_GET_HOST = CURLcode.CURLE_FTP_CANT_GET_HOST; +alias CURLE_HTTP2 = CURLcode.CURLE_HTTP2; +alias CURLE_FTP_COULDNT_SET_TYPE = CURLcode.CURLE_FTP_COULDNT_SET_TYPE; +alias CURLE_PARTIAL_FILE = CURLcode.CURLE_PARTIAL_FILE; +alias CURLE_FTP_COULDNT_RETR_FILE = CURLcode.CURLE_FTP_COULDNT_RETR_FILE; +alias CURLE_OBSOLETE20 = CURLcode.CURLE_OBSOLETE20; +alias CURLE_QUOTE_ERROR = CURLcode.CURLE_QUOTE_ERROR; +alias CURLE_HTTP_RETURNED_ERROR = CURLcode.CURLE_HTTP_RETURNED_ERROR; +alias CURLE_WRITE_ERROR = CURLcode.CURLE_WRITE_ERROR; +alias CURLE_OBSOLETE24 = CURLcode.CURLE_OBSOLETE24; +alias CURLE_UPLOAD_FAILED = CURLcode.CURLE_UPLOAD_FAILED; +alias CURLE_READ_ERROR = CURLcode.CURLE_READ_ERROR; +alias CURLE_OUT_OF_MEMORY = CURLcode.CURLE_OUT_OF_MEMORY; +alias CURLE_OPERATION_TIMEDOUT = CURLcode.CURLE_OPERATION_TIMEDOUT; +alias CURLE_OBSOLETE29 = CURLcode.CURLE_OBSOLETE29; +alias CURLE_FTP_PORT_FAILED = CURLcode.CURLE_FTP_PORT_FAILED; +alias CURLE_FTP_COULDNT_USE_REST = CURLcode.CURLE_FTP_COULDNT_USE_REST; +alias CURLE_OBSOLETE32 = CURLcode.CURLE_OBSOLETE32; +alias CURLE_RANGE_ERROR = CURLcode.CURLE_RANGE_ERROR; +alias CURLE_OBSOLETE34 = CURLcode.CURLE_OBSOLETE34; +alias CURLE_SSL_CONNECT_ERROR = CURLcode.CURLE_SSL_CONNECT_ERROR; +alias CURLE_BAD_DOWNLOAD_RESUME = CURLcode.CURLE_BAD_DOWNLOAD_RESUME; +alias CURLE_FILE_COULDNT_READ_FILE = CURLcode.CURLE_FILE_COULDNT_READ_FILE; +alias CURLE_LDAP_CANNOT_BIND = CURLcode.CURLE_LDAP_CANNOT_BIND; +alias CURLE_LDAP_SEARCH_FAILED = CURLcode.CURLE_LDAP_SEARCH_FAILED; +alias CURLE_OBSOLETE40 = CURLcode.CURLE_OBSOLETE40; +alias CURLE_OBSOLETE41 = CURLcode.CURLE_OBSOLETE41; +alias CURLE_ABORTED_BY_CALLBACK = CURLcode.CURLE_ABORTED_BY_CALLBACK; +alias CURLE_BAD_FUNCTION_ARGUMENT = CURLcode.CURLE_BAD_FUNCTION_ARGUMENT; +alias CURLE_OBSOLETE44 = CURLcode.CURLE_OBSOLETE44; +alias CURLE_INTERFACE_FAILED = CURLcode.CURLE_INTERFACE_FAILED; +alias CURLE_OBSOLETE46 = CURLcode.CURLE_OBSOLETE46; +alias CURLE_TOO_MANY_REDIRECTS = CURLcode.CURLE_TOO_MANY_REDIRECTS; +alias CURLE_UNKNOWN_OPTION = CURLcode.CURLE_UNKNOWN_OPTION; +alias CURLE_SETOPT_OPTION_SYNTAX = CURLcode.CURLE_SETOPT_OPTION_SYNTAX; +alias CURLE_OBSOLETE50 = CURLcode.CURLE_OBSOLETE50; +alias CURLE_OBSOLETE51 = CURLcode.CURLE_OBSOLETE51; +alias CURLE_GOT_NOTHING = CURLcode.CURLE_GOT_NOTHING; +alias CURLE_SSL_ENGINE_NOTFOUND = CURLcode.CURLE_SSL_ENGINE_NOTFOUND; +alias CURLE_SSL_ENGINE_SETFAILED = CURLcode.CURLE_SSL_ENGINE_SETFAILED; +alias CURLE_SEND_ERROR = CURLcode.CURLE_SEND_ERROR; +alias CURLE_RECV_ERROR = CURLcode.CURLE_RECV_ERROR; +alias CURLE_OBSOLETE57 = CURLcode.CURLE_OBSOLETE57; +alias CURLE_SSL_CERTPROBLEM = CURLcode.CURLE_SSL_CERTPROBLEM; +alias CURLE_SSL_CIPHER = CURLcode.CURLE_SSL_CIPHER; +alias CURLE_PEER_FAILED_VERIFICATION = CURLcode.CURLE_PEER_FAILED_VERIFICATION; +alias CURLE_BAD_CONTENT_ENCODING = CURLcode.CURLE_BAD_CONTENT_ENCODING; +alias CURLE_OBSOLETE62 = CURLcode.CURLE_OBSOLETE62; +alias CURLE_FILESIZE_EXCEEDED = CURLcode.CURLE_FILESIZE_EXCEEDED; +alias CURLE_USE_SSL_FAILED = CURLcode.CURLE_USE_SSL_FAILED; +alias CURLE_SEND_FAIL_REWIND = CURLcode.CURLE_SEND_FAIL_REWIND; +alias CURLE_SSL_ENGINE_INITFAILED = CURLcode.CURLE_SSL_ENGINE_INITFAILED; +alias CURLE_LOGIN_DENIED = CURLcode.CURLE_LOGIN_DENIED; +alias CURLE_TFTP_NOTFOUND = CURLcode.CURLE_TFTP_NOTFOUND; +alias CURLE_TFTP_PERM = CURLcode.CURLE_TFTP_PERM; +alias CURLE_REMOTE_DISK_FULL = CURLcode.CURLE_REMOTE_DISK_FULL; +alias CURLE_TFTP_ILLEGAL = CURLcode.CURLE_TFTP_ILLEGAL; +alias CURLE_TFTP_UNKNOWNID = CURLcode.CURLE_TFTP_UNKNOWNID; +alias CURLE_REMOTE_FILE_EXISTS = CURLcode.CURLE_REMOTE_FILE_EXISTS; +alias CURLE_TFTP_NOSUCHUSER = CURLcode.CURLE_TFTP_NOSUCHUSER; +alias CURLE_OBSOLETE75 = CURLcode.CURLE_OBSOLETE75; +alias CURLE_OBSOLETE76 = CURLcode.CURLE_OBSOLETE76; +alias CURLE_SSL_CACERT_BADFILE = CURLcode.CURLE_SSL_CACERT_BADFILE; +alias CURLE_REMOTE_FILE_NOT_FOUND = CURLcode.CURLE_REMOTE_FILE_NOT_FOUND; +alias CURLE_SSH = CURLcode.CURLE_SSH; +alias CURLE_SSL_SHUTDOWN_FAILED = CURLcode.CURLE_SSL_SHUTDOWN_FAILED; +alias CURLE_AGAIN = CURLcode.CURLE_AGAIN; +alias CURLE_SSL_CRL_BADFILE = CURLcode.CURLE_SSL_CRL_BADFILE; +alias CURLE_SSL_ISSUER_ERROR = CURLcode.CURLE_SSL_ISSUER_ERROR; +alias CURLE_FTP_PRET_FAILED = CURLcode.CURLE_FTP_PRET_FAILED; +alias CURLE_RTSP_CSEQ_ERROR = CURLcode.CURLE_RTSP_CSEQ_ERROR; +alias CURLE_RTSP_SESSION_ERROR = CURLcode.CURLE_RTSP_SESSION_ERROR; +alias CURLE_FTP_BAD_FILE_LIST = CURLcode.CURLE_FTP_BAD_FILE_LIST; +alias CURLE_CHUNK_FAILED = CURLcode.CURLE_CHUNK_FAILED; +alias CURLE_NO_CONNECTION_AVAILABLE = CURLcode.CURLE_NO_CONNECTION_AVAILABLE; +alias CURLE_SSL_PINNEDPUBKEYNOTMATCH = CURLcode.CURLE_SSL_PINNEDPUBKEYNOTMATCH; +alias CURLE_SSL_INVALIDCERTSTATUS = CURLcode.CURLE_SSL_INVALIDCERTSTATUS; +alias CURLE_HTTP2_STREAM = CURLcode.CURLE_HTTP2_STREAM; +alias CURLE_RECURSIVE_API_CALL = CURLcode.CURLE_RECURSIVE_API_CALL; +alias CURLE_AUTH_ERROR = CURLcode.CURLE_AUTH_ERROR; +alias CURLE_HTTP3 = CURLcode.CURLE_HTTP3; +alias CURLE_QUIC_CONNECT_ERROR = CURLcode.CURLE_QUIC_CONNECT_ERROR; +alias CURLE_PROXY = CURLcode.CURLE_PROXY; +alias CURLE_SSL_CLIENTCERT = CURLcode.CURLE_SSL_CLIENTCERT; +alias CURLE_UNRECOVERABLE_POLL = CURLcode.CURLE_UNRECOVERABLE_POLL; +alias CURLE_TOO_LARGE = CURLcode.CURLE_TOO_LARGE; +alias CURLE_ECH_REQUIRED = CURLcode.CURLE_ECH_REQUIRED; +alias CURL_LAST = CURLcode.CURL_LAST; + +enum CURLE_FUNCTION_NOT_FOUND = CURLcode.CURLE_OBSOLETE41; +enum CURLE_HTTP_POST_ERROR = CURLcode.CURLE_OBSOLETE34; +enum CURLE_OBSOLETE16 = CURLcode.CURLE_HTTP2; +enum CURLE_OBSOLETE10 = CURLcode.CURLE_FTP_ACCEPT_FAILED; +enum CURLE_OBSOLETE12 = CURLcode.CURLE_FTP_ACCEPT_TIMEOUT; +enum CURLOPT_ENCODING = CURLoption.CURLOPT_ACCEPT_ENCODING; +enum CURLE_FTP_WEIRD_SERVER_REPLY = CURLcode.CURLE_WEIRD_SERVER_REPLY; +enum CURLE_SSL_CACERT = CURLcode.CURLE_PEER_FAILED_VERIFICATION; +enum CURLE_UNKNOWN_TELNET_OPTION = CURLcode.CURLE_UNKNOWN_OPTION; +enum CURLE_TELNET_OPTION_SYNTAX = CURLcode.CURLE_SETOPT_OPTION_SYNTAX; +enum CURLE_SSL_PEER_CERTIFICATE = CURLcode.CURLE_PEER_FAILED_VERIFICATION; +enum CURLE_OBSOLETE = CURLcode.CURLE_OBSOLETE50; +enum CURLE_BAD_PASSWORD_ENTERED = CURLcode.CURLE_OBSOLETE46; +enum CURLE_BAD_CALLING_ORDER = CURLcode.CURLE_OBSOLETE44; +enum CURLE_FTP_USER_PASSWORD_INCORRECT = CURLE_OBSOLETE10; +enum CURLE_FTP_CANT_RECONNECT = CURLE_OBSOLETE16; +enum CURLE_FTP_COULDNT_GET_SIZE = CURLcode.CURLE_OBSOLETE32; +enum CURLE_FTP_COULDNT_SET_ASCII = CURLcode.CURLE_OBSOLETE29; +enum CURLE_FTP_WEIRD_USER_REPLY = CURLE_OBSOLETE12; +enum CURLE_FTP_WRITE_ERROR = CURLcode.CURLE_OBSOLETE20; +enum CURLE_LIBRARY_NOT_FOUND = CURLcode.CURLE_OBSOLETE40; +enum CURLE_MALFORMAT_USER = CURLcode.CURLE_OBSOLETE24; +enum CURLE_SHARE_IN_USE = CURLcode.CURLE_OBSOLETE57; +enum CURLE_URL_MALFORMAT_USER = CURLcode.CURLE_NOT_BUILT_IN; +enum CURLE_FTP_ACCESS_DENIED = CURLcode.CURLE_REMOTE_ACCESS_DENIED; +enum CURLE_FTP_COULDNT_SET_BINARY = CURLcode.CURLE_FTP_COULDNT_SET_TYPE; +enum CURLE_FTP_QUOTE_ERROR = CURLcode.CURLE_QUOTE_ERROR; +enum CURLE_TFTP_DISKFULL = CURLcode.CURLE_REMOTE_DISK_FULL; +enum CURLE_TFTP_EXISTS = CURLcode.CURLE_REMOTE_FILE_EXISTS; +enum CURLE_HTTP_RANGE_ERROR = CURLcode.CURLE_RANGE_ERROR; +enum CURLE_FTP_SSL_FAILED = CURLcode.CURLE_USE_SSL_FAILED; +enum CURLE_OPERATION_TIMEOUTED = CURLcode.CURLE_OPERATION_TIMEDOUT; +enum CURLE_HTTP_NOT_FOUND = CURLcode.CURLE_HTTP_RETURNED_ERROR; +enum CURLE_HTTP_PORT_FAILED = CURLcode.CURLE_INTERFACE_FAILED; +enum CURLE_FTP_COULDNT_STOR_FILE = CURLcode.CURLE_UPLOAD_FAILED; +enum CURLE_FTP_PARTIAL_FILE = CURLcode.CURLE_PARTIAL_FILE; +enum CURLE_FTP_BAD_DOWNLOAD_RESUME = CURLcode.CURLE_BAD_DOWNLOAD_RESUME; +enum CURLE_LDAP_INVALID_URL = CURLcode.CURLE_OBSOLETE62; +enum CURLE_CONV_REQD = CURLcode.CURLE_OBSOLETE76; +enum CURLE_CONV_FAILED = CURLcode.CURLE_OBSOLETE75; +enum CURLE_ALREADY_COMPLETE = 99999; +enum CURLOPT_FILE = CURLoption.CURLOPT_WRITEDATA; +enum CURLOPT_INFILE = CURLoption.CURLOPT_READDATA; +enum CURLOPT_WRITEHEADER = CURLoption.CURLOPT_HEADERDATA; +enum CURLOPT_WRITEINFO = CURLOPT_OBSOLETE40; +enum CURLOPT_CLOSEPOLICY = CURLOPT_OBSOLETE72; +enum CURLOPT_OBSOLETE72 = 9999; +enum CURLOPT_OBSOLETE40 = 9999; + +enum CURLproxycode +{ + CURLPX_OK = 0, + CURLPX_BAD_ADDRESS_TYPE = 1, + CURLPX_BAD_VERSION = 2, + CURLPX_CLOSED = 3, + CURLPX_GSSAPI = 4, + CURLPX_GSSAPI_PERMSG = 5, + CURLPX_GSSAPI_PROTECTION = 6, + CURLPX_IDENTD = 7, + CURLPX_IDENTD_DIFFER = 8, + CURLPX_LONG_HOSTNAME = 9, + CURLPX_LONG_PASSWD = 10, + CURLPX_LONG_USER = 11, + CURLPX_NO_AUTH = 12, + CURLPX_RECV_ADDRESS = 13, + CURLPX_RECV_AUTH = 14, + CURLPX_RECV_CONNECT = 15, + CURLPX_RECV_REQACK = 16, + CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED = 17, + CURLPX_REPLY_COMMAND_NOT_SUPPORTED = 18, + CURLPX_REPLY_CONNECTION_REFUSED = 19, + CURLPX_REPLY_GENERAL_SERVER_FAILURE = 20, + CURLPX_REPLY_HOST_UNREACHABLE = 21, + CURLPX_REPLY_NETWORK_UNREACHABLE = 22, + CURLPX_REPLY_NOT_ALLOWED = 23, + CURLPX_REPLY_TTL_EXPIRED = 24, + CURLPX_REPLY_UNASSIGNED = 25, + CURLPX_REQUEST_FAILED = 26, + CURLPX_RESOLVE_HOST = 27, + CURLPX_SEND_AUTH = 28, + CURLPX_SEND_CONNECT = 29, + CURLPX_SEND_REQUEST = 30, + CURLPX_UNKNOWN_FAIL = 31, + CURLPX_UNKNOWN_MODE = 32, + CURLPX_USER_REJECTED = 33, + CURLPX_LAST = 34 +} + +alias CURLPX_OK = CURLproxycode.CURLPX_OK; +alias CURLPX_BAD_ADDRESS_TYPE = CURLproxycode.CURLPX_BAD_ADDRESS_TYPE; +alias CURLPX_BAD_VERSION = CURLproxycode.CURLPX_BAD_VERSION; +alias CURLPX_CLOSED = CURLproxycode.CURLPX_CLOSED; +alias CURLPX_GSSAPI = CURLproxycode.CURLPX_GSSAPI; +alias CURLPX_GSSAPI_PERMSG = CURLproxycode.CURLPX_GSSAPI_PERMSG; +alias CURLPX_GSSAPI_PROTECTION = CURLproxycode.CURLPX_GSSAPI_PROTECTION; +alias CURLPX_IDENTD = CURLproxycode.CURLPX_IDENTD; +alias CURLPX_IDENTD_DIFFER = CURLproxycode.CURLPX_IDENTD_DIFFER; +alias CURLPX_LONG_HOSTNAME = CURLproxycode.CURLPX_LONG_HOSTNAME; +alias CURLPX_LONG_PASSWD = CURLproxycode.CURLPX_LONG_PASSWD; +alias CURLPX_LONG_USER = CURLproxycode.CURLPX_LONG_USER; +alias CURLPX_NO_AUTH = CURLproxycode.CURLPX_NO_AUTH; +alias CURLPX_RECV_ADDRESS = CURLproxycode.CURLPX_RECV_ADDRESS; +alias CURLPX_RECV_AUTH = CURLproxycode.CURLPX_RECV_AUTH; +alias CURLPX_RECV_CONNECT = CURLproxycode.CURLPX_RECV_CONNECT; +alias CURLPX_RECV_REQACK = CURLproxycode.CURLPX_RECV_REQACK; +alias CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED = CURLproxycode.CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED; +alias CURLPX_REPLY_COMMAND_NOT_SUPPORTED = CURLproxycode.CURLPX_REPLY_COMMAND_NOT_SUPPORTED; +alias CURLPX_REPLY_CONNECTION_REFUSED = CURLproxycode.CURLPX_REPLY_CONNECTION_REFUSED; +alias CURLPX_REPLY_GENERAL_SERVER_FAILURE = CURLproxycode.CURLPX_REPLY_GENERAL_SERVER_FAILURE; +alias CURLPX_REPLY_HOST_UNREACHABLE = CURLproxycode.CURLPX_REPLY_HOST_UNREACHABLE; +alias CURLPX_REPLY_NETWORK_UNREACHABLE = CURLproxycode.CURLPX_REPLY_NETWORK_UNREACHABLE; +alias CURLPX_REPLY_NOT_ALLOWED = CURLproxycode.CURLPX_REPLY_NOT_ALLOWED; +alias CURLPX_REPLY_TTL_EXPIRED = CURLproxycode.CURLPX_REPLY_TTL_EXPIRED; +alias CURLPX_REPLY_UNASSIGNED = CURLproxycode.CURLPX_REPLY_UNASSIGNED; +alias CURLPX_REQUEST_FAILED = CURLproxycode.CURLPX_REQUEST_FAILED; +alias CURLPX_RESOLVE_HOST = CURLproxycode.CURLPX_RESOLVE_HOST; +alias CURLPX_SEND_AUTH = CURLproxycode.CURLPX_SEND_AUTH; +alias CURLPX_SEND_CONNECT = CURLproxycode.CURLPX_SEND_CONNECT; +alias CURLPX_SEND_REQUEST = CURLproxycode.CURLPX_SEND_REQUEST; +alias CURLPX_UNKNOWN_FAIL = CURLproxycode.CURLPX_UNKNOWN_FAIL; +alias CURLPX_UNKNOWN_MODE = CURLproxycode.CURLPX_UNKNOWN_MODE; +alias CURLPX_USER_REJECTED = CURLproxycode.CURLPX_USER_REJECTED; +alias CURLPX_LAST = CURLproxycode.CURLPX_LAST; + +alias curl_conv_callback = CURLcode function (char* buffer, size_t length); +alias curl_ssl_ctx_callback = CURLcode function (CURL* curl, void* ssl_ctx, void* userptr); + +enum curl_proxytype +{ + CURLPROXY_HTTP = 0, + CURLPROXY_HTTP_1_0 = 1, + CURLPROXY_HTTPS = 2, + CURLPROXY_HTTPS2 = 3, + CURLPROXY_SOCKS4 = 4, + CURLPROXY_SOCKS5 = 5, + CURLPROXY_SOCKS4A = 6, + CURLPROXY_SOCKS5_HOSTNAME = 7 +} + +alias CURLPROXY_HTTP = curl_proxytype.CURLPROXY_HTTP; +alias CURLPROXY_HTTP_1_0 = curl_proxytype.CURLPROXY_HTTP_1_0; +alias CURLPROXY_HTTPS = curl_proxytype.CURLPROXY_HTTPS; +alias CURLPROXY_HTTPS2 = curl_proxytype.CURLPROXY_HTTPS2; +alias CURLPROXY_SOCKS4 = curl_proxytype.CURLPROXY_SOCKS4; +alias CURLPROXY_SOCKS5 = curl_proxytype.CURLPROXY_SOCKS5; +alias CURLPROXY_SOCKS4A = curl_proxytype.CURLPROXY_SOCKS4A; +alias CURLPROXY_SOCKS5_HOSTNAME = curl_proxytype.CURLPROXY_SOCKS5_HOSTNAME; + +enum CURLAUTH_NONE = cast(c_ulong) 0; +enum CURLAUTH_BASIC = (cast(c_ulong) 1) << 0; +enum CURLAUTH_DIGEST = (cast(c_ulong) 1) << 1; +enum CURLAUTH_NEGOTIATE = (cast(c_ulong) 1) << 2; +enum CURLAUTH_GSSNEGOTIATE = CURLAUTH_NEGOTIATE; +enum CURLAUTH_GSSAPI = CURLAUTH_NEGOTIATE; +enum CURLAUTH_NTLM = (cast(c_ulong) 1) << 3; +enum CURLAUTH_DIGEST_IE = (cast(c_ulong) 1) << 4; +enum CURLAUTH_NTLM_WB = (cast(c_ulong) 1) << 5; +enum CURLAUTH_BEARER = (cast(c_ulong) 1) << 6; +enum CURLAUTH_AWS_SIGV4 = (cast(c_ulong) 1) << 7; +enum CURLAUTH_ONLY = (cast(c_ulong) 1) << 31; +enum CURLAUTH_ANY = ~CURLAUTH_DIGEST_IE; +enum CURLAUTH_ANYSAFE = ~(CURLAUTH_BASIC | CURLAUTH_DIGEST_IE); +enum CURLSSH_AUTH_ANY = ~0; +enum CURLSSH_AUTH_NONE = 0; +enum CURLSSH_AUTH_PUBLICKEY = 1 << 0; +enum CURLSSH_AUTH_PASSWORD = 1 << 1; +enum CURLSSH_AUTH_HOST = 1 << 2; +enum CURLSSH_AUTH_KEYBOARD = 1 << 3; +enum CURLSSH_AUTH_AGENT = 1 << 4; +enum CURLSSH_AUTH_GSSAPI = 1 << 5; +enum CURLSSH_AUTH_DEFAULT = CURLSSH_AUTH_ANY; +enum CURLGSSAPI_DELEGATION_NONE = 0; +enum CURLGSSAPI_DELEGATION_POLICY_FLAG = 1 << 0; +enum CURLGSSAPI_DELEGATION_FLAG = 1 << 1; +enum CURL_ERROR_SIZE = 256; + +enum curl_khtype +{ + CURLKHTYPE_UNKNOWN = 0, + CURLKHTYPE_RSA1 = 1, + CURLKHTYPE_RSA = 2, + CURLKHTYPE_DSS = 3, + CURLKHTYPE_ECDSA = 4, + CURLKHTYPE_ED25519 = 5 +} + +alias CURLKHTYPE_UNKNOWN = curl_khtype.CURLKHTYPE_UNKNOWN; +alias CURLKHTYPE_RSA1 = curl_khtype.CURLKHTYPE_RSA1; +alias CURLKHTYPE_RSA = curl_khtype.CURLKHTYPE_RSA; +alias CURLKHTYPE_DSS = curl_khtype.CURLKHTYPE_DSS; +alias CURLKHTYPE_ECDSA = curl_khtype.CURLKHTYPE_ECDSA; +alias CURLKHTYPE_ED25519 = curl_khtype.CURLKHTYPE_ED25519; + +struct curl_khkey +{ + const(char)* key; + size_t len; + curl_khtype keytype; +} + +enum curl_khstat +{ + CURLKHSTAT_FINE_ADD_TO_FILE = 0, + CURLKHSTAT_FINE = 1, + CURLKHSTAT_REJECT = 2, + CURLKHSTAT_DEFER = 3, + CURLKHSTAT_FINE_REPLACE = 4, + CURLKHSTAT_LAST = 5 +} + +alias CURLKHSTAT_FINE_ADD_TO_FILE = curl_khstat.CURLKHSTAT_FINE_ADD_TO_FILE; +alias CURLKHSTAT_FINE = curl_khstat.CURLKHSTAT_FINE; +alias CURLKHSTAT_REJECT = curl_khstat.CURLKHSTAT_REJECT; +alias CURLKHSTAT_DEFER = curl_khstat.CURLKHSTAT_DEFER; +alias CURLKHSTAT_FINE_REPLACE = curl_khstat.CURLKHSTAT_FINE_REPLACE; +alias CURLKHSTAT_LAST = curl_khstat.CURLKHSTAT_LAST; + +enum curl_khmatch +{ + CURLKHMATCH_OK = 0, + CURLKHMATCH_MISMATCH = 1, + CURLKHMATCH_MISSING = 2, + CURLKHMATCH_LAST = 3 +} + +alias CURLKHMATCH_OK = curl_khmatch.CURLKHMATCH_OK; +alias CURLKHMATCH_MISMATCH = curl_khmatch.CURLKHMATCH_MISMATCH; +alias CURLKHMATCH_MISSING = curl_khmatch.CURLKHMATCH_MISSING; +alias CURLKHMATCH_LAST = curl_khmatch.CURLKHMATCH_LAST; + +alias curl_sshkeycallback = int function (CURL* easy, const(curl_khkey)* knownkey, const(curl_khkey)* foundkey, curl_khmatch, void* clientp); +alias curl_sshhostkeycallback = int function (void* clientp, int keytype, const(char)* key, size_t keylen); + +enum curl_usessl +{ + CURLUSESSL_NONE = 0, + CURLUSESSL_TRY = 1, + CURLUSESSL_CONTROL = 2, + CURLUSESSL_ALL = 3, + CURLUSESSL_LAST = 4 +} + +alias CURLUSESSL_NONE = curl_usessl.CURLUSESSL_NONE; +alias CURLUSESSL_TRY = curl_usessl.CURLUSESSL_TRY; +alias CURLUSESSL_CONTROL = curl_usessl.CURLUSESSL_CONTROL; +alias CURLUSESSL_ALL = curl_usessl.CURLUSESSL_ALL; +alias CURLUSESSL_LAST = curl_usessl.CURLUSESSL_LAST; + +enum CURLSSLOPT_ALLOW_BEAST = 1 << 0; +enum CURLSSLOPT_NO_REVOKE = 1 << 1; +enum CURLSSLOPT_NO_PARTIALCHAIN = 1 << 2; +enum CURLSSLOPT_REVOKE_BEST_EFFORT = 1 << 3; +enum CURLSSLOPT_NATIVE_CA = 1 << 4; +enum CURLSSLOPT_AUTO_CLIENT_CERT = 1 << 5; +enum CURLSSLOPT_EARLYDATA = 1 << 6; +enum CURL_HET_DEFAULT = 200L; +enum CURL_UPKEEP_INTERVAL_DEFAULT = 60000L; +enum CURLFTPSSL_NONE = curl_usessl.CURLUSESSL_NONE; +enum CURLFTPSSL_TRY = curl_usessl.CURLUSESSL_TRY; +enum CURLFTPSSL_CONTROL = curl_usessl.CURLUSESSL_CONTROL; +enum CURLFTPSSL_ALL = curl_usessl.CURLUSESSL_ALL; +enum CURLFTPSSL_LAST = curl_usessl.CURLUSESSL_LAST; +alias curl_ftpssl = curl_usessl; + +enum curl_ftpccc +{ + CURLFTPSSL_CCC_NONE = 0, + CURLFTPSSL_CCC_PASSIVE = 1, + CURLFTPSSL_CCC_ACTIVE = 2, + CURLFTPSSL_CCC_LAST = 3 +} + +alias CURLFTPSSL_CCC_NONE = curl_ftpccc.CURLFTPSSL_CCC_NONE; +alias CURLFTPSSL_CCC_PASSIVE = curl_ftpccc.CURLFTPSSL_CCC_PASSIVE; +alias CURLFTPSSL_CCC_ACTIVE = curl_ftpccc.CURLFTPSSL_CCC_ACTIVE; +alias CURLFTPSSL_CCC_LAST = curl_ftpccc.CURLFTPSSL_CCC_LAST; + +enum curl_ftpauth +{ + CURLFTPAUTH_DEFAULT = 0, + CURLFTPAUTH_SSL = 1, + CURLFTPAUTH_TLS = 2, + CURLFTPAUTH_LAST = 3 +} + +alias CURLFTPAUTH_DEFAULT = curl_ftpauth.CURLFTPAUTH_DEFAULT; +alias CURLFTPAUTH_SSL = curl_ftpauth.CURLFTPAUTH_SSL; +alias CURLFTPAUTH_TLS = curl_ftpauth.CURLFTPAUTH_TLS; +alias CURLFTPAUTH_LAST = curl_ftpauth.CURLFTPAUTH_LAST; + +enum curl_ftpcreatedir +{ + CURLFTP_CREATE_DIR_NONE = 0, + CURLFTP_CREATE_DIR = 1, + CURLFTP_CREATE_DIR_RETRY = 2, + CURLFTP_CREATE_DIR_LAST = 3 +} + +alias CURLFTP_CREATE_DIR_NONE = curl_ftpcreatedir.CURLFTP_CREATE_DIR_NONE; +alias CURLFTP_CREATE_DIR = curl_ftpcreatedir.CURLFTP_CREATE_DIR; +alias CURLFTP_CREATE_DIR_RETRY = curl_ftpcreatedir.CURLFTP_CREATE_DIR_RETRY; +alias CURLFTP_CREATE_DIR_LAST = curl_ftpcreatedir.CURLFTP_CREATE_DIR_LAST; + +enum curl_ftpmethod +{ + CURLFTPMETHOD_DEFAULT = 0, + CURLFTPMETHOD_MULTICWD = 1, + CURLFTPMETHOD_NOCWD = 2, + CURLFTPMETHOD_SINGLECWD = 3, + CURLFTPMETHOD_LAST = 4 +} + +alias CURLFTPMETHOD_DEFAULT = curl_ftpmethod.CURLFTPMETHOD_DEFAULT; +alias CURLFTPMETHOD_MULTICWD = curl_ftpmethod.CURLFTPMETHOD_MULTICWD; +alias CURLFTPMETHOD_NOCWD = curl_ftpmethod.CURLFTPMETHOD_NOCWD; +alias CURLFTPMETHOD_SINGLECWD = curl_ftpmethod.CURLFTPMETHOD_SINGLECWD; +alias CURLFTPMETHOD_LAST = curl_ftpmethod.CURLFTPMETHOD_LAST; + +enum CURLHEADER_UNIFIED = 0; +enum CURLHEADER_SEPARATE = 1 << 0; +enum CURLALTSVC_READONLYFILE = 1 << 2; +enum CURLALTSVC_H1 = 1 << 3; +enum CURLALTSVC_H2 = 1 << 4; +enum CURLALTSVC_H3 = 1 << 5; + +struct curl_hstsentry +{ + import std.bitmanip : bitfields; + char* name; + size_t namelen; + + mixin(bitfields!( + uint, "includeSubDomains", 1, + uint, "", 7)); + + char[18] expire; +} + +struct curl_index +{ + size_t index; + size_t total; +} + +enum CURLSTScode +{ + CURLSTS_OK = 0, + CURLSTS_DONE = 1, + CURLSTS_FAIL = 2 +} + +alias CURLSTS_OK = CURLSTScode.CURLSTS_OK; +alias CURLSTS_DONE = CURLSTScode.CURLSTS_DONE; +alias CURLSTS_FAIL = CURLSTScode.CURLSTS_FAIL; + +alias curl_hstsread_callback = CURLSTScode function (CURL* easy, curl_hstsentry* e, void* userp); +alias curl_hstswrite_callback = CURLSTScode function (CURL* easy, curl_hstsentry* e, curl_index* i, void* userp); +enum CURLHSTS_ENABLE = cast(c_long) 1 << 0; +enum CURLHSTS_READONLYFILE = cast(c_long) 1 << 1; +enum CURLPROTO_HTTP = 1 << 0; +enum CURLPROTO_HTTPS = 1 << 1; +enum CURLPROTO_FTP = 1 << 2; +enum CURLPROTO_FTPS = 1 << 3; +enum CURLPROTO_SCP = 1 << 4; +enum CURLPROTO_SFTP = 1 << 5; +enum CURLPROTO_TELNET = 1 << 6; +enum CURLPROTO_LDAP = 1 << 7; +enum CURLPROTO_LDAPS = 1 << 8; +enum CURLPROTO_DICT = 1 << 9; +enum CURLPROTO_FILE = 1 << 10; +enum CURLPROTO_TFTP = 1 << 11; +enum CURLPROTO_IMAP = 1 << 12; +enum CURLPROTO_IMAPS = 1 << 13; +enum CURLPROTO_POP3 = 1 << 14; +enum CURLPROTO_POP3S = 1 << 15; +enum CURLPROTO_SMTP = 1 << 16; +enum CURLPROTO_SMTPS = 1 << 17; +enum CURLPROTO_RTSP = 1 << 18; +enum CURLPROTO_RTMP = 1 << 19; +enum CURLPROTO_RTMPT = 1 << 20; +enum CURLPROTO_RTMPE = 1 << 21; +enum CURLPROTO_RTMPTE = 1 << 22; +enum CURLPROTO_RTMPS = 1 << 23; +enum CURLPROTO_RTMPTS = 1 << 24; +enum CURLPROTO_GOPHER = 1 << 25; +enum CURLPROTO_SMB = 1 << 26; +enum CURLPROTO_SMBS = 1 << 27; +enum CURLPROTO_MQTT = 1 << 28; +enum CURLPROTO_GOPHERS = 1 << 29; +enum CURLPROTO_ALL = ~0; +enum CURLOPTTYPE_LONG = 0; +enum CURLOPTTYPE_OBJECTPOINT = 10000; +enum CURLOPTTYPE_FUNCTIONPOINT = 20000; +enum CURLOPTTYPE_OFF_T = 30000; +enum CURLOPTTYPE_BLOB = 40000; +enum CURLOPTTYPE_STRINGPOINT = CURLOPTTYPE_OBJECTPOINT; +enum CURLOPTTYPE_SLISTPOINT = CURLOPTTYPE_OBJECTPOINT; +enum CURLOPTTYPE_CBPOINT = CURLOPTTYPE_OBJECTPOINT; +enum CURLOPTTYPE_VALUES = CURLOPTTYPE_LONG; + +enum CURLoption +{ + CURLOPT_WRITEDATA = 10001, + CURLOPT_URL = 10002, + CURLOPT_PORT = 3, + CURLOPT_PROXY = 10004, + CURLOPT_USERPWD = 10005, + CURLOPT_PROXYUSERPWD = 10006, + CURLOPT_RANGE = 10007, + CURLOPT_READDATA = 10009, + CURLOPT_ERRORBUFFER = 10010, + CURLOPT_WRITEFUNCTION = 20011, + CURLOPT_READFUNCTION = 20012, + CURLOPT_TIMEOUT = 13, + CURLOPT_INFILESIZE = 14, + CURLOPT_POSTFIELDS = 10015, + CURLOPT_REFERER = 10016, + CURLOPT_FTPPORT = 10017, + CURLOPT_USERAGENT = 10018, + CURLOPT_LOW_SPEED_LIMIT = 19, + CURLOPT_LOW_SPEED_TIME = 20, + CURLOPT_RESUME_FROM = 21, + CURLOPT_COOKIE = 10022, + CURLOPT_HTTPHEADER = 10023, + CURLOPT_HTTPPOST = 10024, + CURLOPT_SSLCERT = 10025, + CURLOPT_KEYPASSWD = 10026, + CURLOPT_CRLF = 27, + CURLOPT_QUOTE = 10028, + CURLOPT_HEADERDATA = 10029, + CURLOPT_COOKIEFILE = 10031, + CURLOPT_SSLVERSION = 32, + CURLOPT_TIMECONDITION = 33, + CURLOPT_TIMEVALUE = 34, + CURLOPT_CUSTOMREQUEST = 10036, + CURLOPT_STDERR = 10037, + CURLOPT_POSTQUOTE = 10039, + CURLOPT_VERBOSE = 41, + CURLOPT_HEADER = 42, + CURLOPT_NOPROGRESS = 43, + CURLOPT_NOBODY = 44, + CURLOPT_FAILONERROR = 45, + CURLOPT_UPLOAD = 46, + CURLOPT_POST = 47, + CURLOPT_DIRLISTONLY = 48, + CURLOPT_APPEND = 50, + CURLOPT_NETRC = 51, + CURLOPT_FOLLOWLOCATION = 52, + CURLOPT_TRANSFERTEXT = 53, + CURLOPT_PUT = 54, + CURLOPT_PROGRESSFUNCTION = 20056, + CURLOPT_XFERINFODATA = 10057, + CURLOPT_AUTOREFERER = 58, + CURLOPT_PROXYPORT = 59, + CURLOPT_POSTFIELDSIZE = 60, + CURLOPT_HTTPPROXYTUNNEL = 61, + CURLOPT_INTERFACE = 10062, + CURLOPT_KRBLEVEL = 10063, + CURLOPT_SSL_VERIFYPEER = 64, + CURLOPT_CAINFO = 10065, + CURLOPT_MAXREDIRS = 68, + CURLOPT_FILETIME = 69, + CURLOPT_TELNETOPTIONS = 10070, + CURLOPT_MAXCONNECTS = 71, + CURLOPT_FRESH_CONNECT = 74, + CURLOPT_FORBID_REUSE = 75, + CURLOPT_RANDOM_FILE = 10076, + CURLOPT_EGDSOCKET = 10077, + CURLOPT_CONNECTTIMEOUT = 78, + CURLOPT_HEADERFUNCTION = 20079, + CURLOPT_HTTPGET = 80, + CURLOPT_SSL_VERIFYHOST = 81, + CURLOPT_COOKIEJAR = 10082, + CURLOPT_SSL_CIPHER_LIST = 10083, + CURLOPT_HTTP_VERSION = 84, + CURLOPT_FTP_USE_EPSV = 85, + CURLOPT_SSLCERTTYPE = 10086, + CURLOPT_SSLKEY = 10087, + CURLOPT_SSLKEYTYPE = 10088, + CURLOPT_SSLENGINE = 10089, + CURLOPT_SSLENGINE_DEFAULT = 90, + CURLOPT_DNS_USE_GLOBAL_CACHE = 91, + CURLOPT_DNS_CACHE_TIMEOUT = 92, + CURLOPT_PREQUOTE = 10093, + CURLOPT_DEBUGFUNCTION = 20094, + CURLOPT_DEBUGDATA = 10095, + CURLOPT_COOKIESESSION = 96, + CURLOPT_CAPATH = 10097, + CURLOPT_BUFFERSIZE = 98, + CURLOPT_NOSIGNAL = 99, + CURLOPT_SHARE = 10100, + CURLOPT_PROXYTYPE = 101, + CURLOPT_ACCEPT_ENCODING = 10102, + CURLOPT_PRIVATE = 10103, + CURLOPT_HTTP200ALIASES = 10104, + CURLOPT_UNRESTRICTED_AUTH = 105, + CURLOPT_FTP_USE_EPRT = 106, + CURLOPT_HTTPAUTH = 107, + CURLOPT_SSL_CTX_FUNCTION = 20108, + CURLOPT_SSL_CTX_DATA = 10109, + CURLOPT_FTP_CREATE_MISSING_DIRS = 110, + CURLOPT_PROXYAUTH = 111, + CURLOPT_SERVER_RESPONSE_TIMEOUT = 112, + CURLOPT_IPRESOLVE = 113, + CURLOPT_MAXFILESIZE = 114, + CURLOPT_INFILESIZE_LARGE = 30115, + CURLOPT_RESUME_FROM_LARGE = 30116, + CURLOPT_MAXFILESIZE_LARGE = 30117, + CURLOPT_NETRC_FILE = 10118, + CURLOPT_USE_SSL = 119, + CURLOPT_POSTFIELDSIZE_LARGE = 30120, + CURLOPT_TCP_NODELAY = 121, + CURLOPT_FTPSSLAUTH = 129, + CURLOPT_IOCTLFUNCTION = 20130, + CURLOPT_IOCTLDATA = 10131, + CURLOPT_FTP_ACCOUNT = 10134, + CURLOPT_COOKIELIST = 10135, + CURLOPT_IGNORE_CONTENT_LENGTH = 136, + CURLOPT_FTP_SKIP_PASV_IP = 137, + CURLOPT_FTP_FILEMETHOD = 138, + CURLOPT_LOCALPORT = 139, + CURLOPT_LOCALPORTRANGE = 140, + CURLOPT_CONNECT_ONLY = 141, + CURLOPT_CONV_FROM_NETWORK_FUNCTION = 20142, + CURLOPT_CONV_TO_NETWORK_FUNCTION = 20143, + CURLOPT_CONV_FROM_UTF8_FUNCTION = 20144, + CURLOPT_MAX_SEND_SPEED_LARGE = 30145, + CURLOPT_MAX_RECV_SPEED_LARGE = 30146, + CURLOPT_FTP_ALTERNATIVE_TO_USER = 10147, + CURLOPT_SOCKOPTFUNCTION = 20148, + CURLOPT_SOCKOPTDATA = 10149, + CURLOPT_SSL_SESSIONID_CACHE = 150, + CURLOPT_SSH_AUTH_TYPES = 151, + CURLOPT_SSH_PUBLIC_KEYFILE = 10152, + CURLOPT_SSH_PRIVATE_KEYFILE = 10153, + CURLOPT_FTP_SSL_CCC = 154, + CURLOPT_TIMEOUT_MS = 155, + CURLOPT_CONNECTTIMEOUT_MS = 156, + CURLOPT_HTTP_TRANSFER_DECODING = 157, + CURLOPT_HTTP_CONTENT_DECODING = 158, + CURLOPT_NEW_FILE_PERMS = 159, + CURLOPT_NEW_DIRECTORY_PERMS = 160, + CURLOPT_POSTREDIR = 161, + CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 = 10162, + CURLOPT_OPENSOCKETFUNCTION = 20163, + CURLOPT_OPENSOCKETDATA = 10164, + CURLOPT_COPYPOSTFIELDS = 10165, + CURLOPT_PROXY_TRANSFER_MODE = 166, + CURLOPT_SEEKFUNCTION = 20167, + CURLOPT_SEEKDATA = 10168, + CURLOPT_CRLFILE = 10169, + CURLOPT_ISSUERCERT = 10170, + CURLOPT_ADDRESS_SCOPE = 171, + CURLOPT_CERTINFO = 172, + CURLOPT_USERNAME = 10173, + CURLOPT_PASSWORD = 10174, + CURLOPT_PROXYUSERNAME = 10175, + CURLOPT_PROXYPASSWORD = 10176, + CURLOPT_NOPROXY = 10177, + CURLOPT_TFTP_BLKSIZE = 178, + CURLOPT_SOCKS5_GSSAPI_SERVICE = 10179, + CURLOPT_SOCKS5_GSSAPI_NEC = 180, + CURLOPT_PROTOCOLS = 181, + CURLOPT_REDIR_PROTOCOLS = 182, + CURLOPT_SSH_KNOWNHOSTS = 10183, + CURLOPT_SSH_KEYFUNCTION = 20184, + CURLOPT_SSH_KEYDATA = 10185, + CURLOPT_MAIL_FROM = 10186, + CURLOPT_MAIL_RCPT = 10187, + CURLOPT_FTP_USE_PRET = 188, + CURLOPT_RTSP_REQUEST = 189, + CURLOPT_RTSP_SESSION_ID = 10190, + CURLOPT_RTSP_STREAM_URI = 10191, + CURLOPT_RTSP_TRANSPORT = 10192, + CURLOPT_RTSP_CLIENT_CSEQ = 193, + CURLOPT_RTSP_SERVER_CSEQ = 194, + CURLOPT_INTERLEAVEDATA = 10195, + CURLOPT_INTERLEAVEFUNCTION = 20196, + CURLOPT_WILDCARDMATCH = 197, + CURLOPT_CHUNK_BGN_FUNCTION = 20198, + CURLOPT_CHUNK_END_FUNCTION = 20199, + CURLOPT_FNMATCH_FUNCTION = 20200, + CURLOPT_CHUNK_DATA = 10201, + CURLOPT_FNMATCH_DATA = 10202, + CURLOPT_RESOLVE = 10203, + CURLOPT_TLSAUTH_USERNAME = 10204, + CURLOPT_TLSAUTH_PASSWORD = 10205, + CURLOPT_TLSAUTH_TYPE = 10206, + CURLOPT_TRANSFER_ENCODING = 207, + CURLOPT_CLOSESOCKETFUNCTION = 20208, + CURLOPT_CLOSESOCKETDATA = 10209, + CURLOPT_GSSAPI_DELEGATION = 210, + CURLOPT_DNS_SERVERS = 10211, + CURLOPT_ACCEPTTIMEOUT_MS = 212, + CURLOPT_TCP_KEEPALIVE = 213, + CURLOPT_TCP_KEEPIDLE = 214, + CURLOPT_TCP_KEEPINTVL = 215, + CURLOPT_SSL_OPTIONS = 216, + CURLOPT_MAIL_AUTH = 10217, + CURLOPT_SASL_IR = 218, + CURLOPT_XFERINFOFUNCTION = 20219, + CURLOPT_XOAUTH2_BEARER = 10220, + CURLOPT_DNS_INTERFACE = 10221, + CURLOPT_DNS_LOCAL_IP4 = 10222, + CURLOPT_DNS_LOCAL_IP6 = 10223, + CURLOPT_LOGIN_OPTIONS = 10224, + CURLOPT_SSL_ENABLE_NPN = 225, + CURLOPT_SSL_ENABLE_ALPN = 226, + CURLOPT_EXPECT_100_TIMEOUT_MS = 227, + CURLOPT_PROXYHEADER = 10228, + CURLOPT_HEADEROPT = 229, + CURLOPT_PINNEDPUBLICKEY = 10230, + CURLOPT_UNIX_SOCKET_PATH = 10231, + CURLOPT_SSL_VERIFYSTATUS = 232, + CURLOPT_SSL_FALSESTART = 233, + CURLOPT_PATH_AS_IS = 234, + CURLOPT_PROXY_SERVICE_NAME = 10235, + CURLOPT_SERVICE_NAME = 10236, + CURLOPT_PIPEWAIT = 237, + CURLOPT_DEFAULT_PROTOCOL = 10238, + CURLOPT_STREAM_WEIGHT = 239, + CURLOPT_STREAM_DEPENDS = 10240, + CURLOPT_STREAM_DEPENDS_E = 10241, + CURLOPT_TFTP_NO_OPTIONS = 242, + CURLOPT_CONNECT_TO = 10243, + CURLOPT_TCP_FASTOPEN = 244, + CURLOPT_KEEP_SENDING_ON_ERROR = 245, + CURLOPT_PROXY_CAINFO = 10246, + CURLOPT_PROXY_CAPATH = 10247, + CURLOPT_PROXY_SSL_VERIFYPEER = 248, + CURLOPT_PROXY_SSL_VERIFYHOST = 249, + CURLOPT_PROXY_SSLVERSION = 250, + CURLOPT_PROXY_TLSAUTH_USERNAME = 10251, + CURLOPT_PROXY_TLSAUTH_PASSWORD = 10252, + CURLOPT_PROXY_TLSAUTH_TYPE = 10253, + CURLOPT_PROXY_SSLCERT = 10254, + CURLOPT_PROXY_SSLCERTTYPE = 10255, + CURLOPT_PROXY_SSLKEY = 10256, + CURLOPT_PROXY_SSLKEYTYPE = 10257, + CURLOPT_PROXY_KEYPASSWD = 10258, + CURLOPT_PROXY_SSL_CIPHER_LIST = 10259, + CURLOPT_PROXY_CRLFILE = 10260, + CURLOPT_PROXY_SSL_OPTIONS = 261, + CURLOPT_PRE_PROXY = 10262, + CURLOPT_PROXY_PINNEDPUBLICKEY = 10263, + CURLOPT_ABSTRACT_UNIX_SOCKET = 10264, + CURLOPT_SUPPRESS_CONNECT_HEADERS = 265, + CURLOPT_REQUEST_TARGET = 10266, + CURLOPT_SOCKS5_AUTH = 267, + CURLOPT_SSH_COMPRESSION = 268, + CURLOPT_MIMEPOST = 10269, + CURLOPT_TIMEVALUE_LARGE = 30270, + CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS = 271, + CURLOPT_RESOLVER_START_FUNCTION = 20272, + CURLOPT_RESOLVER_START_DATA = 10273, + CURLOPT_HAPROXYPROTOCOL = 274, + CURLOPT_DNS_SHUFFLE_ADDRESSES = 275, + CURLOPT_TLS13_CIPHERS = 10276, + CURLOPT_PROXY_TLS13_CIPHERS = 10277, + CURLOPT_DISALLOW_USERNAME_IN_URL = 278, + CURLOPT_DOH_URL = 10279, + CURLOPT_UPLOAD_BUFFERSIZE = 280, + CURLOPT_UPKEEP_INTERVAL_MS = 281, + CURLOPT_CURLU = 10282, + CURLOPT_TRAILERFUNCTION = 20283, + CURLOPT_TRAILERDATA = 10284, + CURLOPT_HTTP09_ALLOWED = 285, + CURLOPT_ALTSVC_CTRL = 286, + CURLOPT_ALTSVC = 10287, + CURLOPT_MAXAGE_CONN = 288, + CURLOPT_SASL_AUTHZID = 10289, + CURLOPT_MAIL_RCPT_ALLOWFAILS = 290, + CURLOPT_SSLCERT_BLOB = 40291, + CURLOPT_SSLKEY_BLOB = 40292, + CURLOPT_PROXY_SSLCERT_BLOB = 40293, + CURLOPT_PROXY_SSLKEY_BLOB = 40294, + CURLOPT_ISSUERCERT_BLOB = 40295, + CURLOPT_PROXY_ISSUERCERT = 10296, + CURLOPT_PROXY_ISSUERCERT_BLOB = 40297, + CURLOPT_SSL_EC_CURVES = 10298, + CURLOPT_HSTS_CTRL = 299, + CURLOPT_HSTS = 10300, + CURLOPT_HSTSREADFUNCTION = 20301, + CURLOPT_HSTSREADDATA = 10302, + CURLOPT_HSTSWRITEFUNCTION = 20303, + CURLOPT_HSTSWRITEDATA = 10304, + CURLOPT_AWS_SIGV4 = 10305, + CURLOPT_DOH_SSL_VERIFYPEER = 306, + CURLOPT_DOH_SSL_VERIFYHOST = 307, + CURLOPT_DOH_SSL_VERIFYSTATUS = 308, + CURLOPT_CAINFO_BLOB = 40309, + CURLOPT_PROXY_CAINFO_BLOB = 40310, + CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 = 10311, + CURLOPT_PREREQFUNCTION = 20312, + CURLOPT_PREREQDATA = 10313, + CURLOPT_MAXLIFETIME_CONN = 314, + CURLOPT_MIME_OPTIONS = 315, + CURLOPT_SSH_HOSTKEYFUNCTION = 20316, + CURLOPT_SSH_HOSTKEYDATA = 10317, + CURLOPT_PROTOCOLS_STR = 10318, + CURLOPT_REDIR_PROTOCOLS_STR = 10319, + CURLOPT_WS_OPTIONS = 320, + CURLOPT_CA_CACHE_TIMEOUT = 321, + CURLOPT_QUICK_EXIT = 322, + CURLOPT_HAPROXY_CLIENT_IP = 10323, + CURLOPT_SERVER_RESPONSE_TIMEOUT_MS = 324, + CURLOPT_ECH = 10325, + CURLOPT_TCP_KEEPCNT = 326, + CURLOPT_LASTENTRY = 327 +} + +alias CURLOPT_WRITEDATA = CURLoption.CURLOPT_WRITEDATA; +alias CURLOPT_URL = CURLoption.CURLOPT_URL; +alias CURLOPT_PORT = CURLoption.CURLOPT_PORT; +alias CURLOPT_PROXY = CURLoption.CURLOPT_PROXY; +alias CURLOPT_USERPWD = CURLoption.CURLOPT_USERPWD; +alias CURLOPT_PROXYUSERPWD = CURLoption.CURLOPT_PROXYUSERPWD; +alias CURLOPT_RANGE = CURLoption.CURLOPT_RANGE; +alias CURLOPT_READDATA = CURLoption.CURLOPT_READDATA; +alias CURLOPT_ERRORBUFFER = CURLoption.CURLOPT_ERRORBUFFER; +alias CURLOPT_WRITEFUNCTION = CURLoption.CURLOPT_WRITEFUNCTION; +alias CURLOPT_READFUNCTION = CURLoption.CURLOPT_READFUNCTION; +alias CURLOPT_TIMEOUT = CURLoption.CURLOPT_TIMEOUT; +alias CURLOPT_INFILESIZE = CURLoption.CURLOPT_INFILESIZE; +alias CURLOPT_POSTFIELDS = CURLoption.CURLOPT_POSTFIELDS; +alias CURLOPT_REFERER = CURLoption.CURLOPT_REFERER; +alias CURLOPT_FTPPORT = CURLoption.CURLOPT_FTPPORT; +alias CURLOPT_USERAGENT = CURLoption.CURLOPT_USERAGENT; +alias CURLOPT_LOW_SPEED_LIMIT = CURLoption.CURLOPT_LOW_SPEED_LIMIT; +alias CURLOPT_LOW_SPEED_TIME = CURLoption.CURLOPT_LOW_SPEED_TIME; +alias CURLOPT_RESUME_FROM = CURLoption.CURLOPT_RESUME_FROM; +alias CURLOPT_COOKIE = CURLoption.CURLOPT_COOKIE; +alias CURLOPT_HTTPHEADER = CURLoption.CURLOPT_HTTPHEADER; +alias CURLOPT_HTTPPOST = CURLoption.CURLOPT_HTTPPOST; +alias CURLOPT_SSLCERT = CURLoption.CURLOPT_SSLCERT; +alias CURLOPT_KEYPASSWD = CURLoption.CURLOPT_KEYPASSWD; +alias CURLOPT_CRLF = CURLoption.CURLOPT_CRLF; +alias CURLOPT_QUOTE = CURLoption.CURLOPT_QUOTE; +alias CURLOPT_HEADERDATA = CURLoption.CURLOPT_HEADERDATA; +alias CURLOPT_COOKIEFILE = CURLoption.CURLOPT_COOKIEFILE; +alias CURLOPT_SSLVERSION = CURLoption.CURLOPT_SSLVERSION; +alias CURLOPT_TIMECONDITION = CURLoption.CURLOPT_TIMECONDITION; +alias CURLOPT_TIMEVALUE = CURLoption.CURLOPT_TIMEVALUE; +alias CURLOPT_CUSTOMREQUEST = CURLoption.CURLOPT_CUSTOMREQUEST; +alias CURLOPT_STDERR = CURLoption.CURLOPT_STDERR; +alias CURLOPT_POSTQUOTE = CURLoption.CURLOPT_POSTQUOTE; +alias CURLOPT_VERBOSE = CURLoption.CURLOPT_VERBOSE; +alias CURLOPT_HEADER = CURLoption.CURLOPT_HEADER; +alias CURLOPT_NOPROGRESS = CURLoption.CURLOPT_NOPROGRESS; +alias CURLOPT_NOBODY = CURLoption.CURLOPT_NOBODY; +alias CURLOPT_FAILONERROR = CURLoption.CURLOPT_FAILONERROR; +alias CURLOPT_UPLOAD = CURLoption.CURLOPT_UPLOAD; +alias CURLOPT_POST = CURLoption.CURLOPT_POST; +alias CURLOPT_DIRLISTONLY = CURLoption.CURLOPT_DIRLISTONLY; +alias CURLOPT_APPEND = CURLoption.CURLOPT_APPEND; +alias CURLOPT_NETRC = CURLoption.CURLOPT_NETRC; +alias CURLOPT_FOLLOWLOCATION = CURLoption.CURLOPT_FOLLOWLOCATION; +alias CURLOPT_TRANSFERTEXT = CURLoption.CURLOPT_TRANSFERTEXT; +alias CURLOPT_PUT = CURLoption.CURLOPT_PUT; +alias CURLOPT_PROGRESSFUNCTION = CURLoption.CURLOPT_PROGRESSFUNCTION; +alias CURLOPT_XFERINFODATA = CURLoption.CURLOPT_XFERINFODATA; +alias CURLOPT_AUTOREFERER = CURLoption.CURLOPT_AUTOREFERER; +alias CURLOPT_PROXYPORT = CURLoption.CURLOPT_PROXYPORT; +alias CURLOPT_POSTFIELDSIZE = CURLoption.CURLOPT_POSTFIELDSIZE; +alias CURLOPT_HTTPPROXYTUNNEL = CURLoption.CURLOPT_HTTPPROXYTUNNEL; +alias CURLOPT_INTERFACE = CURLoption.CURLOPT_INTERFACE; +alias CURLOPT_KRBLEVEL = CURLoption.CURLOPT_KRBLEVEL; +alias CURLOPT_SSL_VERIFYPEER = CURLoption.CURLOPT_SSL_VERIFYPEER; +alias CURLOPT_CAINFO = CURLoption.CURLOPT_CAINFO; +alias CURLOPT_MAXREDIRS = CURLoption.CURLOPT_MAXREDIRS; +alias CURLOPT_FILETIME = CURLoption.CURLOPT_FILETIME; +alias CURLOPT_TELNETOPTIONS = CURLoption.CURLOPT_TELNETOPTIONS; +alias CURLOPT_MAXCONNECTS = CURLoption.CURLOPT_MAXCONNECTS; +alias CURLOPT_FRESH_CONNECT = CURLoption.CURLOPT_FRESH_CONNECT; +alias CURLOPT_FORBID_REUSE = CURLoption.CURLOPT_FORBID_REUSE; +alias CURLOPT_RANDOM_FILE = CURLoption.CURLOPT_RANDOM_FILE; +alias CURLOPT_EGDSOCKET = CURLoption.CURLOPT_EGDSOCKET; +alias CURLOPT_CONNECTTIMEOUT = CURLoption.CURLOPT_CONNECTTIMEOUT; +alias CURLOPT_HEADERFUNCTION = CURLoption.CURLOPT_HEADERFUNCTION; +alias CURLOPT_HTTPGET = CURLoption.CURLOPT_HTTPGET; +alias CURLOPT_SSL_VERIFYHOST = CURLoption.CURLOPT_SSL_VERIFYHOST; +alias CURLOPT_COOKIEJAR = CURLoption.CURLOPT_COOKIEJAR; +alias CURLOPT_SSL_CIPHER_LIST = CURLoption.CURLOPT_SSL_CIPHER_LIST; +alias CURLOPT_HTTP_VERSION = CURLoption.CURLOPT_HTTP_VERSION; +alias CURLOPT_FTP_USE_EPSV = CURLoption.CURLOPT_FTP_USE_EPSV; +alias CURLOPT_SSLCERTTYPE = CURLoption.CURLOPT_SSLCERTTYPE; +alias CURLOPT_SSLKEY = CURLoption.CURLOPT_SSLKEY; +alias CURLOPT_SSLKEYTYPE = CURLoption.CURLOPT_SSLKEYTYPE; +alias CURLOPT_SSLENGINE = CURLoption.CURLOPT_SSLENGINE; +alias CURLOPT_SSLENGINE_DEFAULT = CURLoption.CURLOPT_SSLENGINE_DEFAULT; +alias CURLOPT_DNS_USE_GLOBAL_CACHE = CURLoption.CURLOPT_DNS_USE_GLOBAL_CACHE; +alias CURLOPT_DNS_CACHE_TIMEOUT = CURLoption.CURLOPT_DNS_CACHE_TIMEOUT; +alias CURLOPT_PREQUOTE = CURLoption.CURLOPT_PREQUOTE; +alias CURLOPT_DEBUGFUNCTION = CURLoption.CURLOPT_DEBUGFUNCTION; +alias CURLOPT_DEBUGDATA = CURLoption.CURLOPT_DEBUGDATA; +alias CURLOPT_COOKIESESSION = CURLoption.CURLOPT_COOKIESESSION; +alias CURLOPT_CAPATH = CURLoption.CURLOPT_CAPATH; +alias CURLOPT_BUFFERSIZE = CURLoption.CURLOPT_BUFFERSIZE; +alias CURLOPT_NOSIGNAL = CURLoption.CURLOPT_NOSIGNAL; +alias CURLOPT_SHARE = CURLoption.CURLOPT_SHARE; +alias CURLOPT_PROXYTYPE = CURLoption.CURLOPT_PROXYTYPE; +alias CURLOPT_ACCEPT_ENCODING = CURLoption.CURLOPT_ACCEPT_ENCODING; +alias CURLOPT_PRIVATE = CURLoption.CURLOPT_PRIVATE; +alias CURLOPT_HTTP200ALIASES = CURLoption.CURLOPT_HTTP200ALIASES; +alias CURLOPT_UNRESTRICTED_AUTH = CURLoption.CURLOPT_UNRESTRICTED_AUTH; +alias CURLOPT_FTP_USE_EPRT = CURLoption.CURLOPT_FTP_USE_EPRT; +alias CURLOPT_HTTPAUTH = CURLoption.CURLOPT_HTTPAUTH; +alias CURLOPT_SSL_CTX_FUNCTION = CURLoption.CURLOPT_SSL_CTX_FUNCTION; +alias CURLOPT_SSL_CTX_DATA = CURLoption.CURLOPT_SSL_CTX_DATA; +alias CURLOPT_FTP_CREATE_MISSING_DIRS = CURLoption.CURLOPT_FTP_CREATE_MISSING_DIRS; +alias CURLOPT_PROXYAUTH = CURLoption.CURLOPT_PROXYAUTH; +alias CURLOPT_SERVER_RESPONSE_TIMEOUT = CURLoption.CURLOPT_SERVER_RESPONSE_TIMEOUT; +alias CURLOPT_IPRESOLVE = CURLoption.CURLOPT_IPRESOLVE; +alias CURLOPT_MAXFILESIZE = CURLoption.CURLOPT_MAXFILESIZE; +alias CURLOPT_INFILESIZE_LARGE = CURLoption.CURLOPT_INFILESIZE_LARGE; +alias CURLOPT_RESUME_FROM_LARGE = CURLoption.CURLOPT_RESUME_FROM_LARGE; +alias CURLOPT_MAXFILESIZE_LARGE = CURLoption.CURLOPT_MAXFILESIZE_LARGE; +alias CURLOPT_NETRC_FILE = CURLoption.CURLOPT_NETRC_FILE; +alias CURLOPT_USE_SSL = CURLoption.CURLOPT_USE_SSL; +alias CURLOPT_POSTFIELDSIZE_LARGE = CURLoption.CURLOPT_POSTFIELDSIZE_LARGE; +alias CURLOPT_TCP_NODELAY = CURLoption.CURLOPT_TCP_NODELAY; +alias CURLOPT_FTPSSLAUTH = CURLoption.CURLOPT_FTPSSLAUTH; +alias CURLOPT_IOCTLFUNCTION = CURLoption.CURLOPT_IOCTLFUNCTION; +alias CURLOPT_IOCTLDATA = CURLoption.CURLOPT_IOCTLDATA; +alias CURLOPT_FTP_ACCOUNT = CURLoption.CURLOPT_FTP_ACCOUNT; +alias CURLOPT_COOKIELIST = CURLoption.CURLOPT_COOKIELIST; +alias CURLOPT_IGNORE_CONTENT_LENGTH = CURLoption.CURLOPT_IGNORE_CONTENT_LENGTH; +alias CURLOPT_FTP_SKIP_PASV_IP = CURLoption.CURLOPT_FTP_SKIP_PASV_IP; +alias CURLOPT_FTP_FILEMETHOD = CURLoption.CURLOPT_FTP_FILEMETHOD; +alias CURLOPT_LOCALPORT = CURLoption.CURLOPT_LOCALPORT; +alias CURLOPT_LOCALPORTRANGE = CURLoption.CURLOPT_LOCALPORTRANGE; +alias CURLOPT_CONNECT_ONLY = CURLoption.CURLOPT_CONNECT_ONLY; +alias CURLOPT_CONV_FROM_NETWORK_FUNCTION = CURLoption.CURLOPT_CONV_FROM_NETWORK_FUNCTION; +alias CURLOPT_CONV_TO_NETWORK_FUNCTION = CURLoption.CURLOPT_CONV_TO_NETWORK_FUNCTION; +alias CURLOPT_CONV_FROM_UTF8_FUNCTION = CURLoption.CURLOPT_CONV_FROM_UTF8_FUNCTION; +alias CURLOPT_MAX_SEND_SPEED_LARGE = CURLoption.CURLOPT_MAX_SEND_SPEED_LARGE; +alias CURLOPT_MAX_RECV_SPEED_LARGE = CURLoption.CURLOPT_MAX_RECV_SPEED_LARGE; +alias CURLOPT_FTP_ALTERNATIVE_TO_USER = CURLoption.CURLOPT_FTP_ALTERNATIVE_TO_USER; +alias CURLOPT_SOCKOPTFUNCTION = CURLoption.CURLOPT_SOCKOPTFUNCTION; +alias CURLOPT_SOCKOPTDATA = CURLoption.CURLOPT_SOCKOPTDATA; +alias CURLOPT_SSL_SESSIONID_CACHE = CURLoption.CURLOPT_SSL_SESSIONID_CACHE; +alias CURLOPT_SSH_AUTH_TYPES = CURLoption.CURLOPT_SSH_AUTH_TYPES; +alias CURLOPT_SSH_PUBLIC_KEYFILE = CURLoption.CURLOPT_SSH_PUBLIC_KEYFILE; +alias CURLOPT_SSH_PRIVATE_KEYFILE = CURLoption.CURLOPT_SSH_PRIVATE_KEYFILE; +alias CURLOPT_FTP_SSL_CCC = CURLoption.CURLOPT_FTP_SSL_CCC; +alias CURLOPT_TIMEOUT_MS = CURLoption.CURLOPT_TIMEOUT_MS; +alias CURLOPT_CONNECTTIMEOUT_MS = CURLoption.CURLOPT_CONNECTTIMEOUT_MS; +alias CURLOPT_HTTP_TRANSFER_DECODING = CURLoption.CURLOPT_HTTP_TRANSFER_DECODING; +alias CURLOPT_HTTP_CONTENT_DECODING = CURLoption.CURLOPT_HTTP_CONTENT_DECODING; +alias CURLOPT_NEW_FILE_PERMS = CURLoption.CURLOPT_NEW_FILE_PERMS; +alias CURLOPT_NEW_DIRECTORY_PERMS = CURLoption.CURLOPT_NEW_DIRECTORY_PERMS; +alias CURLOPT_POSTREDIR = CURLoption.CURLOPT_POSTREDIR; +alias CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 = CURLoption.CURLOPT_SSH_HOST_PUBLIC_KEY_MD5; +alias CURLOPT_OPENSOCKETFUNCTION = CURLoption.CURLOPT_OPENSOCKETFUNCTION; +alias CURLOPT_OPENSOCKETDATA = CURLoption.CURLOPT_OPENSOCKETDATA; +alias CURLOPT_COPYPOSTFIELDS = CURLoption.CURLOPT_COPYPOSTFIELDS; +alias CURLOPT_PROXY_TRANSFER_MODE = CURLoption.CURLOPT_PROXY_TRANSFER_MODE; +alias CURLOPT_SEEKFUNCTION = CURLoption.CURLOPT_SEEKFUNCTION; +alias CURLOPT_SEEKDATA = CURLoption.CURLOPT_SEEKDATA; +alias CURLOPT_CRLFILE = CURLoption.CURLOPT_CRLFILE; +alias CURLOPT_ISSUERCERT = CURLoption.CURLOPT_ISSUERCERT; +alias CURLOPT_ADDRESS_SCOPE = CURLoption.CURLOPT_ADDRESS_SCOPE; +alias CURLOPT_CERTINFO = CURLoption.CURLOPT_CERTINFO; +alias CURLOPT_USERNAME = CURLoption.CURLOPT_USERNAME; +alias CURLOPT_PASSWORD = CURLoption.CURLOPT_PASSWORD; +alias CURLOPT_PROXYUSERNAME = CURLoption.CURLOPT_PROXYUSERNAME; +alias CURLOPT_PROXYPASSWORD = CURLoption.CURLOPT_PROXYPASSWORD; +alias CURLOPT_NOPROXY = CURLoption.CURLOPT_NOPROXY; +alias CURLOPT_TFTP_BLKSIZE = CURLoption.CURLOPT_TFTP_BLKSIZE; +alias CURLOPT_SOCKS5_GSSAPI_SERVICE = CURLoption.CURLOPT_SOCKS5_GSSAPI_SERVICE; +alias CURLOPT_SOCKS5_GSSAPI_NEC = CURLoption.CURLOPT_SOCKS5_GSSAPI_NEC; +alias CURLOPT_PROTOCOLS = CURLoption.CURLOPT_PROTOCOLS; +alias CURLOPT_REDIR_PROTOCOLS = CURLoption.CURLOPT_REDIR_PROTOCOLS; +alias CURLOPT_SSH_KNOWNHOSTS = CURLoption.CURLOPT_SSH_KNOWNHOSTS; +alias CURLOPT_SSH_KEYFUNCTION = CURLoption.CURLOPT_SSH_KEYFUNCTION; +alias CURLOPT_SSH_KEYDATA = CURLoption.CURLOPT_SSH_KEYDATA; +alias CURLOPT_MAIL_FROM = CURLoption.CURLOPT_MAIL_FROM; +alias CURLOPT_MAIL_RCPT = CURLoption.CURLOPT_MAIL_RCPT; +alias CURLOPT_FTP_USE_PRET = CURLoption.CURLOPT_FTP_USE_PRET; +alias CURLOPT_RTSP_REQUEST = CURLoption.CURLOPT_RTSP_REQUEST; +alias CURLOPT_RTSP_SESSION_ID = CURLoption.CURLOPT_RTSP_SESSION_ID; +alias CURLOPT_RTSP_STREAM_URI = CURLoption.CURLOPT_RTSP_STREAM_URI; +alias CURLOPT_RTSP_TRANSPORT = CURLoption.CURLOPT_RTSP_TRANSPORT; +alias CURLOPT_RTSP_CLIENT_CSEQ = CURLoption.CURLOPT_RTSP_CLIENT_CSEQ; +alias CURLOPT_RTSP_SERVER_CSEQ = CURLoption.CURLOPT_RTSP_SERVER_CSEQ; +alias CURLOPT_INTERLEAVEDATA = CURLoption.CURLOPT_INTERLEAVEDATA; +alias CURLOPT_INTERLEAVEFUNCTION = CURLoption.CURLOPT_INTERLEAVEFUNCTION; +alias CURLOPT_WILDCARDMATCH = CURLoption.CURLOPT_WILDCARDMATCH; +alias CURLOPT_CHUNK_BGN_FUNCTION = CURLoption.CURLOPT_CHUNK_BGN_FUNCTION; +alias CURLOPT_CHUNK_END_FUNCTION = CURLoption.CURLOPT_CHUNK_END_FUNCTION; +alias CURLOPT_FNMATCH_FUNCTION = CURLoption.CURLOPT_FNMATCH_FUNCTION; +alias CURLOPT_CHUNK_DATA = CURLoption.CURLOPT_CHUNK_DATA; +alias CURLOPT_FNMATCH_DATA = CURLoption.CURLOPT_FNMATCH_DATA; +alias CURLOPT_RESOLVE = CURLoption.CURLOPT_RESOLVE; +alias CURLOPT_TLSAUTH_USERNAME = CURLoption.CURLOPT_TLSAUTH_USERNAME; +alias CURLOPT_TLSAUTH_PASSWORD = CURLoption.CURLOPT_TLSAUTH_PASSWORD; +alias CURLOPT_TLSAUTH_TYPE = CURLoption.CURLOPT_TLSAUTH_TYPE; +alias CURLOPT_TRANSFER_ENCODING = CURLoption.CURLOPT_TRANSFER_ENCODING; +alias CURLOPT_CLOSESOCKETFUNCTION = CURLoption.CURLOPT_CLOSESOCKETFUNCTION; +alias CURLOPT_CLOSESOCKETDATA = CURLoption.CURLOPT_CLOSESOCKETDATA; +alias CURLOPT_GSSAPI_DELEGATION = CURLoption.CURLOPT_GSSAPI_DELEGATION; +alias CURLOPT_DNS_SERVERS = CURLoption.CURLOPT_DNS_SERVERS; +alias CURLOPT_ACCEPTTIMEOUT_MS = CURLoption.CURLOPT_ACCEPTTIMEOUT_MS; +alias CURLOPT_TCP_KEEPALIVE = CURLoption.CURLOPT_TCP_KEEPALIVE; +alias CURLOPT_TCP_KEEPIDLE = CURLoption.CURLOPT_TCP_KEEPIDLE; +alias CURLOPT_TCP_KEEPINTVL = CURLoption.CURLOPT_TCP_KEEPINTVL; +alias CURLOPT_SSL_OPTIONS = CURLoption.CURLOPT_SSL_OPTIONS; +alias CURLOPT_MAIL_AUTH = CURLoption.CURLOPT_MAIL_AUTH; +alias CURLOPT_SASL_IR = CURLoption.CURLOPT_SASL_IR; +alias CURLOPT_XFERINFOFUNCTION = CURLoption.CURLOPT_XFERINFOFUNCTION; +alias CURLOPT_XOAUTH2_BEARER = CURLoption.CURLOPT_XOAUTH2_BEARER; +alias CURLOPT_DNS_INTERFACE = CURLoption.CURLOPT_DNS_INTERFACE; +alias CURLOPT_DNS_LOCAL_IP4 = CURLoption.CURLOPT_DNS_LOCAL_IP4; +alias CURLOPT_DNS_LOCAL_IP6 = CURLoption.CURLOPT_DNS_LOCAL_IP6; +alias CURLOPT_LOGIN_OPTIONS = CURLoption.CURLOPT_LOGIN_OPTIONS; +alias CURLOPT_SSL_ENABLE_NPN = CURLoption.CURLOPT_SSL_ENABLE_NPN; +alias CURLOPT_SSL_ENABLE_ALPN = CURLoption.CURLOPT_SSL_ENABLE_ALPN; +alias CURLOPT_EXPECT_100_TIMEOUT_MS = CURLoption.CURLOPT_EXPECT_100_TIMEOUT_MS; +alias CURLOPT_PROXYHEADER = CURLoption.CURLOPT_PROXYHEADER; +alias CURLOPT_HEADEROPT = CURLoption.CURLOPT_HEADEROPT; +alias CURLOPT_PINNEDPUBLICKEY = CURLoption.CURLOPT_PINNEDPUBLICKEY; +alias CURLOPT_UNIX_SOCKET_PATH = CURLoption.CURLOPT_UNIX_SOCKET_PATH; +alias CURLOPT_SSL_VERIFYSTATUS = CURLoption.CURLOPT_SSL_VERIFYSTATUS; +alias CURLOPT_SSL_FALSESTART = CURLoption.CURLOPT_SSL_FALSESTART; +alias CURLOPT_PATH_AS_IS = CURLoption.CURLOPT_PATH_AS_IS; +alias CURLOPT_PROXY_SERVICE_NAME = CURLoption.CURLOPT_PROXY_SERVICE_NAME; +alias CURLOPT_SERVICE_NAME = CURLoption.CURLOPT_SERVICE_NAME; +alias CURLOPT_PIPEWAIT = CURLoption.CURLOPT_PIPEWAIT; +alias CURLOPT_DEFAULT_PROTOCOL = CURLoption.CURLOPT_DEFAULT_PROTOCOL; +alias CURLOPT_STREAM_WEIGHT = CURLoption.CURLOPT_STREAM_WEIGHT; +alias CURLOPT_STREAM_DEPENDS = CURLoption.CURLOPT_STREAM_DEPENDS; +alias CURLOPT_STREAM_DEPENDS_E = CURLoption.CURLOPT_STREAM_DEPENDS_E; +alias CURLOPT_TFTP_NO_OPTIONS = CURLoption.CURLOPT_TFTP_NO_OPTIONS; +alias CURLOPT_CONNECT_TO = CURLoption.CURLOPT_CONNECT_TO; +alias CURLOPT_TCP_FASTOPEN = CURLoption.CURLOPT_TCP_FASTOPEN; +alias CURLOPT_KEEP_SENDING_ON_ERROR = CURLoption.CURLOPT_KEEP_SENDING_ON_ERROR; +alias CURLOPT_PROXY_CAINFO = CURLoption.CURLOPT_PROXY_CAINFO; +alias CURLOPT_PROXY_CAPATH = CURLoption.CURLOPT_PROXY_CAPATH; +alias CURLOPT_PROXY_SSL_VERIFYPEER = CURLoption.CURLOPT_PROXY_SSL_VERIFYPEER; +alias CURLOPT_PROXY_SSL_VERIFYHOST = CURLoption.CURLOPT_PROXY_SSL_VERIFYHOST; +alias CURLOPT_PROXY_SSLVERSION = CURLoption.CURLOPT_PROXY_SSLVERSION; +alias CURLOPT_PROXY_TLSAUTH_USERNAME = CURLoption.CURLOPT_PROXY_TLSAUTH_USERNAME; +alias CURLOPT_PROXY_TLSAUTH_PASSWORD = CURLoption.CURLOPT_PROXY_TLSAUTH_PASSWORD; +alias CURLOPT_PROXY_TLSAUTH_TYPE = CURLoption.CURLOPT_PROXY_TLSAUTH_TYPE; +alias CURLOPT_PROXY_SSLCERT = CURLoption.CURLOPT_PROXY_SSLCERT; +alias CURLOPT_PROXY_SSLCERTTYPE = CURLoption.CURLOPT_PROXY_SSLCERTTYPE; +alias CURLOPT_PROXY_SSLKEY = CURLoption.CURLOPT_PROXY_SSLKEY; +alias CURLOPT_PROXY_SSLKEYTYPE = CURLoption.CURLOPT_PROXY_SSLKEYTYPE; +alias CURLOPT_PROXY_KEYPASSWD = CURLoption.CURLOPT_PROXY_KEYPASSWD; +alias CURLOPT_PROXY_SSL_CIPHER_LIST = CURLoption.CURLOPT_PROXY_SSL_CIPHER_LIST; +alias CURLOPT_PROXY_CRLFILE = CURLoption.CURLOPT_PROXY_CRLFILE; +alias CURLOPT_PROXY_SSL_OPTIONS = CURLoption.CURLOPT_PROXY_SSL_OPTIONS; +alias CURLOPT_PRE_PROXY = CURLoption.CURLOPT_PRE_PROXY; +alias CURLOPT_PROXY_PINNEDPUBLICKEY = CURLoption.CURLOPT_PROXY_PINNEDPUBLICKEY; +alias CURLOPT_ABSTRACT_UNIX_SOCKET = CURLoption.CURLOPT_ABSTRACT_UNIX_SOCKET; +alias CURLOPT_SUPPRESS_CONNECT_HEADERS = CURLoption.CURLOPT_SUPPRESS_CONNECT_HEADERS; +alias CURLOPT_REQUEST_TARGET = CURLoption.CURLOPT_REQUEST_TARGET; +alias CURLOPT_SOCKS5_AUTH = CURLoption.CURLOPT_SOCKS5_AUTH; +alias CURLOPT_SSH_COMPRESSION = CURLoption.CURLOPT_SSH_COMPRESSION; +alias CURLOPT_MIMEPOST = CURLoption.CURLOPT_MIMEPOST; +alias CURLOPT_TIMEVALUE_LARGE = CURLoption.CURLOPT_TIMEVALUE_LARGE; +alias CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS = CURLoption.CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS; +alias CURLOPT_RESOLVER_START_FUNCTION = CURLoption.CURLOPT_RESOLVER_START_FUNCTION; +alias CURLOPT_RESOLVER_START_DATA = CURLoption.CURLOPT_RESOLVER_START_DATA; +alias CURLOPT_HAPROXYPROTOCOL = CURLoption.CURLOPT_HAPROXYPROTOCOL; +alias CURLOPT_DNS_SHUFFLE_ADDRESSES = CURLoption.CURLOPT_DNS_SHUFFLE_ADDRESSES; +alias CURLOPT_TLS13_CIPHERS = CURLoption.CURLOPT_TLS13_CIPHERS; +alias CURLOPT_PROXY_TLS13_CIPHERS = CURLoption.CURLOPT_PROXY_TLS13_CIPHERS; +alias CURLOPT_DISALLOW_USERNAME_IN_URL = CURLoption.CURLOPT_DISALLOW_USERNAME_IN_URL; +alias CURLOPT_DOH_URL = CURLoption.CURLOPT_DOH_URL; +alias CURLOPT_UPLOAD_BUFFERSIZE = CURLoption.CURLOPT_UPLOAD_BUFFERSIZE; +alias CURLOPT_UPKEEP_INTERVAL_MS = CURLoption.CURLOPT_UPKEEP_INTERVAL_MS; +alias CURLOPT_CURLU = CURLoption.CURLOPT_CURLU; +alias CURLOPT_TRAILERFUNCTION = CURLoption.CURLOPT_TRAILERFUNCTION; +alias CURLOPT_TRAILERDATA = CURLoption.CURLOPT_TRAILERDATA; +alias CURLOPT_HTTP09_ALLOWED = CURLoption.CURLOPT_HTTP09_ALLOWED; +alias CURLOPT_ALTSVC_CTRL = CURLoption.CURLOPT_ALTSVC_CTRL; +alias CURLOPT_ALTSVC = CURLoption.CURLOPT_ALTSVC; +alias CURLOPT_MAXAGE_CONN = CURLoption.CURLOPT_MAXAGE_CONN; +alias CURLOPT_SASL_AUTHZID = CURLoption.CURLOPT_SASL_AUTHZID; +alias CURLOPT_MAIL_RCPT_ALLOWFAILS = CURLoption.CURLOPT_MAIL_RCPT_ALLOWFAILS; +alias CURLOPT_SSLCERT_BLOB = CURLoption.CURLOPT_SSLCERT_BLOB; +alias CURLOPT_SSLKEY_BLOB = CURLoption.CURLOPT_SSLKEY_BLOB; +alias CURLOPT_PROXY_SSLCERT_BLOB = CURLoption.CURLOPT_PROXY_SSLCERT_BLOB; +alias CURLOPT_PROXY_SSLKEY_BLOB = CURLoption.CURLOPT_PROXY_SSLKEY_BLOB; +alias CURLOPT_ISSUERCERT_BLOB = CURLoption.CURLOPT_ISSUERCERT_BLOB; +alias CURLOPT_PROXY_ISSUERCERT = CURLoption.CURLOPT_PROXY_ISSUERCERT; +alias CURLOPT_PROXY_ISSUERCERT_BLOB = CURLoption.CURLOPT_PROXY_ISSUERCERT_BLOB; +alias CURLOPT_SSL_EC_CURVES = CURLoption.CURLOPT_SSL_EC_CURVES; +alias CURLOPT_HSTS_CTRL = CURLoption.CURLOPT_HSTS_CTRL; +alias CURLOPT_HSTS = CURLoption.CURLOPT_HSTS; +alias CURLOPT_HSTSREADFUNCTION = CURLoption.CURLOPT_HSTSREADFUNCTION; +alias CURLOPT_HSTSREADDATA = CURLoption.CURLOPT_HSTSREADDATA; +alias CURLOPT_HSTSWRITEFUNCTION = CURLoption.CURLOPT_HSTSWRITEFUNCTION; +alias CURLOPT_HSTSWRITEDATA = CURLoption.CURLOPT_HSTSWRITEDATA; +alias CURLOPT_AWS_SIGV4 = CURLoption.CURLOPT_AWS_SIGV4; +alias CURLOPT_DOH_SSL_VERIFYPEER = CURLoption.CURLOPT_DOH_SSL_VERIFYPEER; +alias CURLOPT_DOH_SSL_VERIFYHOST = CURLoption.CURLOPT_DOH_SSL_VERIFYHOST; +alias CURLOPT_DOH_SSL_VERIFYSTATUS = CURLoption.CURLOPT_DOH_SSL_VERIFYSTATUS; +alias CURLOPT_CAINFO_BLOB = CURLoption.CURLOPT_CAINFO_BLOB; +alias CURLOPT_PROXY_CAINFO_BLOB = CURLoption.CURLOPT_PROXY_CAINFO_BLOB; +alias CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 = CURLoption.CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256; +alias CURLOPT_PREREQFUNCTION = CURLoption.CURLOPT_PREREQFUNCTION; +alias CURLOPT_PREREQDATA = CURLoption.CURLOPT_PREREQDATA; +alias CURLOPT_MAXLIFETIME_CONN = CURLoption.CURLOPT_MAXLIFETIME_CONN; +alias CURLOPT_MIME_OPTIONS = CURLoption.CURLOPT_MIME_OPTIONS; +alias CURLOPT_SSH_HOSTKEYFUNCTION = CURLoption.CURLOPT_SSH_HOSTKEYFUNCTION; +alias CURLOPT_SSH_HOSTKEYDATA = CURLoption.CURLOPT_SSH_HOSTKEYDATA; +alias CURLOPT_PROTOCOLS_STR = CURLoption.CURLOPT_PROTOCOLS_STR; +alias CURLOPT_REDIR_PROTOCOLS_STR = CURLoption.CURLOPT_REDIR_PROTOCOLS_STR; +alias CURLOPT_WS_OPTIONS = CURLoption.CURLOPT_WS_OPTIONS; +alias CURLOPT_CA_CACHE_TIMEOUT = CURLoption.CURLOPT_CA_CACHE_TIMEOUT; +alias CURLOPT_QUICK_EXIT = CURLoption.CURLOPT_QUICK_EXIT; +alias CURLOPT_HAPROXY_CLIENT_IP = CURLoption.CURLOPT_HAPROXY_CLIENT_IP; +alias CURLOPT_SERVER_RESPONSE_TIMEOUT_MS = CURLoption.CURLOPT_SERVER_RESPONSE_TIMEOUT_MS; +alias CURLOPT_ECH = CURLoption.CURLOPT_ECH; +alias CURLOPT_TCP_KEEPCNT = CURLoption.CURLOPT_TCP_KEEPCNT; +alias CURLOPT_LASTENTRY = CURLoption.CURLOPT_LASTENTRY; + +enum CURLOPT_PROGRESSDATA = CURLoption.CURLOPT_XFERINFODATA; +enum CURLOPT_POST301 = CURLoption.CURLOPT_POSTREDIR; +enum CURLOPT_SSLKEYPASSWD = CURLoption.CURLOPT_KEYPASSWD; +enum CURLOPT_FTPAPPEND = CURLoption.CURLOPT_APPEND; +enum CURLOPT_FTPLISTONLY = CURLoption.CURLOPT_DIRLISTONLY; +enum CURLOPT_FTP_SSL = CURLoption.CURLOPT_USE_SSL; +enum CURLOPT_SSLCERTPASSWD = CURLoption.CURLOPT_KEYPASSWD; +enum CURLOPT_KRB4LEVEL = CURLoption.CURLOPT_KRBLEVEL; +enum CURLOPT_FTP_RESPONSE_TIMEOUT = CURLoption.CURLOPT_SERVER_RESPONSE_TIMEOUT; +enum CURLOPT_MAIL_RCPT_ALLLOWFAILS = CURLoption.CURLOPT_MAIL_RCPT_ALLOWFAILS; +enum CURL_IPRESOLVE_WHATEVER = 0; +enum CURL_IPRESOLVE_V4 = 1; +enum CURL_IPRESOLVE_V6 = 2; +enum CURLOPT_RTSPHEADER = CURLoption.CURLOPT_HTTPHEADER; + +enum httpver +{ + CURL_HTTP_VERSION_NONE = 0, + CURL_HTTP_VERSION_1_0 = 1, + CURL_HTTP_VERSION_1_1 = 2, + CURL_HTTP_VERSION_2_0 = 3, + CURL_HTTP_VERSION_2TLS = 4, + CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE = 5, + CURL_HTTP_VERSION_3 = 30, + CURL_HTTP_VERSION_3ONLY = 31, + CURL_HTTP_VERSION_LAST = 32 +} + +alias CURL_HTTP_VERSION_NONE = httpver.CURL_HTTP_VERSION_NONE; +alias CURL_HTTP_VERSION_1_0 = httpver.CURL_HTTP_VERSION_1_0; +alias CURL_HTTP_VERSION_1_1 = httpver.CURL_HTTP_VERSION_1_1; +alias CURL_HTTP_VERSION_2_0 = httpver.CURL_HTTP_VERSION_2_0; +alias CURL_HTTP_VERSION_2TLS = httpver.CURL_HTTP_VERSION_2TLS; +alias CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE = httpver.CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE; +alias CURL_HTTP_VERSION_3 = httpver.CURL_HTTP_VERSION_3; +alias CURL_HTTP_VERSION_3ONLY = httpver.CURL_HTTP_VERSION_3ONLY; +alias CURL_HTTP_VERSION_LAST = httpver.CURL_HTTP_VERSION_LAST; + +enum CURL_HTTP_VERSION_2 = httpver.CURL_HTTP_VERSION_2_0; + +enum hz +{ + CURL_RTSPREQ_NONE = 0, + CURL_RTSPREQ_OPTIONS = 1, + CURL_RTSPREQ_DESCRIBE = 2, + CURL_RTSPREQ_ANNOUNCE = 3, + CURL_RTSPREQ_SETUP = 4, + CURL_RTSPREQ_PLAY = 5, + CURL_RTSPREQ_PAUSE = 6, + CURL_RTSPREQ_TEARDOWN = 7, + CURL_RTSPREQ_GET_PARAMETER = 8, + CURL_RTSPREQ_SET_PARAMETER = 9, + CURL_RTSPREQ_RECORD = 10, + CURL_RTSPREQ_RECEIVE = 11, + CURL_RTSPREQ_LAST = 12 +} + +alias CURL_RTSPREQ_NONE = hz.CURL_RTSPREQ_NONE; +alias CURL_RTSPREQ_OPTIONS = hz.CURL_RTSPREQ_OPTIONS; +alias CURL_RTSPREQ_DESCRIBE = hz.CURL_RTSPREQ_DESCRIBE; +alias CURL_RTSPREQ_ANNOUNCE = hz.CURL_RTSPREQ_ANNOUNCE; +alias CURL_RTSPREQ_SETUP = hz.CURL_RTSPREQ_SETUP; +alias CURL_RTSPREQ_PLAY = hz.CURL_RTSPREQ_PLAY; +alias CURL_RTSPREQ_PAUSE = hz.CURL_RTSPREQ_PAUSE; +alias CURL_RTSPREQ_TEARDOWN = hz.CURL_RTSPREQ_TEARDOWN; +alias CURL_RTSPREQ_GET_PARAMETER = hz.CURL_RTSPREQ_GET_PARAMETER; +alias CURL_RTSPREQ_SET_PARAMETER = hz.CURL_RTSPREQ_SET_PARAMETER; +alias CURL_RTSPREQ_RECORD = hz.CURL_RTSPREQ_RECORD; +alias CURL_RTSPREQ_RECEIVE = hz.CURL_RTSPREQ_RECEIVE; +alias CURL_RTSPREQ_LAST = hz.CURL_RTSPREQ_LAST; + +enum CURL_NETRC_OPTION +{ + CURL_NETRC_IGNORED = 0, + CURL_NETRC_OPTIONAL = 1, + CURL_NETRC_REQUIRED = 2, + CURL_NETRC_LAST = 3 +} + +alias CURL_NETRC_IGNORED = CURL_NETRC_OPTION.CURL_NETRC_IGNORED; +alias CURL_NETRC_OPTIONAL = CURL_NETRC_OPTION.CURL_NETRC_OPTIONAL; +alias CURL_NETRC_REQUIRED = CURL_NETRC_OPTION.CURL_NETRC_REQUIRED; +alias CURL_NETRC_LAST = CURL_NETRC_OPTION.CURL_NETRC_LAST; + +enum CURL_SSLVERSION_DEFAULT = 0; +enum CURL_SSLVERSION_TLSv1 = 1; +enum CURL_SSLVERSION_SSLv2 = 2; +enum CURL_SSLVERSION_SSLv3 = 3; +enum CURL_SSLVERSION_TLSv1_0 = 4; +enum CURL_SSLVERSION_TLSv1_1 = 5; +enum CURL_SSLVERSION_TLSv1_2 = 6; +enum CURL_SSLVERSION_TLSv1_3 = 7; +enum CURL_SSLVERSION_LAST = 8; +enum CURL_SSLVERSION_MAX_NONE = 0; +enum CURL_SSLVERSION_MAX_DEFAULT = CURL_SSLVERSION_TLSv1 << 16; +enum CURL_SSLVERSION_MAX_TLSv1_0 = CURL_SSLVERSION_TLSv1_0 << 16; +enum CURL_SSLVERSION_MAX_TLSv1_1 = CURL_SSLVERSION_TLSv1_1 << 16; +enum CURL_SSLVERSION_MAX_TLSv1_2 = CURL_SSLVERSION_TLSv1_2 << 16; +enum CURL_SSLVERSION_MAX_TLSv1_3 = CURL_SSLVERSION_TLSv1_3 << 16; +enum CURL_SSLVERSION_MAX_LAST = CURL_SSLVERSION_LAST << 16; + +enum CURL_TLSAUTH +{ + CURL_TLSAUTH_NONE = 0, + CURL_TLSAUTH_SRP = 1, + CURL_TLSAUTH_LAST = 2 +} + +alias CURL_TLSAUTH_NONE = CURL_TLSAUTH.CURL_TLSAUTH_NONE; +alias CURL_TLSAUTH_SRP = CURL_TLSAUTH.CURL_TLSAUTH_SRP; +alias CURL_TLSAUTH_LAST = CURL_TLSAUTH.CURL_TLSAUTH_LAST; + +enum CURL_REDIR_GET_ALL = 0; +enum CURL_REDIR_POST_301 = 1; +enum CURL_REDIR_POST_302 = 2; +enum CURL_REDIR_POST_303 = 4; +enum CURL_REDIR_POST_ALL = CURL_REDIR_POST_301 | CURL_REDIR_POST_302 | CURL_REDIR_POST_303; + +enum curl_TimeCond +{ + CURL_TIMECOND_NONE = 0, + CURL_TIMECOND_IFMODSINCE = 1, + CURL_TIMECOND_IFUNMODSINCE = 2, + CURL_TIMECOND_LASTMOD = 3, + CURL_TIMECOND_LAST = 4 +} + +alias CURL_TIMECOND_NONE = curl_TimeCond.CURL_TIMECOND_NONE; +alias CURL_TIMECOND_IFMODSINCE = curl_TimeCond.CURL_TIMECOND_IFMODSINCE; +alias CURL_TIMECOND_IFUNMODSINCE = curl_TimeCond.CURL_TIMECOND_IFUNMODSINCE; +alias CURL_TIMECOND_LASTMOD = curl_TimeCond.CURL_TIMECOND_LASTMOD; +alias CURL_TIMECOND_LAST = curl_TimeCond.CURL_TIMECOND_LAST; + +enum CURL_ZERO_TERMINATED = cast(size_t) -1; +int curl_strequal (const(char)* s1, const(char)* s2); +int curl_strnequal (const(char)* s1, const(char)* s2, size_t n); +struct curl_mime; +struct curl_mimepart; +enum CURLMIMEOPT_FORMESCAPE = 1 << 0; +curl_mime* curl_mime_init (CURL* easy); +void curl_mime_free (curl_mime* mime); +curl_mimepart* curl_mime_addpart (curl_mime* mime); +CURLcode curl_mime_name (curl_mimepart* part, const(char)* name); +CURLcode curl_mime_filename (curl_mimepart* part, const(char)* filename); +CURLcode curl_mime_type (curl_mimepart* part, const(char)* mimetype); +CURLcode curl_mime_encoder (curl_mimepart* part, const(char)* encoding); +CURLcode curl_mime_data (curl_mimepart* part, const(char)* data, size_t datasize); +CURLcode curl_mime_filedata (curl_mimepart* part, const(char)* filename); +CURLcode curl_mime_data_cb (curl_mimepart* part, curl_off_t datasize, curl_read_callback readfunc, curl_seek_callback seekfunc, curl_free_callback freefunc, void* arg); +CURLcode curl_mime_subparts (curl_mimepart* part, curl_mime* subparts); +CURLcode curl_mime_headers (curl_mimepart* part, curl_slist* headers, int take_ownership); + +enum CURLformoption +{ + CURLFORM_NOTHING = 0, + CURLFORM_COPYNAME = 1, + CURLFORM_PTRNAME = 2, + CURLFORM_NAMELENGTH = 3, + CURLFORM_COPYCONTENTS = 4, + CURLFORM_PTRCONTENTS = 5, + CURLFORM_CONTENTSLENGTH = 6, + CURLFORM_FILECONTENT = 7, + CURLFORM_ARRAY = 8, + CURLFORM_OBSOLETE = 9, + CURLFORM_FILE = 10, + CURLFORM_BUFFER = 11, + CURLFORM_BUFFERPTR = 12, + CURLFORM_BUFFERLENGTH = 13, + CURLFORM_CONTENTTYPE = 14, + CURLFORM_CONTENTHEADER = 15, + CURLFORM_FILENAME = 16, + CURLFORM_END = 17, + CURLFORM_OBSOLETE2 = 18, + CURLFORM_STREAM = 19, + CURLFORM_CONTENTLEN = 20, + CURLFORM_LASTENTRY = 21 +} + +alias CURLFORM_NOTHING = CURLformoption.CURLFORM_NOTHING; +alias CURLFORM_COPYNAME = CURLformoption.CURLFORM_COPYNAME; +alias CURLFORM_PTRNAME = CURLformoption.CURLFORM_PTRNAME; +alias CURLFORM_NAMELENGTH = CURLformoption.CURLFORM_NAMELENGTH; +alias CURLFORM_COPYCONTENTS = CURLformoption.CURLFORM_COPYCONTENTS; +alias CURLFORM_PTRCONTENTS = CURLformoption.CURLFORM_PTRCONTENTS; +alias CURLFORM_CONTENTSLENGTH = CURLformoption.CURLFORM_CONTENTSLENGTH; +alias CURLFORM_FILECONTENT = CURLformoption.CURLFORM_FILECONTENT; +alias CURLFORM_ARRAY = CURLformoption.CURLFORM_ARRAY; +alias CURLFORM_OBSOLETE = CURLformoption.CURLFORM_OBSOLETE; +alias CURLFORM_FILE = CURLformoption.CURLFORM_FILE; +alias CURLFORM_BUFFER = CURLformoption.CURLFORM_BUFFER; +alias CURLFORM_BUFFERPTR = CURLformoption.CURLFORM_BUFFERPTR; +alias CURLFORM_BUFFERLENGTH = CURLformoption.CURLFORM_BUFFERLENGTH; +alias CURLFORM_CONTENTTYPE = CURLformoption.CURLFORM_CONTENTTYPE; +alias CURLFORM_CONTENTHEADER = CURLformoption.CURLFORM_CONTENTHEADER; +alias CURLFORM_FILENAME = CURLformoption.CURLFORM_FILENAME; +alias CURLFORM_END = CURLformoption.CURLFORM_END; +alias CURLFORM_OBSOLETE2 = CURLformoption.CURLFORM_OBSOLETE2; +alias CURLFORM_STREAM = CURLformoption.CURLFORM_STREAM; +alias CURLFORM_CONTENTLEN = CURLformoption.CURLFORM_CONTENTLEN; +alias CURLFORM_LASTENTRY = CURLformoption.CURLFORM_LASTENTRY; + +struct curl_forms +{ + CURLformoption option; + const(char)* value; +} + +enum CURLFORMcode +{ + CURL_FORMADD_OK = 0, + CURL_FORMADD_MEMORY = 1, + CURL_FORMADD_OPTION_TWICE = 2, + CURL_FORMADD_NULL = 3, + CURL_FORMADD_UNKNOWN_OPTION = 4, + CURL_FORMADD_INCOMPLETE = 5, + CURL_FORMADD_ILLEGAL_ARRAY = 6, + CURL_FORMADD_DISABLED = 7, + CURL_FORMADD_LAST = 8 +} + +alias CURL_FORMADD_OK = CURLFORMcode.CURL_FORMADD_OK; +alias CURL_FORMADD_MEMORY = CURLFORMcode.CURL_FORMADD_MEMORY; +alias CURL_FORMADD_OPTION_TWICE = CURLFORMcode.CURL_FORMADD_OPTION_TWICE; +alias CURL_FORMADD_NULL = CURLFORMcode.CURL_FORMADD_NULL; +alias CURL_FORMADD_UNKNOWN_OPTION = CURLFORMcode.CURL_FORMADD_UNKNOWN_OPTION; +alias CURL_FORMADD_INCOMPLETE = CURLFORMcode.CURL_FORMADD_INCOMPLETE; +alias CURL_FORMADD_ILLEGAL_ARRAY = CURLFORMcode.CURL_FORMADD_ILLEGAL_ARRAY; +alias CURL_FORMADD_DISABLED = CURLFORMcode.CURL_FORMADD_DISABLED; +alias CURL_FORMADD_LAST = CURLFORMcode.CURL_FORMADD_LAST; + +CURLFORMcode curl_formadd (curl_httppost** httppost, curl_httppost** last_post, ...); +alias curl_formget_callback = c_ulong function (void* arg, const(char)* buf, size_t len); +int curl_formget (curl_httppost* form, void* arg, curl_formget_callback append); +void curl_formfree (curl_httppost* form); +char* curl_getenv (const(char)* variable); +char* curl_version (); +char* curl_easy_escape (CURL* handle, const(char)* string, int length); +char* curl_escape (const(char)* string, int length); +char* curl_easy_unescape (CURL* handle, const(char)* string, int length, int* outlength); +char* curl_unescape (const(char)* string, int length); +void curl_free (void* p); +CURLcode curl_global_init (c_long flags); +CURLcode curl_global_init_mem (c_long flags, curl_malloc_callback m, curl_free_callback f, curl_realloc_callback r, curl_strdup_callback s, curl_calloc_callback c); +void curl_global_cleanup (); +CURLcode curl_global_trace (const(char)* config); + +struct curl_slist +{ +} + +struct curl_ssl_backend +{ + curl_sslbackend id; + const(char)* name; +} + +enum CURLsslset +{ + CURLSSLSET_OK = 0, + CURLSSLSET_UNKNOWN_BACKEND = 1, + CURLSSLSET_TOO_LATE = 2, + CURLSSLSET_NO_BACKENDS = 3 +} + +alias CURLSSLSET_OK = CURLsslset.CURLSSLSET_OK; +alias CURLSSLSET_UNKNOWN_BACKEND = CURLsslset.CURLSSLSET_UNKNOWN_BACKEND; +alias CURLSSLSET_TOO_LATE = CURLsslset.CURLSSLSET_TOO_LATE; +alias CURLSSLSET_NO_BACKENDS = CURLsslset.CURLSSLSET_NO_BACKENDS; + +CURLsslset curl_global_sslset (curl_sslbackend id, const(char)* name, const(curl_ssl_backend**)* avail); + +curl_slist* curl_slist_append (curl_slist* list, const(char)* data); + +void curl_slist_free_all (curl_slist* list); + +time_t curl_getdate (const(char)* p, const(time_t)* unused); + +struct curl_certinfo +{ + int num_of_certs; + curl_slist** certinfo; +} + +struct curl_tlssessioninfo +{ + curl_sslbackend backend; + void* internals; +} + +enum CURLINFO_STRING = 0x100000; +enum CURLINFO_LONG = 0x200000; +enum CURLINFO_DOUBLE = 0x300000; +enum CURLINFO_SLIST = 0x400000; +enum CURLINFO_PTR = 0x400000; +enum CURLINFO_SOCKET = 0x500000; +enum CURLINFO_OFF_T = 0x600000; +enum CURLINFO_MASK = 0x0fffff; +enum CURLINFO_TYPEMASK = 0xf00000; + +enum CURLINFO +{ + CURLINFO_NONE = 0, + CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, + CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, + CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, + CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, + CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, + CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, + CURLINFO_SIZE_UPLOAD = 3145735, + CURLINFO_SIZE_UPLOAD_T = CURLINFO_OFF_T + 7, + CURLINFO_SIZE_DOWNLOAD = 3145736, + CURLINFO_SIZE_DOWNLOAD_T = CURLINFO_OFF_T + 8, + CURLINFO_SPEED_DOWNLOAD = 3145737, + CURLINFO_SPEED_DOWNLOAD_T = CURLINFO_OFF_T + 9, + CURLINFO_SPEED_UPLOAD = 3145738, + CURLINFO_SPEED_UPLOAD_T = CURLINFO_OFF_T + 10, + CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, + CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, + CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, + CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_FILETIME_T = CURLINFO_OFF_T + 14, + CURLINFO_CONTENT_LENGTH_DOWNLOAD = 3145743, + CURLINFO_CONTENT_LENGTH_DOWNLOAD_T = CURLINFO_OFF_T + 15, + CURLINFO_CONTENT_LENGTH_UPLOAD = 3145744, + CURLINFO_CONTENT_LENGTH_UPLOAD_T = CURLINFO_OFF_T + 16, + CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, + CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, + CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, + CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, + CURLINFO_PRIVATE = CURLINFO_STRING + 21, + CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, + CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, + CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, + CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, + CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, + CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, + CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, + CURLINFO_LASTSOCKET = 2097181, + CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, + CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, + CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, + CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, + CURLINFO_CERTINFO = CURLINFO_PTR + 34, + CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, + CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, + CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, + CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, + CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, + CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, + CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, + CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, + CURLINFO_TLS_SESSION = 4194347, + CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, + CURLINFO_TLS_SSL_PTR = CURLINFO_PTR + 45, + CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46, + CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47, + CURLINFO_PROTOCOL = 2097200, + CURLINFO_SCHEME = CURLINFO_STRING + 49, + CURLINFO_TOTAL_TIME_T = CURLINFO_OFF_T + 50, + CURLINFO_NAMELOOKUP_TIME_T = CURLINFO_OFF_T + 51, + CURLINFO_CONNECT_TIME_T = CURLINFO_OFF_T + 52, + CURLINFO_PRETRANSFER_TIME_T = CURLINFO_OFF_T + 53, + CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54, + CURLINFO_REDIRECT_TIME_T = CURLINFO_OFF_T + 55, + CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56, + CURLINFO_RETRY_AFTER = CURLINFO_OFF_T + 57, + CURLINFO_EFFECTIVE_METHOD = CURLINFO_STRING + 58, + CURLINFO_PROXY_ERROR = CURLINFO_LONG + 59, + CURLINFO_REFERER = CURLINFO_STRING + 60, + CURLINFO_CAINFO = CURLINFO_STRING + 61, + CURLINFO_CAPATH = CURLINFO_STRING + 62, + CURLINFO_XFER_ID = CURLINFO_OFF_T + 63, + CURLINFO_CONN_ID = CURLINFO_OFF_T + 64, + CURLINFO_QUEUE_TIME_T = CURLINFO_OFF_T + 65, + CURLINFO_USED_PROXY = CURLINFO_LONG + 66, + CURLINFO_POSTTRANSFER_TIME_T = CURLINFO_OFF_T + 67, + CURLINFO_EARLYDATA_SENT_T = CURLINFO_OFF_T + 68, + CURLINFO_LASTONE = 68 +} + +alias CURLINFO_NONE = CURLINFO.CURLINFO_NONE; +alias CURLINFO_EFFECTIVE_URL = CURLINFO.CURLINFO_EFFECTIVE_URL; +alias CURLINFO_RESPONSE_CODE = CURLINFO.CURLINFO_RESPONSE_CODE; +alias CURLINFO_TOTAL_TIME = CURLINFO.CURLINFO_TOTAL_TIME; +alias CURLINFO_NAMELOOKUP_TIME = CURLINFO.CURLINFO_NAMELOOKUP_TIME; +alias CURLINFO_CONNECT_TIME = CURLINFO.CURLINFO_CONNECT_TIME; +alias CURLINFO_PRETRANSFER_TIME = CURLINFO.CURLINFO_PRETRANSFER_TIME; +alias CURLINFO_SIZE_UPLOAD = CURLINFO.CURLINFO_SIZE_UPLOAD; +alias CURLINFO_SIZE_UPLOAD_T = CURLINFO.CURLINFO_SIZE_UPLOAD_T; +alias CURLINFO_SIZE_DOWNLOAD = CURLINFO.CURLINFO_SIZE_DOWNLOAD; +alias CURLINFO_SIZE_DOWNLOAD_T = CURLINFO.CURLINFO_SIZE_DOWNLOAD_T; +alias CURLINFO_SPEED_DOWNLOAD = CURLINFO.CURLINFO_SPEED_DOWNLOAD; +alias CURLINFO_SPEED_DOWNLOAD_T = CURLINFO.CURLINFO_SPEED_DOWNLOAD_T; +alias CURLINFO_SPEED_UPLOAD = CURLINFO.CURLINFO_SPEED_UPLOAD; +alias CURLINFO_SPEED_UPLOAD_T = CURLINFO.CURLINFO_SPEED_UPLOAD_T; +alias CURLINFO_HEADER_SIZE = CURLINFO.CURLINFO_HEADER_SIZE; +alias CURLINFO_REQUEST_SIZE = CURLINFO.CURLINFO_REQUEST_SIZE; +alias CURLINFO_SSL_VERIFYRESULT = CURLINFO.CURLINFO_SSL_VERIFYRESULT; +alias CURLINFO_FILETIME = CURLINFO.CURLINFO_FILETIME; +alias CURLINFO_FILETIME_T = CURLINFO.CURLINFO_FILETIME_T; +alias CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO.CURLINFO_CONTENT_LENGTH_DOWNLOAD; +alias CURLINFO_CONTENT_LENGTH_DOWNLOAD_T = CURLINFO.CURLINFO_CONTENT_LENGTH_DOWNLOAD_T; +alias CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO.CURLINFO_CONTENT_LENGTH_UPLOAD; +alias CURLINFO_CONTENT_LENGTH_UPLOAD_T = CURLINFO.CURLINFO_CONTENT_LENGTH_UPLOAD_T; +alias CURLINFO_STARTTRANSFER_TIME = CURLINFO.CURLINFO_STARTTRANSFER_TIME; +alias CURLINFO_CONTENT_TYPE = CURLINFO.CURLINFO_CONTENT_TYPE; +alias CURLINFO_REDIRECT_TIME = CURLINFO.CURLINFO_REDIRECT_TIME; +alias CURLINFO_REDIRECT_COUNT = CURLINFO.CURLINFO_REDIRECT_COUNT; +alias CURLINFO_PRIVATE = CURLINFO.CURLINFO_PRIVATE; +alias CURLINFO_HTTP_CONNECTCODE = CURLINFO.CURLINFO_HTTP_CONNECTCODE; +alias CURLINFO_HTTPAUTH_AVAIL = CURLINFO.CURLINFO_HTTPAUTH_AVAIL; +alias CURLINFO_PROXYAUTH_AVAIL = CURLINFO.CURLINFO_PROXYAUTH_AVAIL; +alias CURLINFO_OS_ERRNO = CURLINFO.CURLINFO_OS_ERRNO; +alias CURLINFO_NUM_CONNECTS = CURLINFO.CURLINFO_NUM_CONNECTS; +alias CURLINFO_SSL_ENGINES = CURLINFO.CURLINFO_SSL_ENGINES; +alias CURLINFO_COOKIELIST = CURLINFO.CURLINFO_COOKIELIST; +alias CURLINFO_LASTSOCKET = CURLINFO.CURLINFO_LASTSOCKET; +alias CURLINFO_FTP_ENTRY_PATH = CURLINFO.CURLINFO_FTP_ENTRY_PATH; +alias CURLINFO_REDIRECT_URL = CURLINFO.CURLINFO_REDIRECT_URL; +alias CURLINFO_PRIMARY_IP = CURLINFO.CURLINFO_PRIMARY_IP; +alias CURLINFO_APPCONNECT_TIME = CURLINFO.CURLINFO_APPCONNECT_TIME; +alias CURLINFO_CERTINFO = CURLINFO.CURLINFO_CERTINFO; +alias CURLINFO_CONDITION_UNMET = CURLINFO.CURLINFO_CONDITION_UNMET; +alias CURLINFO_RTSP_SESSION_ID = CURLINFO.CURLINFO_RTSP_SESSION_ID; +alias CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO.CURLINFO_RTSP_CLIENT_CSEQ; +alias CURLINFO_RTSP_SERVER_CSEQ = CURLINFO.CURLINFO_RTSP_SERVER_CSEQ; +alias CURLINFO_RTSP_CSEQ_RECV = CURLINFO.CURLINFO_RTSP_CSEQ_RECV; +alias CURLINFO_PRIMARY_PORT = CURLINFO.CURLINFO_PRIMARY_PORT; +alias CURLINFO_LOCAL_IP = CURLINFO.CURLINFO_LOCAL_IP; +alias CURLINFO_LOCAL_PORT = CURLINFO.CURLINFO_LOCAL_PORT; +alias CURLINFO_TLS_SESSION = CURLINFO.CURLINFO_TLS_SESSION; +alias CURLINFO_ACTIVESOCKET = CURLINFO.CURLINFO_ACTIVESOCKET; +alias CURLINFO_TLS_SSL_PTR = CURLINFO.CURLINFO_TLS_SSL_PTR; +alias CURLINFO_HTTP_VERSION = CURLINFO.CURLINFO_HTTP_VERSION; +alias CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO.CURLINFO_PROXY_SSL_VERIFYRESULT; +alias CURLINFO_PROTOCOL = CURLINFO.CURLINFO_PROTOCOL; +alias CURLINFO_SCHEME = CURLINFO.CURLINFO_SCHEME; +alias CURLINFO_TOTAL_TIME_T = CURLINFO.CURLINFO_TOTAL_TIME_T; +alias CURLINFO_NAMELOOKUP_TIME_T = CURLINFO.CURLINFO_NAMELOOKUP_TIME_T; +alias CURLINFO_CONNECT_TIME_T = CURLINFO.CURLINFO_CONNECT_TIME_T; +alias CURLINFO_PRETRANSFER_TIME_T = CURLINFO.CURLINFO_PRETRANSFER_TIME_T; +alias CURLINFO_STARTTRANSFER_TIME_T = CURLINFO.CURLINFO_STARTTRANSFER_TIME_T; +alias CURLINFO_REDIRECT_TIME_T = CURLINFO.CURLINFO_REDIRECT_TIME_T; +alias CURLINFO_APPCONNECT_TIME_T = CURLINFO.CURLINFO_APPCONNECT_TIME_T; +alias CURLINFO_RETRY_AFTER = CURLINFO.CURLINFO_RETRY_AFTER; +alias CURLINFO_EFFECTIVE_METHOD = CURLINFO.CURLINFO_EFFECTIVE_METHOD; +alias CURLINFO_PROXY_ERROR = CURLINFO.CURLINFO_PROXY_ERROR; +alias CURLINFO_REFERER = CURLINFO.CURLINFO_REFERER; +alias CURLINFO_CAINFO = CURLINFO.CURLINFO_CAINFO; +alias CURLINFO_CAPATH = CURLINFO.CURLINFO_CAPATH; +alias CURLINFO_XFER_ID = CURLINFO.CURLINFO_XFER_ID; +alias CURLINFO_CONN_ID = CURLINFO.CURLINFO_CONN_ID; +alias CURLINFO_QUEUE_TIME_T = CURLINFO.CURLINFO_QUEUE_TIME_T; +alias CURLINFO_USED_PROXY = CURLINFO.CURLINFO_USED_PROXY; +alias CURLINFO_POSTTRANSFER_TIME_T = CURLINFO.CURLINFO_POSTTRANSFER_TIME_T; +alias CURLINFO_EARLYDATA_SENT_T = CURLINFO.CURLINFO_EARLYDATA_SENT_T; +alias CURLINFO_LASTONE = CURLINFO.CURLINFO_LASTONE; + +enum CURLINFO_HTTP_CODE = CURLINFO.CURLINFO_RESPONSE_CODE; + +enum curl_closepolicy +{ + CURLCLOSEPOLICY_NONE = 0, + + CURLCLOSEPOLICY_OLDEST = 1, + CURLCLOSEPOLICY_LEAST_RECENTLY_USED = 2, + CURLCLOSEPOLICY_LEAST_TRAFFIC = 3, + CURLCLOSEPOLICY_SLOWEST = 4, + CURLCLOSEPOLICY_CALLBACK = 5, + + CURLCLOSEPOLICY_LAST = 6 +} + +alias CURLCLOSEPOLICY_NONE = curl_closepolicy.CURLCLOSEPOLICY_NONE; +alias CURLCLOSEPOLICY_OLDEST = curl_closepolicy.CURLCLOSEPOLICY_OLDEST; +alias CURLCLOSEPOLICY_LEAST_RECENTLY_USED = curl_closepolicy.CURLCLOSEPOLICY_LEAST_RECENTLY_USED; +alias CURLCLOSEPOLICY_LEAST_TRAFFIC = curl_closepolicy.CURLCLOSEPOLICY_LEAST_TRAFFIC; +alias CURLCLOSEPOLICY_SLOWEST = curl_closepolicy.CURLCLOSEPOLICY_SLOWEST; +alias CURLCLOSEPOLICY_CALLBACK = curl_closepolicy.CURLCLOSEPOLICY_CALLBACK; +alias CURLCLOSEPOLICY_LAST = curl_closepolicy.CURLCLOSEPOLICY_LAST; + +enum CURL_GLOBAL_SSL = 1 << 0; +enum CURL_GLOBAL_WIN32 = 1 << 1; +enum CURL_GLOBAL_ALL = CURL_GLOBAL_SSL | CURL_GLOBAL_WIN32; +enum CURL_GLOBAL_NOTHING = 0; +enum CURL_GLOBAL_DEFAULT = CURL_GLOBAL_ALL; +enum CURL_GLOBAL_ACK_EINTR = 1 << 2; + +enum curl_lock_data +{ + CURL_LOCK_DATA_NONE = 0, + + CURL_LOCK_DATA_SHARE = 1, + CURL_LOCK_DATA_COOKIE = 2, + CURL_LOCK_DATA_DNS = 3, + CURL_LOCK_DATA_SSL_SESSION = 4, + CURL_LOCK_DATA_CONNECT = 5, + CURL_LOCK_DATA_PSL = 6, + CURL_LOCK_DATA_HSTS = 7, + CURL_LOCK_DATA_LAST = 8 +} + +alias CURL_LOCK_DATA_NONE = curl_lock_data.CURL_LOCK_DATA_NONE; +alias CURL_LOCK_DATA_SHARE = curl_lock_data.CURL_LOCK_DATA_SHARE; +alias CURL_LOCK_DATA_COOKIE = curl_lock_data.CURL_LOCK_DATA_COOKIE; +alias CURL_LOCK_DATA_DNS = curl_lock_data.CURL_LOCK_DATA_DNS; +alias CURL_LOCK_DATA_SSL_SESSION = curl_lock_data.CURL_LOCK_DATA_SSL_SESSION; +alias CURL_LOCK_DATA_CONNECT = curl_lock_data.CURL_LOCK_DATA_CONNECT; +alias CURL_LOCK_DATA_PSL = curl_lock_data.CURL_LOCK_DATA_PSL; +alias CURL_LOCK_DATA_HSTS = curl_lock_data.CURL_LOCK_DATA_HSTS; +alias CURL_LOCK_DATA_LAST = curl_lock_data.CURL_LOCK_DATA_LAST; + +enum curl_lock_access +{ + CURL_LOCK_ACCESS_NONE = 0, + CURL_LOCK_ACCESS_SHARED = 1, + CURL_LOCK_ACCESS_SINGLE = 2, + CURL_LOCK_ACCESS_LAST = 3 +} + +alias CURL_LOCK_ACCESS_NONE = curl_lock_access.CURL_LOCK_ACCESS_NONE; +alias CURL_LOCK_ACCESS_SHARED = curl_lock_access.CURL_LOCK_ACCESS_SHARED; +alias CURL_LOCK_ACCESS_SINGLE = curl_lock_access.CURL_LOCK_ACCESS_SINGLE; +alias CURL_LOCK_ACCESS_LAST = curl_lock_access.CURL_LOCK_ACCESS_LAST; + +alias curl_lock_function = void function (CURL* handle, curl_lock_data data, curl_lock_access locktype, void* userptr); +alias curl_unlock_function = void function (CURL* handle, curl_lock_data data, void* userptr); + +enum CURLSHcode +{ + CURLSHE_OK = 0, + CURLSHE_BAD_OPTION = 1, + CURLSHE_IN_USE = 2, + CURLSHE_INVALID = 3, + CURLSHE_NOMEM = 4, + CURLSHE_NOT_BUILT_IN = 5, + CURLSHE_LAST = 6 +} + +alias CURLSHE_OK = CURLSHcode.CURLSHE_OK; +alias CURLSHE_BAD_OPTION = CURLSHcode.CURLSHE_BAD_OPTION; +alias CURLSHE_IN_USE = CURLSHcode.CURLSHE_IN_USE; +alias CURLSHE_INVALID = CURLSHcode.CURLSHE_INVALID; +alias CURLSHE_NOMEM = CURLSHcode.CURLSHE_NOMEM; +alias CURLSHE_NOT_BUILT_IN = CURLSHcode.CURLSHE_NOT_BUILT_IN; +alias CURLSHE_LAST = CURLSHcode.CURLSHE_LAST; + +enum CURLSHoption +{ + CURLSHOPT_NONE = 0, + CURLSHOPT_SHARE = 1, + CURLSHOPT_UNSHARE = 2, + CURLSHOPT_LOCKFUNC = 3, + CURLSHOPT_UNLOCKFUNC = 4, + CURLSHOPT_USERDATA = 5, + + CURLSHOPT_LAST = 6 +} + +alias CURLSHOPT_NONE = CURLSHoption.CURLSHOPT_NONE; +alias CURLSHOPT_SHARE = CURLSHoption.CURLSHOPT_SHARE; +alias CURLSHOPT_UNSHARE = CURLSHoption.CURLSHOPT_UNSHARE; +alias CURLSHOPT_LOCKFUNC = CURLSHoption.CURLSHOPT_LOCKFUNC; +alias CURLSHOPT_UNLOCKFUNC = CURLSHoption.CURLSHOPT_UNLOCKFUNC; +alias CURLSHOPT_USERDATA = CURLSHoption.CURLSHOPT_USERDATA; +alias CURLSHOPT_LAST = CURLSHoption.CURLSHOPT_LAST; + +CURLSH* curl_share_init (); +CURLSHcode curl_share_setopt (CURLSH* share, CURLSHoption option, ...); +CURLSHcode curl_share_cleanup (CURLSH* share); + +enum CURLversion +{ + CURLVERSION_FIRST = 0, + CURLVERSION_SECOND = 1, + CURLVERSION_THIRD = 2, + CURLVERSION_FOURTH = 3, + CURLVERSION_FIFTH = 4, + CURLVERSION_SIXTH = 5, + CURLVERSION_SEVENTH = 6, + CURLVERSION_EIGHTH = 7, + CURLVERSION_NINTH = 8, + CURLVERSION_TENTH = 9, + CURLVERSION_ELEVENTH = 10, + CURLVERSION_TWELFTH = 11, + CURLVERSION_LAST = 12 +} + +alias CURLVERSION_FIRST = CURLversion.CURLVERSION_FIRST; +alias CURLVERSION_SECOND = CURLversion.CURLVERSION_SECOND; +alias CURLVERSION_THIRD = CURLversion.CURLVERSION_THIRD; +alias CURLVERSION_FOURTH = CURLversion.CURLVERSION_FOURTH; +alias CURLVERSION_FIFTH = CURLversion.CURLVERSION_FIFTH; +alias CURLVERSION_SIXTH = CURLversion.CURLVERSION_SIXTH; +alias CURLVERSION_SEVENTH = CURLversion.CURLVERSION_SEVENTH; +alias CURLVERSION_EIGHTH = CURLversion.CURLVERSION_EIGHTH; +alias CURLVERSION_NINTH = CURLversion.CURLVERSION_NINTH; +alias CURLVERSION_TENTH = CURLversion.CURLVERSION_TENTH; +alias CURLVERSION_ELEVENTH = CURLversion.CURLVERSION_ELEVENTH; +alias CURLVERSION_TWELFTH = CURLversion.CURLVERSION_TWELFTH; +alias CURLVERSION_LAST = CURLversion.CURLVERSION_LAST; + +enum CURLVERSION_NOW = CURLversion.CURLVERSION_TWELFTH; + +struct curl_version_info_data +{ + CURLversion age; + const(char)* version_; + uint version_num; + const(char)* host; + int features; + const(char)* ssl_version; + c_long ssl_version_num; + const(char)* libz_version; + + const(char*)* protocols; + + const(char)* ares; + int ares_num; + + const(char)* libidn; + + int iconv_ver_num; + + const(char)* libssh_version; + + uint brotli_ver_num; + + const(char)* brotli_version; + + uint nghttp2_ver_num; + + const(char)* nghttp2_version; + const(char)* quic_version; + + const(char)* cainfo; + + const(char)* capath; + + uint zstd_ver_num; + + const(char)* zstd_version; + + const(char)* hyper_version; + + const(char)* gsasl_version; + + const(char*)* feature_names; + + const(char)* rtmp_version; +} + +enum CURL_VERSION_IPV6 = 1 << 0; +enum CURL_VERSION_KERBEROS4 = 1 << 1; + +enum CURL_VERSION_SSL = 1 << 2; +enum CURL_VERSION_LIBZ = 1 << 3; +enum CURL_VERSION_NTLM = 1 << 4; +enum CURL_VERSION_GSSNEGOTIATE = 1 << 5; + +enum CURL_VERSION_DEBUG = 1 << 6; +enum CURL_VERSION_ASYNCHDNS = 1 << 7; +enum CURL_VERSION_SPNEGO = 1 << 8; +enum CURL_VERSION_LARGEFILE = 1 << 9; +enum CURL_VERSION_IDN = 1 << 10; + +enum CURL_VERSION_SSPI = 1 << 11; +enum CURL_VERSION_CONV = 1 << 12; +enum CURL_VERSION_CURLDEBUG = 1 << 13; +enum CURL_VERSION_TLSAUTH_SRP = 1 << 14; +enum CURL_VERSION_NTLM_WB = 1 << 15; + +enum CURL_VERSION_HTTP2 = 1 << 16; +enum CURL_VERSION_GSSAPI = 1 << 17; +enum CURL_VERSION_KERBEROS5 = 1 << 18; +enum CURL_VERSION_UNIX_SOCKETS = 1 << 19; +enum CURL_VERSION_PSL = 1 << 20; + +enum CURL_VERSION_HTTPS_PROXY = 1 << 21; +enum CURL_VERSION_MULTI_SSL = 1 << 22; +enum CURL_VERSION_BROTLI = 1 << 23; +enum CURL_VERSION_ALTSVC = 1 << 24; +enum CURL_VERSION_HTTP3 = 1 << 25; +enum CURL_VERSION_ZSTD = 1 << 26; +enum CURL_VERSION_UNICODE = 1 << 27; +enum CURL_VERSION_HSTS = 1 << 28; +enum CURL_VERSION_GSASL = 1 << 29; +enum CURL_VERSION_THREADSAFE = 1 << 30; + +curl_version_info_data* curl_version_info (CURLversion); + +const(char)* curl_easy_strerror (CURLcode); + +const(char)* curl_share_strerror (CURLSHcode); + +CURLcode curl_easy_pause (CURL* handle, int bitmask); + +enum CURLPAUSE_RECV = 1 << 0; +enum CURLPAUSE_RECV_CONT = 0; + +enum CURLPAUSE_SEND = 1 << 2; +enum CURLPAUSE_SEND_CONT = 0; + +enum CURLPAUSE_ALL = CURLPAUSE_RECV | CURLPAUSE_SEND; +enum CURLPAUSE_CONT = CURLPAUSE_RECV_CONT | CURLPAUSE_SEND_CONT; + +CURL* curl_easy_init(); +CURLcode curl_easy_perform(CURL* curl); +void curl_easy_cleanup(CURL* curl); + +CURLcode curl_easy_setopt(CURL* curl, CURLoption option, ...); +CURLcode curl_easy_getinfo(CURL* curl, CURLINFO info, ...); +// CURLSHcode curl_share_setopt(CURLSH*, CURLSHoption option, ...); +// CURLMcode curl_multi_setopt(CURLM* multi_handle, CURLMoption option, ...); diff --git a/source/bindings/olm/error.d b/source/bindings/olm/error.d new file mode 100644 index 0000000..52c9106 --- /dev/null +++ b/source/bindings/olm/error.d @@ -0,0 +1,93 @@ +/* Copyright 2015-2016 OpenMarket Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +module libolm.error; + +extern (C): + +enum OlmErrorCode +{ + OLM_SUCCESS = 0, /*!< There wasn't an error */ + OLM_NOT_ENOUGH_RANDOM = 1, /*!< Not enough entropy was supplied */ + OLM_OUTPUT_BUFFER_TOO_SMALL = 2, /*!< Supplied output buffer is too small */ + OLM_BAD_MESSAGE_VERSION = 3, /*!< The message version is unsupported */ + OLM_BAD_MESSAGE_FORMAT = 4, /*!< The message couldn't be decoded */ + OLM_BAD_MESSAGE_MAC = 5, /*!< The message couldn't be decrypted */ + OLM_BAD_MESSAGE_KEY_ID = 6, /*!< The message references an unknown key id */ + OLM_INVALID_BASE64 = 7, /*!< The input base64 was invalid */ + OLM_BAD_ACCOUNT_KEY = 8, /*!< The supplied account key is invalid */ + OLM_UNKNOWN_PICKLE_VERSION = 9, /*!< The pickled object is too new */ + OLM_CORRUPTED_PICKLE = 10, /*!< The pickled object couldn't be decoded */ + + OLM_BAD_SESSION_KEY = 11, /*!< Attempt to initialise an inbound group + session from an invalid session key */ + OLM_UNKNOWN_MESSAGE_INDEX = 12, /*!< Attempt to decode a message whose + * index is earlier than our earliest + * known session key. + */ + + /** + * Attempt to unpickle an account which uses pickle version 1 (which did + * not save enough space for the Ed25519 key; the key should be considered + * compromised. We don't let the user reload the account. + */ + OLM_BAD_LEGACY_ACCOUNT_PICKLE = 13, + + /** + * Received message had a bad signature + */ + OLM_BAD_SIGNATURE = 14, + + OLM_INPUT_BUFFER_TOO_SMALL = 15, + + /** + * SAS doesn't have their key set. + */ + OLM_SAS_THEIR_KEY_NOT_SET = 16, + + /** + * The pickled object was successfully decoded, but the unpickling still failed + * because it had some extraneous junk data at the end. + */ + OLM_PICKLE_EXTRA_DATA = 17 + + /* remember to update the list of string constants in error.c when updating + * this list. */ +} + +alias OLM_SUCCESS = OlmErrorCode.OLM_SUCCESS; +alias OLM_NOT_ENOUGH_RANDOM = OlmErrorCode.OLM_NOT_ENOUGH_RANDOM; +alias OLM_OUTPUT_BUFFER_TOO_SMALL = OlmErrorCode.OLM_OUTPUT_BUFFER_TOO_SMALL; +alias OLM_BAD_MESSAGE_VERSION = OlmErrorCode.OLM_BAD_MESSAGE_VERSION; +alias OLM_BAD_MESSAGE_FORMAT = OlmErrorCode.OLM_BAD_MESSAGE_FORMAT; +alias OLM_BAD_MESSAGE_MAC = OlmErrorCode.OLM_BAD_MESSAGE_MAC; +alias OLM_BAD_MESSAGE_KEY_ID = OlmErrorCode.OLM_BAD_MESSAGE_KEY_ID; +alias OLM_INVALID_BASE64 = OlmErrorCode.OLM_INVALID_BASE64; +alias OLM_BAD_ACCOUNT_KEY = OlmErrorCode.OLM_BAD_ACCOUNT_KEY; +alias OLM_UNKNOWN_PICKLE_VERSION = OlmErrorCode.OLM_UNKNOWN_PICKLE_VERSION; +alias OLM_CORRUPTED_PICKLE = OlmErrorCode.OLM_CORRUPTED_PICKLE; +alias OLM_BAD_SESSION_KEY = OlmErrorCode.OLM_BAD_SESSION_KEY; +alias OLM_UNKNOWN_MESSAGE_INDEX = OlmErrorCode.OLM_UNKNOWN_MESSAGE_INDEX; +alias OLM_BAD_LEGACY_ACCOUNT_PICKLE = OlmErrorCode.OLM_BAD_LEGACY_ACCOUNT_PICKLE; +alias OLM_BAD_SIGNATURE = OlmErrorCode.OLM_BAD_SIGNATURE; +alias OLM_INPUT_BUFFER_TOO_SMALL = OlmErrorCode.OLM_INPUT_BUFFER_TOO_SMALL; +alias OLM_SAS_THEIR_KEY_NOT_SET = OlmErrorCode.OLM_SAS_THEIR_KEY_NOT_SET; +alias OLM_PICKLE_EXTRA_DATA = OlmErrorCode.OLM_PICKLE_EXTRA_DATA; + +/** get a string representation of the given error code. */ +const(char)* _olm_error_to_string (OlmErrorCode error); + +// extern "C" + +/* OLM_ERROR_H_ */ diff --git a/source/bindings/olm/inbound.d b/source/bindings/olm/inbound.d new file mode 100644 index 0000000..55d2648 --- /dev/null +++ b/source/bindings/olm/inbound.d @@ -0,0 +1,188 @@ +module libolm.inbound; +/* Copyright 2016 OpenMarket Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import libolm.error; + +@nogc: +extern (C): + +struct OlmInboundGroupSession; + +/** get the size of an inbound group session, in bytes. */ +size_t olm_inbound_group_session_size (); + +/** + * Initialise an inbound group session object using the supplied memory + * The supplied memory should be at least olm_inbound_group_session_size() + * bytes. + */ +OlmInboundGroupSession* olm_inbound_group_session (void* memory); + +/** + * A null terminated string describing the most recent error to happen to a + * group session */ +const(char)* olm_inbound_group_session_last_error (const(OlmInboundGroupSession)* session); + +/** + * An error code describing the most recent error to happen to a group + * session */ +OlmErrorCode olm_inbound_group_session_last_error_code (const(OlmInboundGroupSession)* session); + +/** Clears the memory used to back this group session */ +size_t olm_clear_inbound_group_session (OlmInboundGroupSession* session); + +/** Returns the number of bytes needed to store an inbound group session */ +size_t olm_pickle_inbound_group_session_length (const(OlmInboundGroupSession)* session); + +/** + * Stores a group session as a base64 string. Encrypts the session using the + * supplied key. Returns the length of the session on success. + * + * Returns olm_error() on failure. If the pickle output buffer + * is smaller than olm_pickle_inbound_group_session_length() then + * olm_inbound_group_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" + */ +size_t olm_pickle_inbound_group_session (OlmInboundGroupSession* session, const(void)* key, size_t key_length, void* pickled, size_t pickled_length); + +/** + * Loads a group session from a pickled base64 string. Decrypts the session + * using the supplied key. + * + * Returns olm_error() on failure. If the key doesn't match the one used to + * encrypt the account then olm_inbound_group_session_last_error() will be + * "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then + * olm_inbound_group_session_last_error() will be "INVALID_BASE64". The input + * pickled buffer is destroyed + */ +size_t olm_unpickle_inbound_group_session (OlmInboundGroupSession* session, const(void)* key, size_t key_length, void* pickled, size_t pickled_length); + +/** + * Start a new inbound group session, from a key exported from + * olm_outbound_group_session_key + * + * Returns olm_error() on failure. On failure last_error will be set with an + * error code. The last_error will be: + * + * * OLM_INVALID_BASE64 if the session_key is not valid base64 + * * OLM_BAD_SESSION_KEY if the session_key is invalid + */ + +/* base64-encoded keys */ +size_t olm_init_inbound_group_session (OlmInboundGroupSession* session, const(ubyte)* session_key, size_t session_key_length); + +/** + * Import an inbound group session, from a previous export. + * + * Returns olm_error() on failure. On failure last_error will be set with an + * error code. The last_error will be: + * + * * OLM_INVALID_BASE64 if the session_key is not valid base64 + * * OLM_BAD_SESSION_KEY if the session_key is invalid + */ + +/* base64-encoded keys; note that it will be overwritten with the base64-decoded + data. */ +size_t olm_import_inbound_group_session (OlmInboundGroupSession* session, const(ubyte)* session_key, size_t session_key_length); + +/** + * Get an upper bound on the number of bytes of plain-text the decrypt method + * will write for a given input message length. The actual size could be + * different due to padding. + * + * The input message buffer is destroyed. + * + * Returns olm_error() on failure. + */ +size_t olm_group_decrypt_max_plaintext_length (OlmInboundGroupSession* session, ubyte* message, size_t message_length); + +/** + * Decrypt a message. + * + * The input message buffer is destroyed. + * + * Returns the length of the decrypted plain-text, or olm_error() on failure. + * + * On failure last_error will be set with an error code. The last_error will + * be: + * * OLM_OUTPUT_BUFFER_TOO_SMALL if the plain-text buffer is too small + * * OLM_INVALID_BASE64 if the message is not valid base-64 + * * OLM_BAD_MESSAGE_VERSION if the message was encrypted with an unsupported + * version of the protocol + * * OLM_BAD_MESSAGE_FORMAT if the message headers could not be decoded + * * OLM_BAD_MESSAGE_MAC if the message could not be verified + * * OLM_UNKNOWN_MESSAGE_INDEX if we do not have a session key corresponding to the + * message's index (ie, it was sent before the session key was shared with + * us) + */ + +/* input; note that it will be overwritten with the base64-decoded + message. */ + +/* output */ +size_t olm_group_decrypt (OlmInboundGroupSession* session, ubyte* message, size_t message_length, ubyte* plaintext, size_t max_plaintext_length, uint* message_index); + +/** + * Get the number of bytes returned by olm_inbound_group_session_id() + */ +size_t olm_inbound_group_session_id_length (const(OlmInboundGroupSession)* session); + +/** + * Get a base64-encoded identifier for this session. + * + * Returns the length of the session id on success or olm_error() on + * failure. On failure last_error will be set with an error code. The + * last_error will be OUTPUT_BUFFER_TOO_SMALL if the id buffer was too + * small. + */ +size_t olm_inbound_group_session_id (OlmInboundGroupSession* session, ubyte* id, size_t id_length); + +/** + * Get the first message index we know how to decrypt. + */ +uint olm_inbound_group_session_first_known_index (const(OlmInboundGroupSession)* session); + +/** + * Check if the session has been verified as a valid session. + * + * (A session is verified either because the original session share was signed, + * or because we have subsequently successfully decrypted a message.) + * + * This is mainly intended for the unit tests, currently. + */ +int olm_inbound_group_session_is_verified (const(OlmInboundGroupSession)* session); + +/** + * Get the number of bytes returned by olm_export_inbound_group_session() + */ +size_t olm_export_inbound_group_session_length (const(OlmInboundGroupSession)* session); + +/** + * Export the base64-encoded ratchet key for this session, at the given index, + * in a format which can be used by olm_import_inbound_group_session + * + * Returns the length of the ratchet key on success or olm_error() on + * failure. On failure last_error will be set with an error code. The + * last_error will be: + * * OUTPUT_BUFFER_TOO_SMALL if the buffer was too small + * * OLM_UNKNOWN_MESSAGE_INDEX if we do not have a session key corresponding to the + * given index (ie, it was sent before the session key was shared with + * us) + */ +size_t olm_export_inbound_group_session (OlmInboundGroupSession* session, ubyte* key, size_t key_length, uint message_index); + +// extern "C" + +/* OLM_INBOUND_GROUP_SESSION_H_ */ diff --git a/source/bindings/olm/olm.d b/source/bindings/olm/olm.d new file mode 100644 index 0000000..2b07928 --- /dev/null +++ b/source/bindings/olm/olm.d @@ -0,0 +1,349 @@ +/* Copyright 2015, 2016 OpenMarket Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import libolm.error; +extern (C): + +extern __gshared const size_t OLM_MESSAGE_TYPE_PRE_KEY; +extern __gshared const size_t OLM_MESSAGE_TYPE_MESSAGE; + +struct OlmAccount; +struct OlmSession; +struct OlmUtility; + +/** Get the version number of the library. + * Arguments will be updated if non-null. + */ +void olm_get_library_version (ubyte* major, ubyte* minor, ubyte* patch); + +/** The size of an account object in bytes */ +size_t olm_account_size (); + +/** The size of a session object in bytes */ +size_t olm_session_size (); + +/** The size of a utility object in bytes */ +size_t olm_utility_size (); + +/** Initialise an account object using the supplied memory + * The supplied memory must be at least olm_account_size() bytes */ +OlmAccount* olm_account (void* memory); + +/** Initialise a session object using the supplied memory + * The supplied memory must be at least olm_session_size() bytes */ +OlmSession* olm_session (void* memory); + +/** Initialise a utility object using the supplied memory + * The supplied memory must be at least olm_utility_size() bytes */ +OlmUtility* olm_utility (void* memory); + +/** The value that olm will return from a function if there was an error */ +size_t olm_error (); + +/** A null terminated string describing the most recent error to happen to an + * account */ +const(char)* olm_account_last_error (const(OlmAccount)* account); + +/** An error code describing the most recent error to happen to an account */ +OlmErrorCode olm_account_last_error_code (const(OlmAccount)* account); + +/** A null terminated string describing the most recent error to happen to a + * session */ +const(char)* olm_session_last_error (const(OlmSession)* session); + +/** An error code describing the most recent error to happen to a session */ +OlmErrorCode olm_session_last_error_code (const(OlmSession)* session); + +/** A null terminated string describing the most recent error to happen to a + * utility */ +const(char)* olm_utility_last_error (const(OlmUtility)* utility); + +/** An error code describing the most recent error to happen to a utility */ +OlmErrorCode olm_utility_last_error_code (const(OlmUtility)* utility); + +/** Clears the memory used to back this account */ +size_t olm_clear_account (OlmAccount* account); + +/** Clears the memory used to back this session */ +size_t olm_clear_session (OlmSession* session); + +/** Clears the memory used to back this utility */ +size_t olm_clear_utility (OlmUtility* utility); + +/** Returns the number of bytes needed to store an account */ +size_t olm_pickle_account_length (const(OlmAccount)* account); + +/** Returns the number of bytes needed to store a session */ +size_t olm_pickle_session_length (const(OlmSession)* session); + +/** Stores an account as a base64 string. Encrypts the account using the + * supplied key. Returns the length of the pickled account on success. + * Returns olm_error() on failure. If the pickle output buffer + * is smaller than olm_pickle_account_length() then + * olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */ +size_t olm_pickle_account (OlmAccount* account, const(void)* key, size_t key_length, void* pickled, size_t pickled_length); + +/** Stores a session as a base64 string. Encrypts the session using the + * supplied key. Returns the length of the pickled session on success. + * Returns olm_error() on failure. If the pickle output buffer + * is smaller than olm_pickle_session_length() then + * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */ +size_t olm_pickle_session (OlmSession* session, const(void)* key, size_t key_length, void* pickled, size_t pickled_length); + +/** Loads an account from a pickled base64 string. Decrypts the account using + * the supplied key. Returns olm_error() on failure. If the key doesn't + * match the one used to encrypt the account then olm_account_last_error() + * will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then + * olm_account_last_error() will be "INVALID_BASE64". The input pickled + * buffer is destroyed */ +size_t olm_unpickle_account (OlmAccount* account, const(void)* key, size_t key_length, void* pickled, size_t pickled_length); + +/** Loads a session from a pickled base64 string. Decrypts the session using + * the supplied key. Returns olm_error() on failure. If the key doesn't + * match the one used to encrypt the account then olm_session_last_error() + * will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then + * olm_session_last_error() will be "INVALID_BASE64". The input pickled + * buffer is destroyed */ +size_t olm_unpickle_session (OlmSession* session, const(void)* key, size_t key_length, void* pickled, size_t pickled_length); + +/** The number of random bytes needed to create an account.*/ +size_t olm_create_account_random_length (const(OlmAccount)* account); + +/** Creates a new account. Returns olm_error() on failure. If there weren't + * enough random bytes then olm_account_last_error() will be + * "NOT_ENOUGH_RANDOM" */ +size_t olm_create_account (OlmAccount* account, void* random, size_t random_length); + +/** The size of the output buffer needed to hold the identity keys */ +size_t olm_account_identity_keys_length (const(OlmAccount)* account); + +/** Writes the public parts of the identity keys for the account into the + * identity_keys output buffer. Returns olm_error() on failure. If the + * identity_keys buffer was too small then olm_account_last_error() will be + * "OUTPUT_BUFFER_TOO_SMALL". */ +size_t olm_account_identity_keys (OlmAccount* account, void* identity_keys, size_t identity_key_length); + +/** The length of an ed25519 signature encoded as base64. */ +size_t olm_account_signature_length (const(OlmAccount)* account); + +/** Signs a message with the ed25519 key for this account. Returns olm_error() + * on failure. If the signature buffer was too small then + * olm_account_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */ +size_t olm_account_sign (OlmAccount* account, const(void)* message, size_t message_length, void* signature, size_t signature_length); + +/** The size of the output buffer needed to hold the one time keys */ +size_t olm_account_one_time_keys_length (const(OlmAccount)* account); + +/** Writes the public parts of the unpublished one time keys for the account + * into the one_time_keys output buffer. + *

+ * The returned data is a JSON-formatted object with the single property + * curve25519, which is itself an object mapping key id to + * base64-encoded Curve25519 key. For example: + *

+ * {
+ *     curve25519: {
+ *         "AAAAAA": "wo76WcYtb0Vk/pBOdmduiGJ0wIEjW4IBMbbQn7aSnTo",
+ *         "AAAAAB": "LRvjo46L1X2vx69sS9QNFD29HWulxrmW11Up5AfAjgU"
+ *     }
+ * }
+ * 
+ * Returns olm_error() on failure. + *

+ * If the one_time_keys buffer was too small then olm_account_last_error() + * will be "OUTPUT_BUFFER_TOO_SMALL". */ +size_t olm_account_one_time_keys (OlmAccount* account, void* one_time_keys, size_t one_time_keys_length); + +/** Marks the current set of one time keys and fallback key as being published + * Once marked as published, the one time keys will no longer be returned by + * olm_account_one_time_keys(), and the fallback key will no longer be returned + * by olm_account_unpublished_fallback_key(). + * + * Returns the number of one-time keys that were marked as published. Note that + * this count does not include the fallback key. */ +size_t olm_account_mark_keys_as_published (OlmAccount* account); + +/** The largest number of one time keys this account can store. */ +size_t olm_account_max_number_of_one_time_keys (const(OlmAccount)* account); + +/** The number of random bytes needed to generate a given number of new one + * time keys. */ +size_t olm_account_generate_one_time_keys_random_length (const(OlmAccount)* account, size_t number_of_keys); + +/** Generates a number of new one time keys. If the total number of keys stored + * by this account exceeds max_number_of_one_time_keys() then the old keys are + * discarded. Returns olm_error() on error. If the number of random bytes is + * too small then olm_account_last_error() will be "NOT_ENOUGH_RANDOM". */ +size_t olm_account_generate_one_time_keys (OlmAccount* account, size_t number_of_keys, void* random, size_t random_length); + +/** The number of random bytes needed to generate a fallback key. */ +size_t olm_account_generate_fallback_key_random_length (const(OlmAccount)* account); + +/** Generates a new fallback key. Only one previous fallback key is + * stored. Returns olm_error() on error. If the number of random bytes is too + * small then olm_account_last_error() will be "NOT_ENOUGH_RANDOM". */ +size_t olm_account_generate_fallback_key (OlmAccount* account, void* random, size_t random_length); + +/** The number of bytes needed to hold the fallback key as returned by + * olm_account_fallback_key. */ +size_t olm_account_fallback_key_length (const(OlmAccount)* account); + +/** Deprecated: use olm_account_unpublished_fallback_key instead */ +size_t olm_account_fallback_key (OlmAccount* account, void* fallback_key, size_t fallback_key_size); + +/** The number of bytes needed to hold the unpublished fallback key as returned + * by olm_account_unpublished fallback_key. */ +size_t olm_account_unpublished_fallback_key_length (const(OlmAccount)* account); + +/** Returns the fallback key (if present, and if unpublished) into the + * fallback_key buffer */ +size_t olm_account_unpublished_fallback_key (OlmAccount* account, void* fallback_key, size_t fallback_key_size); + +/** Forget about the old fallback key. This should be called once you are + * reasonably certain that you will not receive any more messages that use + * the old fallback key (e.g. 5 minutes after the new fallback key has been + * published). + */ +void olm_account_forget_old_fallback_key (OlmAccount* account); + +/** The number of random bytes needed to create an outbound session */ +size_t olm_create_outbound_session_random_length (const(OlmSession)* session); + +/** Creates a new out-bound session for sending messages to a given identity_key + * and one_time_key. Returns olm_error() on failure. If the keys couldn't be + * decoded as base64 then olm_session_last_error() will be "INVALID_BASE64" + * If there weren't enough random bytes then olm_session_last_error() will + * be "NOT_ENOUGH_RANDOM". */ +size_t olm_create_outbound_session (OlmSession* session, const(OlmAccount)* account, const(void)* their_identity_key, size_t their_identity_key_length, const(void)* their_one_time_key, size_t their_one_time_key_length, void* random, size_t random_length); + +/** Create a new in-bound session for sending/receiving messages from an + * incoming PRE_KEY message. Returns olm_error() on failure. If the base64 + * couldn't be decoded then olm_session_last_error will be "INVALID_BASE64". + * If the message was for an unsupported protocol version then + * olm_session_last_error() will be "BAD_MESSAGE_VERSION". If the message + * couldn't be decoded then olm_session_last_error() will be + * "BAD_MESSAGE_FORMAT". If the message refers to an unknown one time + * key then olm_session_last_error() will be "BAD_MESSAGE_KEY_ID". */ +size_t olm_create_inbound_session (OlmSession* session, OlmAccount* account, void* one_time_key_message, size_t message_length); + +/** Same as olm_create_inbound_session, but ensures that the identity key + * in the pre-key message matches the expected identity key, supplied via the + * `their_identity_key` parameter. Fails early if there is no match. */ +size_t olm_create_inbound_session_from (OlmSession* session, OlmAccount* account, const(void)* their_identity_key, size_t their_identity_key_length, void* one_time_key_message, size_t message_length); + +/** The length of the buffer needed to return the id for this session. */ +size_t olm_session_id_length (const(OlmSession)* session); + +/** An identifier for this session. Will be the same for both ends of the + * conversation. If the id buffer is too small then olm_session_last_error() + * will be "OUTPUT_BUFFER_TOO_SMALL". */ +size_t olm_session_id (OlmSession* session, void* id, size_t id_length); + +int olm_session_has_received_message (const(OlmSession)* session); + +/** + * Write a null-terminated string describing the internal state of an olm + * session to the buffer provided for debugging and logging purposes. If the + * buffer is not large enough to hold the entire string, it will be truncated + * and will end with "...". A buffer length of 600 will be enough to hold any + * output. + */ +void olm_session_describe (OlmSession* session, char* buf, size_t buflen); + +/** Checks if the PRE_KEY message is for this in-bound session. This can happen + * if multiple messages are sent to this account before this account sends a + * message in reply. The one_time_key_message buffer is destroyed. Returns 1 if + * the session matches. Returns 0 if the session does not match. Returns + * olm_error() on failure. If the base64 couldn't be decoded then + * olm_session_last_error will be "INVALID_BASE64". If the message was for an + * unsupported protocol version then olm_session_last_error() will be + * "BAD_MESSAGE_VERSION". If the message couldn't be decoded then then + * olm_session_last_error() will be "BAD_MESSAGE_FORMAT". */ +size_t olm_matches_inbound_session (OlmSession* session, void* one_time_key_message, size_t message_length); + +/** Checks if the PRE_KEY message is for this in-bound session. This can happen + * if multiple messages are sent to this account before this account sends a + * message in reply. The one_time_key_message buffer is destroyed. Returns 1 if + * the session matches. Returns 0 if the session does not match. Returns + * olm_error() on failure. If the base64 couldn't be decoded then + * olm_session_last_error will be "INVALID_BASE64". If the message was for an + * unsupported protocol version then olm_session_last_error() will be + * "BAD_MESSAGE_VERSION". If the message couldn't be decoded then then + * olm_session_last_error() will be "BAD_MESSAGE_FORMAT". */ +size_t olm_matches_inbound_session_from (OlmSession* session, const(void)* their_identity_key, size_t their_identity_key_length, void* one_time_key_message, size_t message_length); + +/** Removes the one time keys that the session used from the account. Returns + * olm_error() on failure. If the account doesn't have any matching one time + * keys then olm_account_last_error() will be "BAD_MESSAGE_KEY_ID". */ +size_t olm_remove_one_time_keys (OlmAccount* account, OlmSession* session); + +/** The type of the next message that olm_encrypt() will return. Returns + * OLM_MESSAGE_TYPE_PRE_KEY if the message will be a PRE_KEY message. + * Returns OLM_MESSAGE_TYPE_MESSAGE if the message will be a normal message. + * Returns olm_error on failure. */ +size_t olm_encrypt_message_type (const(OlmSession)* session); + +/** The number of random bytes needed to encrypt the next message. */ +size_t olm_encrypt_random_length (const(OlmSession)* session); + +/** The size of the next message in bytes for the given number of plain-text + * bytes. */ +size_t olm_encrypt_message_length (const(OlmSession)* session, size_t plaintext_length); + +/** Encrypts a message using the session. Returns the length of the message in + * bytes on success. Writes the message as base64 into the message buffer. + * Returns olm_error() on failure. If the message buffer is too small then + * olm_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". If there + * weren't enough random bytes then olm_session_last_error() will be + * "NOT_ENOUGH_RANDOM". */ +size_t olm_encrypt (OlmSession* session, const(void)* plaintext, size_t plaintext_length, void* random, size_t random_length, void* message, size_t message_length); + +/** The maximum number of bytes of plain-text a given message could decode to. + * The actual size could be different due to padding. The input message buffer + * is destroyed. Returns olm_error() on failure. If the message base64 + * couldn't be decoded then olm_session_last_error() will be + * "INVALID_BASE64". If the message is for an unsupported version of the + * protocol then olm_session_last_error() will be "BAD_MESSAGE_VERSION". + * If the message couldn't be decoded then olm_session_last_error() will be + * "BAD_MESSAGE_FORMAT". */ +size_t olm_decrypt_max_plaintext_length (OlmSession* session, size_t message_type, void* message, size_t message_length); + +/** Decrypts a message using the session. The input message buffer is destroyed. + * Returns the length of the plain-text on success. Returns olm_error() on + * failure. If the plain-text buffer is smaller than + * olm_decrypt_max_plaintext_length() then olm_session_last_error() + * will be "OUTPUT_BUFFER_TOO_SMALL". If the base64 couldn't be decoded then + * olm_session_last_error() will be "INVALID_BASE64". If the message is for + * an unsupported version of the protocol then olm_session_last_error() will + * be "BAD_MESSAGE_VERSION". If the message couldn't be decoded then + * olm_session_last_error() will be BAD_MESSAGE_FORMAT". + * If the MAC on the message was invalid then olm_session_last_error() will + * be "BAD_MESSAGE_MAC". */ +size_t olm_decrypt (OlmSession* session, size_t message_type, void* message, size_t message_length, void* plaintext, size_t max_plaintext_length); + +/** The length of the buffer needed to hold the SHA-256 hash. */ +size_t olm_sha256_length (const(OlmUtility)* utility); + +/** Calculates the SHA-256 hash of the input and encodes it as base64. If the + * output buffer is smaller than olm_sha256_length() then + * olm_utility_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". */ +size_t olm_sha256 (OlmUtility* utility, const(void)* input, size_t input_length, void* output, size_t output_length); + +/** Verify an ed25519 signature. If the key was too small then + * olm_utility_last_error() will be "INVALID_BASE64". If the signature was invalid + * then olm_utility_last_error() will be "BAD_MESSAGE_MAC". */ +size_t olm_ed25519_verify (OlmUtility* utility, const(void)* key, size_t key_length, const(void)* message, size_t message_length, void* signature, size_t signature_length); + +/* OLM_H_ */ diff --git a/source/bindings/olm/outbound.d b/source/bindings/olm/outbound.d new file mode 100644 index 0000000..ac61577 --- /dev/null +++ b/source/bindings/olm/outbound.d @@ -0,0 +1,136 @@ +module libolm.outbound; + +/* Copyright 2016 OpenMarket Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import libolm.error; +extern (C): + +struct OlmOutboundGroupSession; + +/** get the size of an outbound group session, in bytes. */ +size_t olm_outbound_group_session_size (); + +/** + * Initialise an outbound group session object using the supplied memory + * The supplied memory should be at least olm_outbound_group_session_size() + * bytes. + */ +OlmOutboundGroupSession* olm_outbound_group_session (void* memory); + +/** + * A null terminated string describing the most recent error to happen to a + * group session */ +const(char)* olm_outbound_group_session_last_error (const(OlmOutboundGroupSession)* session); + +/** + * An error code describing the most recent error to happen to a group + * session */ +OlmErrorCode olm_outbound_group_session_last_error_code (const(OlmOutboundGroupSession)* session); + +/** Clears the memory used to back this group session */ +size_t olm_clear_outbound_group_session (OlmOutboundGroupSession* session); + +/** Returns the number of bytes needed to store an outbound group session */ +size_t olm_pickle_outbound_group_session_length (const(OlmOutboundGroupSession)* session); + +/** + * Stores a group session as a base64 string. Encrypts the session using the + * supplied key. Returns the length of the session on success. + * + * Returns olm_error() on failure. If the pickle output buffer + * is smaller than olm_pickle_outbound_group_session_length() then + * olm_outbound_group_session_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" + */ +size_t olm_pickle_outbound_group_session (OlmOutboundGroupSession* session, const(void)* key, size_t key_length, void* pickled, size_t pickled_length); + +/** + * Loads a group session from a pickled base64 string. Decrypts the session + * using the supplied key. + * + * Returns olm_error() on failure. If the key doesn't match the one used to + * encrypt the account then olm_outbound_group_session_last_error() will be + * "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then + * olm_outbound_group_session_last_error() will be "INVALID_BASE64". The input + * pickled buffer is destroyed + */ +size_t olm_unpickle_outbound_group_session (OlmOutboundGroupSession* session, const(void)* key, size_t key_length, void* pickled, size_t pickled_length); + +/** The number of random bytes needed to create an outbound group session */ +size_t olm_init_outbound_group_session_random_length (const(OlmOutboundGroupSession)* session); + +/** + * Start a new outbound group session. Returns olm_error() on failure. On + * failure last_error will be set with an error code. The last_error will be + * NOT_ENOUGH_RANDOM if the number of random bytes was too small. + */ +size_t olm_init_outbound_group_session (OlmOutboundGroupSession* session, ubyte* random, size_t random_length); + +/** + * The number of bytes that will be created by encrypting a message + */ +size_t olm_group_encrypt_message_length (OlmOutboundGroupSession* session, size_t plaintext_length); + +/** + * Encrypt some plain-text. Returns the length of the encrypted message or + * olm_error() on failure. On failure last_error will be set with an + * error code. The last_error will be OUTPUT_BUFFER_TOO_SMALL if the output + * buffer is too small. + */ +size_t olm_group_encrypt (OlmOutboundGroupSession* session, const(ubyte)* plaintext, size_t plaintext_length, ubyte* message, size_t message_length); + +/** + * Get the number of bytes returned by olm_outbound_group_session_id() + */ +size_t olm_outbound_group_session_id_length (const(OlmOutboundGroupSession)* session); + +/** + * Get a base64-encoded identifier for this session. + * + * Returns the length of the session id on success or olm_error() on + * failure. On failure last_error will be set with an error code. The + * last_error will be OUTPUT_BUFFER_TOO_SMALL if the id buffer was too + * small. + */ +size_t olm_outbound_group_session_id (OlmOutboundGroupSession* session, ubyte* id, size_t id_length); + +/** + * Get the current message index for this session. + * + * Each message is sent with an increasing index; this returns the index for + * the next message. + */ +uint olm_outbound_group_session_message_index (OlmOutboundGroupSession* session); + +/** + * Get the number of bytes returned by olm_outbound_group_session_key() + */ +size_t olm_outbound_group_session_key_length (const(OlmOutboundGroupSession)* session); + +/** + * Get the base64-encoded current ratchet key for this session. + * + * Each message is sent with a different ratchet key. This function returns the + * ratchet key that will be used for the next message. + * + * Returns the length of the ratchet key on success or olm_error() on + * failure. On failure last_error will be set with an error code. The + * last_error will be OUTPUT_BUFFER_TOO_SMALL if the buffer was too small. + */ +size_t olm_outbound_group_session_key (OlmOutboundGroupSession* session, ubyte* key, size_t key_length); + +// extern "C" + +/* OLM_OUTBOUND_GROUP_SESSION_H_ */ diff --git a/source/bindings/olm/package.d b/source/bindings/olm/package.d new file mode 100644 index 0000000..375848b --- /dev/null +++ b/source/bindings/olm/package.d @@ -0,0 +1,37 @@ +module bindings.olm; + +// import api: Encrypted; +// void decrypt(Encrypted* evt) @nogc { +// import main: session; +// import libolm.inbound; +// import core.stdc.stdlib; +// import core.stdc.string: strcpy; +// // import std.stdio; + +// char[] buf = cast(char[])malloc(evt.ciphertext.length)[0..evt.ciphertext.length]; +// strcpy(cast(char*)buf, cast(char*)evt.ciphertext); + +// size_t mlen = olm_group_decrypt_max_plaintext_length ( +// session, +// cast(ubyte*)buf, +// buf.length +// ); + +// char[] decbuf = cast(char[])malloc(mlen)[0..mlen]; + +// size_t dcr = olm_group_decrypt ( +// session, +// cast(ubyte*)buf, +// buf.length, +// cast(ubyte*)decbuf, +// mlen, +// null +// ); + +// import core.stdc.stdio; +// printf("%d\n", dcr); + +// // // string msg = cast(string)decbuf[0..dcr]; +// // writeln(dcr); +// // writeln(msg); +// } \ No newline at end of file diff --git a/source/bindings/olm/pk.d b/source/bindings/olm/pk.d new file mode 100644 index 0000000..399afbd --- /dev/null +++ b/source/bindings/olm/pk.d @@ -0,0 +1,203 @@ +/* Copyright 2018, 2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import libolm.error; +extern (C): + +struct OlmPkEncryption; + +/* The size of an encryption object in bytes */ +size_t olm_pk_encryption_size (); + +/** Initialise an encryption object using the supplied memory + * The supplied memory must be at least olm_pk_encryption_size() bytes */ +OlmPkEncryption* olm_pk_encryption (void* memory); + +/** A null terminated string describing the most recent error to happen to an + * encryption object */ +const(char)* olm_pk_encryption_last_error (const(OlmPkEncryption)* encryption); + +/** An error code describing the most recent error to happen to an encryption + * object */ +OlmErrorCode olm_pk_encryption_last_error_code (const(OlmPkEncryption)* encryption); + +/** Clears the memory used to back this encryption object */ +size_t olm_clear_pk_encryption (OlmPkEncryption* encryption); + +/** Set the recipient's public key for encrypting to */ +size_t olm_pk_encryption_set_recipient_key (OlmPkEncryption* encryption, const(void)* public_key, size_t public_key_length); + +/** Get the length of the ciphertext that will correspond to a plaintext of the + * given length. */ +size_t olm_pk_ciphertext_length (const(OlmPkEncryption)* encryption, size_t plaintext_length); + +/** Get the length of the message authentication code. */ +size_t olm_pk_mac_length (const(OlmPkEncryption)* encryption); + +/** Get the length of a public or ephemeral key */ +size_t olm_pk_key_length (); + +/** The number of random bytes needed to encrypt a message. */ +size_t olm_pk_encrypt_random_length (const(OlmPkEncryption)* encryption); + +/** Encrypt a plaintext for the recipient set using + * olm_pk_encryption_set_recipient_key. Writes to the ciphertext, mac, and + * ephemeral_key buffers, whose values should be sent to the recipient. mac is + * a Message Authentication Code to ensure that the data is received and + * decrypted properly. ephemeral_key is the public part of the ephemeral key + * used (together with the recipient's key) to generate a symmetric encryption + * key. Returns olm_error() on failure. If the ciphertext, mac, or + * ephemeral_key buffers were too small then olm_pk_encryption_last_error() + * will be "OUTPUT_BUFFER_TOO_SMALL". If there weren't enough random bytes then + * olm_pk_encryption_last_error() will be "OLM_INPUT_BUFFER_TOO_SMALL". */ +size_t olm_pk_encrypt (OlmPkEncryption* encryption, const(void)* plaintext, size_t plaintext_length, void* ciphertext, size_t ciphertext_length, void* mac, size_t mac_length, void* ephemeral_key, size_t ephemeral_key_size, const(void)* random, size_t random_length); + +struct OlmPkDecryption; + +/* The size of a decryption object in bytes */ +size_t olm_pk_decryption_size (); + +/** Initialise a decryption object using the supplied memory + * The supplied memory must be at least olm_pk_decryption_size() bytes */ +OlmPkDecryption* olm_pk_decryption (void* memory); + +/** A null terminated string describing the most recent error to happen to a + * decription object */ +const(char)* olm_pk_decryption_last_error (const(OlmPkDecryption)* decryption); + +/** An error code describing the most recent error to happen to a decription + * object */ +OlmErrorCode olm_pk_decryption_last_error_code (const(OlmPkDecryption)* decryption); + +/** Clears the memory used to back this decryption object */ +size_t olm_clear_pk_decryption (OlmPkDecryption* decryption); + +/** Get the number of bytes required to store an olm private key + */ +size_t olm_pk_private_key_length (); + +/** DEPRECATED: Use olm_pk_private_key_length() + */ +size_t olm_pk_generate_key_random_length (); + +/** Initialise the key from the private part of a key as returned by + * olm_pk_get_private_key(). The associated public key will be written to the + * pubkey buffer. Returns olm_error() on failure. If the pubkey buffer is too + * small then olm_pk_decryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". + * If the private key was not long enough then olm_pk_decryption_last_error() + * will be "OLM_INPUT_BUFFER_TOO_SMALL". + * + * Note that the pubkey is a base64 encoded string, but the private key is + * an unencoded byte array + */ +size_t olm_pk_key_from_private (OlmPkDecryption* decryption, void* pubkey, size_t pubkey_length, const(void)* privkey, size_t privkey_length); + +/** DEPRECATED: Use olm_pk_key_from_private + */ +size_t olm_pk_generate_key (OlmPkDecryption* decryption, void* pubkey, size_t pubkey_length, const(void)* privkey, size_t privkey_length); + +/** Returns the number of bytes needed to store a decryption object. */ +size_t olm_pickle_pk_decryption_length (const(OlmPkDecryption)* decryption); + +/** Stores decryption object as a base64 string. Encrypts the object using the + * supplied key. Returns the length of the pickled object on success. + * Returns olm_error() on failure. If the pickle output buffer + * is smaller than olm_pickle_pk_decryption_length() then + * olm_pk_decryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL" */ +size_t olm_pickle_pk_decryption (OlmPkDecryption* decryption, const(void)* key, size_t key_length, void* pickled, size_t pickled_length); + +/** Loads a decryption object from a pickled base64 string. The associated + * public key will be written to the pubkey buffer. Decrypts the object using + * the supplied key. Returns olm_error() on failure. If the key doesn't + * match the one used to encrypt the account then olm_pk_decryption_last_error() + * will be "BAD_ACCOUNT_KEY". If the base64 couldn't be decoded then + * olm_pk_decryption_last_error() will be "INVALID_BASE64". The input pickled + * buffer is destroyed */ +size_t olm_unpickle_pk_decryption (OlmPkDecryption* decryption, const(void)* key, size_t key_length, void* pickled, size_t pickled_length, void* pubkey, size_t pubkey_length); + +/** Get the length of the plaintext that will correspond to a ciphertext of the + * given length. */ +size_t olm_pk_max_plaintext_length (const(OlmPkDecryption)* decryption, size_t ciphertext_length); + +/** Decrypt a ciphertext. The input ciphertext buffer is destroyed. See the + * olm_pk_encrypt function for descriptions of the ephemeral_key and mac + * arguments. Returns the length of the plaintext on success. Returns + * olm_error() on failure. If the plaintext buffer is too small then + * olm_pk_encryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". */ +size_t olm_pk_decrypt (OlmPkDecryption* decryption, const(void)* ephemeral_key, size_t ephemeral_key_length, const(void)* mac, size_t mac_length, void* ciphertext, size_t ciphertext_length, void* plaintext, size_t max_plaintext_length); + +/** + * Get the private key for an OlmDecryption object as an unencoded byte array + * private_key must be a pointer to a buffer of at least + * olm_pk_private_key_length() bytes and this length must be passed in + * private_key_length. If the given buffer is too small, returns olm_error() + * and olm_pk_encryption_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". + * Returns the number of bytes written. + */ +size_t olm_pk_get_private_key (OlmPkDecryption* decryption, void* private_key, size_t private_key_length); + +struct OlmPkSigning; + +/* The size of a signing object in bytes */ +size_t olm_pk_signing_size (); + +/** Initialise a signing object using the supplied memory + * The supplied memory must be at least olm_pk_signing_size() bytes */ +OlmPkSigning* olm_pk_signing (void* memory); + +/** A null terminated string describing the most recent error to happen to a + * signing object */ +const(char)* olm_pk_signing_last_error (const(OlmPkSigning)* sign); + +/** A null terminated string describing the most recent error to happen to a + * signing object */ +OlmErrorCode olm_pk_signing_last_error_code (const(OlmPkSigning)* sign); + +/** Clears the memory used to back this signing object */ +size_t olm_clear_pk_signing (OlmPkSigning* sign); + +/** + * Initialise the signing object with a public/private keypair from a seed. The + * associated public key will be written to the pubkey buffer. Returns + * olm_error() on failure. If the public key buffer is too small then + * olm_pk_signing_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". If the seed + * buffer is too small then olm_pk_signing_last_error() will be + * "INPUT_BUFFER_TOO_SMALL". + */ +size_t olm_pk_signing_key_from_seed (OlmPkSigning* sign, void* pubkey, size_t pubkey_length, const(void)* seed, size_t seed_length); + +/** + * The size required for the seed for initialising a signing object. + */ +size_t olm_pk_signing_seed_length (); + +/** + * The size of the public key of a signing object. + */ +size_t olm_pk_signing_public_key_length (); + +/** + * The size of a signature created by a signing object. + */ +size_t olm_pk_signature_length (); + +/** + * Sign a message. The signature will be written to the signature + * buffer. Returns olm_error() on failure. If the signature buffer is too + * small, olm_pk_signing_last_error() will be "OUTPUT_BUFFER_TOO_SMALL". + */ +size_t olm_pk_sign (OlmPkSigning* sign, const(ubyte)* message, size_t message_length, ubyte* signature, size_t signature_length); + +/* OLM_PK_H_ */ diff --git a/source/bindings/olm/sas.d b/source/bindings/olm/sas.d new file mode 100644 index 0000000..39cae78 --- /dev/null +++ b/source/bindings/olm/sas.d @@ -0,0 +1,142 @@ +/* Copyright 2018-2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import libolm.error; +extern (C): + +/** @defgroup SAS Short Authentication String verification + * These functions are used for verifying keys using the Short Authentication + * String (SAS) method. + * @{ + */ + +struct OlmSAS; + +/** A null terminated string describing the most recent error to happen to an + * SAS object. */ +const(char)* olm_sas_last_error (const(OlmSAS)* sas); + +/** An error code describing the most recent error to happen to an SAS + * object. */ +OlmErrorCode olm_sas_last_error_code (const(OlmSAS)* sas); + +/** The size of an SAS object in bytes. */ +size_t olm_sas_size (); + +/** Initialize an SAS object using the supplied memory. + * The supplied memory must be at least `olm_sas_size()` bytes. */ +OlmSAS* olm_sas (void* memory); + +/** Clears the memory used to back an SAS object. */ +size_t olm_clear_sas (OlmSAS* sas); + +/** The number of random bytes needed to create an SAS object. */ +size_t olm_create_sas_random_length (const(OlmSAS)* sas); + +/** Creates a new SAS object. + * + * @param[in] sas the SAS object to create, initialized by `olm_sas()`. + * @param[in] random array of random bytes. The contents of the buffer may be + * overwritten. + * @param[in] random_length the number of random bytes provided. Must be at + * least `olm_create_sas_random_length()`. + * + * @return `olm_error()` on failure. If there weren't enough random bytes then + * `olm_sas_last_error()` will be `NOT_ENOUGH_RANDOM`. + */ +size_t olm_create_sas (OlmSAS* sas, void* random, size_t random_length); + +/** The size of a public key in bytes. */ +size_t olm_sas_pubkey_length (const(OlmSAS)* sas); + +/** Get the public key for the SAS object. + * + * @param[in] sas the SAS object. + * @param[out] pubkey buffer to store the public key. + * @param[in] pubkey_length the size of the `pubkey` buffer. Must be at least + * `olm_sas_pubkey_length()`. + * + * @return `olm_error()` on failure. If the `pubkey` buffer is too small, then + * `olm_sas_last_error()` will be `OUTPUT_BUFFER_TOO_SMALL`. + */ +size_t olm_sas_get_pubkey (OlmSAS* sas, void* pubkey, size_t pubkey_length); + +/** Sets the public key of other user. + * + * @param[in] sas the SAS object. + * @param[in] their_key the other user's public key. The contents of the + * buffer will be overwritten. + * @param[in] their_key_length the size of the `their_key` buffer. + * + * @return `olm_error()` on failure. If the `their_key` buffer is too small, + * then `olm_sas_last_error()` will be `INPUT_BUFFER_TOO_SMALL`. + */ +size_t olm_sas_set_their_key (OlmSAS* sas, void* their_key, size_t their_key_length); + +/** Checks if their key was set. + * + * @param[in] sas the SAS object. + * + */ +int olm_sas_is_their_key_set (const(OlmSAS)* sas); + +/** Generate bytes to use for the short authentication string. + * + * @param[in] sas the SAS object. + * @param[in] info extra information to mix in when generating the bytes, as + * per the Matrix spec. + * @param[in] info_length the length of the `info` parameter. + * @param[out] output the output buffer. + * @param[in] output_length the size of the output buffer. For hex-based SAS + * as in the Matrix spec, this will be 5. + * + * @return `olm_error()` on failure. If their key wasn't set then + * `olm_sas_last_error()` will be `SAS_THEIR_KEY_NOT_SET`. + */ +size_t olm_sas_generate_bytes (OlmSAS* sas, const(void)* info, size_t info_length, void* output, size_t output_length); + +/** The size of the message authentication code generated by + * olm_sas_calculate_mac()`. */ +size_t olm_sas_mac_length (const(OlmSAS)* sas); + +/** Generate a message authentication code (MAC) based on the shared secret. + * + * @param[in] sas the SAS object. + * @param[in] input the message to produce the authentication code for. + * @param[in] input_length the length of the message. + * @param[in] info extra information to mix in when generating the MAC, as per + * the Matrix spec. + * @param[in] info_length the length of the `info` parameter. + * @param[out] mac the buffer in which to store the MAC. + * @param[in] mac_length the size of the `mac` buffer. Must be at least + * `olm_sas_mac_length()` + * + * @return `olm_error()` on failure. If the `mac` buffer is too small, then + * `olm_sas_last_error()` will be `OUTPUT_BUFFER_TOO_SMALL`. + */ +size_t olm_sas_calculate_mac (OlmSAS* sas, const(void)* input, size_t input_length, const(void)* info, size_t info_length, void* mac, size_t mac_length); + +// A version of the calculate mac function that produces base64 strings that are +// compatible with other base64 implementations. +size_t olm_sas_calculate_mac_fixed_base64 (OlmSAS* sas, const(void)* input, size_t input_length, const(void)* info, size_t info_length, void* mac, size_t mac_length); + +// for compatibility with an old version of Riot +size_t olm_sas_calculate_mac_long_kdf (OlmSAS* sas, const(void)* input, size_t input_length, const(void)* info, size_t info_length, void* mac, size_t mac_length); + +/** @} */ // end of SAS group + +// extern "C" + +/* OLM_SAS_H_ */ diff --git a/source/commands.d b/source/commands.d deleted file mode 100644 index 2527a52..0000000 --- a/source/commands.d +++ /dev/null @@ -1,40 +0,0 @@ -module commands; -import util; - -// UDA -struct Command { - string description = "No description provided"; - string name; -} - -@Command("Отображает аватар пользователя") -auto avatar(Arguments argz, EventWithoutRoomID* evt) { - import std.net.curl: get; - string url = cast(string)get(homeserver~"/_matrix/client/v3/profile/" ~ - ((argz.parsed.length == 0) ? evt.sender : argz.parsed[0]) ~ "/avatar_url"); - if (url == "{}") return MSG("User has no avatar"); - return MSG(evt.sender, ``); -} - -@Command("", "пинг") -auto ping(Arguments, EventWithoutRoomID* evt) { - import std.datetime: Clock, SysTime, unixTimeToStdTime; - auto delay = (Clock.currTime() - SysTime(unixTimeToStdTime(0))).total!"msecs" - evt.origin_server_ts; - return MSG("PONG [" ~ intToStr(delay) ~ " ms]"); -} - -@Command("хз мне лень делать описание") -auto echo(Arguments argz, EventWithoutRoomID* evt) { - return MSG((argz.raw.length > 6) ? argz.raw[6..$] : "Too small MSG"); -} - -@Command() -string[2] huy = [":orehussmile:", - `:orehussmile:`]; - -@Command("Версия бота", "версия") -string ver = "SkunkyBot Pre-Alpha 0.1 :: https://git.macaw.me/skunky/skunkybot-d"; - -@Command("test") -static string compver = "Compiler version: "~intToStr(__VERSION__); \ No newline at end of file diff --git a/source/commands/apod.d b/source/commands/apod.d new file mode 100644 index 0000000..c45d235 --- /dev/null +++ b/source/commands/apod.d @@ -0,0 +1,105 @@ +module commands.apod; + +import util, api, api_data; +import commands.util; +import main: db; + +struct APOD { + string url; + string hdurl; + string title; + string explanation; +} + +struct APOD_internal { + string subscribed_room; + string mxc, title, body, mimetype; + int untill, size, width, height; +} + +auto apod_get() { + import asdf, api: upload; + import gamut: Image; + + MSG msg; + Image img; + auto data = mkrqst("https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY", null, null, true) + .body.deserialize!APOD; + auto image = mkrqst(data.hdurl, null, null, true); + + img.loadFromMemory(image.body); + msg.info.w = img.width; + msg.info.h = img.height; + msg.info.size = image.body.length; + msg.info.mimetype = image.getHeader("Content-Type"); + + msg.url = upload(image.body); + msg.msgtype = "m.image"; + msg.filename = data.hdurl; + msg.body = data.title; + msg.formatted_body = "

"~data.title~"

"~data.explanation~"

"; + return msg; +} + +// 🇮🇳🇮🇳🇮🇳 यह बकवास का एक बुरा टुकड़ा है, लेकिन मैं इसे ठीक करने के लिए बहुत आलसी हूं । +MSG cached_apod() { + import core.stdc.time: time; + + auto now = time(null); + auto q = db.query("select * from apod where subscribed_room = 'CACHE'"); + + if (q.step) { + APOD_internal data = q.get!APOD_internal; + if (data.untill > now) { + MSG msg = MSG(data.title, data.body); + msg.url = data.mxc; + msg.info.w = data.width; + msg.info.h = data.height; + msg.info.size = data.size; + msg.info.mimetype = data.mimetype; + msg.filename = data.title ~ ".jpg"; + msg.msgtype = "m.image"; + return msg; + } + } + + MSG msg = apod_get; + db.exec("insert into apod + (subscribed_room, width, height, size, mxc, mimetype, title, body, untill) + values ('CACHE',?,?,?,?,?,?,?,?) + on conflict (mxc) do update set + mxc = excluded.mxc, + body = excluded.body, + size = excluded.size, + title = excluded.title, + width = excluded.width, + height = excluded.height, + mimetype = excluded.mimetype", + msg.info.w, msg.info.h, msg.info.size, msg.url, msg.info.mimetype, + msg.body, msg.formatted_body, now + Time.day); + + return msg; +} + +@Command("Astronomy Picture Of the Day") +auto apod(Arguments arg, EventWithoutRoomID* evt) { + if (arg.parsed.length == 0) return cached_apod; + + auto powerlevel = getUsrPL(evt.room, evt.sender); + bool subscribed = db.query("select * from apod where subscribed_room = ?", evt.room).step; + + if (powerlevel < 50) return MSG("Unauthorized"); + if (arg.parsed[0] == "subscribe") { + if (subscribed) + return MSG("Room is already subscribed to APOD."); + db.exec("insert into apod (subscribed_room) values (?)", evt.room); + return MSG("Room has been subcribed to APOD!"); + } else if (arg.parsed[0] == "unsubscribe") { + if (subscribed) { + db.exec("delete from apod where subscribed_room = ?", evt.room); + return MSG("Room has been unsubscribed from APOD."); + } else return MSG("Room is not subscribed to APOD."); + } + + return MSG("Unknown argument"); +} \ No newline at end of file diff --git a/source/commands/misc.d b/source/commands/misc.d new file mode 100644 index 0000000..c695dcd --- /dev/null +++ b/source/commands/misc.d @@ -0,0 +1,51 @@ +module commands.misc; + +import util, api_data; +import commands.util; + +@Command("хз", "хуй") +string[2] huy = [":orehussmile:", + `:orehussmile:`]; + +@Command("Версия бота", "версия") +string ver = "Neptune Alpha 1.0 :: https://git.macaw.me/skunky/neptune"; + +@Command("компвер") +static string compver = "Compiler version: "~intToStr(__VERSION__); + + +@Command("Измеряет пинг") +auto ping(Arguments, EventWithoutRoomID* evt) { + static enum Time: int { + millisecond = 1, + second = 1000, + minute = 60 * second, + hour = 60 * minute, + day = 24 * hour, + week = 7 * day, + month = 4 * week, + year = 12 * month + } + + import std.datetime: Clock, SysTime, unixTimeToStdTime; + auto delay = (Clock.currTime() - SysTime(unixTimeToStdTime(0))).total!"msecs" - evt.origin_server_ts; + + static foreach_reverse(unit; __traits(allMembers,Time)) + if (delay >= __traits(getMember, Time, unit)) // реализовать функцию floatToStr + return MSG("PONG [" ~ intToStr(delay / __traits(getMember, Time, unit)) ~ ' ' ~ unit ~ "s]"); + return MSG("шота пошло не так"); +} + +@Command("хз мне лень делать описание") +auto echo(Arguments argz, EventWithoutRoomID* evt) { + return MSG((argz.raw.length > 6) ? argz.raw[6..$] : "Too small MSG"); +} + +// @Command("Отображает аватар пользователя") +// auto avatar(Arguments argz, EventWithoutRoomID* evt) { +// string url = cast (string) mkrqst(homeserver~"/_matrix/client/v3/profile/" ~ +// ((argz.parsed.length == 0) ? evt.sender : argz.parsed[0]) ~ "/avatar_url").body; +// if (url == "{}") return MSG("User has no avatar"); +// return MSG(evt.sender, ``); +// } \ No newline at end of file diff --git a/source/commands/moderation.d b/source/commands/moderation.d new file mode 100644 index 0000000..72be6a4 --- /dev/null +++ b/source/commands/moderation.d @@ -0,0 +1,128 @@ +module commands.moderation; + +import util, api_data, api; +import asdf; +import core.stdc.time: time; +import commands.util; + +import main: db; + +enum TimeErr: int { + @("Not enough arguments") NotEnoughArguments = -1, + @("Invalid date") InvalidDate = -2, + @("Invalid unit") InvalidUnit = -3 +} + +int parseTime(string str) @nogc pure { + if (str.length < 2) return TimeErr.NotEnoughArguments; + foreach (short c; str[0..$-1]) + if (!(c >= 48 && c <= 57)) + return TimeErr.InvalidDate; + + static foreach(unit; __traits(allMembers, Time)) + if (str[$-1] == __traits(getAttributes, __traits(getMember, Time, unit))[0]) + return strToInt(str[0..$-1]) * __traits(getMember, Time, unit); + + return TimeErr.InvalidUnit; +} + +@Command("Admin tools") +MSG nctl(Arguments arg, EventWithoutRoomID* evt) { + if (arg.parsed.length != 2) return MSG("❌️ Not enough arguments"); + if (getUsrPL(evt.room, evt.sender) < 50) return MSG("❌️ Unauthorized"); + db.exec("create table if not exists nctl (room string, user string, nc string, type string, unt integer)"); + + bool wd, err; + string cntnt, type; + + int dur; + auto durStr = arg.getArg("D"); + if (durStr) dur = parseTime(durStr); + + if (dur < 0) { + static foreach(Terr; __traits(allMembers, TimeErr)) { + if (dur == __traits(getMember, TimeErr, Terr)) { + return MSG("💥 " ~ __traits(getAttributes, __traits(getMember, TimeErr, Terr))[0]); + } + } + } + + void mrq(string ep) { + short rq = mkhsrq( + "/_matrix/client/v3/rooms/"~evt.room~'/'~ep, + "POST", + Moderate(arg.parsed[1], "Moderated by "~evt.sender).serializeToJson + ).status; + if (rq != 200) err = true; + } + + void setpl(short pl) { + auto pls = State.PowerLevels(getUsrsPLs(evt.room)); + if (dur) cntnt = pls.serializeToJson; + pls.users[arg.parsed[1]] = pl; + state(evt.room, "m.room.power_levels", pls); + } + + bool c() { + if (db.query("select type from nctl where room = ? and user = ?",evt.room, arg.parsed[1]).step) + return true; + return false; + } + + switch (arg.parsed[0]) { + case "ban": + wd = true; + mrq("ban"); + break; + case "kick", "unban": + mrq(arg.parsed[0]); + break; + case "mute": + if(c) goto e; + type = "m.room.power_levels"; + wd = true; + setpl(-100); + break; + case "unmute": setpl(0); break; + case "acl", "delete-acl": + State.ACL acls = getState!(State.ACL)(evt.room, "m.room.server_acl"); + if (dur) cntnt = acls.serializeToJson; + + if (arg.parsed[0] == "acl") { + if(c) goto e; + type = "m.room.server_acl"; + wd = true; + acls.deny ~= arg.parsed[1]; + } else { + foreach (n, srv; acls.deny) { + if (srv == arg.parsed[1]) + acls.deny = acls.deny[0..n] ~ acls.deny[n+1..$]; + } + } + + state(evt.room, "m.room.server_acl", acls); + break; + default: return MSG("❓️ Invalid argument"); + } + + if (err) return MSG("💥 Something went wrong"); + + if (dur && wd) { + import std.datetime.systime: SysTime; + auto untill = time(null) + dur; + + db.exec( + "insert into nctl (room, user, nc, type, unt) values (?,?,?,?,?)", + evt.room, + arg.parsed[1], + cntnt, + type, + untill + ); + + return MSG("✅️ Blocked untill " ~ SysTime.fromUnixTime(untill).toSimpleString); + } + + return MSG("✅️"); + e: return MSG("💥 Already moderated!"); +} \ No newline at end of file diff --git a/source/commands/mozhi.d b/source/commands/mozhi.d new file mode 100644 index 0000000..fe42298 --- /dev/null +++ b/source/commands/mozhi.d @@ -0,0 +1,54 @@ +module commands.mozhi; + +// import api; +// import util; +// import commands.util; +// import api_data; + +// import asdf; + +// @Command("Translates text via Mozhi") +// auto tr(Arguments argz, EventWithoutRoomID* evt) { +// struct RqRsp { +// string engine; +// string detected; +// @serdeKeys("translated-text") string translatedText; +// string source_language; +// string target_language; +// } + +// MSG msg; +// string text; +// auto ngn = argz.getArg("E"); +// auto instance = argz.getArg("I"); +// MSG origin = evt.content.raw.deserialize!MSG; + +// if (argz.parsed.length == 2) { +// auto reply = event(origin.relates.reply.event_id, evt.room).body; +// foreach (chr; reply) { +// if (chr == ' ') text ~= '+'; +// else text ~= chr; +// } +// } else for (short i = 2; i < argz.parsed.length; ++i) +// text ~= argz.parsed[i] ~ '+'; + +// auto rq = mkrqst ( +// "https://" ~ (instance ? instance : "mozhi.gitro.xyz") ~ "/api/translate", "POST", +// "engine=" ~ (ngn ? ngn : "google") +// ~ "&from=" ~ argz.parsed[0] +// ~ "&to=" ~ argz.parsed[1] +// ~ "&text=" ~ text, +// false +// ); + +// if (rq.status != 200) return MSG(intToStr(rq.status)); +// auto content = rq.body.deserialize!RqRsp; + +// msg = MSG("ЙАЗЫКНЙЭВЫ|БРАН", content.translatedText); +// return msg; +// } + +// @Command("Creates audio with text, using Mozhi") +// auto tts(Arguments argz, EventWithoutRoomID* evt) { + +// } \ No newline at end of file diff --git a/source/commands/slaves.d b/source/commands/slaves.d new file mode 100644 index 0000000..e269fd1 --- /dev/null +++ b/source/commands/slaves.d @@ -0,0 +1,81 @@ +module commands.slaves; + +enum Parallel; + +import util; +import api; +import api_data; +import main: db; + +void apod_slave() @Parallel { + import core.thread; + import commands.apod; + import core.stdc.time: time; + + db.exec("create table if not exists apod ( + subscribed_room string, + mxc string unique, + body string, + title string, + mimetype string, + size integer, + width integer, + height integer, + untill integer + )"); + + for (;;) { + int v; + auto q = db.query("select untill from apod where subscribed_room = 'CACHE'"); + if (q.step) v = q.get!int; + for (q = db.query("select subscribed_room from apod where subscribed_room != 'CACHE'"); q.step;) { + if (v == 0 || v < time(null)) { + send(cached_apod, q.get!string); + db.exec("delete from apod where subscribed_room = 'CACHE'"); + } + } + Thread.sleep(30.seconds); + } +} + +void nctl_slave() @Parallel { + import core.thread: Thread; + import core.time: Duration, dur; + import core.stdc.time: time; + + import asdf: serializeToJson; + + static Duration tms = dur!"msecs"(10); + + struct udr { + string room; + string user; + string type; + string nc; + int unt; + } + + for (;;) { + auto q = db.query("select * from nctl"); + while (q.step) { + try { + udr z = q.get!udr; + if (time(null) >= z.unt) { + if (z.type == null) { + mkhsrq( + "/_matrix/client/v3/rooms/"~z.room~"/unban", + "POST", + Moderate(z.user, "Its time to unban!").serializeToJson + ); + } + else rawState(z.room, z.type, z.nc); + db.exec("delete from nctl where user = ? and room = ?", z.user, z.room); + } + } catch (Exception e) { + import core.stdc.stdio; + printf("[nctl_slave] ERROR: %s\n", cast(char*)e.msg); + } + } + Thread.sleep(tms); + } +} \ No newline at end of file diff --git a/source/commands/util.d b/source/commands/util.d new file mode 100644 index 0000000..83a65cb --- /dev/null +++ b/source/commands/util.d @@ -0,0 +1,92 @@ +module commands.util; + +struct Command { + string description = "No description provided"; + string name; +} + +static enum Time: int { + @('s') second = 1, + @('m') minute = 60 * second, + @('h') hour = 60 * minute, + @('d') day = 24 * hour, + @('w') week = 7 * day, + @('M') month = 30 * day, + @('y') year = 12 * month +} + +struct Arguments { + string raw; + string command; + string[] parsed; + char[] options; + string getArg(string arg) @nogc { + int prev, splt; + for (int i; i < options.length; ++i) { + if (options[i] == '\0') splt = i; + else if (options[i] == '\1') { + if (arg == options[prev..splt]) + return cast(string)options[splt+1..i]; + prev = i + 1; + } + } + return null; + } +} + +auto parseMsg(string cmd) { + import std.stdio; + Arguments argz = Arguments(cmd); + if (argz.raw[0] == '#') { + string buf; + for (ulong i = 1; i < argz.raw.length; ++i) + if (argz.raw[i] != ' ' && argz.raw[i] != '=') { + buf ~= argz.raw[i]; + if (i+1 == argz.raw.length || (argz.raw[i+1] == ' ' || argz.raw[i+1] == '=')) { + argz.parsed ~= buf; + buf = null; + } + } + argz.command = argz.parsed[0]; argz.parsed = argz.parsed[1..$]; + + for (ulong i; i < argz.parsed.length; ++i) + if (argz.parsed[i][0] == '-') { + string key = argz.parsed[i]; + auto val = (i+1 < argz.parsed.length && argz.parsed[i+1][0] != '-') + ? argz.parsed[i+1] : null; + if (key[1] == '-') + argz.options ~= key[2..$] ~ '\0' ~ val ~ '\1'; + else for (ulong x = 1; x < key.length; ++x) + argz.options ~= key[x..x+1] ~ '\0' ~ val ~ '\1'; + + auto x = (val) ? i + 2 : i + 1; + argz.parsed = argz.parsed[0..i] ~ argz.parsed[x..$]; + i = i - (x - i); + } + } + return argz; +} + +int getUsrPL(string room, string user) { + import main: db; + auto q = db.query("select pl from room_pls where room = ? and user = ?", room, user); + if (q.step) return q.get!int; + return 0; +} + +short[string] getUsrsPLs(string room) { + struct hz { + string user; + short pl; + } + + import main: db; + short[string] buf; + auto q = db.query("select user, pl from room_pls where room = ?", room); + while (q.step) { + auto x = q.get!hz; + buf[x.user] = x.pl; + } + + return buf; +} \ No newline at end of file diff --git a/source/listener.d b/source/listener.d new file mode 100644 index 0000000..58e2bce --- /dev/null +++ b/source/listener.d @@ -0,0 +1,114 @@ +module listener; + +import api, api_data; +import commands.util; +import main: db; +import util; + +import std.stdio: writeln; +import core.thread; + +import asdf: deserialize; + +__gshared string syncUrl, initialBatch; + +void listen(Modules...)() { + static MSG helpgen() { + MSG msg; + static foreach (mod; Modules) { + static foreach (member; __traits(allMembers, mod)) { + static foreach (attr; __traits(getAttributes, __traits(getMember, mod, member))) { + static if (is(typeof(attr) == Command)) msg.body ~= member ~ ": " ~ attr.description ~ '\n'; + } + } + } + return msg; + } + + auto content = Sync(); + content.next_batch = initialBatch; + for (;;) { + string bthUrl = syncUrl ~ content.next_batch; + try { + content = mkhsrq(bthUrl).body.deserialize!Sync; + db.exec("update client set latest_batch = ?", content.next_batch); + } catch (Exception e) { writeln(e.msg); continue; } + + // https://github.com/trikko/serverino/blob/3e3e6273a5aaa32615ae9d007a1a83877bc23ab4/source/serverino/worker.d#L168 + new Thread(delegate { + foreach (room, _; content.rooms.invite) { + writeln("Joining to room: ", room); + mkhsrq("/_matrix/client/v3/rooms/"~room~"/join", "POST", "{}"); + send(MSG("Йа криведко"), room); + fetchMembers(room); + } + + foreach (room, roomContent; content.rooms.join) { + foreach(event; roomContent.timeline.events) { + if (event.type == "m.room.message") { + try { + auto evt = deserialize!MSG(event.content.raw); + if (!evt.body.length) break; + event.room = room; + auto argz = parseMsg(evt.body); + + if (argz.command == "hlp") { + auto h = helpgen; + h.relates.reply.event_id = event.event_id; + send(h, room); + break; + } + + static foreach (mod; Modules) { + static foreach (member; __traits(allMembers, mod)) { + // if (argz.command == member) { + foreach (attr; __traits(getAttributes, __traits(getMember, mod, member))) { + if (is(typeof(attr) == Command) + && (argz.command == member + || (argz.command == attr.name && attr.name != null))) + { + alias command = __traits(getMember, mod, member); + static if (is(typeof(command) == function)) + auto content = command(argz, &event); + else static if (__traits(isStaticArray, command)) + auto content = MSG(command[0], command[1]); + else auto content = MSG(command); + content.relates.reply.event_id = event.event_id; + send(content, room); + } + } + // } + } + } + } catch (Exception e) { + writeln(e.msg); + send(MSG(e.msg), room); + } + } + else if (event.type == "m.room.power_levels") { + auto pls = deserialize!(State.PowerLevels)(event.content.raw); + foreach (user, pl; pls.users) { + auto q = db.query("select pl from room_pls where room = ? and user = ?", room, user); + if (q.step) { + if (q.get!int != pl) + db.exec("update room_pls set pl = ? where room = ? and user = ?", pl, room, user); + } else db.exec("insert into room_pls (room, user, pl) values (?, ?, ?)", room, user, pl); + } + } + // else if (event.type == "m.room.encrypted") { + // import encryption; + // auto e = deserialize!Encrypted(event.content.raw); + // decrypt(&e); + // } + } + } + }).start; + } +} + +void fetchMembers(string room) { + auto state = getState!(State.PowerLevels)(room, "m.room.power_levels"); + foreach (user, pl; state.users) { + db.exec("insert into room_pls (room, user, pl) values (?, ?, ?)", room, user, pl); + } +} \ No newline at end of file diff --git a/source/util.d b/source/util.d index 6c58c08..b8fe6af 100644 --- a/source/util.d +++ b/source/util.d @@ -1,14 +1,37 @@ module util; import asdf; -string homeserver; +__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)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 { @@ -20,102 +43,111 @@ struct JsonObject { return null; } - void serialize(S)(ref S serializer) { - try serializer.sink.putSmallEscaped(data.parseJson.to!string); - catch (Exception) serializer.sink.putSmallEscaped("{}"); - } + // void serialize(S)(ref S serializer) { + // try serializer.sink.putSmallEscaped(data.parseJson.to!string); + // catch (Exception) serializer.sink.putSmallEscaped("{}"); + // } } -struct EventWithoutRoomID { - JsonObject content; - string event_id; - ulong origin_server_ts; - @serdeOptional string sender, state_key, type; - // Unsigned unsigned; -} - -struct Sync { - struct StrippedStateEvent { - JsonObject content; - string sender, state_key, type; - } - - struct Unsigned { - int age; - string membership, transaction_id; - } - - struct Rooms { - struct Invited { - struct IS { StrippedStateEvent[] events; } - IS invite_state; - } - struct Joined { - struct Timeline { - EventWithoutRoomID[] events; - bool limited; - string prev_batch; +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; } - - struct UNC { - int highlight_count; - int notification_count; - } - - @serdeOptional Timeline timeline; - UNC unread_notifications; } + return null; + } +} - @serdeOptional Invited[string] invite; - @serdeOptional Joined[string] join; +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); } - @serdeOptional Rooms rooms; - string next_batch; + 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; } -// EVENTS -struct MSG { - string body; - @serdeOptional @serdeIgnoreDefault string formatted_body; - string msgtype = "m.notice"; - @serdeOptional string format = "org.matrix.custom.html"; -} - -struct Arguments { - string raw; - string command; - string[] parsed; - string[string] options; -} - -auto parseMsg(string cmd) { - Arguments argz = Arguments(cmd); - if (argz.raw[0] == '#') { - string buf; - for (ulong i = 1; i < argz.raw.length; ++i) - if (argz.raw[i] != ' ' && argz.raw[i] != '=') { - buf ~= argz.raw[i]; - if (i+1 == argz.raw.length || (argz.raw[i+1] == ' ' || argz.raw[i+1] == '=')) { - argz.parsed ~= buf; - buf = null; - } - } - argz.command = argz.parsed[0]; argz.parsed = argz.parsed[1..$]; - - for (ulong i; i < argz.parsed.length; ++i) - if (argz.parsed[i][0] == '-') { - string key = argz.parsed[i]; - auto val = (i+1 < argz.parsed.length && argz.parsed[i+1][0] != '-') - ? argz.parsed[i+1] : null; - if (key[1] == '-') argz.options[key[2..$]] = val; - else for (ulong x = 1; x < key.length; ++x) - argz.options[key[x..x+1]] = val; - - auto x = (val) ? i + 2 : i + 1; - argz.parsed = argz.parsed[0..i] ~ argz.parsed[x..$]; - i = i - (x - i); - } - } - return argz; +RqRsp mkhsrq(string uri, string method = "GET", string content = null) { + return mkrqst(cfg.homeserver ~ uri, method, content, true); } \ No newline at end of file