mirror of https://github.com/adamdruppe/arsd.git
more relaibility under crappy connections
This commit is contained in:
parent
fcb59c4c55
commit
c8c61150d5
98
cgi.d
98
cgi.d
|
@ -2649,56 +2649,64 @@ mixin template CustomCgiMainImpl(CustomCgi, alias fun, long maxContentLength = d
|
||||||
i = addr.sizeof;
|
i = addr.sizeof;
|
||||||
int s = accept(sock, &addr, &i);
|
int s = accept(sock, &addr, &i);
|
||||||
|
|
||||||
if(s == -1)
|
try {
|
||||||
throw new Exception("accept");
|
|
||||||
//ubyte[__traits(classInstanceSize, BufferedInputRange)] bufferedRangeContainer;
|
|
||||||
auto ir = new BufferedInputRange(s);
|
|
||||||
//auto ir = emplace!BufferedInputRange(bufferedRangeContainer, s, backingBuffer);
|
|
||||||
|
|
||||||
while(!ir.empty) {
|
if(s == -1)
|
||||||
ubyte[__traits(classInstanceSize, CustomCgi)] cgiContainer;
|
throw new Exception("accept");
|
||||||
|
|
||||||
Cgi cgi;
|
scope(failure) close(s);
|
||||||
try {
|
//ubyte[__traits(classInstanceSize, BufferedInputRange)] bufferedRangeContainer;
|
||||||
cgi = new CustomCgi(ir, &closeConnection);
|
auto ir = new BufferedInputRange(s);
|
||||||
//cgi = emplace!CustomCgi(cgiContainer, ir, &closeConnection);
|
//auto ir = emplace!BufferedInputRange(bufferedRangeContainer, s, backingBuffer);
|
||||||
} catch(Throwable t) {
|
|
||||||
// a construction error is either bad code or bad request; bad request is what it should be since this is bug free :P
|
|
||||||
// anyway let's kill the connection
|
|
||||||
stderr.writeln(t.toString());
|
|
||||||
sendAll(ir.source, plainHttpError(false, "400 Bad Request", t));
|
|
||||||
closeConnection = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert(cgi !is null);
|
|
||||||
scope(exit)
|
|
||||||
cgi.dispose();
|
|
||||||
|
|
||||||
try {
|
while(!ir.empty) {
|
||||||
fun(cgi);
|
ubyte[__traits(classInstanceSize, CustomCgi)] cgiContainer;
|
||||||
cgi.close();
|
|
||||||
} catch(ConnectionException ce) {
|
Cgi cgi;
|
||||||
closeConnection = true;
|
try {
|
||||||
} catch(Throwable t) {
|
cgi = new CustomCgi(ir, &closeConnection);
|
||||||
// a processing error can be recovered from
|
//cgi = emplace!CustomCgi(cgiContainer, ir, &closeConnection);
|
||||||
stderr.writeln(t.toString);
|
} catch(Throwable t) {
|
||||||
if(!handleException(cgi, t))
|
// a construction error is either bad code or bad request; bad request is what it should be since this is bug free :P
|
||||||
|
// anyway let's kill the connection
|
||||||
|
stderr.writeln(t.toString());
|
||||||
|
sendAll(ir.source, plainHttpError(false, "400 Bad Request", t));
|
||||||
closeConnection = true;
|
closeConnection = true;
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
assert(cgi !is null);
|
||||||
|
scope(exit)
|
||||||
|
cgi.dispose();
|
||||||
|
|
||||||
if(closeConnection) {
|
try {
|
||||||
ir.source.close();
|
fun(cgi);
|
||||||
break;
|
cgi.close();
|
||||||
} else {
|
} catch(ConnectionException ce) {
|
||||||
if(!ir.empty)
|
closeConnection = true;
|
||||||
ir.popFront(); // get the next
|
} catch(Throwable t) {
|
||||||
else if(ir.sourceClosed) {
|
// a processing error can be recovered from
|
||||||
|
stderr.writeln(t.toString);
|
||||||
|
if(!handleException(cgi, t))
|
||||||
|
closeConnection = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(closeConnection) {
|
||||||
ir.source.close();
|
ir.source.close();
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if(!ir.empty)
|
||||||
|
ir.popFront(); // get the next
|
||||||
|
else if(ir.sourceClosed) {
|
||||||
|
ir.source.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ir.source.close();
|
ir.source.close();
|
||||||
|
} catch(Throwable t) {
|
||||||
|
debug writeln(t);
|
||||||
|
// most likely cause is a timeout
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
processCount++;
|
processCount++;
|
||||||
|
@ -3138,6 +3146,9 @@ class BufferedInputRange {
|
||||||
}
|
}
|
||||||
|
|
||||||
this(Socket source, ubyte[] buffer = null) {
|
this(Socket source, ubyte[] buffer = null) {
|
||||||
|
// if they connect but never send stuff to us, we don't want it wasting the process
|
||||||
|
// so setting a time out
|
||||||
|
source.setOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, dur!"seconds"(3));
|
||||||
this.source = source;
|
this.source = source;
|
||||||
if(buffer is null) {
|
if(buffer is null) {
|
||||||
underlyingBuffer = new ubyte[4096];
|
underlyingBuffer = new ubyte[4096];
|
||||||
|
@ -3194,10 +3205,11 @@ class BufferedInputRange {
|
||||||
if(ret == Socket.ERROR) {
|
if(ret == Socket.ERROR) {
|
||||||
version(Posix) {
|
version(Posix) {
|
||||||
import core.stdc.errno;
|
import core.stdc.errno;
|
||||||
if(errno == EINTR)
|
if(errno == EINTR) {
|
||||||
goto try_again;
|
goto try_again;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new Exception("uh oh " ~ lastSocketError); // FIXME
|
throw new Exception(lastSocketError); // FIXME
|
||||||
}
|
}
|
||||||
if(ret == 0) {
|
if(ret == 0) {
|
||||||
sourceClosed = true;
|
sourceClosed = true;
|
||||||
|
|
Loading…
Reference in New Issue