NetServices: Remove BHttpRequest::SerializeTo(BDataIO*)

The private version that serializes to a HttpBuffer is now used.

Change-Id: I034933a641e98b3a8f918470a024ba32ea7c8663
This commit is contained in:
Niels Sascha Reedijk
2022-08-07 07:17:38 +01:00
parent c7f925c3ee
commit 6d1bb0e7ad
5 changed files with 21 additions and 112 deletions
-20
View File
@@ -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());
} }