mirror of
https://review.haiku-os.org/haiku
synced 2025-01-31 10:47:14 +01:00
13bfff7be3
The user of the API can set whether redirects should be followed, and if so, how many. This is part of the BHttpRequest API. The BHttpSession then follows those instructions, and executes the maximum number of redirects the user would like to follow. As part of this commit, the BHttpStatusClass and BHttpStatusCodes helper enums have been added, to give a friendlier access to HTTP status codes and status classes. Change-Id: Ic8c9e3fda158e2cce549c8f1d360951f7ac83311
629 lines
14 KiB
Plaintext
629 lines
14 KiB
Plaintext
/*
|
|
* Copyright 2022 Haiku, Inc. All rights reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Niels Sascha Reedijk, niels.reedijk@gmail.com
|
|
*
|
|
* Corresponds to:
|
|
* headers/private/netservices2/HttpRequest.h hrev?????
|
|
* src/kits/network/libnetservices2/HttpRequest.cpp hrev?????
|
|
*/
|
|
|
|
|
|
#if __cplusplus >= 201703L
|
|
|
|
|
|
/*!
|
|
\file HttpRequest.h
|
|
\ingroup netservices
|
|
\brief Provides the classes and tools to build HTTP Requests.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
namespace BPrivate {
|
|
|
|
namespace Network {
|
|
|
|
|
|
/*!
|
|
\class BHttpMethod
|
|
\ingroup netservices
|
|
\brief Represent a HTTP method.
|
|
|
|
The <a href="https://datatracker.ietf.org/doc/html/rfc7231#section-4.1">HTTP standard</a>
|
|
specifies that HTTP requests have a method. Common methods are \c GET and \c HEAD methods.
|
|
Standardized and common methods are in the form of \em verbs and are in capitalized letters
|
|
from the ASCII token set, though any valid token can be used.
|
|
|
|
It is most likely that you will not use the methods of this class directly, instead you will
|
|
use the implicit constructors while interacting with the \ref BHttpRequest class.
|
|
|
|
\code
|
|
auto url = BUrl("https://www.haiku-os.org/");
|
|
// implicitly construct a standard get request
|
|
auto standard = BHttpRequest(url, BHttpMethod::Get);
|
|
// implicitly construct a nonstandard patch request
|
|
auto custom = BHttpRequest(url, "PATCH"sv);
|
|
\endcode
|
|
|
|
\note When you are using the standard list of verbs, there will never be an exception when
|
|
creating objects of this type. When you create a custom method, exceptions may be raised
|
|
when the system runs out of memory, or when your custom method contains invalid characters.
|
|
In almost all cases, you can probably safely assume you will not run into these exceptions,
|
|
except for cases where you use user input to create methods or you are very defensive
|
|
about memory management.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\class BHttpMethod::InvalidMethod
|
|
\ingroup netservices
|
|
\brief Error that represents when a custom method does not conform to the HTTP standard.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\var BString BHttpMethod::InvalidMethod::input
|
|
\brief The input that contains the invalid contents.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BHttpMethod::InvalidMethod::InvalidMethod(const char *origin, BString input)
|
|
\brief Constructor that sets the \a origin and the invalid \a input.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\enum BHttpMethod::Verb
|
|
\ingroup netservices
|
|
\brief A list of standard HTTP methods.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\var BHttpMethod::Verb BHttpMethod::Get
|
|
\brief Represents the \c GET method.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\var BHttpMethod::Verb BHttpMethod::Head
|
|
\brief Represents the \c HEAD method.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\var BHttpMethod::Verb BHttpMethod::Post
|
|
\brief Represents the \c POST method.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\var BHttpMethod::Verb BHttpMethod::Put
|
|
\brief Represents the \c PUT method.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\var BHttpMethod::Verb BHttpMethod::Delete
|
|
\brief Represents the \c DELETE method.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\var BHttpMethod::Verb BHttpMethod::Connect
|
|
\brief Represents the \c CONNECT method.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\var BHttpMethod::Verb BHttpMethod::Options
|
|
\brief Represents the \c OPTIONS method.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\var BHttpMethod::Verb BHttpMethod::Trace
|
|
\brief Represents the \c TRACE method.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BHttpMethod::BHttpMethod(BHttpMethod &&other) noexcept
|
|
\brief Move constructor.
|
|
|
|
Moves the data from the \a other to this object. The \a other object will be set to
|
|
\ref BHttpMethod::Get.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BHttpMethod::BHttpMethod(const BHttpMethod &other)
|
|
\brief Copy constructor.
|
|
|
|
Copy data from an \a other object.
|
|
|
|
\exception std::bad_alloc When the \a other object contains a custom verb, this exception
|
|
will be raised if it is impossible to allocate memory.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BHttpMethod::BHttpMethod(const std::string_view &method)
|
|
\brief Construct a custom method.
|
|
|
|
\param method The verb for the method.
|
|
|
|
\exception std::bad_alloc In case it is not possible to allocate memory for the custom string.
|
|
\exception BHttpMethod::InvalidMethod In case the \a method is empty or contains invalid
|
|
characters.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BHttpMethod::BHttpMethod(Verb verb) noexcept
|
|
\brief Construct a standard method.
|
|
|
|
\param verb The chosen method.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BHttpMethod::~BHttpMethod()
|
|
\brief Destructor.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn bool BHttpMethod::operator==(const Verb &other) const noexcept
|
|
\brief Comparison operator.
|
|
|
|
\param other The verb to compare to.
|
|
|
|
\retval true This method is equal to \a other.
|
|
\retval false This method is different from \a other.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn bool BHttpMethod::operator!=(const Verb &other) const noexcept
|
|
\brief Comparison operator.
|
|
|
|
\param other The verb to compare to.
|
|
|
|
\retval true This method is different from \a other.
|
|
\retval false This method is equal to \a other.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn const std::string_view BHttpMethod::Method() const noexcept
|
|
\brief Get a string representation of the method.
|
|
|
|
\return A \c std::string_view that is a string representation of the standard or custom method
|
|
in this object. The lifetime of the string view is bound to the lifetime of this method.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BHttpMethod& BHttpMethod::operator=(BHttpMethod &&other) noexcept
|
|
\brief Move assignment.
|
|
Moves the data from the \a other to this object. The \a other object will be set to
|
|
\ref BHttpMethod::Get.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BHttpMethod& BHttpMethod::operator=(const BHttpMethod &other)
|
|
\brief Copy assignment.
|
|
|
|
Copy data from an \a other object.
|
|
|
|
\exception std::bad_alloc When the \a other object contains a custom verb, this exception
|
|
will be raised if it is impossible to allocate memory.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\struct BHttpRedirectOptions
|
|
\ingroup netservices
|
|
\brief Describe redirection options for a \ref BHttpRequest.
|
|
|
|
\see These options are used by \ref BHttpRequest::Redirect() and
|
|
\ref BHttpRequest::SetRedirect()
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\var bool BHttpRedirectOptions::followRedirect
|
|
\brief Describe whether the request should follow redirects.
|
|
|
|
\see These options are used by \ref BHttpRequest::Redirect() and
|
|
\ref BHttpRequest::SetRedirect()
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\var uint8 BHttpRedirectOptions::maxRedirections
|
|
\brief The maximum number of redirects that should be followed.
|
|
|
|
\see These options are used by \ref BHttpRequest::Redirect() and
|
|
\ref BHttpRequest::SetRedirect()
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\class BHttpRequest
|
|
\ingroup netservices
|
|
\brief Represent a HTTP request.
|
|
|
|
This class can be used to construct HTTP requests that can be executed by the Network Services
|
|
Kit. A request has two states, either it is is a valid request, or it is an empty request. The
|
|
criterium is whether or not the request has a URL.
|
|
|
|
This class has all kinds of convenience methods set and retrieve particular options. Most
|
|
options are wrapped in specialized container classes that do some form of validation.
|
|
|
|
The default options are:
|
|
<table>
|
|
<tr><th>Getter</th><th>Setter</th><th>Description</th><th>Default</th></tr>
|
|
<tr>
|
|
<td> \ref Url() </td>
|
|
<td> \ref SetUrl() </td>
|
|
<td> The URL. This must start with http or https. </td>
|
|
<td> Defaults to an empty \ref BUrl </td>
|
|
</tr>
|
|
<tr>
|
|
<td> \ref Method() </td>
|
|
<td> \ref SetMethod() </td>
|
|
<td> The HTTP method for the request </td>
|
|
<td> Defaults to \ref BHttpMethod::Get </td>
|
|
</tr>
|
|
<tr>
|
|
<td> \ref Redirect() </td>
|
|
<td> \ref SetRedirect() </td>
|
|
<td> Whether redirects should be followed, and if so, how many </td>
|
|
<td> By default redirects are followed, up to 8 redirects for one request </td>
|
|
</tr>
|
|
</table>
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\name Constructors and Destructor
|
|
*/
|
|
|
|
|
|
//! @{
|
|
|
|
|
|
/*!
|
|
\fn BHttpRequest::BHttpRequest()
|
|
\brief Construct an empty HTTP request.
|
|
|
|
\exception std::bad_alloc This exception may be raised if it is impossible to allocate memory.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BHttpRequest::BHttpRequest(const BUrl &url)
|
|
\brief Construct a HTTP request for an \a url.
|
|
|
|
\param url A valid URL with the \c http or \c https protocol.
|
|
|
|
\exception std::bad_alloc This exception may be raised if it is impossible to allocate memory.
|
|
\exception BUnsupportedProtocol This exception is raised when the protocol of the URL cannot be
|
|
handled.
|
|
\exception BInvalidUrl This exception is raised when the \a url is invalid.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BHttpRequest::BHttpRequest(const BHttpRequest &other)=delete
|
|
\brief Copying is not allowed.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BHttpRequest::BHttpRequest(BHttpRequest &&other) noexcept
|
|
\brief Move constructor.
|
|
|
|
After a move, the \a other object is left in an empty state.
|
|
|
|
\param other The request to move data from.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BPrivate::Network::BHttpRequest::~BHttpRequest()
|
|
\brief Destructor
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
//! @}
|
|
|
|
|
|
/*!
|
|
\name Assignment operators
|
|
*/
|
|
|
|
|
|
//! @{
|
|
|
|
|
|
/*!
|
|
\fn BHttpRequest& BHttpRequest::operator=(const BHttpRequest &other)=delete
|
|
\brief Copy assignment is not allowed.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn BHttpRequest& BHttpRequest::operator=(BHttpRequest &&other) noexcept
|
|
\brief Move assignment
|
|
|
|
After a move, the \a other object is left in an empty state.
|
|
|
|
\param other The request to move data from.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
//! @}
|
|
|
|
|
|
/*!
|
|
\name Valid or empty
|
|
*/
|
|
|
|
|
|
//! @{
|
|
|
|
|
|
/*!
|
|
\fn bool BHttpRequest::IsEmpty() const noexcept
|
|
\brief Check if the request is valid or empty
|
|
|
|
\retval true The request is empty.
|
|
\retval false The request is valid.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
//! @}
|
|
|
|
|
|
/*!
|
|
\name Current Options
|
|
*/
|
|
|
|
|
|
//! @{
|
|
|
|
|
|
/*!
|
|
\fn const BHttpMethod& BHttpRequest::Method() const noexcept
|
|
\brief Get the current method for the request.
|
|
|
|
This will either return the custom value set for this request, or the default as is listed in
|
|
the overview documentation of this class.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn const BHttpRedirectOptions& BHttpRequest::Redirect() const noexcept
|
|
\brief Get the current redirection options for this request.
|
|
|
|
\see \ref BHttpRequest::SetRedirect() for details on the options.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn const BUrl& BHttpRequest::Url() const noexcept
|
|
\brief Get the current Url for the request.
|
|
|
|
This will either return the custom value set for this request, or the default as is listed in
|
|
the overview documentation of this class.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
//! @}
|
|
|
|
|
|
/*!
|
|
\name Setting Options
|
|
*/
|
|
|
|
|
|
//! @{
|
|
|
|
|
|
/*!
|
|
\fn void BHttpRequest::SetMethod(const BHttpMethod &method)
|
|
\brief Set the \a method for this request.
|
|
|
|
Note that there currently is no additional validation done on any semantical incompatibilities.
|
|
This means that it is currently allowed to do a \c GET or \c HEAD request with data, while that
|
|
is forbidden by the standard.
|
|
|
|
\param method The method to use for the request.
|
|
|
|
\exception std::bad_alloc This exception may be raised if it is impossible to allocate memory.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn void BHttpRequest::SetRedirect(const BHttpRedirectOptions &redirectOptions)
|
|
\brief Set the redirection options for this request.
|
|
|
|
The HTTP protocol allows the server to redirect requests if the resources have moved to a new
|
|
location. For your convenience, you can instruct the network services kit to follow these
|
|
redirections.
|
|
|
|
The \ref BHttpRedirectOptions allows you to set what the redirection policy should be. You can
|
|
set whether redirects should be followed at all, and if so, how many redirects should be
|
|
followed. The maximum value is that of an unsigned 8 bit int, so maximum is 256 redirects. This
|
|
prevents the request from staying stuck in a redirection loop.
|
|
|
|
If redirects are disabled, or the maximum number of redirects have been processed, then the
|
|
response will be set to the actual (last) received redirection response.
|
|
|
|
\param redirectOptions The options for redirections.
|
|
|
|
\exception std::bad_alloc This exception may be raised if it is impossible to allocate memory.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
/*!
|
|
\fn void BHttpRequest::SetUrl(const BUrl &url)
|
|
\brief Set the \a url for this request.
|
|
|
|
\param url A valid URL with the \c http or \c https protocol.
|
|
|
|
\exception std::bad_alloc This exception may be raised if it is impossible to allocate memory.
|
|
\exception BUnsupportedProtocol This exception is raised when the protocol of the URL cannot be
|
|
handled.
|
|
\exception BInvalidUrl This exception is raised when the \a url is invalid.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
//! @}
|
|
|
|
|
|
/*!
|
|
\name Serialization
|
|
*/
|
|
|
|
|
|
//! @{
|
|
|
|
|
|
/*!
|
|
\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.
|
|
|
|
The HTTP header consists of the request line, and the fields, serialized as text according to
|
|
the HTTP specification.
|
|
|
|
This method can be used to debug requests.
|
|
|
|
\return A new string that represents the HTTP request.
|
|
|
|
\exception std::bad_alloc In case it is not possible to allocate memory for the output string.
|
|
|
|
\since Haiku R1
|
|
*/
|
|
|
|
|
|
//! @}
|
|
|
|
|
|
} // namespace Network
|
|
|
|
} // namespace BPrivate
|
|
|
|
#endif
|