From 6d1bb0e7ad1ab679f07729d00b6a1dadf7500736 Mon Sep 17 00:00:00 2001 From: Niels Sascha Reedijk Date: Sun, 7 Aug 2022 07:17:38 +0100 Subject: [PATCH] NetServices: Remove BHttpRequest::SerializeTo(BDataIO*) The private version that serializes to a HttpBuffer is now used. Change-Id: I034933a641e98b3a8f918470a024ba32ea7c8663 --- docs/user/netservices/HttpRequest.dox | 20 ---- headers/private/netservices2/HttpRequest.h | 1 - .../network/libnetservices2/HttpBuffer.cpp | 16 +++- src/kits/network/libnetservices2/HttpBuffer.h | 4 +- .../network/libnetservices2/HttpRequest.cpp | 92 +------------------ 5 files changed, 21 insertions(+), 112 deletions(-) diff --git a/docs/user/netservices/HttpRequest.dox b/docs/user/netservices/HttpRequest.dox index 5b5c137da0..796f740c15 100644 --- a/docs/user/netservices/HttpRequest.dox +++ b/docs/user/netservices/HttpRequest.dox @@ -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 \brief Serialize the HTTP Header of this request to a string. diff --git a/headers/private/netservices2/HttpRequest.h b/headers/private/netservices2/HttpRequest.h index da41e3ab66..dd72b6b296 100644 --- a/headers/private/netservices2/HttpRequest.h +++ b/headers/private/netservices2/HttpRequest.h @@ -131,7 +131,6 @@ public: std::unique_ptr ClearRequestBody() noexcept; // Serialization - ssize_t SerializeHeaderTo(BDataIO* target) const; BString HeaderToString() const; private: diff --git a/src/kits/network/libnetservices2/HttpBuffer.cpp b/src/kits/network/libnetservices2/HttpBuffer.cpp index 07c64c39d5..c0cb8123c8 100644 --- a/src/kits/network/libnetservices2/HttpBuffer.cpp +++ b/src/kits/network/libnetservices2/HttpBuffer.cpp @@ -147,7 +147,7 @@ HttpBuffer::GetNextLine() \brief Get the number of remaining bytes in this buffer. */ size_t -HttpBuffer::RemainingBytes() noexcept +HttpBuffer::RemainingBytes() const noexcept { 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(fBuffer.data()) + fCurrentOffset, + RemainingBytes()); + } else + return std::string_view(); +} + + /*! \brief Load data into the buffer diff --git a/src/kits/network/libnetservices2/HttpBuffer.h b/src/kits/network/libnetservices2/HttpBuffer.h index 983b6d64fe..dd268227bd 100644 --- a/src/kits/network/libnetservices2/HttpBuffer.h +++ b/src/kits/network/libnetservices2/HttpBuffer.h @@ -32,11 +32,13 @@ public: std::optional maxSize = std::nullopt); std::optional GetNextLine(); - size_t RemainingBytes() noexcept; + size_t RemainingBytes() const noexcept; void Flush() noexcept; void Clear() noexcept; + std::string_view Data() const noexcept; + // load data into the buffer HttpBuffer& operator<<(const std::string_view& data); diff --git a/src/kits/network/libnetservices2/HttpRequest.cpp b/src/kits/network/libnetservices2/HttpRequest.cpp index c254adb0db..497ada8468 100644 --- a/src/kits/network/libnetservices2/HttpRequest.cpp +++ b/src/kits/network/libnetservices2/HttpRequest.cpp @@ -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 BHttpRequest::HeaderToString() const { - BMallocIO buffer; - auto size = SerializeHeaderTo(&buffer); + HttpBuffer buffer; + SerializeHeaderTo(buffer); - return BString(static_cast(buffer.Buffer()), size); + return BString(static_cast(buffer.Data().data()), buffer.RemainingBytes()); }