systemd stdio maybe... untested lol

This commit is contained in:
Adam D. Ruppe 2021-05-29 20:58:04 -04:00
parent 543d3a2b5d
commit 1ccb81159d
1 changed files with 64 additions and 2 deletions

66
cgi.d
View File

@ -1638,9 +1638,9 @@ class Cgi {
// see: https://github.com/dlang/phobos/pull/7383
// but this might be more useful anyway tbh for this case
version(Posix)
this(ir, cast(UnixAddress) ira ? "unix:" : ira.toString(), port, 0, false, &rdo, null, closeConnection);
this(ir, ira is null ? null : cast(UnixAddress) ira ? "unix:" : ira.toString(), port, 0, false, &rdo, null, closeConnection);
else
this(ir, ira.toString(), port, 0, false, &rdo, null, closeConnection);
this(ir, ira is null ? null : ira.toString(), port, 0, false, &rdo, null, closeConnection);
}
/**
@ -3520,6 +3520,9 @@ struct RequestServer {
} else
version(fastcgi) {
serveFastCgi!(fun, CustomCgi, maxContentLength)(this);
} else
version(stdiocgi) {
serveSingleHttpConnectionOnStdio!(fun, CustomCgi, maxContentLength)();
} else {
//version=plain_cgi;
handleCgiRequest!(fun, CustomCgi, maxContentLength)();
@ -3535,6 +3538,18 @@ struct RequestServer {
manager.listen();
}
/++
Serves a single "connection", but the connection is spoken on stdin and stdout instead of on a socket.
Intended for cases like working from systemd, like discussed here: https://forum.dlang.org/post/avmkfdiitirnrenzljwc@forum.dlang.org
History:
Added May 29, 2021
+/
void serveSingleHttpConnectionOnStdio(alias fun, CustomCgi = Cgi, long maxContentLength = defaultMaxContentLength)() {
doThreadHttpConnectionGuts!(CustomCgi, fun, true)(new FakeSocketForStdin());
}
void stop() {
// FIXME
}
@ -4655,6 +4670,53 @@ class BufferedInputRange {
bool sourceClosed;
}
private class FakeSocketForStdin : Socket {
import std.stdio;
this() {
}
private bool closed;
override ptrdiff_t receive(void[] buffer, std.socket.SocketFlags) @trusted {
if(closed)
throw new Exception("Closed");
return stdin.rawRead(buffer).length;
}
override ptrdiff_t send(const void[] buffer, std.socket.SocketFlags) @trusted {
if(closed)
throw new Exception("Closed");
stdout.rawWrite(buffer);
return buffer.length;
}
override void close() @trusted {
(cast(void delegate() @nogc nothrow) &realClose)();
}
override void shutdown(SocketShutdown s) {
// FIXME
}
override void setOption(SocketOptionLevel, SocketOption, void[]) {}
override void setOption(SocketOptionLevel, SocketOption, Duration) {}
override @property @trusted Address remoteAddress() { return null; }
override @property @trusted Address localAddress() { return null; }
void realClose() {
closed = true;
try {
stdin.close();
stdout.close();
} catch(Exception e) {
}
}
}
import core.sync.semaphore;
import core.atomic;