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