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