1 /* GNet - Networking library
2  * Copyright (C) 2000-2004  David Helder
3  * Copyright (C) 2004       Tim-Philipp Müller <tim centricular net>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA  02111-1307, USA.
19  */
20 
21 
22 #ifndef _GNET_CONN_HTTP_H
23 #define _GNET_CONN_HTTP_H
24 
25 #include "conn.h"
26 #include "uri.h"
27 #include "inetaddr.h"
28 
29 G_BEGIN_DECLS
30 
31 /**
32  *   GConnHttpHeaderFlags
33  *   @GNET_CONN_HTTP_FLAG_SKIP_HEADER_CHECK: do not check whether
34  *   the header is a standard header
35  *
36  *   Flags for gnet_conn_http_set_header().
37  *
38  **/
39 typedef enum
40 {
41   GNET_CONN_HTTP_FLAG_SKIP_HEADER_CHECK  = 1
42 } GConnHttpHeaderFlags;
43 
44 /**
45  *   GConnHttpMethod
46  *   @GNET_CONN_HTTP_METHOD_GET: HTTP GET method
47  *   @GNET_CONN_HTTP_METHOD_POST: HTTP POST method
48  *
49  *   HTTP request method.  Use with gnet_conn_http_set_method().
50  *
51  **/
52 typedef enum
53 {
54  GNET_CONN_HTTP_METHOD_GET,
55  GNET_CONN_HTTP_METHOD_POST
56 } GConnHttpMethod;
57 
58 /**
59  *  GConnHttp
60  *
61  *  HTTP Connection. The entire GConnHttp struct is opaque and private.
62  *
63  **/
64 typedef struct _GConnHttp GConnHttp;
65 
66 /**
67  *   GConnHttpError
68  *   @GNET_CONN_HTTP_ERROR_UNSPECIFIED: connection error
69  *   @GNET_CONN_HTTP_ERROR_PROTOCOL_UNSUPPORTED: unsupported protocol (ie. not http)
70  *   @GNET_CONN_HTTP_ERROR_HOSTNAME_RESOLUTION: the hostname could not be resolved
71  *
72  *   Error codes.  Used by #GConnHttpEventError.  Note that
73  *    errors by the HTTP server will be communicated to the
74  *    client via the #GConnHttpEventResponse event.
75  *
76  **/
77 typedef enum
78 {
79  GNET_CONN_HTTP_ERROR_UNSPECIFIED,
80  GNET_CONN_HTTP_ERROR_PROTOCOL_UNSUPPORTED,
81  GNET_CONN_HTTP_ERROR_HOSTNAME_RESOLUTION
82 } GConnHttpError;
83 
84 
85 /***************************************************************************
86  *                                                                         *
87  *   Event structures - work similar to GdkEvent                           *
88  *                                                                         *
89  ***************************************************************************/
90 
91 /**
92  *   GConnHttpEventType
93  *   @GNET_CONN_HTTP_RESOLVED: the host name has been
94  *   resolved or host name resolution failed. The event
95  *   structure will be a #GConnHttpEventResolved structure
96  *   @GNET_CONN_HTTP_CONNECTED: the TCP connection to
97  *   the HTTP server has been established
98  *   @GNET_CONN_HTTP_RESPONSE: the HTTP server has sent
99  *   a response and response headers. The event
100  *   structure will be a #GConnHttpEventResponse structure
101  *   @GNET_CONN_HTTP_REDIRECT: the HTTP server has sent
102  *   a redirect response. The event structure will be a
103  *   #GConnHttpEventRedirect structure
104  *   @GNET_CONN_HTTP_DATA_PARTIAL: data has been received.
105  *   The buffer is caller-owned (ie. owned by GNet), but
106  *   may be emptied using gnet_conn_http_steal_buffer(). The
107  *   event structure will be a #GConnHttpEventData structure
108  *   @GNET_CONN_HTTP_DATA_COMPLETE: data has been received
109  *   in full.  The buffer is caller-owned (ie. owned by GNet),
110  *   but may be emptied using gnet_conn_http_steal_buffer(). The
111  *   event structure will be a #GConnHttpEventData structure
112  *   @GNET_CONN_HTTP_TIMEOUT: the connection timed out
113  *   @GNET_CONN_HTTP_ERROR: #GConnHttp problem (not a server
114  *   error response). The event structure will be a
115  *   #GConnHttpEventError structure
116  *
117  *   GConnHttp event type.
118  *
119  **/
120 typedef enum
121 {
122  GNET_CONN_HTTP_RESOLVED,           /* resolved host name           */
123  GNET_CONN_HTTP_CONNECTED,          /* connected to host            */
124  GNET_CONN_HTTP_RESPONSE,           /* got response (incl. headers) */
125  GNET_CONN_HTTP_REDIRECT,           /* got redirect                 */
126  GNET_CONN_HTTP_DATA_PARTIAL,       /* we got some data             */
127  GNET_CONN_HTTP_DATA_COMPLETE,      /* we got all data              */
128  GNET_CONN_HTTP_TIMEOUT,            /* the connection timed out     */
129  GNET_CONN_HTTP_ERROR               /* GConnHttp problem            */
130 } GConnHttpEventType;
131 
132 typedef struct _GConnHttpEvent         GConnHttpEvent;
133 typedef struct _GConnHttpEventResolved GConnHttpEventResolved;
134 typedef struct _GConnHttpEventResponse GConnHttpEventResponse;
135 typedef struct _GConnHttpEventRedirect GConnHttpEventRedirect;
136 typedef struct _GConnHttpEventData     GConnHttpEventData;
137 typedef struct _GConnHttpEventError    GConnHttpEventError;
138 
139 /**
140  *  GConnHttpEvent
141  *  @type: event type
142  *
143  *  GConnHttp Base Event.  Check event->type and then cast the event
144  *   structure into the corresponding specialised event structure.
145  *
146  **/
147 struct _GConnHttpEvent
148 {
149  GConnHttpEventType   type;           /* type of event (see above)         */
150 
151  /*< private >*/
152  gsize                stsize;         /* size of underlying event struct   */
153  gpointer             padding[4];     /* padding for future expansion      */
154 };
155 
156 /**
157  *  GConnHttpEventResolved
158  *  @ia: a #GInetAddr of the resolved host name.
159  *
160  *  GConnHttp Host Name Resolved Event.  Emitted when the host name has
161  *   been resolved to an IP address, primarily to give progress feedback
162  *   to the user. @ia will be NULL if the host name could not be resolved.
163  *
164  **/
165 struct _GConnHttpEventResolved
166 {
167  /*< private >*/
168  GConnHttpEvent       parent;         /* GConnHttpEvent structure          */
169 
170  /*< public >*/
171  GInetAddr           *ia;             /* GInetAddr of the host name        */
172 
173  /*< private >*/
174  gpointer             padding[4];     /* padding for future expansion      */
175 };
176 
177 /**
178  *  GConnHttpEventRedirect
179  *  @num_redirects: number of redirects so far
180  *  @max_redirects: maximum number of redirects allowed
181  *  @new_location: redirect location, or NULL if not provided
182  *  @auto_redirect: FALSE if action by the client is needed. Set
183  *                  to FALSE to prevent automatic redirection
184  *
185  *  Emitted when the server sends a redirect response.
186  *
187  **/
188 struct _GConnHttpEventRedirect
189 {
190  /*< private >*/
191  GConnHttpEvent       parent;         /* GConnHttpEvent structure          */
192 
193  /*< public >*/
194  guint                num_redirects;  /* number of redirects so far        */
195  guint                max_redirects;  /* max. num. of redirects allowed    */
196  gchar               *new_location;   /* redirect location if provided     */
197  gboolean             auto_redirect;  /* FALSE if action is needed         */
198 
199  /*< private >*/
200  gpointer             padding[4];     /* padding for future expansion      */
201 };
202 
203 /**
204  *  GConnHttpEventResponse
205  *  @response_code: response code from the HTTP server (e.g. 200 or 404)
206  *  @header_fields: array of header field strings, NULL-terminated
207  *  @header_values: array of header value strings, NULL-terminated
208  *
209  *  Emitted when the server has sent a response and response headers.
210  *
211  **/
212 struct _GConnHttpEventResponse
213 {
214  /*< private >*/
215  GConnHttpEvent       parent;         /* GConnHttpEvent structure          */
216 
217  /*< public >*/
218  guint                response_code;  /* response code, e.g. 200, or 404   */
219  gchar              **header_fields;  /* NULL-terminated array of strings  */
220  gchar              **header_values;  /* NULL-terminated array of strings  */
221 
222  /*< private >*/
223  gpointer             padding[8];     /* padding for future expansion      */
224 };
225 
226 /**
227  *  GConnHttpEventData
228  *  @content_length: set if available, otherwise 0
229  *  @data_received: total amount of data received so far
230  *  @buffer: buffer with data received so far. Use
231  *  gnet_conn_http_steal_buffer() to empty the buffer.
232  *  @buffer_length: buffer length
233  *
234  *  Emitted when data has been received. Useful for progress feedback
235  *   to the user or to process data before all of it has been received.
236  *   The client is responsible for emptying the buffer regularly when the
237  *   amount of data received or expected is larger than the amount that
238  *   should be kept in memory (e.g. in the case of large binary files).
239  *
240  **/
241 struct _GConnHttpEventData
242 {
243  /*< private >*/
244  GConnHttpEvent       parent;         /* GConnHttpEvent structure          */
245 
246  /*< public >*/
247  guint64              content_length; /* set if available, otherwise 0     */
248  guint64              data_received;  /* bytes received so far             */
249  const gchar         *buffer;         /* buffer                            */
250  gsize                buffer_length;  /* buffer length                     */
251 
252  /*< private >*/
253  gpointer             padding[8];     /* padding for future expansion      */
254 };
255 
256 /**
257  *  GConnHttpEventError
258  *  @code: one of the #GConnHttpError codes
259  *  @message: clear-text error message (for debugging purposes only)
260  *
261  *  Emitted when an error has occured. Note that HTTP server errors are
262  *   communicated to the client by means of a #GConnHttpEventResponse event.
263  *
264  **/
265 struct _GConnHttpEventError
266 {
267  /*< private >*/
268  GConnHttpEvent       parent;         /* GConnHttpEvent structure          */
269 
270  /*< public >*/
271  GConnHttpError       code;           /* error code                        */
272  gchar               *message;        /* message (use for debugging only)  */
273 
274  /*< private >*/
275  gpointer             padding[4];     /* padding for future expansion      */
276 };
277 
278 /***************************************************************************
279  *                                                                         *
280  *   GConnHttp callback function prototype                                 *
281  *                                                                         *
282  ***************************************************************************/
283 
284 /**
285  *  GConnHttpFunc
286  *  @conn: #GConnHttp
287  *  @event: event (caller-owned, do not free)
288  *  @user_data: user data specified in gnet_conn_http_run()
289  *              or gnet_conn_http_run_async()
290  *
291  *  Callback for #GConnHttp.
292  *
293  *  Check event->type and then cast the event into the appropriate
294  *   event structure. event->type will be one of
295  *
296  *  %GNET_CONN_HTTP_RESOLVED: this event occurs when the host name
297  *  has been resolved or host name resolution failed
298  *
299  *  %GNET_CONN_HTTP_CONNECTED: the TCP connection to the
300  *  HTTP server has been established
301  *
302  *  %GNET_CONN_HTTP_RESPONSE: the HTTP server has sent a response
303  *  and response headers
304  *
305  *  %GNET_CONN_HTTP_REDIRECT: the HTTP server has sent a redirect
306  *  response
307  *
308  *  %GNET_CONN_HTTP_DATA_PARTIAL: data has been read. The buffer is
309  *  owned by GNet and you must not modify it or free it. You can
310  *  take ownership of the buffer with gnet_conn_http_steal_buffer()
311  *
312  *  %GNET_CONN_HTTP_DATA_COMPLETE: data has been received in full.
313  *  The buffer is owned by GNet and you must not modify it or free
314  *  it. You can acquire ownership of the buffer by calling
315  *  gnet_conn_http_steal_buffer()
316  *
317  *  %GNET_CONN_HTTP_TIMEOUT: the connection timed out
318  *
319  *  %GNET_CONN_HTTP_ERROR: #GConnHttp problem (not a server error response)
320  *
321  **/
322 typedef void   (*GConnHttpFunc) (GConnHttp *conn, GConnHttpEvent *event, gpointer user_data);
323 
324 /***************************************************************************
325  *                                                                         *
326  *   GConnHttp API functions                                               *
327  *                                                                         *
328  ***************************************************************************/
329 
330 GConnHttp       *gnet_conn_http_new                (void);
331 
332 gboolean         gnet_conn_http_set_uri            (GConnHttp        *conn,
333                                                     const gchar      *uri);
334 
335 gboolean         gnet_conn_http_set_escaped_uri    (GConnHttp        *conn,
336                                                     const gchar      *uri);
337 
338 gboolean         gnet_conn_http_set_header         (GConnHttp           *conn,
339                                                     const gchar         *field,
340                                                     const gchar         *value,
341                                                     GConnHttpHeaderFlags flags);
342 
343 void             gnet_conn_http_set_max_redirects  (GConnHttp        *conn,
344                                                     guint             num);
345 
346 void             gnet_conn_http_set_timeout        (GConnHttp        *conn,
347                                                     guint             timeout);
348 
349 gboolean         gnet_conn_http_set_user_agent     (GConnHttp        *conn,
350                                                     const gchar      *agent);
351 
352 gboolean         gnet_conn_http_set_method         (GConnHttp        *conn,
353                                                     GConnHttpMethod   method,
354                                                     const gchar      *post_data,
355                                                     gsize             post_data_len);
356 
357 gboolean         gnet_conn_http_set_main_context   (GConnHttp        *conn,
358                                                     GMainContext     *context);
359 
360 void             gnet_conn_http_run_async          (GConnHttp        *conn,
361                                                     GConnHttpFunc     func,
362                                                     gpointer          user_data);
363 
364 gboolean         gnet_conn_http_run                (GConnHttp        *conn,
365                                                     GConnHttpFunc     func,
366                                                     gpointer          user_data);
367 
368 gboolean         gnet_conn_http_steal_buffer       (GConnHttp        *conn,
369                                                     gchar           **buffer,
370                                                     gsize            *length);
371 
372 void             gnet_conn_http_cancel             (GConnHttp        *conn);
373 
374 void             gnet_conn_http_delete             (GConnHttp        *conn);
375 
376 gboolean         gnet_http_get                     (const gchar      *url,
377                                                     gchar           **buffer,
378                                                     gsize            *length,
379                                                     guint            *response);
380 
381 G_END_DECLS
382 
383 #endif /* _GNET_CONN_HTTP_H */
384