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 namespace BPrivate { 27 28 namespace Network { 29 30 31 class BHttpRequest : public BNetworkRequest { 32 public: 33 virtual ~BHttpRequest(); 34 35 void SetMethod(const char* const method); 36 void SetFollowLocation(bool follow); 37 void SetMaxRedirections(int8 maxRedirections); 38 void SetReferrer(const BString& referrer); 39 void SetUserAgent(const BString& agent); 40 void SetDiscardData(bool discard); 41 void SetDisableListener(bool disable); 42 void SetAutoReferrer(bool enable); 43 void SetStopOnError(bool stop); 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 BDataIO* output, 72 bool ssl = false, 73 const char* protocolName = "HTTP", 74 BUrlProtocolListener* listener = NULL, 75 BUrlContext* context = NULL); 76 BHttpRequest(const BHttpRequest& other); 77 78 void _ResetOptions(); 79 status_t _ProtocolLoop(); 80 status_t _MakeRequest(); 81 82 BString _SerializeRequest(); 83 BString _SerializeHeaders(); 84 void _SendPostData(); 85 86 void _ParseStatus(); 87 void _ParseHeaders(); 88 89 // URL result parameters access 90 BPositionIO* _ResultRawData(); 91 BHttpHeaders& _ResultHeaders(); 92 void _SetResultStatusCode(int32 statusCode); 93 BString& _ResultStatusText(); 94 95 // SSL failure management 96 friend class BPrivate::CheckedSecureSocket; 97 friend class BPrivate::CheckedProxySecureSocket; 98 bool _CertificateVerificationFailed( 99 BCertificate& certificate, 100 const char* message); 101 102 // Utility methods 103 bool _IsDefaultPort(); 104 105 106 private: 107 bool fSSL; 108 109 BString fRequestMethod; 110 int8 fHttpVersion; 111 112 BHttpHeaders fHeaders; 113 114 // Request status 115 116 BHttpResult fResult; 117 118 // Request state/events 119 enum { 120 kRequestInitialState, 121 kRequestStatusReceived, 122 kRequestHeadersReceived, 123 kRequestContentReceived, 124 kRequestTrailingHeadersReceived 125 } fRequestStatus; 126 127 128 // Protocol options 129 uint8 fOptMaxRedirs; 130 BString fOptReferer; 131 BString fOptUserAgent; 132 BString fOptUsername; 133 BString fOptPassword; 134 uint32 fOptAuthMethods; 135 BHttpHeaders* fOptHeaders; 136 BHttpForm* fOptPostFields; 137 BDataIO* fOptInputData; 138 ssize_t fOptInputDataSize; 139 off_t fOptRangeStart; 140 off_t fOptRangeEnd; 141 bool fOptSetCookies : 1; 142 bool fOptFollowLocation : 1; 143 bool fOptDiscardData : 1; 144 bool fOptDisableListener : 1; 145 bool fOptAutoReferer : 1; 146 bool fOptStopOnError : 1; 147 }; 148 149 // Request method 150 const char* const B_HTTP_GET = "GET"; 151 const char* const B_HTTP_POST = "POST"; 152 const char* const B_HTTP_PUT = "PUT"; 153 const char* const B_HTTP_HEAD = "HEAD"; 154 const char* const B_HTTP_DELETE = "DELETE"; 155 const char* const B_HTTP_OPTIONS = "OPTIONS"; 156 const char* const B_HTTP_TRACE = "TRACE"; 157 const char* const B_HTTP_CONNECT = "CONNECT"; 158 159 160 // HTTP Version 161 enum { 162 B_HTTP_10 = 1, 163 B_HTTP_11 164 }; 165 166 167 // HTTP status classes 168 enum http_status_code_class { 169 B_HTTP_STATUS_CLASS_INVALID = 000, 170 B_HTTP_STATUS_CLASS_INFORMATIONAL = 100, 171 B_HTTP_STATUS_CLASS_SUCCESS = 200, 172 B_HTTP_STATUS_CLASS_REDIRECTION = 300, 173 B_HTTP_STATUS_CLASS_CLIENT_ERROR = 400, 174 B_HTTP_STATUS_CLASS_SERVER_ERROR = 500 175 }; 176 177 178 // Known HTTP status codes 179 enum http_status_code { 180 // Informational status codes 181 B_HTTP_STATUS__INFORMATIONAL_BASE = 100, 182 B_HTTP_STATUS_CONTINUE = B_HTTP_STATUS__INFORMATIONAL_BASE, 183 B_HTTP_STATUS_SWITCHING_PROTOCOLS, 184 B_HTTP_STATUS__INFORMATIONAL_END, 185 186 // Success status codes 187 B_HTTP_STATUS__SUCCESS_BASE = 200, 188 B_HTTP_STATUS_OK = B_HTTP_STATUS__SUCCESS_BASE, 189 B_HTTP_STATUS_CREATED, 190 B_HTTP_STATUS_ACCEPTED, 191 B_HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION, 192 B_HTTP_STATUS_NO_CONTENT, 193 B_HTTP_STATUS_RESET_CONTENT, 194 B_HTTP_STATUS_PARTIAL_CONTENT, 195 B_HTTP_STATUS__SUCCESS_END, 196 197 // Redirection status codes 198 B_HTTP_STATUS__REDIRECTION_BASE = 300, 199 B_HTTP_STATUS_MULTIPLE_CHOICE = B_HTTP_STATUS__REDIRECTION_BASE, 200 B_HTTP_STATUS_MOVED_PERMANENTLY, 201 B_HTTP_STATUS_FOUND, 202 B_HTTP_STATUS_SEE_OTHER, 203 B_HTTP_STATUS_NOT_MODIFIED, 204 B_HTTP_STATUS_USE_PROXY, 205 B_HTTP_STATUS_TEMPORARY_REDIRECT, 206 B_HTTP_STATUS__REDIRECTION_END, 207 208 // Client error status codes 209 B_HTTP_STATUS__CLIENT_ERROR_BASE = 400, 210 B_HTTP_STATUS_BAD_REQUEST = B_HTTP_STATUS__CLIENT_ERROR_BASE, 211 B_HTTP_STATUS_UNAUTHORIZED, 212 B_HTTP_STATUS_PAYMENT_REQUIRED, 213 B_HTTP_STATUS_FORBIDDEN, 214 B_HTTP_STATUS_NOT_FOUND, 215 B_HTTP_STATUS_METHOD_NOT_ALLOWED, 216 B_HTTP_STATUS_NOT_ACCEPTABLE, 217 B_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED, 218 B_HTTP_STATUS_REQUEST_TIMEOUT, 219 B_HTTP_STATUS_CONFLICT, 220 B_HTTP_STATUS_GONE, 221 B_HTTP_STATUS_LENGTH_REQUIRED, 222 B_HTTP_STATUS_PRECONDITION_FAILED, 223 B_HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE, 224 B_HTTP_STATUS_REQUEST_URI_TOO_LARGE, 225 B_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, 226 B_HTTP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE, 227 B_HTTP_STATUS_EXPECTATION_FAILED, 228 B_HTTP_STATUS__CLIENT_ERROR_END, 229 230 // Server error status codes 231 B_HTTP_STATUS__SERVER_ERROR_BASE = 500, 232 B_HTTP_STATUS_INTERNAL_SERVER_ERROR = B_HTTP_STATUS__SERVER_ERROR_BASE, 233 B_HTTP_STATUS_NOT_IMPLEMENTED, 234 B_HTTP_STATUS_BAD_GATEWAY, 235 B_HTTP_STATUS_SERVICE_UNAVAILABLE, 236 B_HTTP_STATUS_GATEWAY_TIMEOUT, 237 B_HTTP_STATUS__SERVER_ERROR_END 238 }; 239 240 241 // HTTP default User-Agent 242 #define B_HTTP_PROTOCOL_USER_AGENT_FORMAT "ServicesKit (%s)" 243 244 245 } // namespace Network 246 247 } // namespace BPrivate 248 249 #endif // _B_URL_PROTOCOL_HTTP_H_ 250