Merge branch 'master' into with_orm
This commit is contained in:
commit
e54aba423c
|
@ -14,11 +14,11 @@ int main()
|
|||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
client->sendRequest(req, [&](ReqResult result, const HttpResponse &response) {
|
||||
client->sendRequest(req, [&](ReqResult result, const HttpResponsePtr &response) {
|
||||
std::cout << "receive response!" << std::endl;
|
||||
//auto headers=response.
|
||||
count++;
|
||||
std::cout << response.getBody() << std::endl;
|
||||
std::cout << response->getBody() << std::endl;
|
||||
std::cout << "count=" << count << std::endl;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ class Attachment : public drogon::HttpController<Attachment>
|
|||
public:
|
||||
METHOD_LIST_BEGIN
|
||||
//use METHOD_ADD to add your custom processing function here;
|
||||
METHOD_ADD(Attachment::get, "", Post); //Path will be '/api/attachment'
|
||||
|
||||
METHOD_ADD(Attachment::get, "", Get); //Path will be '/api/attachment'
|
||||
METHOD_ADD(Attachment::upload,"/upload",Post);
|
||||
METHOD_LIST_END
|
||||
//your declaration of processing function maybe like this:
|
||||
void get(const HttpRequestPtr &req,
|
||||
|
|
|
@ -28,7 +28,7 @@ enum class ReqResult
|
|||
BadServerAddress,
|
||||
Timeout
|
||||
};
|
||||
typedef std::function<void(ReqResult, const HttpResponse &response)> HttpReqCallback;
|
||||
typedef std::function<void(ReqResult, const HttpResponsePtr &response)> HttpReqCallback;
|
||||
class HttpClient;
|
||||
typedef std::shared_ptr<HttpClient> HttpClientPtr;
|
||||
class HttpClient : public trantor::NonCopyable
|
||||
|
|
|
@ -0,0 +1,253 @@
|
|||
// Copyright 2010, Shuo Chen. All rights reserved.
|
||||
// http://code.google.com/p/muduo/
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the License file.
|
||||
|
||||
// Author: Shuo Chen (chenshuo at chenshuo dot com)
|
||||
//
|
||||
|
||||
//taken from muduo and modified
|
||||
|
||||
/**
|
||||
*
|
||||
* @file
|
||||
* @author An Tao
|
||||
* @section LICENSE
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* @section DESCRIPTION
|
||||
*
|
||||
*/
|
||||
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include "HttpClientContext.h"
|
||||
#include <iostream>
|
||||
using namespace trantor;
|
||||
using namespace drogon;
|
||||
HttpClientContext::HttpClientContext(const trantor::TcpConnectionPtr &connPtr)
|
||||
: _state(HttpResponseParseState::kExpectResponseLine),
|
||||
_response(new HttpResponseImpl),
|
||||
_conn(connPtr)
|
||||
{
|
||||
}
|
||||
|
||||
bool HttpClientContext::processResponseLine(const char *begin, const char *end)
|
||||
{
|
||||
const char *start = begin;
|
||||
const char *space = std::find(start, end, ' ');
|
||||
if (space != end)
|
||||
{
|
||||
LOG_TRACE << *(space - 1);
|
||||
if (*(space - 1) == '1')
|
||||
{
|
||||
_response->setVersion(HttpResponse::kHttp11);
|
||||
}
|
||||
else if (*(space - 1) == '0')
|
||||
{
|
||||
_response->setVersion(HttpResponse::kHttp10);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
start = space + 1;
|
||||
space = std::find(start, end, ' ');
|
||||
if (space != end)
|
||||
{
|
||||
std::string status_code(start, space - start);
|
||||
std::string status_message(space + 1, end - space - 1);
|
||||
LOG_TRACE << status_code << " " << status_message;
|
||||
auto code = atoi(status_code.c_str());
|
||||
_response->setStatusCode(HttpResponse::HttpStatusCode(code), status_message);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// return false if any error
|
||||
bool HttpClientContext::parseResponse(MsgBuffer *buf)
|
||||
{
|
||||
bool ok = true;
|
||||
bool hasMore = true;
|
||||
while (hasMore)
|
||||
{
|
||||
if (_state == HttpResponseParseState::kExpectResponseLine)
|
||||
{
|
||||
const char *crlf = buf->findCRLF();
|
||||
if (crlf)
|
||||
{
|
||||
ok = processResponseLine(buf->peek(), crlf);
|
||||
if (ok)
|
||||
{
|
||||
//_response->setReceiveTime(receiveTime);
|
||||
buf->retrieveUntil(crlf + 2);
|
||||
_state = HttpResponseParseState::kExpectHeaders;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else if (_state == HttpResponseParseState::kExpectHeaders)
|
||||
{
|
||||
const char *crlf = buf->findCRLF();
|
||||
if (crlf)
|
||||
{
|
||||
const char *colon = std::find(buf->peek(), crlf, ':');
|
||||
if (colon != crlf)
|
||||
{
|
||||
_response->addHeader(buf->peek(), colon, crlf);
|
||||
}
|
||||
else
|
||||
{
|
||||
// empty line, end of header
|
||||
// FIXME:
|
||||
std::string len = _response->getHeader("Content-Length");
|
||||
LOG_INFO << "content len=" << len;
|
||||
if (len != "")
|
||||
{
|
||||
_response->_left_body_length = atoi(len.c_str());
|
||||
_state = HttpResponseParseState::kExpectBody;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string encode = _response->getHeader("Transfer-Encoding");
|
||||
if (encode == "chunked")
|
||||
{
|
||||
_state = HttpResponseParseState::kExpectChunkLen;
|
||||
hasMore = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_state = HttpResponseParseState::kExpectClose;
|
||||
hasMore = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
buf->retrieveUntil(crlf + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else if (_state == HttpResponseParseState::kExpectBody)
|
||||
{
|
||||
//LOG_INFO << "expectBody:len=" << request_->contentLen;
|
||||
//LOG_INFO << "expectBody:buf=" << buf;
|
||||
if (buf->readableBytes() == 0)
|
||||
{
|
||||
if (_response->_left_body_length == 0)
|
||||
{
|
||||
_state = HttpResponseParseState::kGotAll;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (_response->_left_body_length >= buf->readableBytes())
|
||||
{
|
||||
_response->_left_body_length -= buf->readableBytes();
|
||||
_response->_bodyPtr->append(std::string(buf->peek(), buf->readableBytes()));
|
||||
buf->retrieveAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
_response->_bodyPtr->append(std::string(buf->peek(), _response->_left_body_length));
|
||||
buf->retrieve(_response->_left_body_length);
|
||||
_response->_left_body_length = 0;
|
||||
}
|
||||
if (_response->_left_body_length == 0)
|
||||
{
|
||||
_state = HttpResponseParseState::kGotAll;
|
||||
LOG_TRACE << "post got all:len=" << _response->_left_body_length;
|
||||
//LOG_INFO<<"content:"<<request_->content_;
|
||||
LOG_TRACE << "content(END)";
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else if (_state == HttpResponseParseState::kExpectClose)
|
||||
{
|
||||
_response->_bodyPtr->append(std::string(buf->peek(), buf->readableBytes()));
|
||||
buf->retrieveAll();
|
||||
break;
|
||||
}
|
||||
else if (_state == HttpResponseParseState::kExpectChunkLen)
|
||||
{
|
||||
const char *crlf = buf->findCRLF();
|
||||
if (crlf)
|
||||
{
|
||||
//chunk length line
|
||||
std::string len(buf->peek(), crlf - buf->peek());
|
||||
char *end;
|
||||
_response->_current_chunk_length = strtol(len.c_str(), &end, 16);
|
||||
//LOG_TRACE << "chun length : " << _response->_current_chunk_length;
|
||||
if (_response->_current_chunk_length != 0)
|
||||
{
|
||||
_state = HttpResponseParseState::kExpectChunkBody;
|
||||
}
|
||||
else
|
||||
{
|
||||
_state = HttpResponseParseState::kExpectLastEmptyChunk;
|
||||
}
|
||||
buf->retrieveUntil(crlf + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else if (_state == HttpResponseParseState::kExpectChunkBody)
|
||||
{
|
||||
//LOG_TRACE<<"expect chunk len="<<_response->_current_chunk_length;
|
||||
if (buf->readableBytes() >= (_response->_current_chunk_length + 2))
|
||||
{
|
||||
if (*(buf->peek() + _response->_current_chunk_length) == '\r' &&
|
||||
*(buf->peek() + _response->_current_chunk_length + 1) == '\n')
|
||||
{
|
||||
_response->_bodyPtr->append(std::string(buf->peek(), _response->_current_chunk_length));
|
||||
buf->retrieve(_response->_current_chunk_length + 2);
|
||||
_response->_current_chunk_length = 0;
|
||||
_state = HttpResponseParseState::kExpectChunkLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
//error!
|
||||
buf->retrieveAll();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else if (_state == HttpResponseParseState::kExpectLastEmptyChunk)
|
||||
{
|
||||
//last empty chunk
|
||||
const char *crlf = buf->findCRLF();
|
||||
if (crlf)
|
||||
{
|
||||
buf->retrieveUntil(crlf + 2);
|
||||
_state = HttpResponseParseState::kGotAll;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
// Copyright 2010, Shuo Chen. All rights reserved.
|
||||
// http://code.google.com/p/muduo/
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the License file.
|
||||
|
||||
// Author: Shuo Chen (chenshuo at chenshuo dot com)
|
||||
//
|
||||
// This is an internal header file, you should not include this.
|
||||
|
||||
//taken from muduo and modified
|
||||
|
||||
/**
|
||||
*
|
||||
* @file
|
||||
* @author An Tao
|
||||
* @section LICENSE
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* @section DESCRIPTION
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "HttpResponseImpl.h"
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <drogon/WebSocketConnection.h>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <trantor/net/TcpConnection.h>
|
||||
|
||||
using namespace trantor;
|
||||
namespace drogon
|
||||
{
|
||||
class HttpClientContext
|
||||
{
|
||||
public:
|
||||
|
||||
enum class HttpResponseParseState
|
||||
{
|
||||
kExpectResponseLine,
|
||||
kExpectHeaders,
|
||||
kExpectBody,
|
||||
kExpectChunkLen,
|
||||
kExpectChunkBody,
|
||||
kExpectLastEmptyChunk,
|
||||
kExpectClose,
|
||||
kGotAll,
|
||||
};
|
||||
|
||||
HttpClientContext(const trantor::TcpConnectionPtr &connPtr);
|
||||
|
||||
// default copy-ctor, dtor and assignment are fine
|
||||
|
||||
// return false if any error
|
||||
bool parseResponse(MsgBuffer *buf);
|
||||
|
||||
bool gotAll() const
|
||||
{
|
||||
return _state == HttpResponseParseState::kGotAll;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
_state = HttpResponseParseState::kExpectResponseLine;
|
||||
_response.reset(new HttpResponseImpl);
|
||||
}
|
||||
|
||||
|
||||
const HttpResponsePtr response() const
|
||||
{
|
||||
return _response;
|
||||
}
|
||||
|
||||
HttpResponsePtr response()
|
||||
{
|
||||
return _response;
|
||||
}
|
||||
HttpResponseImplPtr responseImpl()
|
||||
{
|
||||
return _response;
|
||||
}
|
||||
|
||||
private:
|
||||
bool processResponseLine(const char *begin, const char *end);
|
||||
|
||||
HttpResponseParseState _state;
|
||||
HttpResponseImplPtr _response;
|
||||
|
||||
std::weak_ptr<trantor::TcpConnection> _conn;
|
||||
};
|
||||
|
||||
} // namespace drogon
|
|
@ -1,6 +1,6 @@
|
|||
#include "HttpClientImpl.h"
|
||||
#include "HttpRequestImpl.h"
|
||||
#include "HttpContext.h"
|
||||
#include "HttpClientContext.h"
|
||||
#include "HttpAppFrameworkImpl.h"
|
||||
#include <stdlib.h>
|
||||
#include <algorithm>
|
||||
|
@ -95,7 +95,7 @@ void HttpClientImpl::sendRequestInLoop(const drogon::HttpRequestPtr &req,
|
|||
if (InetAddress::resolve(_domain, &_server) == false)
|
||||
{
|
||||
callback(ReqResult::BadServerAddress,
|
||||
HttpResponseImpl());
|
||||
HttpResponse::newHttpResponse());
|
||||
return;
|
||||
}
|
||||
LOG_TRACE << "dns:domain=" << _domain << ";ip=" << _server.toIp();
|
||||
|
@ -117,7 +117,7 @@ void HttpClientImpl::sendRequestInLoop(const drogon::HttpRequestPtr &req,
|
|||
_tcpClient->setConnectionCallback([=](const trantor::TcpConnectionPtr &connPtr) {
|
||||
if (connPtr->connected())
|
||||
{
|
||||
connPtr->setContext(HttpContext(connPtr));
|
||||
connPtr->setContext(HttpClientContext(connPtr));
|
||||
//send request;
|
||||
LOG_TRACE << "Connection established!";
|
||||
auto req = thisPtr->_reqAndCallbacks.front().first;
|
||||
|
@ -130,7 +130,7 @@ void HttpClientImpl::sendRequestInLoop(const drogon::HttpRequestPtr &req,
|
|||
{
|
||||
auto reqCallback = _reqAndCallbacks.front().second;
|
||||
_reqAndCallbacks.pop();
|
||||
reqCallback(ReqResult::NetworkFailure, HttpResponseImpl());
|
||||
reqCallback(ReqResult::NetworkFailure, HttpResponse::newHttpResponse());
|
||||
}
|
||||
thisPtr->_tcpClient.reset();
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ void HttpClientImpl::sendRequestInLoop(const drogon::HttpRequestPtr &req,
|
|||
{
|
||||
auto reqCallback = _reqAndCallbacks.front().second;
|
||||
_reqAndCallbacks.pop();
|
||||
reqCallback(ReqResult::BadServerAddress, HttpResponseImpl());
|
||||
reqCallback(ReqResult::BadServerAddress, HttpResponse::newHttpResponse());
|
||||
}
|
||||
thisPtr->_tcpClient.reset();
|
||||
});
|
||||
|
@ -151,7 +151,7 @@ void HttpClientImpl::sendRequestInLoop(const drogon::HttpRequestPtr &req,
|
|||
else
|
||||
{
|
||||
callback(ReqResult::BadServerAddress,
|
||||
HttpResponseImpl());
|
||||
HttpResponse::newHttpResponse());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -183,33 +183,36 @@ void HttpClientImpl::sendReq(const trantor::TcpConnectionPtr &connPtr, const Htt
|
|||
|
||||
void HttpClientImpl::onRecvMessage(const trantor::TcpConnectionPtr &connPtr, trantor::MsgBuffer *msg)
|
||||
{
|
||||
HttpContext *context = any_cast<HttpContext>(connPtr->getMutableContext());
|
||||
HttpClientContext *context = any_cast<HttpClientContext>(connPtr->getMutableContext());
|
||||
|
||||
//LOG_TRACE << "###:" << msg->readableBytes();
|
||||
if (!context->parseResponse(msg))
|
||||
{
|
||||
assert(!_reqAndCallbacks.empty());
|
||||
auto cb = _reqAndCallbacks.front().second;
|
||||
cb(ReqResult::BadResponse, HttpResponseImpl());
|
||||
cb(ReqResult::BadResponse, HttpResponse::newHttpResponse());
|
||||
_reqAndCallbacks.pop();
|
||||
|
||||
_tcpClient.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->resGotAll())
|
||||
if (context->gotAll())
|
||||
{
|
||||
auto &resp = context->responseImpl();
|
||||
auto resp = context->responseImpl();
|
||||
context->reset();
|
||||
|
||||
assert(!_reqAndCallbacks.empty());
|
||||
auto cb = _reqAndCallbacks.front().second;
|
||||
cb(ReqResult::Ok, resp);
|
||||
_reqAndCallbacks.pop();
|
||||
auto type = resp.getHeader("Content-Type");
|
||||
|
||||
auto type = resp->getHeader("Content-Type");
|
||||
if (type.find("application/json") != std::string::npos)
|
||||
{
|
||||
resp.parseJson();
|
||||
resp->parseJson();
|
||||
}
|
||||
context->resetRes();
|
||||
auto &cb = _reqAndCallbacks.front().second;
|
||||
cb(ReqResult::Ok, resp);
|
||||
_reqAndCallbacks.pop();
|
||||
|
||||
LOG_TRACE << "req buffer size=" << _reqAndCallbacks.size();
|
||||
if (!_reqAndCallbacks.empty())
|
||||
{
|
||||
|
@ -218,7 +221,7 @@ void HttpClientImpl::onRecvMessage(const trantor::TcpConnectionPtr &connPtr, tra
|
|||
}
|
||||
else
|
||||
{
|
||||
if (resp.closeConnection())
|
||||
if (resp->closeConnection())
|
||||
{
|
||||
_tcpClient.reset();
|
||||
}
|
||||
|
|
|
@ -1,477 +0,0 @@
|
|||
// Copyright 2010, Shuo Chen. All rights reserved.
|
||||
// http://code.google.com/p/muduo/
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the License file.
|
||||
|
||||
// Author: Shuo Chen (chenshuo at chenshuo dot com)
|
||||
//
|
||||
|
||||
//taken from muduo and modified
|
||||
|
||||
/**
|
||||
*
|
||||
* @file
|
||||
* @author An Tao
|
||||
* @section LICENSE
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* @section DESCRIPTION
|
||||
*
|
||||
*/
|
||||
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include "HttpContext.h"
|
||||
#include <iostream>
|
||||
using namespace trantor;
|
||||
using namespace drogon;
|
||||
HttpContext::HttpContext(const trantor::TcpConnectionPtr &connPtr)
|
||||
: state_(kExpectRequestLine),
|
||||
request_(new HttpRequestImpl),
|
||||
res_state_(HttpResponseParseState::kExpectResponseLine),
|
||||
_pipeLineMutex(std::make_shared<std::mutex>()),
|
||||
_conn(connPtr)
|
||||
{
|
||||
}
|
||||
bool HttpContext::processRequestLine(const char *begin, const char *end)
|
||||
{
|
||||
bool succeed = false;
|
||||
const char *start = begin;
|
||||
const char *space = std::find(start, end, ' ');
|
||||
if (space != end && request_->setMethod(start, space))
|
||||
{
|
||||
start = space + 1;
|
||||
space = std::find(start, end, ' ');
|
||||
if (space != end)
|
||||
{
|
||||
const char *question = std::find(start, space, '?');
|
||||
if (question != space)
|
||||
{
|
||||
request_->setPath(start, question);
|
||||
request_->setQuery(question + 1, space);
|
||||
}
|
||||
else
|
||||
{
|
||||
request_->setPath(start, space);
|
||||
}
|
||||
start = space + 1;
|
||||
succeed = end - start == 8 && std::equal(start, end - 1, "HTTP/1.");
|
||||
if (succeed)
|
||||
{
|
||||
if (*(end - 1) == '1')
|
||||
{
|
||||
request_->setVersion(HttpRequest::kHttp11);
|
||||
}
|
||||
else if (*(end - 1) == '0')
|
||||
{
|
||||
request_->setVersion(HttpRequest::kHttp10);
|
||||
}
|
||||
else
|
||||
{
|
||||
succeed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return succeed;
|
||||
}
|
||||
|
||||
// return false if any error
|
||||
bool HttpContext::parseRequest(MsgBuffer *buf)
|
||||
{
|
||||
bool ok = true;
|
||||
bool hasMore = true;
|
||||
// std::cout<<std::string(buf->peek(),buf->readableBytes())<<std::endl;
|
||||
while (hasMore)
|
||||
{
|
||||
if (state_ == kExpectRequestLine)
|
||||
{
|
||||
const char *crlf = buf->findCRLF();
|
||||
if (crlf)
|
||||
{
|
||||
ok = processRequestLine(buf->peek(), crlf);
|
||||
if (ok)
|
||||
{
|
||||
//request_->setReceiveTime(receiveTime);
|
||||
buf->retrieveUntil(crlf + 2);
|
||||
state_ = kExpectHeaders;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else if (state_ == kExpectHeaders)
|
||||
{
|
||||
const char *crlf = buf->findCRLF();
|
||||
if (crlf)
|
||||
{
|
||||
const char *colon = std::find(buf->peek(), crlf, ':');
|
||||
if (colon != crlf)
|
||||
{
|
||||
request_->addHeader(buf->peek(), colon, crlf);
|
||||
}
|
||||
else
|
||||
{
|
||||
// empty line, end of header
|
||||
std::string len = request_->getHeader("Content-Length");
|
||||
LOG_TRACE << "content len=" << len;
|
||||
if (len != "")
|
||||
{
|
||||
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<HttpResponseImpl>(resp)
|
||||
->appendToBuffer(&buffer);
|
||||
connPtr->send(std::move(buffer));
|
||||
}
|
||||
}
|
||||
else if (!expect.empty())
|
||||
{
|
||||
LOG_WARN << "417ExpectationFailed for \"" << expect << "\"";
|
||||
auto connPtr = _conn.lock();
|
||||
if (connPtr)
|
||||
{
|
||||
auto resp = HttpResponse::newHttpResponse();
|
||||
resp->setStatusCode(HttpResponse::k417ExpectationFailed);
|
||||
MsgBuffer buffer;
|
||||
std::dynamic_pointer_cast<HttpResponseImpl>(resp)
|
||||
->appendToBuffer(&buffer);
|
||||
connPtr->send(std::move(buffer));
|
||||
buf->retrieveAll();
|
||||
connPtr->forceClose();
|
||||
|
||||
//return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
state_ = kGotAll;
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
buf->retrieveUntil(crlf + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else if (state_ == kExpectBody)
|
||||
{
|
||||
//LOG_INFO << "expectBody:len=" << request_->contentLen;
|
||||
//LOG_INFO << "expectBody:buf=" << buf;
|
||||
if (buf->readableBytes() == 0)
|
||||
{
|
||||
if (request_->contentLen == 0)
|
||||
{
|
||||
state_ = kGotAll;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (request_->contentLen >= buf->readableBytes())
|
||||
{
|
||||
request_->contentLen -= buf->readableBytes();
|
||||
request_->content_ += std::string(buf->peek(), buf->readableBytes());
|
||||
buf->retrieveAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
request_->content_ += std::string(buf->peek(), request_->contentLen);
|
||||
buf->retrieve(request_->contentLen);
|
||||
request_->contentLen = 0;
|
||||
}
|
||||
if (request_->contentLen == 0)
|
||||
{
|
||||
state_ = kGotAll;
|
||||
LOG_TRACE << "post got all:len=" << request_->content_.length();
|
||||
//LOG_INFO<<"content:"<<request_->content_;
|
||||
LOG_TRACE << "content(END)";
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool HttpContext::processResponseLine(const char *begin, const char *end)
|
||||
{
|
||||
const char *start = begin;
|
||||
const char *space = std::find(start, end, ' ');
|
||||
if (space != end)
|
||||
{
|
||||
LOG_TRACE << *(space - 1);
|
||||
if (*(space - 1) == '1')
|
||||
{
|
||||
response_.setVersion(HttpResponse::kHttp11);
|
||||
}
|
||||
else if (*(space - 1) == '0')
|
||||
{
|
||||
response_.setVersion(HttpResponse::kHttp10);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
start = space + 1;
|
||||
space = std::find(start, end, ' ');
|
||||
if (space != end)
|
||||
{
|
||||
std::string status_code(start, space - start);
|
||||
std::string status_message(space + 1, end - space - 1);
|
||||
LOG_TRACE << status_code << " " << status_message;
|
||||
auto code = atoi(status_code.c_str());
|
||||
response_.setStatusCode(HttpResponse::HttpStatusCode(code), status_message);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// return false if any error
|
||||
bool HttpContext::parseResponse(MsgBuffer *buf)
|
||||
{
|
||||
bool ok = true;
|
||||
bool hasMore = true;
|
||||
while (hasMore)
|
||||
{
|
||||
if (res_state_ == HttpResponseParseState::kExpectResponseLine)
|
||||
{
|
||||
const char *crlf = buf->findCRLF();
|
||||
if (crlf)
|
||||
{
|
||||
ok = processResponseLine(buf->peek(), crlf);
|
||||
if (ok)
|
||||
{
|
||||
//response_.setReceiveTime(receiveTime);
|
||||
buf->retrieveUntil(crlf + 2);
|
||||
res_state_ = HttpResponseParseState::kExpectHeaders;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else if (res_state_ == HttpResponseParseState::kExpectHeaders)
|
||||
{
|
||||
const char *crlf = buf->findCRLF();
|
||||
if (crlf)
|
||||
{
|
||||
const char *colon = std::find(buf->peek(), crlf, ':');
|
||||
if (colon != crlf)
|
||||
{
|
||||
response_.addHeader(buf->peek(), colon, crlf);
|
||||
}
|
||||
else
|
||||
{
|
||||
// empty line, end of header
|
||||
// FIXME:
|
||||
std::string len = response_.getHeader("Content-Length");
|
||||
LOG_INFO << "content len=" << len;
|
||||
if (len != "")
|
||||
{
|
||||
response_._left_body_length = atoi(len.c_str());
|
||||
res_state_ = HttpResponseParseState::kExpectBody;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string encode = response_.getHeader("Transfer-Encoding");
|
||||
if (encode == "chunked")
|
||||
{
|
||||
res_state_ = HttpResponseParseState::kExpectChunkLen;
|
||||
hasMore = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
res_state_ = HttpResponseParseState::kExpectClose;
|
||||
hasMore = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
buf->retrieveUntil(crlf + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else if (res_state_ == HttpResponseParseState::kExpectBody)
|
||||
{
|
||||
//LOG_INFO << "expectBody:len=" << request_->contentLen;
|
||||
//LOG_INFO << "expectBody:buf=" << buf;
|
||||
if (buf->readableBytes() == 0)
|
||||
{
|
||||
if (response_._left_body_length == 0)
|
||||
{
|
||||
res_state_ = HttpResponseParseState::kGotAll;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (response_._left_body_length >= buf->readableBytes())
|
||||
{
|
||||
response_._left_body_length -= buf->readableBytes();
|
||||
response_._bodyPtr->append(std::string(buf->peek(), buf->readableBytes()));
|
||||
buf->retrieveAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
response_._bodyPtr->append(std::string(buf->peek(), response_._left_body_length));
|
||||
buf->retrieve(request_->contentLen);
|
||||
response_._left_body_length = 0;
|
||||
}
|
||||
if (response_._left_body_length == 0)
|
||||
{
|
||||
res_state_ = HttpResponseParseState::kGotAll;
|
||||
LOG_TRACE << "post got all:len=" << response_._left_body_length;
|
||||
//LOG_INFO<<"content:"<<request_->content_;
|
||||
LOG_TRACE << "content(END)";
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else if (res_state_ == HttpResponseParseState::kExpectClose)
|
||||
{
|
||||
response_._bodyPtr->append(std::string(buf->peek(), buf->readableBytes()));
|
||||
buf->retrieveAll();
|
||||
break;
|
||||
}
|
||||
else if (res_state_ == HttpResponseParseState::kExpectChunkLen)
|
||||
{
|
||||
const char *crlf = buf->findCRLF();
|
||||
if (crlf)
|
||||
{
|
||||
//chunk length line
|
||||
std::string len(buf->peek(), crlf - buf->peek());
|
||||
char *end;
|
||||
response_._current_chunk_length = strtol(len.c_str(), &end, 16);
|
||||
//LOG_TRACE << "chun length : " << response_._current_chunk_length;
|
||||
if (response_._current_chunk_length != 0)
|
||||
{
|
||||
res_state_ = HttpResponseParseState::kExpectChunkBody;
|
||||
}
|
||||
else
|
||||
{
|
||||
res_state_ = HttpResponseParseState::kExpectLastEmptyChunk;
|
||||
}
|
||||
buf->retrieveUntil(crlf + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else if (res_state_ == HttpResponseParseState::kExpectChunkBody)
|
||||
{
|
||||
//LOG_TRACE<<"expect chunk len="<<response_._current_chunk_length;
|
||||
if (buf->readableBytes() >= (response_._current_chunk_length + 2))
|
||||
{
|
||||
if (*(buf->peek() + response_._current_chunk_length) == '\r' &&
|
||||
*(buf->peek() + response_._current_chunk_length + 1) == '\n')
|
||||
{
|
||||
response_._bodyPtr->append(std::string(buf->peek(), response_._current_chunk_length));
|
||||
buf->retrieve(response_._current_chunk_length + 2);
|
||||
response_._current_chunk_length = 0;
|
||||
res_state_ = HttpResponseParseState::kExpectChunkLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
//error!
|
||||
buf->retrieveAll();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else if (res_state_ == HttpResponseParseState::kExpectLastEmptyChunk)
|
||||
{
|
||||
//last empty chunk
|
||||
const char *crlf = buf->findCRLF();
|
||||
if (crlf)
|
||||
{
|
||||
buf->retrieveUntil(crlf + 2);
|
||||
res_state_ = HttpResponseParseState::kGotAll;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
void HttpContext::pushRquestToPipeLine(const HttpRequestPtr &req)
|
||||
{
|
||||
std::pair<HttpRequestPtr, HttpResponsePtr> reqPair(req, HttpResponseImplPtr());
|
||||
|
||||
_requestPipeLine.push_back(std::move(reqPair));
|
||||
}
|
||||
HttpRequestPtr HttpContext::getFirstRequest() const
|
||||
{
|
||||
if (_requestPipeLine.size() > 0)
|
||||
{
|
||||
return _requestPipeLine.front().first;
|
||||
}
|
||||
return HttpRequestImplPtr();
|
||||
}
|
||||
HttpResponsePtr HttpContext::getFirstResponse() const
|
||||
{
|
||||
if (_requestPipeLine.size() > 0)
|
||||
{
|
||||
return _requestPipeLine.front().second;
|
||||
}
|
||||
return HttpResponseImplPtr();
|
||||
}
|
||||
void HttpContext::popFirstRequest()
|
||||
{
|
||||
_requestPipeLine.pop_front();
|
||||
}
|
||||
void HttpContext::pushResponseToPipeLine(const HttpRequestPtr &req,
|
||||
const HttpResponsePtr &resp)
|
||||
{
|
||||
for (auto &iter : _requestPipeLine)
|
||||
{
|
||||
if (iter.first == req)
|
||||
{
|
||||
iter.second = resp;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::mutex &HttpContext::getPipeLineMutex()
|
||||
{
|
||||
return *_pipeLineMutex;
|
||||
}
|
|
@ -44,8 +44,7 @@ namespace drogon
|
|||
class HttpRequestImpl : public HttpRequest
|
||||
{
|
||||
public:
|
||||
friend class HttpContext;
|
||||
|
||||
friend class HttpServerContext;
|
||||
HttpRequestImpl()
|
||||
: _method(Invalid),
|
||||
_version(kUnknown),
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace drogon
|
|||
{
|
||||
class HttpResponseImpl : public HttpResponse
|
||||
{
|
||||
friend class HttpContext;
|
||||
friend class HttpClientContext;
|
||||
|
||||
public:
|
||||
explicit HttpResponseImpl()
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
#include "HttpServer.h"
|
||||
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include "HttpContext.h"
|
||||
#include "HttpServerContext.h"
|
||||
#include "HttpResponseImpl.h"
|
||||
#include <drogon/HttpRequest.h>
|
||||
#include <drogon/HttpResponse.h>
|
||||
#include <drogon/utils/Utilities.h>
|
||||
|
@ -85,12 +86,12 @@ void HttpServer::onConnection(const TcpConnectionPtr &conn)
|
|||
{
|
||||
if (conn->connected())
|
||||
{
|
||||
conn->setContext(HttpContext(conn));
|
||||
conn->setContext(HttpServerContext(conn));
|
||||
}
|
||||
else if (conn->disconnected())
|
||||
{
|
||||
LOG_TRACE << "conn disconnected!";
|
||||
HttpContext *context = any_cast<HttpContext>(conn->getMutableContext());
|
||||
HttpServerContext *context = any_cast<HttpServerContext>(conn->getMutableContext());
|
||||
|
||||
// LOG_INFO << "###:" << string(buf->peek(), buf->readableBytes());
|
||||
if (context->webSocketConn())
|
||||
|
@ -105,7 +106,7 @@ void HttpServer::onConnection(const TcpConnectionPtr &conn)
|
|||
void HttpServer::onMessage(const TcpConnectionPtr &conn,
|
||||
MsgBuffer *buf)
|
||||
{
|
||||
HttpContext *context = any_cast<HttpContext>(conn->getMutableContext());
|
||||
HttpServerContext *context = any_cast<HttpServerContext>(conn->getMutableContext());
|
||||
|
||||
// LOG_INFO << "###:" << string(buf->peek(), buf->readableBytes());
|
||||
if (context->webSocketConn())
|
||||
|
@ -167,7 +168,7 @@ void HttpServer::onRequest(const TcpConnectionPtr &conn, const HttpRequestPtr &r
|
|||
{
|
||||
req->setMethod(Get);
|
||||
}
|
||||
HttpContext *context = any_cast<HttpContext>(conn->getMutableContext());
|
||||
HttpServerContext *context = any_cast<HttpServerContext>(conn->getMutableContext());
|
||||
//request will be received in same thread,so we don't need mutex;
|
||||
context->pushRquestToPipeLine(req);
|
||||
httpAsyncCallback_(req, [=](const HttpResponsePtr &response) {
|
||||
|
|
|
@ -0,0 +1,261 @@
|
|||
// Copyright 2010, Shuo Chen. All rights reserved.
|
||||
// http://code.google.com/p/muduo/
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the License file.
|
||||
|
||||
// Author: Shuo Chen (chenshuo at chenshuo dot com)
|
||||
//
|
||||
|
||||
//taken from muduo and modified
|
||||
|
||||
/**
|
||||
*
|
||||
* @file
|
||||
* @author An Tao
|
||||
* @section LICENSE
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* @section DESCRIPTION
|
||||
*
|
||||
*/
|
||||
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include "HttpServerContext.h"
|
||||
#include "HttpResponseImpl.h"
|
||||
#include <iostream>
|
||||
using namespace trantor;
|
||||
using namespace drogon;
|
||||
HttpServerContext::HttpServerContext(const trantor::TcpConnectionPtr &connPtr)
|
||||
: state_(kExpectRequestLine),
|
||||
request_(new HttpRequestImpl),
|
||||
_pipeLineMutex(std::make_shared<std::mutex>()),
|
||||
_conn(connPtr)
|
||||
{
|
||||
}
|
||||
bool HttpServerContext::processRequestLine(const char *begin, const char *end)
|
||||
{
|
||||
bool succeed = false;
|
||||
const char *start = begin;
|
||||
const char *space = std::find(start, end, ' ');
|
||||
if (space != end && request_->setMethod(start, space))
|
||||
{
|
||||
start = space + 1;
|
||||
space = std::find(start, end, ' ');
|
||||
if (space != end)
|
||||
{
|
||||
const char *question = std::find(start, space, '?');
|
||||
if (question != space)
|
||||
{
|
||||
request_->setPath(start, question);
|
||||
request_->setQuery(question + 1, space);
|
||||
}
|
||||
else
|
||||
{
|
||||
request_->setPath(start, space);
|
||||
}
|
||||
start = space + 1;
|
||||
succeed = end - start == 8 && std::equal(start, end - 1, "HTTP/1.");
|
||||
if (succeed)
|
||||
{
|
||||
if (*(end - 1) == '1')
|
||||
{
|
||||
request_->setVersion(HttpRequest::kHttp11);
|
||||
}
|
||||
else if (*(end - 1) == '0')
|
||||
{
|
||||
request_->setVersion(HttpRequest::kHttp10);
|
||||
}
|
||||
else
|
||||
{
|
||||
succeed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return succeed;
|
||||
}
|
||||
|
||||
// return false if any error
|
||||
bool HttpServerContext::parseRequest(MsgBuffer *buf)
|
||||
{
|
||||
bool ok = true;
|
||||
bool hasMore = true;
|
||||
// std::cout<<std::string(buf->peek(),buf->readableBytes())<<std::endl;
|
||||
while (hasMore)
|
||||
{
|
||||
if (state_ == kExpectRequestLine)
|
||||
{
|
||||
const char *crlf = buf->findCRLF();
|
||||
if (crlf)
|
||||
{
|
||||
ok = processRequestLine(buf->peek(), crlf);
|
||||
if (ok)
|
||||
{
|
||||
//request_->setReceiveTime(receiveTime);
|
||||
buf->retrieveUntil(crlf + 2);
|
||||
state_ = kExpectHeaders;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else if (state_ == kExpectHeaders)
|
||||
{
|
||||
const char *crlf = buf->findCRLF();
|
||||
if (crlf)
|
||||
{
|
||||
const char *colon = std::find(buf->peek(), crlf, ':');
|
||||
if (colon != crlf)
|
||||
{
|
||||
request_->addHeader(buf->peek(), colon, crlf);
|
||||
}
|
||||
else
|
||||
{
|
||||
// empty line, end of header
|
||||
std::string len = request_->getHeader("Content-Length");
|
||||
LOG_TRACE << "content len=" << len;
|
||||
if (len != "")
|
||||
{
|
||||
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<HttpResponseImpl>(resp)
|
||||
->appendToBuffer(&buffer);
|
||||
connPtr->send(std::move(buffer));
|
||||
}
|
||||
}
|
||||
else if (!expect.empty())
|
||||
{
|
||||
LOG_WARN << "417ExpectationFailed for \"" << expect << "\"";
|
||||
auto connPtr = _conn.lock();
|
||||
if (connPtr)
|
||||
{
|
||||
auto resp = HttpResponse::newHttpResponse();
|
||||
resp->setStatusCode(HttpResponse::k417ExpectationFailed);
|
||||
MsgBuffer buffer;
|
||||
std::dynamic_pointer_cast<HttpResponseImpl>(resp)
|
||||
->appendToBuffer(&buffer);
|
||||
connPtr->send(std::move(buffer));
|
||||
buf->retrieveAll();
|
||||
connPtr->forceClose();
|
||||
|
||||
//return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
state_ = kGotAll;
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
buf->retrieveUntil(crlf + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
else if (state_ == kExpectBody)
|
||||
{
|
||||
//LOG_INFO << "expectBody:len=" << request_->contentLen;
|
||||
//LOG_INFO << "expectBody:buf=" << buf;
|
||||
if (buf->readableBytes() == 0)
|
||||
{
|
||||
if (request_->contentLen == 0)
|
||||
{
|
||||
state_ = kGotAll;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (request_->contentLen >= buf->readableBytes())
|
||||
{
|
||||
request_->contentLen -= buf->readableBytes();
|
||||
request_->content_ += std::string(buf->peek(), buf->readableBytes());
|
||||
buf->retrieveAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
request_->content_ += std::string(buf->peek(), request_->contentLen);
|
||||
buf->retrieve(request_->contentLen);
|
||||
request_->contentLen = 0;
|
||||
}
|
||||
if (request_->contentLen == 0)
|
||||
{
|
||||
state_ = kGotAll;
|
||||
LOG_TRACE << "post got all:len=" << request_->content_.length();
|
||||
//LOG_INFO<<"content:"<<request_->content_;
|
||||
LOG_TRACE << "content(END)";
|
||||
hasMore = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void HttpServerContext::pushRquestToPipeLine(const HttpRequestPtr &req)
|
||||
{
|
||||
std::pair<HttpRequestPtr, HttpResponsePtr> reqPair(req, HttpResponseImplPtr());
|
||||
|
||||
_requestPipeLine.push_back(std::move(reqPair));
|
||||
}
|
||||
HttpRequestPtr HttpServerContext::getFirstRequest() const
|
||||
{
|
||||
if (_requestPipeLine.size() > 0)
|
||||
{
|
||||
return _requestPipeLine.front().first;
|
||||
}
|
||||
return HttpRequestImplPtr();
|
||||
}
|
||||
HttpResponsePtr HttpServerContext::getFirstResponse() const
|
||||
{
|
||||
if (_requestPipeLine.size() > 0)
|
||||
{
|
||||
return _requestPipeLine.front().second;
|
||||
}
|
||||
return HttpResponseImplPtr();
|
||||
}
|
||||
void HttpServerContext::popFirstRequest()
|
||||
{
|
||||
_requestPipeLine.pop_front();
|
||||
}
|
||||
void HttpServerContext::pushResponseToPipeLine(const HttpRequestPtr &req,
|
||||
const HttpResponsePtr &resp)
|
||||
{
|
||||
for (auto &iter : _requestPipeLine)
|
||||
{
|
||||
if (iter.first == req)
|
||||
{
|
||||
iter.second = resp;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::mutex &HttpServerContext::getPipeLineMutex()
|
||||
{
|
||||
return *_pipeLineMutex;
|
||||
}
|
|
@ -26,9 +26,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "HttpRequestImpl.h"
|
||||
#include "HttpResponseImpl.h"
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <drogon/WebSocketConnection.h>
|
||||
#include <drogon/HttpResponse.h>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <trantor/net/TcpConnection.h>
|
||||
|
@ -36,7 +36,7 @@
|
|||
using namespace trantor;
|
||||
namespace drogon
|
||||
{
|
||||
class HttpContext
|
||||
class HttpServerContext
|
||||
{
|
||||
public:
|
||||
enum HttpRequestParseState
|
||||
|
@ -47,54 +47,22 @@ class HttpContext
|
|||
kGotAll,
|
||||
};
|
||||
|
||||
enum class HttpResponseParseState
|
||||
{
|
||||
kExpectResponseLine,
|
||||
kExpectHeaders,
|
||||
kExpectBody,
|
||||
kExpectChunkLen,
|
||||
kExpectChunkBody,
|
||||
kExpectLastEmptyChunk,
|
||||
kExpectClose,
|
||||
kGotAll,
|
||||
};
|
||||
|
||||
HttpContext(const trantor::TcpConnectionPtr &connPtr);
|
||||
HttpServerContext(const trantor::TcpConnectionPtr &connPtr);
|
||||
|
||||
// default copy-ctor, dtor and assignment are fine
|
||||
|
||||
// return false if any error
|
||||
bool parseRequest(MsgBuffer *buf);
|
||||
bool parseResponse(MsgBuffer *buf);
|
||||
|
||||
bool gotAll() const
|
||||
{
|
||||
return state_ == kGotAll;
|
||||
}
|
||||
|
||||
bool resGotAll() const
|
||||
{
|
||||
return res_state_ == HttpResponseParseState::kGotAll;
|
||||
}
|
||||
|
||||
bool resExpectResponseLine() const
|
||||
{
|
||||
return res_state_ == HttpResponseParseState::kExpectResponseLine;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
state_ = kExpectRequestLine;
|
||||
res_state_ = HttpResponseParseState::kExpectResponseLine;
|
||||
request_.reset(new HttpRequestImpl);
|
||||
// HttpResponseImpl dummy_res;
|
||||
// response_.swap(dummy_res);
|
||||
}
|
||||
|
||||
void resetRes()
|
||||
{
|
||||
res_state_ = HttpResponseParseState::kExpectResponseLine;
|
||||
response_.clear();
|
||||
}
|
||||
|
||||
const HttpRequestPtr request() const
|
||||
|
@ -112,19 +80,6 @@ class HttpContext
|
|||
return request_;
|
||||
}
|
||||
|
||||
const HttpResponse &response() const
|
||||
{
|
||||
return response_;
|
||||
}
|
||||
|
||||
HttpResponse &response()
|
||||
{
|
||||
return response_;
|
||||
}
|
||||
HttpResponseImpl &responseImpl()
|
||||
{
|
||||
return response_;
|
||||
}
|
||||
bool firstReq()
|
||||
{
|
||||
if (_firstRequest)
|
||||
|
@ -152,13 +107,10 @@ class HttpContext
|
|||
|
||||
private:
|
||||
bool processRequestLine(const char *begin, const char *end);
|
||||
bool processResponseLine(const char *begin, const char *end);
|
||||
|
||||
HttpRequestParseState state_;
|
||||
HttpRequestImplPtr request_;
|
||||
|
||||
HttpResponseParseState res_state_;
|
||||
HttpResponseImpl response_;
|
||||
bool _firstRequest = true;
|
||||
WebSocketConnectionPtr _websockConnPtr;
|
||||
|
Loading…
Reference in New Issue