VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox4/include/HappyHttp.h@ 10971

Last change on this file since 10971 was 8155, checked in by vboxsync, 17 years ago

The Big Sun Rebranding Header Change

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 9.9 KB
Line 
1/** @file
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * HappyHTTP library.
5 * Modified for VirtualBox. Original copyright below.
6 */
7
8/*
9 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
20 * Clara, CA 95054 USA or visit http://www.sun.com if you need
21 * additional information or have any questions.
22 */
23
24/*
25 * HappyHTTP - a simple HTTP library
26 * Version 0.1
27 *
28 * Copyright (c) 2006 Ben Campbell
29 *
30 * This software is provided 'as-is', without any express or implied
31 * warranty. In no event will the authors be held liable for any damages
32 * arising from the use of this software.
33 *
34 * Permission is granted to anyone to use this software for any purpose,
35 * including commercial applications, and to alter it and redistribute it
36 * freely, subject to the following restrictions:
37 *
38 * 1. The origin of this software must not be misrepresented; you must not
39 * claim that you wrote the original software. If you use this software in a
40 * product, an acknowledgment in the product documentation would be
41 * appreciated but is not required.
42 *
43 * 2. Altered source versions must be plainly marked as such, and must not
44 * be misrepresented as being the original software.
45 *
46 * 3. This notice may not be removed or altered from any source distribution.
47 *
48 */
49
50
51#ifndef HAPPYHTTP_H
52#define HAPPYHTTP_H
53
54
55#include <string>
56#include <map>
57#include <vector>
58#include <deque>
59
60
61
62
63// forward decl
64struct in_addr;
65
66namespace happyhttp
67{
68
69
70class Response;
71
72// Helper Functions
73void BailOnSocketError( const char* context );
74struct in_addr *atoaddr( const char* address);
75
76
77typedef void (*ResponseBegin_CB)( const Response* r, void* userdata );
78typedef void (*ResponseData_CB)( const Response* r, void* userdata, const unsigned char* data, int numbytes );
79typedef void (*ResponseComplete_CB)( const Response* r, void* userdata );
80
81
82// HTTP status codes
83enum {
84 // 1xx informational
85 CONTINUE = 100,
86 SWITCHING_PROTOCOLS = 101,
87 PROCESSING = 102,
88
89 // 2xx successful
90 OK = 200,
91 CREATED = 201,
92 ACCEPTED = 202,
93 NON_AUTHORITATIVE_INFORMATION = 203,
94 NO_CONTENT = 204,
95 RESET_CONTENT = 205,
96 PARTIAL_CONTENT = 206,
97 MULTI_STATUS = 207,
98 IM_USED = 226,
99
100 // 3xx redirection
101 MULTIPLE_CHOICES = 300,
102 MOVED_PERMANENTLY = 301,
103 FOUND = 302,
104 SEE_OTHER = 303,
105 NOT_MODIFIED = 304,
106 USE_PROXY = 305,
107 TEMPORARY_REDIRECT = 307,
108
109 // 4xx client error
110 BAD_REQUEST = 400,
111 UNAUTHORIZED = 401,
112 PAYMENT_REQUIRED = 402,
113 FORBIDDEN = 403,
114 NOT_FOUND = 404,
115 METHOD_NOT_ALLOWED = 405,
116 NOT_ACCEPTABLE = 406,
117 PROXY_AUTHENTICATION_REQUIRED = 407,
118 REQUEST_TIMEOUT = 408,
119 CONFLICT = 409,
120 GONE = 410,
121 LENGTH_REQUIRED = 411,
122 PRECONDITION_FAILED = 412,
123 REQUEST_ENTITY_TOO_LARGE = 413,
124 REQUEST_URI_TOO_LONG = 414,
125 UNSUPPORTED_MEDIA_TYPE = 415,
126 REQUESTED_RANGE_NOT_SATISFIABLE = 416,
127 EXPECTATION_FAILED = 417,
128 UNPROCESSABLE_ENTITY = 422,
129 LOCKED = 423,
130 FAILED_DEPENDENCY = 424,
131 UPGRADE_REQUIRED = 426,
132
133 // 5xx server error
134 INTERNAL_SERVER_ERROR = 500,
135 NOT_IMPLEMENTED = 501,
136 BAD_GATEWAY = 502,
137 SERVICE_UNAVAILABLE = 503,
138 GATEWAY_TIMEOUT = 504,
139 HTTP_VERSION_NOT_SUPPORTED = 505,
140 INSUFFICIENT_STORAGE = 507,
141 NOT_EXTENDED = 510,
142};
143
144
145
146// Exception class
147
148class Wobbly
149{
150public:
151 Wobbly( const char* fmt, ... );
152 const char* what() const
153 { return m_Message; }
154protected:
155 enum { MAXLEN=256 };
156 char m_Message[ MAXLEN ];
157};
158
159
160
161//-------------------------------------------------
162// Connection
163//
164// Handles the socket connection, issuing of requests and managing
165// responses.
166// ------------------------------------------------
167
168class Connection
169{
170 friend class Response;
171public:
172 // doesn't connect immediately
173 Connection( const char* host, int port );
174 ~Connection();
175
176 // Set up the response handling callbacks. These will be invoked during
177 // calls to pump().
178 // begincb - called when the responses headers have been received
179 // datacb - called repeatedly to handle body data
180 // completecb - response is completed
181 // userdata is passed as a param to all callbacks.
182 void setcallbacks(
183 ResponseBegin_CB begincb,
184 ResponseData_CB datacb,
185 ResponseComplete_CB completecb,
186 void* userdata );
187
188 // Don't need to call connect() explicitly as issuing a request will
189 // call it automatically if needed.
190 // But it could block (for name lookup etc), so you might prefer to
191 // call it in advance.
192 void connect();
193
194 // close connection, discarding any pending requests.
195 void close();
196
197 // Update the connection (non-blocking)
198 // Just keep calling this regularly to service outstanding requests.
199 void pump();
200
201 // any requests still outstanding?
202 bool outstanding() const
203 { return !m_Outstanding.empty(); }
204
205 // ---------------------------
206 // high-level request interface
207 // ---------------------------
208
209 // method is "GET", "POST" etc...
210 // url is only path part: eg "/index.html"
211 // headers is array of name/value pairs, terminated by a null-ptr
212 // body & bodysize specify body data of request (eg values for a form)
213 void request( const char* method, const char* url, const char* headers[]=0,
214 const unsigned char* body=0, int bodysize=0 );
215
216 // ---------------------------
217 // low-level request interface
218 // ---------------------------
219
220 // begin request
221 // method is "GET", "POST" etc...
222 // url is only path part: eg "/index.html"
223 void putrequest( const char* method, const char* url );
224
225 // Add a header to the request (call after putrequest() )
226 void putheader( const char* header, const char* value );
227 void putheader( const char* header, int numericvalue ); // alternate version
228
229 // Finished adding headers, issue the request.
230 void endheaders();
231
232 // send body data if any.
233 // To be called after endheaders()
234 void send( const unsigned char* buf, int numbytes );
235
236protected:
237 // some bits of implementation exposed to Response class
238
239 // callbacks
240 ResponseBegin_CB m_ResponseBeginCB;
241 ResponseData_CB m_ResponseDataCB;
242 ResponseComplete_CB m_ResponseCompleteCB;
243 void* m_UserData;
244
245private:
246 enum { IDLE, REQ_STARTED, REQ_SENT } m_State;
247 std::string m_Host;
248 int m_Port;
249 int m_Sock;
250 std::vector< std::string > m_Buffer; // lines of request
251
252 std::deque< Response* > m_Outstanding; // responses for outstanding requests
253};
254
255
256
257
258
259
260//-------------------------------------------------
261// Response
262//
263// Handles parsing of response data.
264// ------------------------------------------------
265
266
267class Response
268{
269 friend class Connection;
270public:
271
272 // retrieve a header (returns 0 if not present)
273 const char* getheader( const char* name ) const;
274
275 bool completed() const
276 { return m_State == COMPLETE; }
277
278
279 // get the HTTP status code
280 int getstatus() const;
281
282 // get the HTTP response reason string
283 const char* getreason() const;
284
285 // true if connection is expected to close after this response.
286 bool willclose() const
287 { return m_WillClose; }
288protected:
289 // interface used by Connection
290
291 // only Connection creates Responses.
292 Response( const char* method, Connection& conn );
293
294 // pump some data in for processing.
295 // Returns the number of bytes used.
296 // Will always return 0 when response is complete.
297 int pump( const unsigned char* data, int datasize );
298
299 // tell response that connection has closed
300 void notifyconnectionclosed();
301
302private:
303 enum {
304 STATUSLINE, // start here. status line is first line of response.
305 HEADERS, // reading in header lines
306 BODY, // waiting for some body data (all or a chunk)
307 CHUNKLEN, // expecting a chunk length indicator (in hex)
308 CHUNKEND, // got the chunk, now expecting a trailing blank line
309 TRAILERS, // reading trailers after body.
310 COMPLETE, // response is complete!
311 } m_State;
312
313 Connection& m_Connection; // to access callback ptrs
314 std::string m_Method; // req method: "GET", "POST" etc...
315
316 // status line
317 std::string m_VersionString; // HTTP-Version
318 int m_Version; // 10: HTTP/1.0 11: HTTP/1.x (where x>=1)
319 int m_Status; // Status-Code
320 std::string m_Reason; // Reason-Phrase
321
322 // header/value pairs
323 std::map<std::string,std::string> m_Headers;
324
325 int m_BytesRead; // body bytes read so far
326 bool m_Chunked; // response is chunked?
327 int m_ChunkLeft; // bytes left in current chunk
328 int m_Length; // -1 if unknown
329 bool m_WillClose; // connection will close at response end?
330
331 std::string m_LineBuf; // line accumulation for states that want it
332 std::string m_HeaderAccum; // accumulation buffer for headers
333
334
335 void FlushHeader();
336 void ProcessStatusLine( std::string const& line );
337 void ProcessHeaderLine( std::string const& line );
338 void ProcessTrailerLine( std::string const& line );
339 void ProcessChunkLenLine( std::string const& line );
340
341 int ProcessDataChunked( const unsigned char* data, int count );
342 int ProcessDataNonChunked( const unsigned char* data, int count );
343
344 void BeginBody();
345 bool CheckClose();
346 void Finish();
347};
348
349
350
351} // end namespace happyhttp
352
353
354#endif // HAPPYHTTP_H
355
356
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette