NetServices: Introduce BHttpRequest class
Objects of this class describe a HTTP request. It contains several convenience functions that will allow a user to describe the properties of the request. More options to be added later. Change-Id: If6a00d26808c5ed4b121cb36dc75a2a1cc449f95
This commit is contained in:
parent
ec865cb87e
commit
6ce6e96470
@ -248,6 +248,231 @@ namespace Network {
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\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>
|
||||
</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 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::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
|
||||
*/
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
|
||||
} // namespace Network
|
||||
|
||||
} // namespace BPrivate
|
||||
|
@ -6,12 +6,15 @@
|
||||
#ifndef _B_HTTP_REQUEST_H_
|
||||
#define _B_HTTP_REQUEST_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
|
||||
#include <ErrorsExt.h>
|
||||
#include <String.h>
|
||||
|
||||
class BUrl;
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
@ -62,8 +65,36 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class BHttpRequest {
|
||||
public:
|
||||
// Constructors and Destructor
|
||||
BHttpRequest();
|
||||
BHttpRequest(const BUrl& url);
|
||||
BHttpRequest(const BHttpRequest& other) = delete;
|
||||
BHttpRequest(BHttpRequest&& other) noexcept;
|
||||
~BHttpRequest();
|
||||
|
||||
// Assignment operators
|
||||
BHttpRequest& operator=(const BHttpRequest& other) = delete;
|
||||
BHttpRequest& operator=(BHttpRequest&&) noexcept;
|
||||
|
||||
// Access
|
||||
bool IsEmpty() const noexcept;
|
||||
const BHttpMethod& Method() const noexcept;
|
||||
const BUrl& Url() const noexcept;
|
||||
|
||||
// Named Setters
|
||||
void SetMethod(const BHttpMethod& method);
|
||||
void SetUrl(const BUrl& url);
|
||||
|
||||
private:
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> fData;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Network
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
#endif // B_HTTP_REQUEST
|
||||
#endif // _B_HTTP_REQUEST_H_
|
||||
|
@ -12,6 +12,9 @@
|
||||
#include <ctype.h>
|
||||
#include <utility>
|
||||
|
||||
#include <NetServicesDefs.h>
|
||||
#include <Url.h>
|
||||
|
||||
#include "HttpPrivate.h"
|
||||
|
||||
using namespace std::literals;
|
||||
@ -125,3 +128,99 @@ BHttpMethod::Method() const noexcept
|
||||
return std::string_view(methodString.String());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -- BHttpRequest::Impl
|
||||
static const BUrl kDefaultUrl = BUrl();
|
||||
static const BHttpMethod kDefaultMethod = BHttpMethod::Get;
|
||||
|
||||
|
||||
struct BHttpRequest::Impl {
|
||||
BUrl url;
|
||||
BHttpMethod method = kDefaultMethod;
|
||||
bool ssl = false;
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark -- BHttpRequest
|
||||
|
||||
|
||||
BHttpRequest::BHttpRequest()
|
||||
: fData(std::make_unique<Impl>())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
BHttpRequest::BHttpRequest(const BUrl& url)
|
||||
: fData(std::make_unique<Impl>())
|
||||
{
|
||||
SetUrl(url);
|
||||
}
|
||||
|
||||
|
||||
BHttpRequest::BHttpRequest(BHttpRequest&& other) noexcept = default;
|
||||
|
||||
|
||||
BHttpRequest::~BHttpRequest() = default;
|
||||
|
||||
|
||||
BHttpRequest&
|
||||
BHttpRequest::operator=(BHttpRequest&&) noexcept = default;
|
||||
|
||||
|
||||
bool
|
||||
BHttpRequest::IsEmpty() const noexcept
|
||||
{
|
||||
return (!fData || !fData->url.IsValid());
|
||||
}
|
||||
|
||||
|
||||
const BHttpMethod&
|
||||
BHttpRequest::Method() const noexcept
|
||||
{
|
||||
if (!fData)
|
||||
return kDefaultMethod;
|
||||
return fData->method;
|
||||
}
|
||||
|
||||
|
||||
const BUrl&
|
||||
BHttpRequest::Url() const noexcept
|
||||
{
|
||||
if (!fData)
|
||||
return kDefaultUrl;
|
||||
return fData->url;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BHttpRequest::SetMethod(const BHttpMethod& method)
|
||||
{
|
||||
if (!fData)
|
||||
fData = std::make_unique<Impl>();
|
||||
fData->method = method;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BHttpRequest::SetUrl(const BUrl& url)
|
||||
{
|
||||
if (!fData)
|
||||
fData = std::make_unique<Impl>();
|
||||
|
||||
if (!url.IsValid())
|
||||
throw BInvalidUrl(__PRETTY_FUNCTION__, BUrl(url));
|
||||
if (url.Protocol() == "http")
|
||||
fData->ssl = false;
|
||||
else if (url.Protocol() == "https")
|
||||
fData->ssl = true;
|
||||
else {
|
||||
// TODO: optimize BStringList with modern language features
|
||||
BStringList list;
|
||||
list.Add("http");
|
||||
list.Add("https");
|
||||
throw BUnsupportedProtocol(__PRETTY_FUNCTION__, BUrl(url), list);
|
||||
}
|
||||
fData->url = url;
|
||||
}
|
||||
|
@ -14,9 +14,11 @@
|
||||
|
||||
#include <HttpFields.h>
|
||||
#include <HttpRequest.h>
|
||||
#include <Url.h>
|
||||
|
||||
using BPrivate::Network::BHttpFields;
|
||||
using BPrivate::Network::BHttpMethod;
|
||||
using BPrivate::Network::BHttpRequest;
|
||||
using BPrivate::Network::BHttpSession;
|
||||
|
||||
|
||||
@ -219,6 +221,18 @@ HttpProtocolTest::HttpMethodTest()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HttpProtocolTest::HttpRequestTest()
|
||||
{
|
||||
// Basic test
|
||||
BHttpRequest request;
|
||||
CPPUNIT_ASSERT(request.IsEmpty());
|
||||
auto url = BUrl("https://www.haiku-os.org");
|
||||
request.SetUrl(url);
|
||||
CPPUNIT_ASSERT(request.Url() == url);
|
||||
}
|
||||
|
||||
|
||||
/* static */ void
|
||||
HttpProtocolTest::AddTests(BTestSuite& parent)
|
||||
{
|
||||
@ -228,6 +242,8 @@ HttpProtocolTest::AddTests(BTestSuite& parent)
|
||||
"HttpProtocolTest::HttpFieldsTest", &HttpProtocolTest::HttpFieldsTest));
|
||||
suite.addTest(new CppUnit::TestCaller<HttpProtocolTest>(
|
||||
"HttpProtocolTest::HttpMethodTest", &HttpProtocolTest::HttpMethodTest));
|
||||
suite.addTest(new CppUnit::TestCaller<HttpProtocolTest>(
|
||||
"HttpProtocolTest::HttpRequestTest", &HttpProtocolTest::HttpRequestTest));
|
||||
|
||||
parent.addTest("HttpProtocolTest", &suite);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ public:
|
||||
|
||||
void HttpFieldsTest();
|
||||
void HttpMethodTest();
|
||||
void HttpRequestTest();
|
||||
|
||||
static void AddTests(BTestSuite& suite);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user