xref: /haiku/headers/private/netservices/HttpRequest.h (revision 9e4c5cf124438891e20947b72d13412d78018800)
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