ext/common/ServerKit/HttpServer.h in passenger-5.0.0.beta2 vs ext/common/ServerKit/HttpServer.h in passenger-5.0.0.beta3

- old
+ new

@@ -1,8 +1,8 @@ /* * Phusion Passenger - https://www.phusionpassenger.com/ - * Copyright (c) 2014 Phusion + * Copyright (c) 2014-2015 Phusion * * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -856,10 +856,14 @@ doneWithCurrentRequest(&c); } else { // Call doneWithCurrentRequest() when data flushed SKC_TRACE(c, 2, "Waiting until output is flushed"); req->httpState = Request::FLUSHING_OUTPUT; + // If the request body is not fully read at this time, + // then ensure that onClientDataReceived() discards any + // request body data that we receive from now on. + req->wantKeepAlive = canKeepAlive(req); } return true; } @@ -889,19 +893,35 @@ Request *req = client->currentRequest; RequestRef ref(req, __FILE__, __LINE__); // Moved outside switch() so that the CPU branch predictor can do its work if (req->httpState == Request::PARSING_HEADERS) { + assert(!req->ended()); return processClientDataWhenParsingHeaders(client, req, buffer, errcode); } else { - switch (req->httpState) { - case Request::PARSING_BODY: - return processClientDataWhenParsingBody(client, req, buffer, errcode); - case Request::PARSING_CHUNKED_BODY: - return processClientDataWhenParsingChunkedBody(client, req, buffer, errcode); - case Request::UPGRADED: - return processClientDataWhenUpgraded(client, req, buffer, errcode); + switch (req->bodyType) { + case Request::RBT_CONTENT_LENGTH: + if (req->ended()) { + assert(!req->wantKeepAlive); + return Channel::Result(buffer.size(), true); + } else { + return processClientDataWhenParsingBody(client, req, buffer, errcode); + } + case Request::RBT_CHUNKED: + if (req->ended()) { + assert(!req->wantKeepAlive); + return Channel::Result(buffer.size(), true); + } else { + return processClientDataWhenParsingChunkedBody(client, req, buffer, errcode); + } + case Request::RBT_UPGRADE: + if (req->ended()) { + assert(!req->wantKeepAlive); + return Channel::Result(buffer.size(), true); + } else { + return processClientDataWhenUpgraded(client, req, buffer, errcode); + } default: P_BUG("Invalid request HTTP state " << (int) req->httpState); // Never reached return Channel::Result(0, false); } @@ -1018,9 +1038,17 @@ req->httpState = Request::WAITING_FOR_REFERENCES; req->headers.clear(); req->secureHeaders.clear(); req->bodyChannel.consumedCallback = NULL; req->bodyChannel.deinitialize(); + } + + + /***** Misc *****/ + + OXT_FORCE_INLINE + static FileBufferedChannel::Callback getClientOutputDataFlushedCallback() { + return _onClientOutputDataFlushed; } public: HttpServer(Context *context) : ParentClass(context),