diff --git a/lib/inc/drogon/HttpRequest.h b/lib/inc/drogon/HttpRequest.h index 18125694..95c5ce8f 100755 --- a/lib/inc/drogon/HttpRequest.h +++ b/lib/inc/drogon/HttpRequest.h @@ -32,7 +32,9 @@ namespace drogon { public: enum Version { - kUnknown, kHttp10, kHttp11 + kUnknown=0, + kHttp10=1, + kHttp11=2 }; enum Method { kInvalid, kGet, kPost, kHead, kPut, kDelete diff --git a/lib/src/HttpClientImpl.cc b/lib/src/HttpClientImpl.cc index 8d75f988..09a4e89b 100644 --- a/lib/src/HttpClientImpl.cc +++ b/lib/src/HttpClientImpl.cc @@ -45,7 +45,7 @@ void HttpClientImpl::sendRequestInLoop(const drogon::HttpRequestPtr &req, const LOG_TRACE<<"connection callback"; if(connPtr->connected()) { - connPtr->setContext(HttpContext()); + connPtr->setContext(HttpContext(connPtr)); //send request; LOG_TRACE<<"Connection established!"; auto req=thisPtr->_reqAndCallbacks.front().first; diff --git a/lib/src/HttpContext.cc b/lib/src/HttpContext.cc index 7b16c837..2e24f8fd 100755 --- a/lib/src/HttpContext.cc +++ b/lib/src/HttpContext.cc @@ -30,11 +30,12 @@ #include using namespace trantor; using namespace drogon; -HttpContext::HttpContext() +HttpContext::HttpContext(const trantor::TcpConnectionPtr &connPtr) : state_(kExpectRequestLine), request_(new HttpRequestImpl), res_state_(HttpResponseParseState::kExpectResponseLine), - _pipeLineMutex(std::make_shared()) + _pipeLineMutex(std::make_shared()), + _conn(connPtr) { } bool HttpContext::processRequestLine(const char *begin, const char *end) @@ -129,6 +130,39 @@ bool HttpContext::parseRequest(MsgBuffer *buf) { request_->contentLen = atoi(len.c_str()); state_ = kExpectBody; + auto expect=request_->getHeader("Expect"); + if(expect=="100-continue"&& + request_->getVersion()>=HttpRequest::kHttp11) + { + //rfc2616-8.2.3 + //TODO:here we can add content-length limitation + auto connPtr=_conn.lock(); + if(connPtr) + { + auto resp=HttpResponse::newHttpResponse(); + resp->setStatusCode(HttpResponse::k100Continue); + MsgBuffer buffer; + std::dynamic_pointer_cast(resp) + ->appendToBuffer(&buffer); + connPtr->send(std::move(buffer)); + } + } + else if(!expect.empty()) + { + LOG_WARN<<"417ExpectationFailed for \""<setStatusCode(HttpResponse::k417ExpectationFailed); + MsgBuffer buffer; + std::dynamic_pointer_cast(resp) + ->appendToBuffer(&buffer); + connPtr->send(std::move(buffer)); + connPtr->shutdown(); + } + + } } else { diff --git a/lib/src/HttpContext.h b/lib/src/HttpContext.h index b1ca89dc..5a9be41b 100755 --- a/lib/src/HttpContext.h +++ b/lib/src/HttpContext.h @@ -32,6 +32,8 @@ #include #include #include +#include + using namespace trantor; namespace drogon { @@ -58,7 +60,7 @@ namespace drogon kGotAll, }; - HttpContext(); + HttpContext(const trantor::TcpConnectionPtr &connPtr); // default copy-ctor, dtor and assignment are fine @@ -163,6 +165,8 @@ namespace drogon std::list> _requestPipeLine; std::shared_ptr _pipeLineMutex; + + std::weak_ptr _conn; }; } diff --git a/lib/src/HttpServer.cc b/lib/src/HttpServer.cc index 7feac650..580d869a 100755 --- a/lib/src/HttpServer.cc +++ b/lib/src/HttpServer.cc @@ -82,7 +82,7 @@ void HttpServer::start() void HttpServer::onConnection(const TcpConnectionPtr& conn) { if (conn->connected()) { - conn->setContext(HttpContext()); + conn->setContext(HttpContext(conn)); } else if(conn->disconnected()) {