Fix HTTP response parsing bug
This commit is contained in:
parent
e28716c343
commit
2391cc1484
|
@ -6,23 +6,15 @@
|
|||
int main()
|
||||
{
|
||||
trantor::Logger::setLogLevel(trantor::Logger::TRACE);
|
||||
struct hostent* he = gethostbyname("www.baidu.com");
|
||||
struct in_addr addr;
|
||||
|
||||
if (he && he->h_addrtype == AF_INET) {
|
||||
addr = *reinterpret_cast<struct in_addr*>(he->h_addr);
|
||||
struct sockaddr_in ad;
|
||||
bzero(&ad, sizeof ad);
|
||||
ad.sin_family = AF_INET;
|
||||
ad.sin_addr=addr;
|
||||
trantor::InetAddress netaddr(ad);
|
||||
auto client=HttpClient::newHttpClient(netaddr.toIp(),80);
|
||||
auto client=HttpClient::newHttpClient("http://www.baidu.com");
|
||||
auto req=HttpRequest::newHttpRequest();
|
||||
req->setMethod(drogon::HttpRequest::kGet);
|
||||
req->setPath("/s");
|
||||
req->setParameter("wd","weixin");
|
||||
int count=0;
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
client->sendRequest(req,[&](ReqResult result,const HttpResponse &response){
|
||||
std::cout<<"receive response!"<<std::endl;
|
||||
//auto headers=response.
|
||||
|
@ -30,8 +22,8 @@ int main()
|
|||
std::cout<<response.getBody()<<std::endl;
|
||||
std::cout<<"count="<<count<<std::endl;
|
||||
});
|
||||
HttpAppFramework::instance().run();
|
||||
} else {
|
||||
std::cout<<"can't find the host"<<std::endl;
|
||||
}
|
||||
|
||||
HttpAppFramework::instance().run();
|
||||
|
||||
}
|
|
@ -35,7 +35,7 @@ namespace drogon{
|
|||
virtual void sendRequest(const HttpRequestPtr &req,const HttpReqCallback &callback)=0;
|
||||
virtual ~HttpClient(){}
|
||||
static HttpClientPtr newHttpClient(const std::string &ip,uint16_t port,bool useSSL=false) ;
|
||||
static HttpClientPtr newHttpClient(const trantor::InetAddress &addr,bool useSSL=false) ;
|
||||
// static HttpClientPtr newHttpClient(const trantor::InetAddress &addr,bool useSSL=false) ;
|
||||
static HttpClientPtr newHttpClient(const std::string &hostString);
|
||||
protected:
|
||||
HttpClient()= default;
|
||||
|
|
|
@ -187,7 +187,7 @@ void HttpClientImpl::onRecvMessage(const trantor::TcpConnectionPtr &connPtr,tran
|
|||
{
|
||||
HttpContext* context = any_cast<HttpContext>(connPtr->getMutableContext());
|
||||
|
||||
LOG_TRACE << "###:" << msg->readableBytes();
|
||||
//LOG_TRACE << "###:" << msg->readableBytes();
|
||||
if (!context->parseResponse(msg)) {
|
||||
assert(!_reqAndCallbacks.empty());
|
||||
auto cb=_reqAndCallbacks.front().second;
|
||||
|
@ -231,11 +231,10 @@ HttpClientPtr HttpClient::newHttpClient(const std::string &ip,uint16_t port,bool
|
|||
{
|
||||
return std::make_shared<HttpClientImpl>(((HttpAppFrameworkImpl &)(HttpAppFramework::instance())).loop(),trantor::InetAddress(ip,port),useSSL);
|
||||
}
|
||||
|
||||
HttpClientPtr HttpClient::newHttpClient(const trantor::InetAddress &addr,bool useSSL)
|
||||
{
|
||||
return std::make_shared<HttpClientImpl>(((HttpAppFrameworkImpl &)(HttpAppFramework::instance())).loop(),addr,useSSL);
|
||||
}
|
||||
//HttpClientPtr HttpClient::newHttpClient(const trantor::InetAddress &addr,bool useSSL)
|
||||
//{
|
||||
// return std::make_shared<HttpClientImpl>(((HttpAppFrameworkImpl &)(HttpAppFramework::instance())).loop(),addr,useSSL);
|
||||
//}
|
||||
HttpClientPtr HttpClient::newHttpClient(const std::string &hostString)
|
||||
{
|
||||
return std::make_shared<HttpClientImpl>(((HttpAppFrameworkImpl &)(HttpAppFramework::instance())).loop(),hostString);
|
||||
|
|
|
@ -374,7 +374,7 @@ bool HttpContext::parseResponse(MsgBuffer *buf)
|
|||
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;
|
||||
//LOG_TRACE << "chun length : " << response_._current_chunk_length;
|
||||
if (response_._current_chunk_length != 0)
|
||||
{
|
||||
res_state_ = HttpResponseParseState::kExpectChunkBody;
|
||||
|
@ -392,28 +392,27 @@ bool HttpContext::parseResponse(MsgBuffer *buf)
|
|||
}
|
||||
else if (res_state_ == HttpResponseParseState::kExpectChunkBody)
|
||||
{
|
||||
const char *crlf = buf->findCRLF();
|
||||
if (crlf)
|
||||
//LOG_TRACE<<"expect chunk len="<<response_._current_chunk_length;
|
||||
if(buf->readableBytes()>=(response_._current_chunk_length+2))
|
||||
{
|
||||
if (response_._current_chunk_length == (size_t)(crlf - buf->peek()))
|
||||
if(*(buf->peek()+response_._current_chunk_length)=='\r'&&
|
||||
*(buf->peek()+response_._current_chunk_length+1)=='\n' )
|
||||
{
|
||||
//current chunk end crlf
|
||||
response_._body += std::string(buf->peek(), response_._current_chunk_length);
|
||||
buf->retrieveUntil(crlf + 2);
|
||||
buf->retrieve(response_._current_chunk_length+2);
|
||||
response_._current_chunk_length = 0;
|
||||
res_state_ = HttpResponseParseState::kExpectChunkLen;
|
||||
}
|
||||
else if (response_._current_chunk_length > (size_t)(crlf - buf->peek()))
|
||||
else
|
||||
{
|
||||
//current chunk body crlf
|
||||
response_._body += std::string(buf->peek(), crlf - buf->peek() + 1);
|
||||
buf->retrieveUntil(crlf + 2);
|
||||
response_._current_chunk_length -= (crlf - buf->peek() + 2);
|
||||
//error!
|
||||
buf->retrieveAll();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hasMore = false;
|
||||
hasMore=false;
|
||||
}
|
||||
}
|
||||
else if (res_state_ == HttpResponseParseState::kExpectLastEmptyChunk)
|
||||
|
|
|
@ -128,7 +128,9 @@ namespace drogon
|
|||
|
||||
virtual std::string getHeader(const std::string& key) const override
|
||||
{
|
||||
auto iter=_headers.find(key);
|
||||
auto field=key;
|
||||
transform(field.begin(), field.end(), field.begin(), ::tolower);
|
||||
auto iter=_headers.find(field);
|
||||
if(iter == _headers.end())
|
||||
{
|
||||
return "";
|
||||
|
@ -140,12 +142,15 @@ namespace drogon
|
|||
}
|
||||
virtual void addHeader(const std::string& key, const std::string& value) override
|
||||
{
|
||||
_headers[key] = value;
|
||||
auto field=key;
|
||||
transform(field.begin(), field.end(), field.begin(), ::tolower);
|
||||
_headers[field] = value;
|
||||
}
|
||||
|
||||
virtual void addHeader(const char* start, const char* colon, const char* end) override
|
||||
{
|
||||
std::string field(start, colon);
|
||||
transform(field.begin(), field.end(), field.begin(), ::tolower);
|
||||
++colon;
|
||||
while (colon < end && isspace(*colon)) {
|
||||
++colon;
|
||||
|
@ -155,7 +160,8 @@ namespace drogon
|
|||
value.resize(value.size() - 1);
|
||||
}
|
||||
_headers[field] = value;
|
||||
transform(field.begin(), field.end(), field.begin(), ::tolower);
|
||||
|
||||
//FIXME:reponse cookie should be "Set-Cookie:...."
|
||||
if(field == "cookie") {
|
||||
//LOG_INFO<<"cookies!!!:"<<value;
|
||||
std::string::size_type pos;
|
||||
|
|
2
trantor
2
trantor
|
@ -1 +1 @@
|
|||
Subproject commit ca985eac44b2a4d0a6ac3498bac9973e4c52ddfe
|
||||
Subproject commit 6cb562a6cced825dcd15732be0990c8a7e0ab112
|
Loading…
Reference in New Issue