Skip to content

Commit

Permalink
more relaibility under crappy connections
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdruppe committed Apr 27, 2017
1 parent fcb59c4 commit c8c6115
Showing 1 changed file with 58 additions and 46 deletions.
104 changes: 58 additions & 46 deletions cgi.d
Original file line number Diff line number Diff line change
Expand Up @@ -2649,56 +2649,64 @@ mixin template CustomCgiMainImpl(CustomCgi, alias fun, long maxContentLength = d
i = addr.sizeof;
int s = accept(sock, &addr, &i);

if(s == -1)
throw new Exception("accept");
//ubyte[__traits(classInstanceSize, BufferedInputRange)] bufferedRangeContainer;
auto ir = new BufferedInputRange(s);
//auto ir = emplace!BufferedInputRange(bufferedRangeContainer, s, backingBuffer);

while(!ir.empty) {
ubyte[__traits(classInstanceSize, CustomCgi)] cgiContainer;

Cgi cgi;
try {
cgi = new CustomCgi(ir, &closeConnection);
//cgi = emplace!CustomCgi(cgiContainer, ir, &closeConnection);
} 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 {
fun(cgi);
cgi.close();
} catch(ConnectionException ce) {
closeConnection = true;
} catch(Throwable t) {
// a processing error can be recovered from
stderr.writeln(t.toString);
if(!handleException(cgi, t))
try {

if(s == -1)
throw new Exception("accept");

scope(failure) close(s);
//ubyte[__traits(classInstanceSize, BufferedInputRange)] bufferedRangeContainer;
auto ir = new BufferedInputRange(s);
//auto ir = emplace!BufferedInputRange(bufferedRangeContainer, s, backingBuffer);

while(!ir.empty) {
ubyte[__traits(classInstanceSize, CustomCgi)] cgiContainer;

Cgi cgi;
try {
cgi = new CustomCgi(ir, &closeConnection);
//cgi = emplace!CustomCgi(cgiContainer, ir, &closeConnection);
} 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 {
fun(cgi);
cgi.close();
} catch(ConnectionException ce) {
closeConnection = true;
} catch(Throwable t) {
// a processing error can be recovered from
stderr.writeln(t.toString);
if(!handleException(cgi, t))
closeConnection = true;
}

if(closeConnection) {
ir.source.close();
break;
} else {
if(!ir.empty)
ir.popFront(); // get the next
else if(ir.sourceClosed) {
if(closeConnection) {
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 {
processCount++;
Expand Down Expand Up @@ -3138,6 +3146,9 @@ class BufferedInputRange {
}

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;
if(buffer is null) {
underlyingBuffer = new ubyte[4096];
Expand Down Expand Up @@ -3194,10 +3205,11 @@ class BufferedInputRange {
if(ret == Socket.ERROR) {
version(Posix) {
import core.stdc.errno;
if(errno == EINTR)
if(errno == EINTR) {
goto try_again;
}
}
throw new Exception("uh oh " ~ lastSocketError); // FIXME
throw new Exception(lastSocketError); // FIXME
}
if(ret == 0) {
sourceClosed = true;
Expand Down

0 comments on commit c8c6115

Please sign in to comment.