1/*
2 * Copyright 2010 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
12#include <HttpAuthentication.h>
13#include <HttpForm.h>
14#include <HttpHeaders.h>
15#include <NetEndpoint.h>
16#include <NetBuffer.h>
17#include <UrlProtocol.h>
18
19
20class BUrlProtocolHttp : public BUrlProtocol {
21public:
22								BUrlProtocolHttp(BUrl& url,
23									BUrlProtocolListener* listener = NULL,
24									BUrlContext* context = NULL,
25									BUrlResult* result = NULL);
26
27	virtual	status_t			SetOption(uint32 option, void* value);
28
29	static	bool				IsInformationalStatusCode(int16 code);
30	static	bool				IsSuccessStatusCode(int16 code);
31	static	bool				IsRedirectionStatusCode(int16 code);
32	static	bool				IsClientErrorStatusCode(int16 code);
33	static	bool				IsServerErrorStatusCode(int16 code);
34	static	int16				StatusCodeClass(int16 code);
35
36	virtual	const char*			StatusString(status_t threadStatus) const;
37
38private:
39			void				_ResetOptions();
40			status_t			_ProtocolLoop();
41			bool 				_ResolveHostName();
42			status_t			_MakeRequest();
43
44			void				_CreateRequest();
45			void				_AddHeaders();
46
47			status_t			_GetLine(BString& destString);
48
49			void				_ParseStatus();
50			void				_ParseHeaders();
51
52			void				_CopyChunkInBuffer(char** buffer,
53									ssize_t* bytesReceived);
54
55			void				_AddOutputBufferLine(const char* line);
56
57
58private:
59			BNetEndpoint		fSocket;
60			BNetAddress			fRemoteAddr;
61
62			int8				fRequestMethod;
63			int8				fHttpVersion;
64
65			BString				fOutputBuffer;
66			BNetBuffer			fInputBuffer;
67
68			BHttpHeaders		fHeaders;
69			BHttpAuthentication	fAuthentication;
70
71	// Request status
72			BHttpHeaders		fOutputHeaders;
73			bool				fStatusReceived;
74			bool				fHeadersReceived;
75			bool				fContentReceived;
76			bool				fTrailingHeadersReceived;
77
78
79	// Protocol options
80			uint8				fOptMaxRedirs;
81			BString				fOptReferer;
82			BString				fOptUserAgent;
83			BString				fOptUsername;
84			BString				fOptPassword;
85			uint32				fOptAuthMethods;
86			BHttpHeaders*		fOptHeaders;
87			BHttpForm*			fOptPostFields;
88			BDataIO*			fOptInputData;
89			bool				fOptSetCookies : 1;
90			bool				fOptFollowLocation : 1;
91			bool				fOptDiscardData : 1;
92			bool				fOptDisableListener : 1;
93			bool				fOptAutoReferer : 1;
94};
95
96// ProtocolLoop return status
97enum {
98	B_PROT_HTTP_NOT_FOUND = B_PROT_THREAD_STATUS__END,
99	B_PROT_HTTP_THREAD_STATUS__END
100};
101
102
103// Request method
104enum {
105	B_HTTP_GET = 1,
106	B_HTTP_POST,
107	B_HTTP_PUT,
108	B_HTTP_HEAD,
109	B_HTTP_DELETE,
110	B_HTTP_OPTIONS
111};
112
113
114// HTTP Version
115enum {
116	B_HTTP_10 = 1,
117	B_HTTP_11
118};
119
120
121// HTTP Protocol options
122enum {
123	B_HTTPOPT_METHOD = 0,
124		// (int) Request method (see B_HTTP_GET, ...)
125	B_HTTPOPT_FOLLOWLOCATION,
126		// (bool) Follow Location: headers
127	B_HTTPOPT_MAXREDIRS,
128		// (int) Max relocation
129	B_HTTPOPT_HEADERS,
130		// (BHttpHeaders*) Headers to be sent
131	B_HTTPOPT_REFERER,
132		// (string) Referer
133	B_HTTPOPT_USERAGENT,
134		// (string) User-Agent
135	B_HTTPOPT_SETCOOKIES,
136		// (bool) Send cookies from context
137	B_HTTPOPT_DISCARD_DATA,
138		// (bool) Discard incoming data (still notified)
139	B_HTTPOPT_DISABLE_LISTENER,
140		// (bool) Don't send notification to the listener
141	B_HTTPOPT_AUTOREFERER,
142		// (bool) Automatically set the Referer header
143	B_HTTPOPT_POSTFIELDS,
144		// (BHttpForm*) POST data to be sent
145	B_HTTPOPT_INPUTDATA,
146		// (BDataIO*) Input data to be sent (POST, PUT)
147	B_HTTPOPT_AUTHUSERNAME,
148		// (string) Authentication username
149	B_HTTPOPT_AUTHPASSWORD,
150		// (string) Authentication password
151	B_HTTPOPT_AUTHMETHOD,
152		// (int) Allowed authentication methods (see BHttpAuthenticationMethod)
153
154	B_HTTPOPT__OPT_NUM
155};
156
157
158// HTTP status classes
159enum http_status_code_class {
160	B_HTTP_STATUS_CLASS_INVALID			= 000,
161	B_HTTP_STATUS_CLASS_INFORMATIONAL 	= 100,
162	B_HTTP_STATUS_CLASS_SUCCESS			= 200,
163	B_HTTP_STATUS_CLASS_REDIRECTION		= 300,
164	B_HTTP_STATUS_CLASS_CLIENT_ERROR	= 400,
165	B_HTTP_STATUS_CLASS_SERVER_ERROR	= 500
166};
167
168
169// Known HTTP status codes
170enum http_status_code {
171	// Informational status codes
172	B_HTTP_STATUS__INFORMATIONAL_BASE	= 100,
173	B_HTTP_STATUS_CONTINUE = B_HTTP_STATUS__INFORMATIONAL_BASE,
174	B_HTTP_STATUS_SWITCHING_PROTOCOLS,
175	B_HTTP_STATUS__INFORMATIONAL_END,
176
177	// Success status codes
178	B_HTTP_STATUS__SUCCESS_BASE			= 200,
179	B_HTTP_STATUS_OK = B_HTTP_STATUS__SUCCESS_BASE,
180	B_HTTP_STATUS_CREATED,
181	B_HTTP_STATUS_ACCEPTED,
182	B_HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION,
183	B_HTTP_STATUS_NO_CONTENT,
184	B_HTTP_STATUS_RESET_CONTENT,
185	B_HTTP_STATUS_PARTIAL_CONTENT,
186	B_HTTP_STATUS__SUCCESS_END,
187
188	// Redirection status codes
189	B_HTTP_STATUS__REDIRECTION_BASE		= 300,
190	B_HTTP_STATUS_MULTIPLE_CHOICE = B_HTTP_STATUS__REDIRECTION_BASE,
191	B_HTTP_STATUS_MOVED_PERMANENTLY,
192	B_HTTP_STATUS_FOUND,
193	B_HTTP_STATUS_SEE_OTHER,
194	B_HTTP_STATUS_NOT_MODIFIED,
195	B_HTTP_STATUS_USE_PROXY,
196	B_HTTP_STATUS_TEMPORARY_REDIRECT,
197	B_HTTP_STATUS__REDIRECTION_END,
198
199	// Client error status codes
200	B_HTTP_STATUS__CLIENT_ERROR_BASE	= 400,
201	B_HTTP_STATUS_BAD_REQUEST = B_HTTP_STATUS__CLIENT_ERROR_BASE,
202	B_HTTP_STATUS_UNAUTHORIZED,
203	B_HTTP_STATUS_PAYMENT_REQUIRED,
204	B_HTTP_STATUS_FORBIDDEN,
205	B_HTTP_STATUS_NOT_FOUND,
206	B_HTTP_STATUS_METHOD_NOT_ALLOWED,
207	B_HTTP_STATUS_NOT_ACCEPTABLE,
208	B_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED,
209	B_HTTP_STATUS_REQUEST_TIMEOUT,
210	B_HTTP_STATUS_CONFLICT,
211	B_HTTP_STATUS_GONE,
212	B_HTTP_STATUS_LENGTH_REQUIRED,
213	B_HTTP_STATUS_PRECONDITION_FAILED,
214	B_HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE,
215	B_HTTP_STATUS_REQUEST_URI_TOO_LARGE,
216	B_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE,
217	B_HTTP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE,
218	B_HTTP_STATUS_EXPECTATION_FAILED,
219	B_HTTP_STATUS__CLIENT_ERROR_END,
220
221	// Server error status codes
222	B_HTTP_STATUS__SERVER_ERROR_BASE 	= 500,
223	B_HTTP_STATUS_INTERNAL_SERVER_ERROR = B_HTTP_STATUS__SERVER_ERROR_BASE,
224	B_HTTP_STATUS_NOT_IMPLEMENTED,
225	B_HTTP_STATUS_BAD_GATEWAY,
226	B_HTTP_STATUS_SERVICE_UNAVAILABLE,
227	B_HTTP_STATUS_GATEWAY_TIMEOUT,
228	B_HTTP_STATUS__SERVER_ERROR_END
229};
230
231
232// HTTP default User-Agent
233#define B_HTTP_PROTOCOL_USER_AGENT_FORMAT "ServicesKit (%s)"
234
235#endif // _B_URL_PROTOCOL_HTTP_H_
236