1 /* 2 * Copyright 2010-2021 Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _B_URL_PROTOCOL_HTTP_H_ 6 #define _B_URL_PROTOCOL_HTTP_H_ 7 8 9 #include <deque> 10 11 #include <Certificate.h> 12 #include <HttpForm.h> 13 #include <HttpHeaders.h> 14 #include <HttpResult.h> 15 #include <NetworkAddress.h> 16 #include <NetworkRequest.h> 17 #include <UrlProtocolRoster.h> 18 19 20 namespace BPrivate { 21 class CheckedSecureSocket; 22 class CheckedProxySecureSocket; 23 }; 24 25 26 #ifndef LIBNETAPI_DEPRECATED 27 namespace BPrivate { 28 29 namespace Network { 30 #endif 31 32 class BHttpRequest : public BNetworkRequest { 33 public: 34 virtual ~BHttpRequest(); 35 36 void SetMethod(const char* const method); 37 void SetFollowLocation(bool follow); 38 void SetMaxRedirections(int8 maxRedirections); 39 void SetReferrer(const BString& referrer); 40 void SetUserAgent(const BString& agent); 41 void SetDiscardData(bool discard); 42 void SetDisableListener(bool disable); 43 void SetAutoReferrer(bool enable); 44 #ifndef LIBNETAPI_DEPRECATED 45 void SetStopOnError(bool stop); 46 #endif 47 void SetUserName(const BString& name); 48 void SetPassword(const BString& password); 49 void SetRangeStart(off_t position); 50 void SetRangeEnd(off_t position); 51 52 void SetPostFields(const BHttpForm& fields); 53 void SetHeaders(const BHttpHeaders& headers); 54 55 void AdoptPostFields(BHttpForm* const fields); 56 void AdoptInputData(BDataIO* const data, 57 const ssize_t size = -1); 58 void AdoptHeaders(BHttpHeaders* const headers); 59 60 status_t Stop(); 61 const BUrlResult& Result() const; 62 63 static bool IsInformationalStatusCode(int16 code); 64 static bool IsSuccessStatusCode(int16 code); 65 static bool IsRedirectionStatusCode(int16 code); 66 static bool IsClientErrorStatusCode(int16 code); 67 static bool IsServerErrorStatusCode(int16 code); 68 static int16 StatusCodeClass(int16 code); 69 70 private: 71 friend class BUrlProtocolRoster; 72 73 #ifdef LIBNETAPI_DEPRECATED 74 BHttpRequest(const BUrl& url, 75 bool ssl = false, 76 const char* protocolName = "HTTP", 77 BUrlProtocolListener* listener = NULL, 78 BUrlContext* context = NULL); 79 #else 80 BHttpRequest(const BUrl& url, 81 BDataIO* output, 82 bool ssl = false, 83 const char* protocolName = "HTTP", 84 BUrlProtocolListener* listener = NULL, 85 BUrlContext* context = NULL); 86 #endif 87 BHttpRequest(const BHttpRequest& other); 88 89 void _ResetOptions(); 90 status_t _ProtocolLoop(); 91 status_t _MakeRequest(); 92 93 BString _SerializeRequest(); 94 BString _SerializeHeaders(); 95 void _SendPostData(); 96 97 void _ParseStatus(); 98 void _ParseHeaders(); 99 100 // URL result parameters access 101 BPositionIO* _ResultRawData(); 102 BHttpHeaders& _ResultHeaders(); 103 void _SetResultStatusCode(int32 statusCode); 104 BString& _ResultStatusText(); 105 106 // SSL failure management 107 friend class BPrivate::CheckedSecureSocket; 108 friend class BPrivate::CheckedProxySecureSocket; 109 bool _CertificateVerificationFailed( 110 BCertificate& certificate, 111 const char* message); 112 113 // Utility methods 114 bool _IsDefaultPort(); 115 116 #ifdef LIBNETAPI_DEPRECATED 117 // Listener notification 118 void _NotifyDataReceived(const char* data, 119 off_t pos, ssize_t length, 120 off_t bytesReceived, ssize_t bytesTotal); 121 #endif 122 123 private: 124 bool fSSL; 125 126 BString fRequestMethod; 127 int8 fHttpVersion; 128 129 BHttpHeaders fHeaders; 130 131 // Request status 132 133 BHttpResult fResult; 134 135 // Request state/events 136 enum { 137 kRequestInitialState, 138 kRequestStatusReceived, 139 kRequestHeadersReceived, 140 kRequestContentReceived, 141 kRequestTrailingHeadersReceived 142 } fRequestStatus; 143 144 145 // Protocol options 146 uint8 fOptMaxRedirs; 147 BString fOptReferer; 148 BString fOptUserAgent; 149 BString fOptUsername; 150 BString fOptPassword; 151 uint32 fOptAuthMethods; 152 BHttpHeaders* fOptHeaders; 153 BHttpForm* fOptPostFields; 154 BDataIO* fOptInputData; 155 ssize_t fOptInputDataSize; 156 off_t fOptRangeStart; 157 off_t fOptRangeEnd; 158 bool fOptSetCookies : 1; 159 bool fOptFollowLocation : 1; 160 bool fOptDiscardData : 1; 161 bool fOptDisableListener : 1; 162 bool fOptAutoReferer : 1; 163 #ifndef LIBNETAPI_DEPRECATED 164 bool fOptStopOnError : 1; 165 #endif 166 }; 167 168 // Request method 169 const char* const B_HTTP_GET = "GET"; 170 const char* const B_HTTP_POST = "POST"; 171 const char* const B_HTTP_PUT = "PUT"; 172 const char* const B_HTTP_HEAD = "HEAD"; 173 const char* const B_HTTP_DELETE = "DELETE"; 174 const char* const B_HTTP_OPTIONS = "OPTIONS"; 175 const char* const B_HTTP_TRACE = "TRACE"; 176 const char* const B_HTTP_CONNECT = "CONNECT"; 177 178 179 // HTTP Version 180 enum { 181 B_HTTP_10 = 1, 182 B_HTTP_11 183 }; 184 185 186 // HTTP status classes 187 enum http_status_code_class { 188 B_HTTP_STATUS_CLASS_INVALID = 000, 189 B_HTTP_STATUS_CLASS_INFORMATIONAL = 100, 190 B_HTTP_STATUS_CLASS_SUCCESS = 200, 191 B_HTTP_STATUS_CLASS_REDIRECTION = 300, 192 B_HTTP_STATUS_CLASS_CLIENT_ERROR = 400, 193 B_HTTP_STATUS_CLASS_SERVER_ERROR = 500 194 }; 195 196 197 // Known HTTP status codes 198 enum http_status_code { 199 // Informational status codes 200 B_HTTP_STATUS__INFORMATIONAL_BASE = 100, 201 B_HTTP_STATUS_CONTINUE = B_HTTP_STATUS__INFORMATIONAL_BASE, 202 B_HTTP_STATUS_SWITCHING_PROTOCOLS, 203 B_HTTP_STATUS__INFORMATIONAL_END, 204 205 // Success status codes 206 B_HTTP_STATUS__SUCCESS_BASE = 200, 207 B_HTTP_STATUS_OK = B_HTTP_STATUS__SUCCESS_BASE, 208 B_HTTP_STATUS_CREATED, 209 B_HTTP_STATUS_ACCEPTED, 210 B_HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION, 211 B_HTTP_STATUS_NO_CONTENT, 212 B_HTTP_STATUS_RESET_CONTENT, 213 B_HTTP_STATUS_PARTIAL_CONTENT, 214 B_HTTP_STATUS__SUCCESS_END, 215 216 // Redirection status codes 217 B_HTTP_STATUS__REDIRECTION_BASE = 300, 218 B_HTTP_STATUS_MULTIPLE_CHOICE = B_HTTP_STATUS__REDIRECTION_BASE, 219 B_HTTP_STATUS_MOVED_PERMANENTLY, 220 B_HTTP_STATUS_FOUND, 221 B_HTTP_STATUS_SEE_OTHER, 222 B_HTTP_STATUS_NOT_MODIFIED, 223 B_HTTP_STATUS_USE_PROXY, 224 B_HTTP_STATUS_TEMPORARY_REDIRECT, 225 B_HTTP_STATUS__REDIRECTION_END, 226 227 // Client error status codes 228 B_HTTP_STATUS__CLIENT_ERROR_BASE = 400, 229 B_HTTP_STATUS_BAD_REQUEST = B_HTTP_STATUS__CLIENT_ERROR_BASE, 230 B_HTTP_STATUS_UNAUTHORIZED, 231 B_HTTP_STATUS_PAYMENT_REQUIRED, 232 B_HTTP_STATUS_FORBIDDEN, 233 B_HTTP_STATUS_NOT_FOUND, 234 B_HTTP_STATUS_METHOD_NOT_ALLOWED, 235 B_HTTP_STATUS_NOT_ACCEPTABLE, 236 B_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED, 237 B_HTTP_STATUS_REQUEST_TIMEOUT, 238 B_HTTP_STATUS_CONFLICT, 239 B_HTTP_STATUS_GONE, 240 B_HTTP_STATUS_LENGTH_REQUIRED, 241 B_HTTP_STATUS_PRECONDITION_FAILED, 242 B_HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE, 243 B_HTTP_STATUS_REQUEST_URI_TOO_LARGE, 244 B_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, 245 B_HTTP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE, 246 B_HTTP_STATUS_EXPECTATION_FAILED, 247 B_HTTP_STATUS__CLIENT_ERROR_END, 248 249 // Server error status codes 250 B_HTTP_STATUS__SERVER_ERROR_BASE = 500, 251 B_HTTP_STATUS_INTERNAL_SERVER_ERROR = B_HTTP_STATUS__SERVER_ERROR_BASE, 252 B_HTTP_STATUS_NOT_IMPLEMENTED, 253 B_HTTP_STATUS_BAD_GATEWAY, 254 B_HTTP_STATUS_SERVICE_UNAVAILABLE, 255 B_HTTP_STATUS_GATEWAY_TIMEOUT, 256 B_HTTP_STATUS__SERVER_ERROR_END 257 }; 258 259 260 // HTTP default User-Agent 261 #define B_HTTP_PROTOCOL_USER_AGENT_FORMAT "ServicesKit (%s)" 262 263 #ifndef LIBNETAPI_DEPRECATED 264 } // namespace Network 265 266 } // namespace BPrivate 267 #endif 268 269 #endif // _B_URL_PROTOCOL_HTTP_H_ 270