haiku/headers/private/netservices/HttpRequest.h
Niels Sascha Reedijk ce64ffdb90 libnetservices.a: Put the experimental API into BPrivate::Network namespace
In order to prevent classes between libnetapi.so with the legacy API and
applications using the libnetservices.a library, the latter will have the
classes in a distinct namespace.

In the implementation, both libbnetapi.so and libnetservices.a will use the
same header and source files. If LIBNETAPI_DEPRECATED is defined during build,
the headers and source will have binary compatible behavior. Otherwise, the
classes and other objects will be put in the HaikuExt namespace.

In order to build the libbnetapi.so and libnetservices.a with the proper
build configuration, there is a stub `src/kits/net/libnetapi_deprecated` folder
that applies the special configuration to the source files.

Currently HaikuDepot, Webpositive, libshared.a and the http_streamer add on
use the compatible API in libbnetapi.so.

Change-Id: Ic73e9f271ef75749adda46f6f72e9a0b2851b461
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3667
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
2021-01-27 19:53:11 +00:00

253 lines
6.7 KiB
C++

/*
* Copyright 2010-2021 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _B_URL_PROTOCOL_HTTP_H_
#define _B_URL_PROTOCOL_HTTP_H_
#include <deque>
#include <Certificate.h>
#include <HttpForm.h>
#include <HttpHeaders.h>
#include <HttpResult.h>
#include <NetworkAddress.h>
#include <NetworkRequest.h>
#include <UrlProtocolRoster.h>
namespace BPrivate {
class CheckedSecureSocket;
class CheckedProxySecureSocket;
};
#ifndef LIBNETAPI_DEPRECATED
namespace BPrivate {
namespace Network {
#endif
class BHttpRequest : public BNetworkRequest {
public:
virtual ~BHttpRequest();
void SetMethod(const char* const method);
void SetFollowLocation(bool follow);
void SetMaxRedirections(int8 maxRedirections);
void SetReferrer(const BString& referrer);
void SetUserAgent(const BString& agent);
void SetDiscardData(bool discard);
void SetDisableListener(bool disable);
void SetAutoReferrer(bool enable);
void SetUserName(const BString& name);
void SetPassword(const BString& password);
void SetRangeStart(off_t position);
void SetRangeEnd(off_t position);
void SetPostFields(const BHttpForm& fields);
void SetHeaders(const BHttpHeaders& headers);
void AdoptPostFields(BHttpForm* const fields);
void AdoptInputData(BDataIO* const data,
const ssize_t size = -1);
void AdoptHeaders(BHttpHeaders* const headers);
status_t Stop();
const BUrlResult& Result() const;
static bool IsInformationalStatusCode(int16 code);
static bool IsSuccessStatusCode(int16 code);
static bool IsRedirectionStatusCode(int16 code);
static bool IsClientErrorStatusCode(int16 code);
static bool IsServerErrorStatusCode(int16 code);
static int16 StatusCodeClass(int16 code);
private:
friend class BUrlProtocolRoster;
BHttpRequest(const BUrl& url,
bool ssl = false,
const char* protocolName = "HTTP",
BUrlProtocolListener* listener = NULL,
BUrlContext* context = NULL);
BHttpRequest(const BHttpRequest& other);
void _ResetOptions();
status_t _ProtocolLoop();
status_t _MakeRequest();
BString _SerializeRequest();
BString _SerializeHeaders();
void _SendPostData();
void _ParseStatus();
void _ParseHeaders();
// URL result parameters access
BPositionIO* _ResultRawData();
BHttpHeaders& _ResultHeaders();
void _SetResultStatusCode(int32 statusCode);
BString& _ResultStatusText();
// SSL failure management
friend class BPrivate::CheckedSecureSocket;
friend class BPrivate::CheckedProxySecureSocket;
bool _CertificateVerificationFailed(
BCertificate& certificate,
const char* message);
// Utility methods
bool _IsDefaultPort();
// Listener notification
void _NotifyDataReceived(const char* data,
off_t pos, ssize_t length,
off_t bytesReceived, ssize_t bytesTotal);
private:
bool fSSL;
BString fRequestMethod;
int8 fHttpVersion;
BHttpHeaders fHeaders;
// Request status
BHttpResult fResult;
// Request state/events
enum {
kRequestInitialState,
kRequestStatusReceived,
kRequestHeadersReceived,
kRequestContentReceived,
kRequestTrailingHeadersReceived
} fRequestStatus;
// Protocol options
uint8 fOptMaxRedirs;
BString fOptReferer;
BString fOptUserAgent;
BString fOptUsername;
BString fOptPassword;
uint32 fOptAuthMethods;
BHttpHeaders* fOptHeaders;
BHttpForm* fOptPostFields;
BDataIO* fOptInputData;
ssize_t fOptInputDataSize;
off_t fOptRangeStart;
off_t fOptRangeEnd;
bool fOptSetCookies : 1;
bool fOptFollowLocation : 1;
bool fOptDiscardData : 1;
bool fOptDisableListener : 1;
bool fOptAutoReferer : 1;
};
// Request method
const char* const B_HTTP_GET = "GET";
const char* const B_HTTP_POST = "POST";
const char* const B_HTTP_PUT = "PUT";
const char* const B_HTTP_HEAD = "HEAD";
const char* const B_HTTP_DELETE = "DELETE";
const char* const B_HTTP_OPTIONS = "OPTIONS";
const char* const B_HTTP_TRACE = "TRACE";
const char* const B_HTTP_CONNECT = "CONNECT";
// HTTP Version
enum {
B_HTTP_10 = 1,
B_HTTP_11
};
// HTTP status classes
enum http_status_code_class {
B_HTTP_STATUS_CLASS_INVALID = 000,
B_HTTP_STATUS_CLASS_INFORMATIONAL = 100,
B_HTTP_STATUS_CLASS_SUCCESS = 200,
B_HTTP_STATUS_CLASS_REDIRECTION = 300,
B_HTTP_STATUS_CLASS_CLIENT_ERROR = 400,
B_HTTP_STATUS_CLASS_SERVER_ERROR = 500
};
// Known HTTP status codes
enum http_status_code {
// Informational status codes
B_HTTP_STATUS__INFORMATIONAL_BASE = 100,
B_HTTP_STATUS_CONTINUE = B_HTTP_STATUS__INFORMATIONAL_BASE,
B_HTTP_STATUS_SWITCHING_PROTOCOLS,
B_HTTP_STATUS__INFORMATIONAL_END,
// Success status codes
B_HTTP_STATUS__SUCCESS_BASE = 200,
B_HTTP_STATUS_OK = B_HTTP_STATUS__SUCCESS_BASE,
B_HTTP_STATUS_CREATED,
B_HTTP_STATUS_ACCEPTED,
B_HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION,
B_HTTP_STATUS_NO_CONTENT,
B_HTTP_STATUS_RESET_CONTENT,
B_HTTP_STATUS_PARTIAL_CONTENT,
B_HTTP_STATUS__SUCCESS_END,
// Redirection status codes
B_HTTP_STATUS__REDIRECTION_BASE = 300,
B_HTTP_STATUS_MULTIPLE_CHOICE = B_HTTP_STATUS__REDIRECTION_BASE,
B_HTTP_STATUS_MOVED_PERMANENTLY,
B_HTTP_STATUS_FOUND,
B_HTTP_STATUS_SEE_OTHER,
B_HTTP_STATUS_NOT_MODIFIED,
B_HTTP_STATUS_USE_PROXY,
B_HTTP_STATUS_TEMPORARY_REDIRECT,
B_HTTP_STATUS__REDIRECTION_END,
// Client error status codes
B_HTTP_STATUS__CLIENT_ERROR_BASE = 400,
B_HTTP_STATUS_BAD_REQUEST = B_HTTP_STATUS__CLIENT_ERROR_BASE,
B_HTTP_STATUS_UNAUTHORIZED,
B_HTTP_STATUS_PAYMENT_REQUIRED,
B_HTTP_STATUS_FORBIDDEN,
B_HTTP_STATUS_NOT_FOUND,
B_HTTP_STATUS_METHOD_NOT_ALLOWED,
B_HTTP_STATUS_NOT_ACCEPTABLE,
B_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED,
B_HTTP_STATUS_REQUEST_TIMEOUT,
B_HTTP_STATUS_CONFLICT,
B_HTTP_STATUS_GONE,
B_HTTP_STATUS_LENGTH_REQUIRED,
B_HTTP_STATUS_PRECONDITION_FAILED,
B_HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE,
B_HTTP_STATUS_REQUEST_URI_TOO_LARGE,
B_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE,
B_HTTP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE,
B_HTTP_STATUS_EXPECTATION_FAILED,
B_HTTP_STATUS__CLIENT_ERROR_END,
// Server error status codes
B_HTTP_STATUS__SERVER_ERROR_BASE = 500,
B_HTTP_STATUS_INTERNAL_SERVER_ERROR = B_HTTP_STATUS__SERVER_ERROR_BASE,
B_HTTP_STATUS_NOT_IMPLEMENTED,
B_HTTP_STATUS_BAD_GATEWAY,
B_HTTP_STATUS_SERVICE_UNAVAILABLE,
B_HTTP_STATUS_GATEWAY_TIMEOUT,
B_HTTP_STATUS__SERVER_ERROR_END
};
// HTTP default User-Agent
#define B_HTTP_PROTOCOL_USER_AGENT_FORMAT "ServicesKit (%s)"
#ifndef LIBNETAPI_DEPRECATED
} // namespace Network
} // namespace BPrivate
#endif
#endif // _B_URL_PROTOCOL_HTTP_H_