Questionable: support ancient Http and connection: close

This commit is contained in:
Alex Hultman
2021-01-11 13:13:06 +01:00
parent 1acbcaf03a
commit 3347bcc4b2
3 changed files with 32 additions and 1 deletions
+23
View File
@@ -151,6 +151,11 @@ private:
/* Mark pending request and emit it */
httpResponseData->state = HttpResponseData<SSL>::HTTP_RESPONSE_PENDING;
/* Mark this response as connectionClose if ancient or connection: close */
if (httpRequest->isAncient() || httpRequest->getHeader("connection").length() == 5) {
httpResponseData->state |= HttpResponseData<SSL>::HTTP_CONNECTION_CLOSE;
}
/* Route the method and URL */
httpContextData->router.getUserData() = {(HttpResponse<SSL> *) s, httpRequest};
if (!httpContextData->router.route(httpRequest->getMethod(), httpRequest->getUrl())) {
@@ -242,6 +247,15 @@ private:
((AsyncSocket<SSL> *) s)->timeout(HTTP_IDLE_TIMEOUT_S);
}
/* We need to check if we should close this socket here now */
if (httpResponseData->state & HttpResponseData<SSL>::HTTP_CONNECTION_CLOSE) {
if ((httpResponseData->state & HttpResponseData<SSL>::HTTP_RESPONSE_PENDING) == 0) {
if (((AsyncSocket<SSL> *) s)->getBufferedAmount() == 0) {
((AsyncSocket<SSL> *) s)->shutdown();
}
}
}
return (us_socket_t *) returnedSocket;
}
@@ -305,6 +319,15 @@ private:
/* Drain any socket buffer, this might empty our backpressure and thus finish the request */
/*auto [written, failed] = */asyncSocket->write(nullptr, 0, true, 0);
/* Should we close this connection after a response - and is this response really done? */
if (httpResponseData->state & HttpResponseData<SSL>::HTTP_CONNECTION_CLOSE) {
if ((httpResponseData->state & HttpResponseData<SSL>::HTTP_RESPONSE_PENDING) == 0) {
if (asyncSocket->getBufferedAmount() == 0) {
asyncSocket->shutdown();
}
}
}
/* Expect another writable event, or another request within the timeout */
asyncSocket->timeout(HTTP_IDLE_TIMEOUT_S);
+8
View File
@@ -45,12 +45,17 @@ private:
struct Header {
std::string_view key, value;
} headers[MAX_HEADERS];
bool ancientHttp;
unsigned int querySeparator;
bool didYield;
BloomFilter bf;
std::pair<int, std::string_view *> currentParameters;
public:
bool isAncient() {
return ancientHttp;
}
bool getYield() {
return didYield;
}
@@ -226,6 +231,9 @@ private:
length -= consumed;
consumedTotal += consumed;
/* Store HTTP version (ancient 1.0 or 1.1) */
req->ancientHttp = req->headers->value.length() && (req->headers->value[req->headers->value.length() - 1] == '0');
/* Strip away tail of first "header value" aka URL */
req->headers->value = std::string_view(req->headers->value.data(), (size_t) std::max<int>(0, (int) req->headers->value.length() - 9));
+1 -1
View File
@@ -39,7 +39,7 @@ private:
HTTP_WRITE_CALLED = 2, // used
HTTP_END_CALLED = 4, // used
HTTP_RESPONSE_PENDING = 8, // used
HTTP_ENDED_STREAM_OUT = 16 // not used
HTTP_CONNECTION_CLOSE = 16 // used
};
/* Per socket event handlers */