Skip to content

Commit

Permalink
Added HttpServerSettings.keepAliveTimeout.
Browse files Browse the repository at this point in the history
Fixed the return value of Libevent2TcpConnection.waitForData.
The HTTP server checks for client disconnects before reading a consecutive request of a keep-alive connection now (avoids "operating on closed connection" errors).
Fixes issues #20 and possibly #43.
  • Loading branch information
s-ludwig committed May 20, 2012
1 parent d5a76b2 commit c9e8e6b
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 4 deletions.
6 changes: 6 additions & 0 deletions source/vibe/core/drivers/libevent2.d
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ class Libevent2Driver : EventDriver {
if( !m_dnsBase ) logError("Failed to initialize DNS lookup.");
}

/*~this()
{
evdns_base_free(m_dnsBase, 1);
event_base_free(m_eventLoop);
}*/

@property event_base* eventLoop() { return m_eventLoop; }
@property evdns_base* dnsEngine() { return m_dnsBase; }

Expand Down
6 changes: 5 additions & 1 deletion source/vibe/core/drivers/libevent2_tcp.d
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,17 @@ package class Libevent2TcpConnection : TcpConnection {
assert(timeout.total!"seconds"() <= int.max, "Timeouts must not be larger than int.max seconds!");
t.tv_sec = cast(int)timeout.total!"seconds"();
t.tv_usec = timeout.fracSec().usecs();
logTrace("add timeout event with %d/%d", t.tv_sec, t.tv_usec);
event_add(evtmout, &t);
logTrace("wait for data");
while( connected ) {
if( dataAvailableForRead || m_timeout_triggered ) break;
rawYield();
}
logTrace(" -> timeout = %s", m_timeout_triggered);
event_del(evtmout);
event_free(evtmout);
return !m_timeout_triggered;
return dataAvailableForRead;
}

alias Stream.write write;
Expand Down Expand Up @@ -479,6 +482,7 @@ package extern(C)

private extern(C) void onTimeout(evutil_socket_t, short events, void* userptr)
{
logTrace("data wait timeout");
auto conn = cast(Libevent2TcpConnection)userptr;
conn.m_timeout_triggered = true;
conn.m_ctx.core.resumeTask(conn.m_fiber);
Expand Down
9 changes: 6 additions & 3 deletions source/vibe/http/server.d
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,9 @@ class HttpServerSettings {

/// Time of a request after which the connection is closed with an error; not supported yet
Duration maxRequestTime = dur!"seconds"(0);

/// Maximum time between two request on a keep-alive connection
Duration keepAliveTimeout = dur!"seconds"(10);

/// Maximum number of transferred bytes per request after which the connection is closed with
/// an error; not supported yet
Expand Down Expand Up @@ -896,7 +899,7 @@ private void handleHttpConnection(TcpConnection conn_, HTTPServerListener listen
if( settings.serverString.length )
res.headers["Server"] = settings.serverString;
res.headers["Date"] = toRFC822DateTimeString(Clock.currTime().toUTC());
if( req.persistent ) res.headers["Keep-Alive"] = "timeout=5";
if( req.persistent ) res.headers["Keep-Alive"] = "timeout="~to!string(settings.keepAliveTimeout.total!"seconds"());


logTrace("handle request (body %d)", req.bodyReader.leastSize);
Expand Down Expand Up @@ -940,12 +943,12 @@ private void handleHttpConnection(TcpConnection conn_, HTTPServerListener listen
foreach( log; context.loggers )
log.log(req, res);

if( req.persistent && !conn_.waitForData(dur!"seconds"(10)) ) {
if( req.persistent && !conn_.waitForData(settings.keepAliveTimeout) ) {
logDebug("persistent connection timeout!");
break;
}

} while( req.persistent );
} while( req.persistent && conn_.connected );
}

private HttpServerRequest parseRequest(Stream conn)
Expand Down

0 comments on commit c9e8e6b

Please sign in to comment.