starrocks/thirdparty/patches/poco-1.12.5-zero-copy.patch

144 lines
4.1 KiB
Diff

diff --git a/Net/include/Poco/Net/HTTPClientSession.h b/Net/include/Poco/Net/HTTPClientSession.h
--- a/Net/include/Poco/Net/HTTPClientSession.h
+++ b/Net/include/Poco/Net/HTTPClientSession.h
@@ -390,6 +390,7 @@ private:
HTTPClientSession(const HTTPClientSession&);
HTTPClientSession& operator = (const HTTPClientSession&);
+ void readDataToResponseIOStream(HTTPResponse& response);
friend class WebSocket;
};
diff --git a/Net/include/Poco/Net/HTTPResponse.h b/Net/include/Poco/Net/HTTPResponse.h
--- a/Net/include/Poco/Net/HTTPResponse.h
+++ b/Net/include/Poco/Net/HTTPResponse.h
@@ -112,6 +112,8 @@ public:
HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511
};
+ typedef std::basic_iostream< char, std::char_traits< char > > IOStream;
+
HTTPResponse();
/// Creates the HTTPResponse with OK status.
@@ -168,6 +170,22 @@ public:
///
/// The reason phrase is set according to the status code.
+
+ void setResponseIOStream(IOStream* ioStream, unsigned char* buffer, size_t size);
+ /// Sets the pre allocated iostream, buffer and size, used for zero-copy
+
+ IOStream* getResponseIOStream();
+ /// Returns the pre allocated iostream
+
+ unsigned char* getPreAllocatedBuffer();
+ /// Returns the pre allocated buffer, use to fill data
+
+ bool isPreAllocated();
+
+ void setBodyFilled(bool bodyFilled);
+
+ bool isBodyFilled();
+
void setDate(const Poco::Timestamp& dateTime);
/// Sets the Date header to the given date/time value.
@@ -276,6 +294,10 @@ private:
HTTPStatus _status;
std::string _reason;
+ IOStream* _io_stream = nullptr;
+ unsigned char* _buffer = nullptr;
+ size_t _size = 0;
+ bool _is_body_filled = false;
};
diff --git a/Net/src/HTTPClientSession.cpp b/Net/src/HTTPClientSession.cpp
--- a/Net/src/HTTPClientSession.cpp
+++ b/Net/src/HTTPClientSession.cpp
@@ -380,7 +380,15 @@ std::istream& HTTPClientSession::receiveResponse(HTTPResponse& response)
_pResponseStream = new HTTPChunkedInputStream(*this, &responseTrailer());
else if (response.hasContentLength())
#if defined(POCO_HAVE_INT64)
- _pResponseStream = new HTTPFixedLengthInputStream(*this, response.getContentLength64());
+ {
+ if (!response.isPreAllocated())
+ _pResponseStream = new HTTPFixedLengthInputStream(*this, response.getContentLength64());
+ else
+ {
+ readDataToResponseIOStream(response);
+ return *response.getResponseIOStream();
+ }
+ }
#else
_pResponseStream = new HTTPFixedLengthInputStream(*this, response.getContentLength());
#endif
@@ -388,6 +396,24 @@ std::istream& HTTPClientSession::receiveResponse(HTTPResponse& response)
_pResponseStream = new HTTPInputStream(*this);
return *_pResponseStream;
+
+}
+
+void HTTPClientSession::readDataToResponseIOStream(HTTPResponse& response) {
+ auto ioStream = response.getResponseIOStream();
+ auto length = response.getContentLength64();
+ char* buffer = reinterpret_cast<char *>(response.getPreAllocatedBuffer());
+ auto n = read(buffer, length);
+ auto current = n;
+ while (n > 0 && current < length) {
+ n = read(buffer + current, length - current);
+ current += n;
+ }
+ if (n <= 0) {
+ throw IllegalStateException("Poco socket read operation failed");
+ }
+ response.setBodyFilled(true);
+ return;
}
diff --git a/Net/src/HTTPResponse.cpp b/Net/src/HTTPResponse.cpp
--- a/Net/src/HTTPResponse.cpp
+++ b/Net/src/HTTPResponse.cpp
@@ -196,6 +196,37 @@ void HTTPResponse::setStatusAndReason(HTTPStatus status)
setStatusAndReason(status, getReasonForStatus(status));
}
+void HTTPResponse::setResponseIOStream(IOStream* ioStream, unsigned char* buffer, size_t size)
+{
+ _io_stream = ioStream;
+ _buffer = buffer;
+ _size = size;
+}
+
+HTTPResponse::IOStream* HTTPResponse::getResponseIOStream()
+{
+ return _io_stream;
+}
+
+unsigned char* HTTPResponse::getPreAllocatedBuffer()
+{
+ return _buffer;
+}
+
+bool HTTPResponse::isPreAllocated()
+{
+ return _size > 0 && _size >= getContentLength64();
+}
+
+void HTTPResponse::setBodyFilled(bool bodyFilled)
+{
+ _is_body_filled = bodyFilled;
+}
+
+bool HTTPResponse::isBodyFilled()
+{
+ return _is_body_filled;
+}
void HTTPResponse::setDate(const Poco::Timestamp& dateTime)
{