Files
lunch-games/source/lunch/http.d
2025-11-27 03:11:44 +01:00

117 lines
2.4 KiB
D

module lunch.http;
import std.stdio;
import std.file;
import std.traits;
import std.string;
import std.net.curl :
c_get = get,
c_post = post,
c_put = put,
HTTP,
CurlException,
AutoProtocol;
import core.thread;
import lunch.logger;
private ReturnType!fun _retry(alias fun)(Parameters!fun args)
{
CurlException last_ex;
for (int n = 0; n < 10; n++)
{
try
return fun(args);
catch (CurlException ex)
last_ex = ex;
Thread.sleep(dur!"msecs"(500));
}
throw last_ex;
}
private const(char)[] _sanitize(const(char)[] url)
{
return url.replace(" ", "%20");
}
T[] get(Conn = AutoProtocol, T = char)(const(char)[] url, Conn conn = Conn())
{
try
{
T[] res = _retry!(c_get!(Conn, T))(_sanitize(url), conn);
infof("GET %s", url);
return res;
}
catch (CurlException ex)
{
erroref("GET %s", ex, url);
assert(0);
}
}
T[] post(T = char, PostUnit)(const(char)[] url, const(PostUnit)[] postData, HTTP conn = HTTP())
{
try
{
T[] res = _retry!(c_post!(T, PostUnit))(_sanitize(url), postData, conn);
infof("POST %s", url);
return res;
}
catch (CurlException ex)
{
erroref("POST %s", ex, url);
assert(0);
}
}
T[] put(Conn = AutoProtocol, T = char, PutUnit)(const(char)[] url, const(PutUnit)[] putData, Conn conn = Conn())
{
try
{
T[] res = _retry!(c_put!(Conn, T, PutUnit))(_sanitize(url), putData, conn);
infof("PUT %s", url);
return res;
}
catch (CurlException ex)
{
erroref("PUT %s", ex, url);
assert(0);
}
}
private void _download(const(char)[] url, string file, void delegate(size_t size) progress)
{
scope (failure)
if (exists(file))
remove(file);
File handle = File(file, "wb");
HTTP http = HTTP(_sanitize(url));
http.onReceive = (ubyte[] data)
{
handle.rawWrite(data);
if (progress)
progress(data.length);
return data.length;
};
http.perform();
}
void download(const(char)[] url, string file, void delegate(size_t size) progress = null)
{
try
{
_retry!_download(url, file, progress);
infof("DL %s", url);
}
catch (CurlException ex)
{
erroref("DL %s", cast(Exception)ex, url);
assert(0);
}
}