Use soup_message_headers_replace(), not soup_message_headers_append(),
[platform/upstream/libsoup.git] / libsoup / soup-message.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * soup-message.c: HTTP request/response
4  *
5  * Copyright (C) 2000-2003, Ximian, Inc.
6  */
7
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include "soup-auth.h"
12 #include "soup-enum-types.h"
13 #include "soup-marshal.h"
14 #include "soup-message.h"
15 #include "soup-message-private.h"
16 #include "soup-misc.h"
17 #include "soup-uri.h"
18
19 /**
20  * SECTION:soup-message
21  * @short_description: An HTTP request and response.
22  * @see_also: #SoupMessageHeaders, #SoupMessageBody
23  *
24  **/
25
26 /**
27  * SoupMessage:
28  * @method: the HTTP method
29  * @status_code: the HTTP status code
30  * @reason_phrase: the status phrase associated with @status_code
31  * @request_body: the request body
32  * @request_headers: the request headers
33  * @response_body: the response body
34  * @response_headers: the response headers
35  *
36  * Represents an HTTP message being sent or received.
37  *
38  * As described in the #SoupMessageBody documentation, the
39  * @request_body and @response_body %data fields will not necessarily
40  * be filled in at all times. When they are filled in, they will be
41  * terminated with a '\0' byte (which is not included in the %length),
42  * so you can use them as ordinary C strings (assuming that you know
43  * that the body doesn't have any other '\0' bytes).
44  *
45  * For a client-side #SoupMessage, @request_body's %data is usually
46  * filled in right before libsoup writes the request to the network,
47  * but you should not count on this; use soup_message_body_flatten()
48  * if you want to ensure that %data is filled in. @response_body's
49  * %data will be filled in before #SoupMessage::finished is emitted,
50  * unless you set the %SOUP_MESSAGE_OVERWRITE_CHUNKS flag.
51  *
52  * For a server-side #SoupMessage, @request_body's %data will be
53  * filled in before #SoupMessage::got_body is emitted.
54  **/
55
56 G_DEFINE_TYPE (SoupMessage, soup_message, G_TYPE_OBJECT)
57
58 enum {
59         WROTE_INFORMATIONAL,
60         WROTE_HEADERS,
61         WROTE_CHUNK,
62         WROTE_BODY,
63
64         GOT_INFORMATIONAL,
65         GOT_HEADERS,
66         GOT_CHUNK,
67         GOT_BODY,
68
69         RESTARTED,
70         FINISHED,
71
72         LAST_SIGNAL
73 };
74
75 static guint signals[LAST_SIGNAL] = { 0 };
76
77 enum {
78         PROP_0,
79
80         PROP_METHOD,
81         PROP_URI,
82         PROP_HTTP_VERSION,
83         PROP_FLAGS,
84         PROP_STATUS_CODE,
85         PROP_REASON_PHRASE,
86
87         LAST_PROP
88 };
89
90 static void got_body (SoupMessage *req);
91 static void restarted (SoupMessage *req);
92 static void finished (SoupMessage *req);
93
94 static void set_property (GObject *object, guint prop_id,
95                           const GValue *value, GParamSpec *pspec);
96 static void get_property (GObject *object, guint prop_id,
97                           GValue *value, GParamSpec *pspec);
98
99 static void
100 soup_message_init (SoupMessage *msg)
101 {
102         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
103
104         priv->io_status = SOUP_MESSAGE_IO_STATUS_IDLE;
105         priv->http_version = SOUP_HTTP_1_1;
106
107         msg->request_body = soup_message_body_new ();
108         msg->request_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_REQUEST);
109         msg->response_body = soup_message_body_new ();
110         msg->response_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE);
111 }
112
113 static void
114 finalize (GObject *object)
115 {
116         SoupMessage *msg = SOUP_MESSAGE (object);
117         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
118
119         soup_message_io_cleanup (msg);
120
121         if (priv->uri)
122                 soup_uri_free (priv->uri);
123
124         if (priv->auth)
125                 g_object_unref (priv->auth);
126         if (priv->proxy_auth)
127                 g_object_unref (priv->proxy_auth);
128
129         soup_message_body_free (msg->request_body);
130         soup_message_headers_free (msg->request_headers);
131         soup_message_body_free (msg->response_body);
132         soup_message_headers_free (msg->response_headers);
133
134         g_free ((char *) msg->reason_phrase);
135
136         G_OBJECT_CLASS (soup_message_parent_class)->finalize (object);
137 }
138
139 static void
140 soup_message_class_init (SoupMessageClass *message_class)
141 {
142         GObjectClass *object_class = G_OBJECT_CLASS (message_class);
143
144         g_type_class_add_private (message_class, sizeof (SoupMessagePrivate));
145
146         /* virtual method definition */
147         message_class->got_body     = got_body;
148         message_class->restarted    = restarted;
149         message_class->finished     = finished;
150
151         /* virtual method override */
152         object_class->finalize = finalize;
153         object_class->set_property = set_property;
154         object_class->get_property = get_property;
155
156         /* signals */
157
158         /**
159          * SoupMessage::wrote-informational:
160          * @msg: the message
161          *
162          * Emitted immediately after writing a 1xx (Informational)
163          * response for a (server-side) message.
164          **/
165         signals[WROTE_INFORMATIONAL] =
166                 g_signal_new ("wrote_informational",
167                               G_OBJECT_CLASS_TYPE (object_class),
168                               G_SIGNAL_RUN_FIRST,
169                               G_STRUCT_OFFSET (SoupMessageClass, wrote_informational),
170                               NULL, NULL,
171                               soup_marshal_NONE__NONE,
172                               G_TYPE_NONE, 0);
173
174         /**
175          * SoupMessage::wrote-headers:
176          * @msg: the message
177          *
178          * Emitted immediately after writing the headers for a
179          * message. (For a client-side message, this is after writing
180          * the request headers; for a server-side message, it is after
181          * writing the response headers.)
182          **/
183         signals[WROTE_HEADERS] =
184                 g_signal_new ("wrote_headers",
185                               G_OBJECT_CLASS_TYPE (object_class),
186                               G_SIGNAL_RUN_FIRST,
187                               G_STRUCT_OFFSET (SoupMessageClass, wrote_headers),
188                               NULL, NULL,
189                               soup_marshal_NONE__NONE,
190                               G_TYPE_NONE, 0);
191
192         /**
193          * SoupMessage::wrote-chunk:
194          * @msg: the message
195          *
196          * Emitted immediately after writing a body chunk for a message.
197          **/
198         signals[WROTE_CHUNK] =
199                 g_signal_new ("wrote_chunk",
200                               G_OBJECT_CLASS_TYPE (object_class),
201                               G_SIGNAL_RUN_FIRST,
202                               G_STRUCT_OFFSET (SoupMessageClass, wrote_chunk),
203                               NULL, NULL,
204                               soup_marshal_NONE__NONE,
205                               G_TYPE_NONE, 0);
206
207         /**
208          * SoupMessage::wrote-body:
209          * @msg: the message
210          *
211          * Emitted immediately after writing the complete body for a
212          * message. (For a client-side message, this means that
213          * libsoup is done writing and is now waiting for the response
214          * from the server. For a server-side message, this means that
215          * libsoup has finished writing the response and is nearly
216          * done with the message.)
217          **/
218         signals[WROTE_BODY] =
219                 g_signal_new ("wrote_body",
220                               G_OBJECT_CLASS_TYPE (object_class),
221                               G_SIGNAL_RUN_FIRST,
222                               G_STRUCT_OFFSET (SoupMessageClass, wrote_body),
223                               NULL, NULL,
224                               soup_marshal_NONE__NONE,
225                               G_TYPE_NONE, 0);
226
227         /**
228          * SoupMessage::got-informational:
229          * @msg: the message
230          *
231          * Emitted after receiving a 1xx (Informational) response for
232          * a (client-side) message. The response_headers will be
233          * filled in with the headers associated with the
234          * informational response; however, those header values will
235          * be erased after this signal is done.
236          *
237          * If you cancel or requeue @msg while processing this signal,
238          * then the current HTTP I/O will be stopped after this signal
239          * emission finished, and @msg's connection will be closed.
240          **/
241         signals[GOT_INFORMATIONAL] =
242                 g_signal_new ("got_informational",
243                               G_OBJECT_CLASS_TYPE (object_class),
244                               G_SIGNAL_RUN_FIRST,
245                               G_STRUCT_OFFSET (SoupMessageClass, got_informational),
246                               NULL, NULL,
247                               soup_marshal_NONE__NONE,
248                               G_TYPE_NONE, 0);
249
250         /**
251          * SoupMessage::got-headers:
252          * @msg: the message
253          *
254          * Emitted after receiving all message headers for a message.
255          * (For a client-side message, this is after receiving the
256          * Status-Line and response headers; for a server-side
257          * message, it is after receiving the Request-Line and request
258          * headers.)
259          *
260          * See also soup_message_add_header_handler() and
261          * soup_message_add_status_code_handler(), which can be used
262          * to connect to a subset of emissions of this signal.
263          *
264          * If you cancel or requeue @msg while processing this signal,
265          * then the current HTTP I/O will be stopped after this signal
266          * emission finished, and @msg's connection will be closed.
267          * (If you need to requeue a message--eg, after handling
268          * authentication or redirection--it is usually better to
269          * requeue it from a #SoupMessage::got_body handler rather
270          * than a #SoupMessage::got_header handler, so that the
271          * existing HTTP connection can be reused.)
272          **/
273         signals[GOT_HEADERS] =
274                 g_signal_new ("got_headers",
275                               G_OBJECT_CLASS_TYPE (object_class),
276                               G_SIGNAL_RUN_FIRST,
277                               G_STRUCT_OFFSET (SoupMessageClass, got_headers),
278                               NULL, NULL,
279                               soup_marshal_NONE__NONE,
280                               G_TYPE_NONE, 0);
281
282         /**
283          * SoupMessage::got-chunk:
284          * @msg: the message
285          * @chunk: the just-read chunk
286          *
287          * Emitted after receiving a chunk of a message body. Note
288          * that "chunk" in this context means any subpiece of the
289          * body, not necessarily the specific HTTP 1.1 chunks sent by
290          * the other side.
291          *
292          * If you cancel or requeue @msg while processing this signal,
293          * then the current HTTP I/O will be stopped after this signal
294          * emission finished, and @msg's connection will be closed.
295          **/
296         signals[GOT_CHUNK] =
297                 g_signal_new ("got_chunk",
298                               G_OBJECT_CLASS_TYPE (object_class),
299                               G_SIGNAL_RUN_FIRST,
300                               G_STRUCT_OFFSET (SoupMessageClass, got_chunk),
301                               NULL, NULL,
302                               soup_marshal_NONE__BOXED,
303                               G_TYPE_NONE, 1,
304                               SOUP_TYPE_BUFFER);
305
306         /**
307          * SoupMessage::got-body:
308          * @msg: the message
309          *
310          * Emitted after receiving the complete message body. (For a
311          * server-side message, this means it has received the request
312          * body. For a client-side message, this means it has received
313          * the response body and is nearly done with the message.)
314          *
315          * See also soup_message_add_header_handler() and
316          * soup_message_add_status_code_handler(), which can be used
317          * to connect to a subset of emissions of this signal.
318          **/
319         signals[GOT_BODY] =
320                 g_signal_new ("got_body",
321                               G_OBJECT_CLASS_TYPE (object_class),
322                               G_SIGNAL_RUN_FIRST,
323                               G_STRUCT_OFFSET (SoupMessageClass, got_body),
324                               NULL, NULL,
325                               soup_marshal_NONE__NONE,
326                               G_TYPE_NONE, 0);
327
328         /**
329          * SoupMessage::restarted:
330          * @msg: the message
331          *
332          * Emitted when a request that was already sent once is now
333          * being sent again (eg, because the first attempt received a
334          * redirection response, or because we needed to use
335          * authentication).
336          **/
337         signals[RESTARTED] =
338                 g_signal_new ("restarted",
339                               G_OBJECT_CLASS_TYPE (object_class),
340                               G_SIGNAL_RUN_FIRST,
341                               G_STRUCT_OFFSET (SoupMessageClass, restarted),
342                               NULL, NULL,
343                               soup_marshal_NONE__NONE,
344                               G_TYPE_NONE, 0);
345
346         /**
347          * SoupMessage::finished:
348          * @msg: the message
349          *
350          * Emitted when all HTTP processing is finished for a message.
351          * (After #SoupMessage::got_body for client-side messages, or
352          * after #SoupMessage::wrote_body for server-side messages.)
353          **/
354         signals[FINISHED] =
355                 g_signal_new ("finished",
356                               G_OBJECT_CLASS_TYPE (object_class),
357                               G_SIGNAL_RUN_FIRST,
358                               G_STRUCT_OFFSET (SoupMessageClass, finished),
359                               NULL, NULL,
360                               soup_marshal_NONE__NONE,
361                               G_TYPE_NONE, 0);
362
363         /* properties */
364         g_object_class_install_property (
365                 object_class, PROP_METHOD,
366                 g_param_spec_string (SOUP_MESSAGE_METHOD,
367                                      "Method",
368                                      "The message's HTTP method",
369                                      SOUP_METHOD_GET,
370                                      G_PARAM_READWRITE));
371         g_object_class_install_property (
372                 object_class, PROP_URI,
373                 g_param_spec_boxed (SOUP_MESSAGE_URI,
374                                     "URI",
375                                     "The message's Request-URI",
376                                     SOUP_TYPE_URI,
377                                     G_PARAM_READWRITE));
378         g_object_class_install_property (
379                 object_class, PROP_HTTP_VERSION,
380                 g_param_spec_enum (SOUP_MESSAGE_HTTP_VERSION,
381                                    "HTTP Version",
382                                    "The HTTP protocol version to use",
383                                    SOUP_TYPE_HTTP_VERSION,
384                                    SOUP_HTTP_1_1,
385                                    G_PARAM_READWRITE));
386         g_object_class_install_property (
387                 object_class, PROP_FLAGS,
388                 g_param_spec_flags (SOUP_MESSAGE_FLAGS,
389                                     "Flags",
390                                     "Various message options",
391                                     SOUP_TYPE_MESSAGE_FLAGS,
392                                     0,
393                                     G_PARAM_READWRITE));
394         g_object_class_install_property (
395                 object_class, PROP_STATUS_CODE,
396                 g_param_spec_uint (SOUP_MESSAGE_STATUS_CODE,
397                                    "Status code",
398                                    "The HTTP response status code",
399                                    0, 599, 0,
400                                    G_PARAM_READWRITE));
401         g_object_class_install_property (
402                 object_class, PROP_REASON_PHRASE,
403                 g_param_spec_string (SOUP_MESSAGE_REASON_PHRASE,
404                                      "Reason phrase",
405                                      "The HTTP response reason phrase",
406                                      NULL,
407                                      G_PARAM_READWRITE));
408 }
409
410 static void
411 set_property (GObject *object, guint prop_id,
412               const GValue *value, GParamSpec *pspec)
413 {
414         SoupMessage *msg = SOUP_MESSAGE (object);
415
416         switch (prop_id) {
417         case PROP_METHOD:
418                 msg->method = g_intern_string (g_value_get_string (value));
419                 break;
420         case PROP_URI:
421                 soup_message_set_uri (msg, g_value_get_boxed (value));
422                 break;
423         case PROP_HTTP_VERSION:
424                 soup_message_set_http_version (msg, g_value_get_enum (value));
425                 break;
426         case PROP_FLAGS:
427                 soup_message_set_flags (msg, g_value_get_flags (value));
428                 break;
429         case PROP_STATUS_CODE:
430                 soup_message_set_status (msg, g_value_get_uint (value));
431                 break;
432         case PROP_REASON_PHRASE:
433                 soup_message_set_status_full (msg, msg->status_code,
434                                               g_value_get_string (value));
435                 break;
436         default:
437                 break;
438         }
439 }
440
441 static void
442 get_property (GObject *object, guint prop_id,
443               GValue *value, GParamSpec *pspec)
444 {
445         SoupMessage *msg = SOUP_MESSAGE (object);
446         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
447
448         switch (prop_id) {
449         case PROP_METHOD:
450                 g_value_set_string (value, msg->method);
451                 break;
452         case PROP_URI:
453                 g_value_set_boxed (value, priv->uri);
454                 break;
455         case PROP_HTTP_VERSION:
456                 g_value_set_enum (value, priv->http_version);
457                 break;
458         case PROP_FLAGS:
459                 g_value_set_flags (value, priv->msg_flags);
460                 break;
461         case PROP_STATUS_CODE:
462                 g_value_set_uint (value, msg->status_code);
463                 break;
464         case PROP_REASON_PHRASE:
465                 g_value_set_string (value, msg->reason_phrase);
466                 break;
467         default:
468                 break;
469         }
470 }
471
472
473 /**
474  * soup_message_new:
475  * @method: the HTTP method for the created request
476  * @uri_string: the destination endpoint (as a string)
477  * 
478  * Creates a new empty #SoupMessage, which will connect to @uri
479  *
480  * Return value: the new #SoupMessage (or %NULL if @uri could not
481  * be parsed).
482  */
483 SoupMessage *
484 soup_message_new (const char *method, const char *uri_string)
485 {
486         SoupMessage *msg;
487         SoupURI *uri;
488
489         g_return_val_if_fail (method != NULL, NULL);
490         g_return_val_if_fail (uri_string != NULL, NULL);
491
492         uri = soup_uri_new (uri_string);
493         if (!uri)
494                 return NULL;
495         if (!uri->host) {
496                 soup_uri_free (uri);
497                 return NULL;
498         }
499
500         msg = soup_message_new_from_uri (method, uri);
501         soup_uri_free (uri);
502         return msg;
503 }
504
505 /**
506  * soup_message_new_from_uri:
507  * @method: the HTTP method for the created request
508  * @uri: the destination endpoint (as a #SoupURI)
509  * 
510  * Creates a new empty #SoupMessage, which will connect to @uri
511  *
512  * Return value: the new #SoupMessage
513  */
514 SoupMessage *
515 soup_message_new_from_uri (const char *method, SoupURI *uri)
516 {
517         return g_object_new (SOUP_TYPE_MESSAGE,
518                              SOUP_MESSAGE_METHOD, method,
519                              SOUP_MESSAGE_URI, uri,
520                              NULL);
521 }
522
523 /**
524  * soup_message_set_request:
525  * @msg: the message
526  * @content_type: MIME Content-Type of the body
527  * @req_use: a #SoupMemoryUse describing how to handle @req_body
528  * @req_body: a data buffer containing the body of the message request.
529  * @req_length: the byte length of @req_body.
530  * 
531  * Convenience function to set the request body of a #SoupMessage. If
532  * @content_type is %NULL, the request body must be empty as well.
533  */
534 void
535 soup_message_set_request (SoupMessage    *msg,
536                           const char     *content_type,
537                           SoupMemoryUse   req_use,
538                           const char     *req_body,
539                           gsize           req_length)
540 {
541         g_return_if_fail (SOUP_IS_MESSAGE (msg));
542         g_return_if_fail (content_type != NULL || req_length == 0);
543
544         if (content_type) {
545                 soup_message_headers_replace (msg->request_headers,
546                                               "Content-Type", content_type);
547                 soup_message_body_append (msg->request_body, req_use,
548                                           req_body, req_length);
549         } else {
550                 soup_message_headers_remove (msg->request_headers,
551                                              "Content-Type");
552                 soup_message_body_truncate (msg->request_body);
553         }
554 }
555
556 /**
557  * soup_message_set_response:
558  * @msg: the message
559  * @content_type: MIME Content-Type of the body
560  * @resp_use: a #SoupMemoryUse describing how to handle @resp_body
561  * @resp_body: a data buffer containing the body of the message response.
562  * @resp_length: the byte length of @resp_body.
563  * 
564  * Convenience function to set the response body of a #SoupMessage. If
565  * @content_type is %NULL, the response body must be empty as well.
566  */
567 void
568 soup_message_set_response (SoupMessage    *msg,
569                            const char     *content_type,
570                            SoupMemoryUse   resp_use,
571                            const char     *resp_body,
572                            gsize           resp_length)
573 {
574         g_return_if_fail (SOUP_IS_MESSAGE (msg));
575         g_return_if_fail (content_type != NULL || resp_length == 0);
576
577         if (content_type) {
578                 soup_message_headers_replace (msg->response_headers,
579                                               "Content-Type", content_type);
580                 soup_message_body_append (msg->response_body, resp_use,
581                                           resp_body, resp_length);
582         } else {
583                 soup_message_headers_remove (msg->response_headers,
584                                              "Content-Type");
585                 soup_message_body_truncate (msg->response_body);
586         }
587 }
588
589 /**
590  * soup_message_wrote_informational:
591  * @msg: a #SoupMessage
592  *
593  * Emits the %wrote_informational signal, indicating that the IO layer
594  * finished writing an informational (1xx) response for @msg.
595  **/
596 void
597 soup_message_wrote_informational (SoupMessage *msg)
598 {
599         g_signal_emit (msg, signals[WROTE_INFORMATIONAL], 0);
600 }
601
602 /**
603  * soup_message_wrote_headers:
604  * @msg: a #SoupMessage
605  *
606  * Emits the %wrote_headers signal, indicating that the IO layer
607  * finished writing the (non-informational) headers for @msg.
608  **/
609 void
610 soup_message_wrote_headers (SoupMessage *msg)
611 {
612         g_signal_emit (msg, signals[WROTE_HEADERS], 0);
613 }
614
615 /**
616  * soup_message_wrote_chunk:
617  * @msg: a #SoupMessage
618  *
619  * Emits the %wrote_chunk signal, indicating that the IO layer
620  * finished writing a chunk of @msg's body.
621  **/
622 void
623 soup_message_wrote_chunk (SoupMessage *msg)
624 {
625         g_signal_emit (msg, signals[WROTE_CHUNK], 0);
626 }
627
628 /**
629  * soup_message_wrote_body:
630  * @msg: a #SoupMessage
631  *
632  * Emits the %wrote_body signal, indicating that the IO layer finished
633  * writing the body for @msg.
634  **/
635 void
636 soup_message_wrote_body (SoupMessage *msg)
637 {
638         g_signal_emit (msg, signals[WROTE_BODY], 0);
639 }
640
641 /**
642  * soup_message_got_informational:
643  * @msg: a #SoupMessage
644  *
645  * Emits the %got_informational signal, indicating that the IO layer
646  * read a complete informational (1xx) response for @msg.
647  **/
648 void
649 soup_message_got_informational (SoupMessage *msg)
650 {
651         g_signal_emit (msg, signals[GOT_INFORMATIONAL], 0);
652 }
653
654 /**
655  * soup_message_got_headers:
656  * @msg: a #SoupMessage
657  *
658  * Emits the %got_headers signal, indicating that the IO layer
659  * finished reading the (non-informational) headers for @msg.
660  **/
661 void
662 soup_message_got_headers (SoupMessage *msg)
663 {
664         g_signal_emit (msg, signals[GOT_HEADERS], 0);
665 }
666
667 /**
668  * soup_message_got_chunk:
669  * @msg: a #SoupMessage
670  * @chunk: the newly-read chunk
671  *
672  * Emits the %got_chunk signal, indicating that the IO layer finished
673  * reading a chunk of @msg's body.
674  **/
675 void
676 soup_message_got_chunk (SoupMessage *msg, SoupBuffer *chunk)
677 {
678         g_signal_emit (msg, signals[GOT_CHUNK], 0, chunk);
679 }
680
681 static void
682 got_body (SoupMessage *req)
683 {
684         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (req);
685
686         if (!(priv->msg_flags & SOUP_MESSAGE_OVERWRITE_CHUNKS)) {
687                 SoupBuffer *buffer;
688
689                 /* Figure out *which* body we read, and flatten it. */
690                 if (req->status_code == 0)
691                         buffer = soup_message_body_flatten (req->request_body);
692                 else
693                         buffer = soup_message_body_flatten (req->response_body);
694                 soup_buffer_free (buffer);
695         }
696 }
697
698 /**
699  * soup_message_got_body:
700  * @msg: a #SoupMessage
701  *
702  * Emits the %got_body signal, indicating that the IO layer finished
703  * reading the body for @msg.
704  **/
705 void
706 soup_message_got_body (SoupMessage *msg)
707 {
708         g_signal_emit (msg, signals[GOT_BODY], 0);
709 }
710
711 static void
712 restarted (SoupMessage *req)
713 {
714         soup_message_io_stop (req);
715 }
716
717 /**
718  * soup_message_restarted:
719  * @msg: a #SoupMessage
720  *
721  * Emits the %restarted signal, indicating that @msg should be
722  * requeued.
723  **/
724 void
725 soup_message_restarted (SoupMessage *msg)
726 {
727         g_signal_emit (msg, signals[RESTARTED], 0);
728 }
729
730 static void
731 finished (SoupMessage *req)
732 {
733         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (req);
734
735         soup_message_io_stop (req);
736         priv->io_status = SOUP_MESSAGE_IO_STATUS_FINISHED;
737 }
738
739 /**
740  * soup_message_finished:
741  * @msg: a #SoupMessage
742  *
743  * Emits the %finished signal, indicating that @msg has been completely
744  * processed.
745  **/
746 void
747 soup_message_finished (SoupMessage *msg)
748 {
749         g_signal_emit (msg, signals[FINISHED], 0);
750 }
751
752 static void
753 header_handler_free (gpointer header_name, GClosure *closure)
754 {
755         g_free (header_name);
756 }
757
758 static void
759 header_handler_metamarshal (GClosure *closure, GValue *return_value,
760                             guint n_param_values, const GValue *param_values,
761                             gpointer invocation_hint, gpointer marshal_data)
762 {
763         SoupMessage *msg = g_value_get_object (&param_values[0]);
764         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
765         const char *header_name = marshal_data;
766         SoupMessageHeaders *hdrs;
767
768         if (priv->io_status != SOUP_MESSAGE_IO_STATUS_RUNNING)
769                 return;
770
771         /* If status_code is SOUP_STATUS_NONE, we're still processing
772          * the request side; if it's not, we're processing the
773          * response side.
774          */
775         hdrs = (msg->status_code == SOUP_STATUS_NONE) ?
776                 msg->request_headers : msg->response_headers;
777
778         if (soup_message_headers_get (hdrs, header_name)) {
779                 closure->marshal (closure, return_value, n_param_values,
780                                   param_values, invocation_hint,
781                                   ((GCClosure *)closure)->callback);
782         }
783 }
784
785 /**
786  * soup_message_add_header_handler:
787  * @msg: a #SoupMessage
788  * @signal: signal to connect the handler to.
789  * @header: HTTP response header to match against
790  * @callback: the header handler
791  * @user_data: data to pass to @handler_cb
792  *
793  * Adds a signal handler to @msg for @signal, as with
794  * g_signal_connect(), but with two differences: the @callback will
795  * only be run if @msg has a header named @header, and it will only be
796  * run if no earlier handler cancelled or requeued the message.
797  *
798  * If @signal is one of the "got" signals (eg, "got_headers"), or
799  * "finished" or "restarted", then @header is matched against the
800  * incoming message headers (that is, the #request_headers for a
801  * client #SoupMessage, or the #response_headers for a server
802  * #SoupMessage). If @signal is one of the "wrote" signals, then
803  * @header is matched against the outgoing message headers.
804  *
805  * Return value: the handler ID from g_signal_connect()
806  **/
807 guint
808 soup_message_add_header_handler (SoupMessage *msg,
809                                  const char  *signal,
810                                  const char  *header,
811                                  GCallback    callback,
812                                  gpointer     user_data)
813 {
814         SoupMessagePrivate *priv;
815         GClosure *closure;
816         char *header_name;
817
818         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
819         g_return_val_if_fail (signal != NULL, 0);
820         g_return_val_if_fail (header != NULL, 0);
821         g_return_val_if_fail (callback != NULL, 0);
822
823         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
824
825         closure = g_cclosure_new (callback, user_data, NULL);
826
827         header_name = g_strdup (header);
828         g_closure_set_meta_marshal (closure, header_name,
829                                     header_handler_metamarshal);
830         g_closure_add_finalize_notifier (closure, header_name,
831                                          header_handler_free);
832
833         return g_signal_connect_closure (msg, signal, closure, FALSE);
834 }
835
836 static void
837 status_handler_metamarshal (GClosure *closure, GValue *return_value,
838                             guint n_param_values, const GValue *param_values,
839                             gpointer invocation_hint, gpointer marshal_data)
840 {
841         SoupMessage *msg = g_value_get_object (&param_values[0]);
842         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
843         guint status = GPOINTER_TO_UINT (marshal_data);
844
845         if (priv->io_status != SOUP_MESSAGE_IO_STATUS_RUNNING)
846                 return;
847
848         if (msg->status_code == status) {
849                 closure->marshal (closure, return_value, n_param_values,
850                                   param_values, invocation_hint,
851                                   ((GCClosure *)closure)->callback);
852         }
853 }
854
855 /**
856  * soup_message_add_status_code_handler:
857  * @msg: a #SoupMessage
858  * @signal: signal to connect the handler to.
859  * @status_code: status code to match against
860  * @callback: the header handler
861  * @user_data: data to pass to @handler_cb
862  *
863  * Adds a signal handler to @msg for @signal, as with
864  * g_signal_connect() but with two differences: the @callback will
865  * only be run if @msg has the status @status_code, and it will only
866  * be run if no earlier handler cancelled or requeued the message.
867  *
868  * @signal must be a signal that will be emitted after @msg's status
869  * is set. For a client #SoupMessage, this means it can't be a "wrote"
870  * signal. For a server #SoupMessage, this means it can't be a "got"
871  * signal.
872  *
873  * Return value: the handler ID from g_signal_connect()
874  **/
875 guint
876 soup_message_add_status_code_handler (SoupMessage *msg,
877                                       const char  *signal,
878                                       guint        status_code,
879                                       GCallback    callback,
880                                       gpointer     user_data)
881 {
882         GClosure *closure;
883
884         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
885         g_return_val_if_fail (signal != NULL, 0);
886         g_return_val_if_fail (callback != NULL, 0);
887
888         closure = g_cclosure_new (callback, user_data, NULL);
889         g_closure_set_meta_marshal (closure, GUINT_TO_POINTER (status_code),
890                                     status_handler_metamarshal);
891
892         return g_signal_connect_closure (msg, signal, closure, FALSE);
893 }
894
895
896 /**
897  * soup_message_set_auth:
898  * @msg: a #SoupMessage
899  * @auth: a #SoupAuth, or %NULL
900  *
901  * Sets @msg to authenticate to its destination using @auth, which
902  * must have already been fully authenticated. If @auth is %NULL, @msg
903  * will not authenticate to its destination.
904  **/
905 void
906 soup_message_set_auth (SoupMessage *msg, SoupAuth *auth)
907 {
908         SoupMessagePrivate *priv;
909         char *token;
910
911         g_return_if_fail (SOUP_IS_MESSAGE (msg));
912         g_return_if_fail (auth == NULL || SOUP_IS_AUTH (auth));
913         g_return_if_fail (auth == NULL || soup_auth_is_authenticated (auth));
914
915         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
916
917         if (priv->auth) {
918                 g_object_unref (priv->auth);
919                 soup_message_headers_remove (msg->request_headers,
920                                              "Authorization");
921         }
922         priv->auth = auth;
923         if (!priv->auth)
924                 return;
925
926         g_object_ref (priv->auth);
927         token = soup_auth_get_authorization (auth, msg);
928         soup_message_headers_replace (msg->request_headers,
929                                       "Authorization", token);
930         g_free (token);
931 }
932
933 /**
934  * soup_message_get_auth:
935  * @msg: a #SoupMessage
936  *
937  * Gets the #SoupAuth used by @msg for authentication.
938  *
939  * Return value: the #SoupAuth used by @msg for authentication, or
940  * %NULL if @msg is unauthenticated.
941  **/
942 SoupAuth *
943 soup_message_get_auth (SoupMessage *msg)
944 {
945         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
946
947         return SOUP_MESSAGE_GET_PRIVATE (msg)->auth;
948 }
949
950 /**
951  * soup_message_set_proxy_auth:
952  * @msg: a #SoupMessage
953  * @auth: a #SoupAuth, or %NULL
954  *
955  * Sets @msg to authenticate to its proxy using @auth, which must have
956  * already been fully authenticated. If @auth is %NULL, @msg will not
957  * authenticate to its proxy.
958  **/
959 void
960 soup_message_set_proxy_auth (SoupMessage *msg, SoupAuth *auth)
961 {
962         SoupMessagePrivate *priv;
963         char *token;
964
965         g_return_if_fail (SOUP_IS_MESSAGE (msg));
966         g_return_if_fail (auth == NULL || SOUP_IS_AUTH (auth));
967         g_return_if_fail (auth == NULL || soup_auth_is_authenticated (auth));
968
969         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
970
971         if (priv->proxy_auth) {
972                 g_object_unref (priv->proxy_auth);
973                 soup_message_headers_remove (msg->request_headers,
974                                              "Proxy-Authorization");
975         }
976         priv->proxy_auth = auth;
977         if (!priv->proxy_auth)
978                 return;
979
980         g_object_ref (priv->proxy_auth);
981         token = soup_auth_get_authorization (auth, msg);
982         soup_message_headers_replace (msg->request_headers,
983                                       "Proxy-Authorization", token);
984         g_free (token);
985 }
986
987 /**
988  * soup_message_get_proxy_auth:
989  * @msg: a #SoupMessage
990  *
991  * Gets the #SoupAuth used by @msg for authentication to its proxy..
992  *
993  * Return value: the #SoupAuth used by @msg for authentication to its
994  * proxy, or %NULL if @msg isn't authenticated to its proxy.
995  **/
996 SoupAuth *
997 soup_message_get_proxy_auth (SoupMessage *msg)
998 {
999         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1000
1001         return SOUP_MESSAGE_GET_PRIVATE (msg)->proxy_auth;
1002 }
1003
1004 /**
1005  * soup_message_cleanup_response:
1006  * @req: a #SoupMessage
1007  *
1008  * Cleans up all response data on @req, so that the request can be sent
1009  * again and receive a new response. (Eg, as a result of a redirect or
1010  * authorization request.)
1011  **/
1012 void
1013 soup_message_cleanup_response (SoupMessage *req)
1014 {
1015         soup_message_body_truncate (req->response_body);
1016         soup_message_headers_clear (req->response_headers);
1017
1018         req->status_code = SOUP_STATUS_NONE;
1019         if (req->reason_phrase) {
1020                 g_free ((char *) req->reason_phrase);
1021                 req->reason_phrase = NULL;
1022         }
1023         g_object_notify (G_OBJECT (req), SOUP_MESSAGE_STATUS_CODE);
1024         g_object_notify (G_OBJECT (req), SOUP_MESSAGE_REASON_PHRASE);
1025 }
1026
1027 /**
1028  * SoupMessageFlags:
1029  * @SOUP_MESSAGE_NO_REDIRECT: The session should not follow redirect
1030  * (3xx) responses received by this message.
1031  * @SOUP_MESSAGE_OVERWRITE_CHUNKS: Each chunk of the response will be
1032  * freed after its corresponding %got_chunk signal is emitted, meaning
1033  * %response will still be empty after the message is complete. You
1034  * can use this to save memory if you expect the response to be large
1035  * and you are able to process it a chunk at a time.
1036  *
1037  * Various flags that can be set on a #SoupMessage to alter its
1038  * behavior.
1039  **/
1040
1041 /**
1042  * soup_message_set_flags:
1043  * @msg: a #SoupMessage
1044  * @flags: a set of #SoupMessageFlags values
1045  *
1046  * Sets the specified flags on @msg.
1047  **/
1048 void
1049 soup_message_set_flags (SoupMessage *msg, SoupMessageFlags flags)
1050 {
1051         g_return_if_fail (SOUP_IS_MESSAGE (msg));
1052
1053         SOUP_MESSAGE_GET_PRIVATE (msg)->msg_flags = flags;
1054         g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_FLAGS);
1055 }
1056
1057 /**
1058  * soup_message_get_flags:
1059  * @msg: a #SoupMessage
1060  *
1061  * Gets the flags on @msg
1062  *
1063  * Return value: the flags
1064  **/
1065 SoupMessageFlags
1066 soup_message_get_flags (SoupMessage *msg)
1067 {
1068         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
1069
1070         return SOUP_MESSAGE_GET_PRIVATE (msg)->msg_flags;
1071 }
1072
1073 /**
1074  * SoupHTTPVersion:
1075  * @SOUP_HTTP_1_0: HTTP 1.0 (RFC 1945)
1076  * @SOUP_HTTP_1_1: HTTP 1.1 (RFC 2616)
1077  *
1078  * Indicates the HTTP protocol version being used.
1079  **/
1080
1081 /**
1082  * soup_message_set_http_version:
1083  * @msg: a #SoupMessage
1084  * @version: the HTTP version
1085  *
1086  * Sets the HTTP version on @msg. The default version is
1087  * %SOUP_HTTP_1_1. Setting it to %SOUP_HTTP_1_0 will prevent certain
1088  * functionality from being used.
1089  **/
1090 void
1091 soup_message_set_http_version (SoupMessage *msg, SoupHTTPVersion version)
1092 {
1093         g_return_if_fail (SOUP_IS_MESSAGE (msg));
1094
1095         SOUP_MESSAGE_GET_PRIVATE (msg)->http_version = version;
1096         g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_HTTP_VERSION);
1097 }
1098
1099 /**
1100  * soup_message_get_http_version:
1101  * @msg: a #SoupMessage
1102  *
1103  * Gets the HTTP version of @msg. This is the minimum of the
1104  * version from the request and the version from the response.
1105  *
1106  * Return value: the HTTP version
1107  **/
1108 SoupHTTPVersion
1109 soup_message_get_http_version (SoupMessage *msg)
1110 {
1111         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), SOUP_HTTP_1_0);
1112
1113         return SOUP_MESSAGE_GET_PRIVATE (msg)->http_version;
1114 }
1115
1116 /**
1117  * soup_message_is_keepalive:
1118  * @msg: a #SoupMessage
1119  *
1120  * Determines whether or not @msg's connection can be kept alive for
1121  * further requests after processing @msg, based on the HTTP version,
1122  * Connection header, etc.
1123  *
1124  * Return value: %TRUE or %FALSE.
1125  **/
1126 gboolean
1127 soup_message_is_keepalive (SoupMessage *msg)
1128 {
1129         const char *c_conn, *s_conn;
1130
1131         c_conn = soup_message_headers_get (msg->request_headers, "Connection");
1132         s_conn = soup_message_headers_get (msg->response_headers, "Connection");
1133
1134         if (msg->status_code == SOUP_STATUS_OK &&
1135             msg->method == SOUP_METHOD_CONNECT)
1136                 return TRUE;
1137
1138         if (SOUP_MESSAGE_GET_PRIVATE (msg)->http_version == SOUP_HTTP_1_0) {
1139                 /* Only persistent if the client requested keepalive
1140                  * and the server agreed.
1141                  */
1142
1143                 if (!c_conn || !s_conn)
1144                         return FALSE;
1145                 if (soup_header_contains (c_conn, "Keep-Alive") ||
1146                     soup_header_contains (s_conn, "Keep-Alive"))
1147                         return FALSE;
1148
1149                 return TRUE;
1150         } else {
1151                 /* Normally persistent unless either side requested otherwise */
1152                 if (c_conn && soup_header_contains (c_conn, "close"))
1153                         return FALSE;
1154                 if (s_conn && soup_header_contains (s_conn, "close"))
1155                         return FALSE;
1156
1157                 /* But not if the server sent a terminate-by-EOF response */
1158                 if (soup_message_headers_get_encoding (msg->response_headers) == SOUP_ENCODING_EOF)
1159                         return FALSE;
1160
1161                 return TRUE;
1162         }
1163 }
1164
1165 /**
1166  * soup_message_set_uri:
1167  * @msg: a #SoupMessage
1168  * @uri: the new #SoupURI
1169  *
1170  * Sets @msg's URI to @uri. If @msg has already been sent and you want
1171  * to re-send it with the new URI, you need to call
1172  * soup_session_requeue_message().
1173  **/
1174 void
1175 soup_message_set_uri (SoupMessage *msg, SoupURI *uri)
1176 {
1177         SoupMessagePrivate *priv;
1178
1179         g_return_if_fail (SOUP_IS_MESSAGE (msg));
1180         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1181
1182         if (priv->uri)
1183                 soup_uri_free (priv->uri);
1184         priv->uri = soup_uri_copy (uri);
1185
1186         g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_URI);
1187 }
1188
1189 /**
1190  * soup_message_get_uri:
1191  * @msg: a #SoupMessage
1192  *
1193  * Gets @msg's URI
1194  *
1195  * Return value: the URI @msg is targeted for.
1196  **/
1197 SoupURI *
1198 soup_message_get_uri (SoupMessage *msg)
1199 {
1200         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1201
1202         return SOUP_MESSAGE_GET_PRIVATE (msg)->uri;
1203 }
1204
1205 /**
1206  * soup_message_set_status:
1207  * @msg: a #SoupMessage
1208  * @status_code: an HTTP status code
1209  *
1210  * Sets @msg's status code to @status_code. If @status_code is a
1211  * known value, it will also set @msg's reason_phrase.
1212  **/
1213 void
1214 soup_message_set_status (SoupMessage *msg, guint status_code)
1215 {
1216         g_return_if_fail (SOUP_IS_MESSAGE (msg));
1217         g_return_if_fail (status_code != 0);
1218
1219         g_free ((char *) msg->reason_phrase);
1220
1221         msg->status_code = status_code;
1222         msg->reason_phrase = g_strdup (soup_status_get_phrase (status_code));
1223         g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_STATUS_CODE);
1224         g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_REASON_PHRASE);
1225 }
1226
1227 /**
1228  * soup_message_set_status_full:
1229  * @msg: a #SoupMessage
1230  * @status_code: an HTTP status code
1231  * @reason_phrase: a description of the status
1232  *
1233  * Sets @msg's status code and reason phrase.
1234  **/
1235 void
1236 soup_message_set_status_full (SoupMessage *msg,
1237                               guint        status_code,
1238                               const char  *reason_phrase)
1239 {
1240         g_return_if_fail (SOUP_IS_MESSAGE (msg));
1241         g_return_if_fail (status_code != 0);
1242         g_return_if_fail (reason_phrase != NULL);
1243
1244         g_free ((char *) msg->reason_phrase);
1245
1246         msg->status_code = status_code;
1247         msg->reason_phrase = g_strdup (reason_phrase);
1248         g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_STATUS_CODE);
1249         g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_REASON_PHRASE);
1250 }
1251
1252 void
1253 soup_message_set_io_status (SoupMessage          *msg,
1254                             SoupMessageIOStatus   status)
1255 {
1256         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1257
1258         priv->io_status = status;
1259 }
1260
1261 SoupMessageIOStatus
1262 soup_message_get_io_status (SoupMessage *msg)
1263 {
1264         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1265
1266         return priv->io_status;
1267 }