Skip to content

Commit bffc90f

Browse files
committed
Add setting chunk callback to http request
1 parent e155df9 commit bffc90f

File tree

6 files changed

+87
-3
lines changed

6 files changed

+87
-3
lines changed

examples/client_example/main.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ int nth_resp = 0;
1414

1515
int main()
1616
{
17+
#if 1
1718
trantor::Logger::setLogLevel(trantor::Logger::kTrace);
1819
{
1920
auto client = HttpClient::newHttpClient("http://www.baidu.com");
@@ -75,6 +76,28 @@ int main()
7576
std::cout << "requestsBufferSize:" << client->requestsBufferSize()
7677
<< std::endl;
7778
}
79+
#else
80+
{
81+
auto client = HttpClient::newHttpClient("http://127.0.0.1:8848/stream");
7882
83+
auto req = HttpRequest::newHttpRequest();
84+
req->setMethod(drogon::Get);
85+
req->setPath("/stream");
86+
req->setChunkCallback([](ResponseChunk ch) {
87+
std::cout << "recv chunk:" << ch.data() << std::endl;
88+
});
89+
client->sendRequest(
90+
req, [](ReqResult result, const HttpResponsePtr &response) {
91+
if (result != ReqResult::Ok)
92+
{
93+
std::cout
94+
<< "error while sending request to server! result: "
95+
<< result << std::endl;
96+
return;
97+
}
98+
std::cout << "recv chunk done" << std::endl;
99+
});
100+
}
101+
#endif
79102
app().run();
80103
}

lib/inc/drogon/HttpRequest.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#include <trantor/net/InetAddress.h>
2626
#include <trantor/net/Certificate.h>
2727
#include <trantor/utils/Date.h>
28+
#include <cstddef>
29+
#include <functional>
2830
#include <memory>
2931
#include <string>
3032
#include <unordered_map>
@@ -37,6 +39,32 @@ namespace drogon
3739
class HttpRequest;
3840
using HttpRequestPtr = std::shared_ptr<HttpRequest>;
3941

42+
class DROGON_EXPORT ResponseChunk
43+
{
44+
public:
45+
ResponseChunk() = default;
46+
47+
ResponseChunk(const char *s, std::size_t count)
48+
{
49+
data_.append(s, count);
50+
}
51+
52+
~ResponseChunk() = default;
53+
54+
ResponseChunk(const ResponseChunk &other) = default;
55+
ResponseChunk(ResponseChunk &&other) noexcept = default;
56+
ResponseChunk &operator=(const ResponseChunk &other) noexcept = default;
57+
ResponseChunk &operator=(ResponseChunk &&other) noexcept = default;
58+
59+
auto &data()
60+
{
61+
return data_;
62+
}
63+
64+
private:
65+
std::string data_;
66+
};
67+
4068
/**
4169
* @brief This template is used to convert a request object to a custom
4270
* type object. Users must specialize the template for a particular type.
@@ -510,6 +538,12 @@ class DROGON_EXPORT HttpRequest
510538
virtual const std::weak_ptr<trantor::TcpConnection> &getConnectionPtr()
511539
const noexcept = 0;
512540

541+
virtual void setChunkCallback(
542+
std::function<void(ResponseChunk)>) noexcept = 0;
543+
544+
virtual const std::function<void(ResponseChunk)> &getChunkCallback()
545+
const noexcept = 0;
546+
513547
virtual ~HttpRequest()
514548
{
515549
}

lib/src/HttpClientImpl.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,8 @@ void HttpClientImpl::onRecvMessage(const trantor::TcpConnectionPtr &connPtr,
618618
{
619619
responseParser->setForHeadMethod();
620620
}
621-
if (!responseParser->parseResponse(msg))
621+
if (!responseParser->parseResponse(msg,
622+
firstReq.first->getChunkCallback()))
622623
{
623624
onError(ReqResult::BadResponse);
624625
bytesReceived_ += (msgSize - msg->readableBytes());

lib/src/HttpRequestImpl.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,18 @@ class HttpRequestImpl : public HttpRequest
579579
return connPtr_;
580580
}
581581

582+
void setChunkCallback(
583+
std::function<void(ResponseChunk)> cb) noexcept override
584+
{
585+
chunkCb_ = std::move(cb);
586+
}
587+
588+
const std::function<void(ResponseChunk)> &getChunkCallback()
589+
const noexcept override
590+
{
591+
return chunkCb_;
592+
}
593+
582594
bool isOnSecureConnection() const noexcept override
583595
{
584596
return isOnSecureConnection_;
@@ -731,6 +743,7 @@ class HttpRequestImpl : public HttpRequest
731743
std::exception_ptr streamExceptionPtr_;
732744
bool startProcessing_{false};
733745
std::weak_ptr<trantor::TcpConnection> connPtr_;
746+
std::function<void(ResponseChunk)> chunkCb_;
734747

735748
protected:
736749
std::string content_;

lib/src/HttpResponseParser.cc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <trantor/utils/Logger.h>
1818
#include <trantor/utils/MsgBuffer.h>
1919
#include <algorithm>
20+
#include <string>
2021

2122
using namespace trantor;
2223
using namespace drogon;
@@ -84,7 +85,9 @@ bool HttpResponseParser::parseResponseOnClose()
8485
}
8586

8687
// return false if any error
87-
bool HttpResponseParser::parseResponse(MsgBuffer *buf)
88+
bool HttpResponseParser::parseResponse(
89+
MsgBuffer *buf,
90+
const std::function<void(ResponseChunk)> &chunkCallback)
8891
{
8992
bool ok = true;
9093
bool hasMore = true;
@@ -277,6 +280,11 @@ bool HttpResponseParser::parseResponse(MsgBuffer *buf)
277280
responsePtr_->bodyPtr_ =
278281
std::make_shared<HttpMessageStringBody>();
279282
}
283+
if (chunkCallback)
284+
{
285+
chunkCallback(
286+
ResponseChunk(buf->peek(), currentChunkLength_));
287+
}
280288
responsePtr_->bodyPtr_->append(buf->peek(),
281289
currentChunkLength_);
282290
buf->retrieve(currentChunkLength_ + 2);

lib/src/HttpResponseParser.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
#pragma once
1616

1717
#include "impl_forwards.h"
18+
#include <drogon/HttpRequest.h>
1819
#include <trantor/utils/NonCopyable.h>
1920
#include <trantor/net/TcpConnection.h>
2021
#include <trantor/utils/MsgBuffer.h>
22+
#include <functional>
2123
#include <list>
2224
#include <mutex>
2325

@@ -43,7 +45,10 @@ class HttpResponseParser : public trantor::NonCopyable
4345
// default copy-ctor, dtor and assignment are fine
4446

4547
// return false if any error
46-
bool parseResponse(trantor::MsgBuffer *buf);
48+
bool parseResponse(
49+
trantor::MsgBuffer *buf,
50+
const std::function<void(ResponseChunk)> &chunkCallback = nullptr);
51+
4752
bool parseResponseOnClose();
4853

4954
bool gotAll() const

0 commit comments

Comments
 (0)