NetServices: Remove BHttpRequest::SerializeTo(BDataIO*)
The private version that serializes to a HttpBuffer is now used. Change-Id: I034933a641e98b3a8f918470a024ba32ea7c8663
This commit is contained in:
@@ -825,26 +825,6 @@ namespace Network {
|
|||||||
//! @{
|
//! @{
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\fn ssize_t BHttpRequest::SerializeHeaderTo(BDataIO *target) const
|
|
||||||
\brief Serialize the HTTP Header of this request to the \a target.
|
|
||||||
|
|
||||||
The HTTP header consists of the request line, and the fields, serialized as text according to
|
|
||||||
the HTTP specification.
|
|
||||||
|
|
||||||
\param target The \ref BDataIO object to write the header to
|
|
||||||
|
|
||||||
\return The total number of byte size of the header.
|
|
||||||
|
|
||||||
\exception BSystemError In case there is an error when calling the \ref BDataIO::Write() call
|
|
||||||
of the provided \a target. Note that writing the string is \em not transactional, and that
|
|
||||||
the error can occur while a part of the header has already been written.
|
|
||||||
\exception std::bad_alloc In case it is not possible to allocate internal buffers.
|
|
||||||
|
|
||||||
\since Haiku R1
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn BString BHttpRequest::HeaderToString() const
|
\fn BString BHttpRequest::HeaderToString() const
|
||||||
\brief Serialize the HTTP Header of this request to a string.
|
\brief Serialize the HTTP Header of this request to a string.
|
||||||
|
|||||||
@@ -131,7 +131,6 @@ public:
|
|||||||
std::unique_ptr<BDataIO> ClearRequestBody() noexcept;
|
std::unique_ptr<BDataIO> ClearRequestBody() noexcept;
|
||||||
|
|
||||||
// Serialization
|
// Serialization
|
||||||
ssize_t SerializeHeaderTo(BDataIO* target) const;
|
|
||||||
BString HeaderToString() const;
|
BString HeaderToString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ HttpBuffer::GetNextLine()
|
|||||||
\brief Get the number of remaining bytes in this buffer.
|
\brief Get the number of remaining bytes in this buffer.
|
||||||
*/
|
*/
|
||||||
size_t
|
size_t
|
||||||
HttpBuffer::RemainingBytes() noexcept
|
HttpBuffer::RemainingBytes() const noexcept
|
||||||
{
|
{
|
||||||
return fBuffer.size() - fCurrentOffset;
|
return fBuffer.size() - fCurrentOffset;
|
||||||
}
|
}
|
||||||
@@ -182,6 +182,20 @@ HttpBuffer::Clear() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Get a view over the current data
|
||||||
|
*/
|
||||||
|
std::string_view
|
||||||
|
HttpBuffer::Data() const noexcept
|
||||||
|
{
|
||||||
|
if (RemainingBytes() > 0) {
|
||||||
|
return std::string_view(reinterpret_cast<const char*>(fBuffer.data()) + fCurrentOffset,
|
||||||
|
RemainingBytes());
|
||||||
|
} else
|
||||||
|
return std::string_view();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Load data into the buffer
|
\brief Load data into the buffer
|
||||||
|
|
||||||
|
|||||||
@@ -32,11 +32,13 @@ public:
|
|||||||
std::optional<size_t> maxSize = std::nullopt);
|
std::optional<size_t> maxSize = std::nullopt);
|
||||||
std::optional<BString> GetNextLine();
|
std::optional<BString> GetNextLine();
|
||||||
|
|
||||||
size_t RemainingBytes() noexcept;
|
size_t RemainingBytes() const noexcept;
|
||||||
|
|
||||||
void Flush() noexcept;
|
void Flush() noexcept;
|
||||||
void Clear() noexcept;
|
void Clear() noexcept;
|
||||||
|
|
||||||
|
std::string_view Data() const noexcept;
|
||||||
|
|
||||||
// load data into the buffer
|
// load data into the buffer
|
||||||
HttpBuffer& operator<<(const std::string_view& data);
|
HttpBuffer& operator<<(const std::string_view& data);
|
||||||
|
|
||||||
|
|||||||
@@ -433,99 +433,13 @@ BHttpRequest::ClearRequestBody() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[[nodiscard]] static inline ssize_t
|
|
||||||
_write_to_dataio(BDataIO* target, const std::string_view& data)
|
|
||||||
{
|
|
||||||
if (auto status = target->WriteExactly(data.data(), data.size()); status != B_OK)
|
|
||||||
throw BSystemError("BDataIO::WriteExactly()", status);
|
|
||||||
return data.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[[nodiscard]] static inline ssize_t
|
|
||||||
_write_to_dataio(BDataIO* target, const BString& string)
|
|
||||||
{
|
|
||||||
auto length = string.Length();
|
|
||||||
if (auto status = target->WriteExactly(string.String(), length); status != B_OK)
|
|
||||||
throw BSystemError("BDataIO::WriteExactly()", status);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
BHttpRequest::SerializeHeaderTo(BDataIO* target) const
|
|
||||||
{
|
|
||||||
auto bytesWritten = _write_to_dataio(target, fData->method.Method());
|
|
||||||
bytesWritten += _write_to_dataio(target, " "sv);
|
|
||||||
|
|
||||||
// TODO: proxy
|
|
||||||
|
|
||||||
if (fData->url.HasPath() && fData->url.Path().Length() > 0)
|
|
||||||
bytesWritten += _write_to_dataio(target, fData->url.Path());
|
|
||||||
else
|
|
||||||
bytesWritten += _write_to_dataio(target, "/"sv);
|
|
||||||
|
|
||||||
// TODO: switch between HTTP 1.0 and 1.1 based on configuration
|
|
||||||
bytesWritten += _write_to_dataio(target, " HTTP/1.1\r\n"sv);
|
|
||||||
|
|
||||||
BHttpFields outputFields;
|
|
||||||
if (true /* http == 1.1 */) {
|
|
||||||
BString host = fData->url.Host();
|
|
||||||
int defaultPort = fData->url.Protocol() == "http" ? 80 : 443;
|
|
||||||
if (fData->url.HasPort() && fData->url.Port() != defaultPort)
|
|
||||||
host << ':' << fData->url.Port();
|
|
||||||
|
|
||||||
outputFields.AddFields({
|
|
||||||
{"Host"sv, std::string_view(host.String())},
|
|
||||||
{"Accept-Encoding"sv, "gzip"sv},
|
|
||||||
// Allows the server to compress data using the "gzip" format.
|
|
||||||
// "deflate" is not supported, because there are two interpretations
|
|
||||||
// of what it means (the RFC and Microsoft products), and we don't
|
|
||||||
// want to handle this. Very few websites support only deflate,
|
|
||||||
// and most of them will send gzip, or at worst, uncompressed data.
|
|
||||||
{"Connection"sv, "close"sv}
|
|
||||||
// Let the remote server close the connection after response since
|
|
||||||
// we don't handle multiple request on a single connection
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fData->authentication) {
|
|
||||||
// This request will add a Basic authorization header
|
|
||||||
BString authorization = build_basic_http_header(fData->authentication->username,
|
|
||||||
fData->authentication->password);
|
|
||||||
outputFields.AddField("Authorization"sv, std::string_view(authorization.String()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fData->requestBody) {
|
|
||||||
outputFields.AddField("Content-Type"sv, std::string_view(fData->requestBody->mimeType.String()));
|
|
||||||
if (fData->requestBody->size)
|
|
||||||
outputFields.AddField("Content-Length"sv, std::to_string(*fData->requestBody->size));
|
|
||||||
else
|
|
||||||
throw BRuntimeError(__PRETTY_FUNCTION__, "Transfer body with unknown content length; chunked transfer not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& field: outputFields) {
|
|
||||||
bytesWritten += _write_to_dataio(target, field.RawField());
|
|
||||||
bytesWritten += _write_to_dataio(target, "\r\n"sv);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& field: fData->optionalFields) {
|
|
||||||
bytesWritten += _write_to_dataio(target, field.RawField());
|
|
||||||
bytesWritten += _write_to_dataio(target, "\r\n"sv);
|
|
||||||
}
|
|
||||||
|
|
||||||
bytesWritten += _write_to_dataio(target, "\r\n"sv);
|
|
||||||
return bytesWritten;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BString
|
BString
|
||||||
BHttpRequest::HeaderToString() const
|
BHttpRequest::HeaderToString() const
|
||||||
{
|
{
|
||||||
BMallocIO buffer;
|
HttpBuffer buffer;
|
||||||
auto size = SerializeHeaderTo(&buffer);
|
SerializeHeaderTo(buffer);
|
||||||
|
|
||||||
return BString(static_cast<const char*>(buffer.Buffer()), size);
|
return BString(static_cast<const char*>(buffer.Data().data()), buffer.RemainingBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user