Git init
[profile/ivi/libsoup2.4.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-address.h"
12 #include "soup-auth.h"
13 #include "soup-enum-types.h"
14 #include "soup-marshal.h"
15 #include "soup-message.h"
16 #include "soup-message-private.h"
17 #include "soup-misc.h"
18 #include "soup-uri.h"
19
20 /**
21  * SECTION:soup-message
22  * @short_description: An HTTP request and response.
23  * @see_also: #SoupMessageHeaders, #SoupMessageBody
24  *
25  * A #SoupMessage represents an HTTP message that is being sent or
26  * received.
27  *
28  * For client-side usage, you would create a #SoupMessage with
29  * soup_message_new() or soup_message_new_from_uri(), set up its
30  * fields appropriate, and send it via a #SoupSession.
31  *
32  * For server-side usage, #SoupServer will create #SoupMessage<!--
33  * -->s automatically for incoming requests, which your application
34  * will receive via handlers.
35  *
36  * Note that libsoup's terminology here does not quite match the HTTP
37  * specification: in RFC 2616, an "HTTP-message" is
38  * <emphasis>either</emphasis> a Request, <emphasis>or</emphasis> a
39  * Response. In libsoup, a #SoupMessage combines both the request and
40  * the response.
41  **/
42
43 /**
44  * SoupMessage:
45  * @method: the HTTP method
46  * @status_code: the HTTP status code
47  * @reason_phrase: the status phrase associated with @status_code
48  * @request_body: the request body
49  * @request_headers: the request headers
50  * @response_body: the response body
51  * @response_headers: the response headers
52  *
53  * Represents an HTTP message being sent or received.
54  *
55  * @status_code will normally be a #SoupKnownStatusCode, eg,
56  * %SOUP_STATUS_OK, though of course it might actually be an unknown
57  * status code. @reason_phrase is the actual text returned from the
58  * server, which may or may not correspond to the "standard"
59  * description of @status_code. At any rate, it is almost certainly
60  * not localized, and not very descriptive even if it is in the user's
61  * language; you should not use @reason_phrase in user-visible
62  * messages. Rather, you should look at @status_code, and determine an
63  * end-user-appropriate message based on that and on what you were
64  * trying to do.
65  *
66  * As described in the #SoupMessageBody documentation, the
67  * @request_body and @response_body %data fields will not necessarily
68  * be filled in at all times. When they are filled in, they will be
69  * terminated with a '\0' byte (which is not included in the %length),
70  * so you can use them as ordinary C strings (assuming that you know
71  * that the body doesn't have any other '\0' bytes).
72  *
73  * For a client-side #SoupMessage, @request_body's %data is usually
74  * filled in right before libsoup writes the request to the network,
75  * but you should not count on this; use soup_message_body_flatten()
76  * if you want to ensure that %data is filled in. @response_body's
77  * %data will be filled in before #SoupMessage::finished is emitted.
78  *
79  * For a server-side #SoupMessage, @request_body's %data will be
80  * filled in before #SoupMessage::got_body is emitted.
81  *
82  * To prevent the %data field from being filled in at all (eg, if you
83  * are handling the data from a #SoupMessage::got_chunk, and so don't
84  * need to see it all at the end), call
85  * soup_message_body_set_accumulate() on @response_body or
86  * @request_body as appropriate, passing %FALSE.
87  **/
88
89 G_DEFINE_TYPE (SoupMessage, soup_message, G_TYPE_OBJECT)
90
91 enum {
92         WROTE_INFORMATIONAL,
93         WROTE_HEADERS,
94         WROTE_CHUNK,
95         WROTE_BODY_DATA,
96         WROTE_BODY,
97
98         GOT_INFORMATIONAL,
99         GOT_HEADERS,
100         GOT_CHUNK,
101         GOT_BODY,
102         CONTENT_SNIFFED,
103
104         RESTARTED,
105         FINISHED,
106
107         LAST_SIGNAL
108 };
109
110 static guint signals[LAST_SIGNAL] = { 0 };
111
112 enum {
113         PROP_0,
114
115         PROP_METHOD,
116         PROP_URI,
117         PROP_HTTP_VERSION,
118         PROP_FLAGS,
119         PROP_SERVER_SIDE,
120         PROP_STATUS_CODE,
121         PROP_REASON_PHRASE,
122         PROP_FIRST_PARTY,
123         PROP_REQUEST_BODY,
124         PROP_REQUEST_HEADERS,
125         PROP_RESPONSE_BODY,
126         PROP_RESPONSE_HEADERS,
127         PROP_TLS_CERTIFICATE,
128         PROP_TLS_ERRORS,
129
130         LAST_PROP
131 };
132
133 static void got_body (SoupMessage *req);
134
135 static void set_property (GObject *object, guint prop_id,
136                           const GValue *value, GParamSpec *pspec);
137 static void get_property (GObject *object, guint prop_id,
138                           GValue *value, GParamSpec *pspec);
139
140 static void
141 soup_message_init (SoupMessage *msg)
142 {
143         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
144
145         priv->http_version = priv->orig_http_version = SOUP_HTTP_1_1;
146
147         msg->request_body = soup_message_body_new ();
148         msg->request_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_REQUEST);
149         msg->response_body = soup_message_body_new ();
150         msg->response_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE);
151 }
152
153 static void
154 finalize (GObject *object)
155 {
156         SoupMessage *msg = SOUP_MESSAGE (object);
157         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
158
159         soup_message_io_cleanup (msg);
160         if (priv->chunk_allocator_dnotify)
161                 priv->chunk_allocator_dnotify (priv->chunk_allocator_data);
162
163         if (priv->uri)
164                 soup_uri_free (priv->uri);
165         if (priv->first_party)
166                 soup_uri_free (priv->first_party);
167         if (priv->addr)
168                 g_object_unref (priv->addr);
169
170         if (priv->auth)
171                 g_object_unref (priv->auth);
172         if (priv->proxy_auth)
173                 g_object_unref (priv->proxy_auth);
174
175         g_slist_free (priv->disabled_features);
176
177         while (priv->decoders) {
178                 g_object_unref (priv->decoders->data);
179                 priv->decoders = g_slist_delete_link (priv->decoders, priv->decoders);
180         }
181
182         if (priv->tls_certificate)
183                 g_object_unref (priv->tls_certificate);
184
185         soup_message_body_free (msg->request_body);
186         soup_message_headers_free (msg->request_headers);
187         soup_message_body_free (msg->response_body);
188         soup_message_headers_free (msg->response_headers);
189
190         g_free (msg->reason_phrase);
191
192         G_OBJECT_CLASS (soup_message_parent_class)->finalize (object);
193 }
194
195 static void
196 soup_message_class_init (SoupMessageClass *message_class)
197 {
198         GObjectClass *object_class = G_OBJECT_CLASS (message_class);
199
200         g_type_class_add_private (message_class, sizeof (SoupMessagePrivate));
201
202         /* virtual method definition */
203         message_class->got_body = got_body;
204
205         /* virtual method override */
206         object_class->finalize = finalize;
207         object_class->set_property = set_property;
208         object_class->get_property = get_property;
209
210         /* signals */
211
212         /**
213          * SoupMessage::wrote-informational:
214          * @msg: the message
215          *
216          * Emitted immediately after writing a 1xx (Informational)
217          * response for a (server-side) message.
218          **/
219         signals[WROTE_INFORMATIONAL] =
220                 g_signal_new ("wrote_informational",
221                               G_OBJECT_CLASS_TYPE (object_class),
222                               G_SIGNAL_RUN_FIRST,
223                               G_STRUCT_OFFSET (SoupMessageClass, wrote_informational),
224                               NULL, NULL,
225                               soup_marshal_NONE__NONE,
226                               G_TYPE_NONE, 0);
227
228         /**
229          * SoupMessage::wrote-headers:
230          * @msg: the message
231          *
232          * Emitted immediately after writing the headers for a
233          * message. (For a client-side message, this is after writing
234          * the request headers; for a server-side message, it is after
235          * writing the response headers.)
236          **/
237         signals[WROTE_HEADERS] =
238                 g_signal_new ("wrote_headers",
239                               G_OBJECT_CLASS_TYPE (object_class),
240                               G_SIGNAL_RUN_FIRST,
241                               G_STRUCT_OFFSET (SoupMessageClass, wrote_headers),
242                               NULL, NULL,
243                               soup_marshal_NONE__NONE,
244                               G_TYPE_NONE, 0);
245
246         /**
247          * SoupMessage::wrote-chunk:
248          * @msg: the message
249          *
250          * Emitted immediately after writing a body chunk for a message.
251          *
252          * Note that this signal is not parallel to
253          * #SoupMessage::got_chunk; it is emitted only when a complete
254          * chunk (added with soup_message_body_append() or
255          * soup_message_body_append_buffer()) has been written. To get
256          * more useful continuous progress information, use
257          * #SoupMessage::wrote_body_data.
258          **/
259         signals[WROTE_CHUNK] =
260                 g_signal_new ("wrote_chunk",
261                               G_OBJECT_CLASS_TYPE (object_class),
262                               G_SIGNAL_RUN_FIRST,
263                               G_STRUCT_OFFSET (SoupMessageClass, wrote_chunk),
264                               NULL, NULL,
265                               soup_marshal_NONE__NONE,
266                               G_TYPE_NONE, 0);
267
268         /**
269          * SoupMessage::wrote-body-data:
270          * @msg: the message
271          * @chunk: the data written
272          *
273          * Emitted immediately after writing a portion of the message
274          * body to the network.
275          *
276          * Unlike #SoupMessage::wrote_chunk, this is emitted after
277          * every successful write() call, not only after finishing a
278          * complete "chunk".
279          *
280          * Since: 2.4.1
281          **/
282         signals[WROTE_BODY_DATA] =
283                 g_signal_new ("wrote_body_data",
284                               G_OBJECT_CLASS_TYPE (object_class),
285                               G_SIGNAL_RUN_FIRST,
286                               0, /* FIXME after next ABI break */
287                               NULL, NULL,
288                               soup_marshal_NONE__BOXED,
289                               G_TYPE_NONE, 1,
290                               SOUP_TYPE_BUFFER);
291
292         /**
293          * SoupMessage::wrote-body:
294          * @msg: the message
295          *
296          * Emitted immediately after writing the complete body for a
297          * message. (For a client-side message, this means that
298          * libsoup is done writing and is now waiting for the response
299          * from the server. For a server-side message, this means that
300          * libsoup has finished writing the response and is nearly
301          * done with the message.)
302          **/
303         signals[WROTE_BODY] =
304                 g_signal_new ("wrote_body",
305                               G_OBJECT_CLASS_TYPE (object_class),
306                               G_SIGNAL_RUN_FIRST,
307                               G_STRUCT_OFFSET (SoupMessageClass, wrote_body),
308                               NULL, NULL,
309                               soup_marshal_NONE__NONE,
310                               G_TYPE_NONE, 0);
311
312         /**
313          * SoupMessage::got-informational:
314          * @msg: the message
315          *
316          * Emitted after receiving a 1xx (Informational) response for
317          * a (client-side) message. The response_headers will be
318          * filled in with the headers associated with the
319          * informational response; however, those header values will
320          * be erased after this signal is done.
321          *
322          * If you cancel or requeue @msg while processing this signal,
323          * then the current HTTP I/O will be stopped after this signal
324          * emission finished, and @msg's connection will be closed.
325          **/
326         signals[GOT_INFORMATIONAL] =
327                 g_signal_new ("got_informational",
328                               G_OBJECT_CLASS_TYPE (object_class),
329                               G_SIGNAL_RUN_FIRST,
330                               G_STRUCT_OFFSET (SoupMessageClass, got_informational),
331                               NULL, NULL,
332                               soup_marshal_NONE__NONE,
333                               G_TYPE_NONE, 0);
334
335         /**
336          * SoupMessage::got-headers:
337          * @msg: the message
338          *
339          * Emitted after receiving all message headers for a message.
340          * (For a client-side message, this is after receiving the
341          * Status-Line and response headers; for a server-side
342          * message, it is after receiving the Request-Line and request
343          * headers.)
344          *
345          * See also soup_message_add_header_handler() and
346          * soup_message_add_status_code_handler(), which can be used
347          * to connect to a subset of emissions of this signal.
348          *
349          * If you cancel or requeue @msg while processing this signal,
350          * then the current HTTP I/O will be stopped after this signal
351          * emission finished, and @msg's connection will be closed.
352          * (If you need to requeue a message--eg, after handling
353          * authentication or redirection--it is usually better to
354          * requeue it from a #SoupMessage::got_body handler rather
355          * than a #SoupMessage::got_header handler, so that the
356          * existing HTTP connection can be reused.)
357          **/
358         signals[GOT_HEADERS] =
359                 g_signal_new ("got_headers",
360                               G_OBJECT_CLASS_TYPE (object_class),
361                               G_SIGNAL_RUN_FIRST,
362                               G_STRUCT_OFFSET (SoupMessageClass, got_headers),
363                               NULL, NULL,
364                               soup_marshal_NONE__NONE,
365                               G_TYPE_NONE, 0);
366
367         /**
368          * SoupMessage::got-chunk:
369          * @msg: the message
370          * @chunk: the just-read chunk
371          *
372          * Emitted after receiving a chunk of a message body. Note
373          * that "chunk" in this context means any subpiece of the
374          * body, not necessarily the specific HTTP 1.1 chunks sent by
375          * the other side.
376          *
377          * If you cancel or requeue @msg while processing this signal,
378          * then the current HTTP I/O will be stopped after this signal
379          * emission finished, and @msg's connection will be closed.
380          **/
381         signals[GOT_CHUNK] =
382                 g_signal_new ("got_chunk",
383                               G_OBJECT_CLASS_TYPE (object_class),
384                               G_SIGNAL_RUN_FIRST,
385                               G_STRUCT_OFFSET (SoupMessageClass, got_chunk),
386                               NULL, NULL,
387                               soup_marshal_NONE__BOXED,
388                               G_TYPE_NONE, 1,
389                               /* Use %G_SIGNAL_TYPE_STATIC_SCOPE so that
390                                * the %SOUP_MEMORY_TEMPORARY buffers used
391                                * by soup-message-io.c when emitting this
392                                * signal don't get forcibly copied by
393                                * g_signal_emit().
394                                */
395                               SOUP_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE);
396
397         /**
398          * SoupMessage::got-body:
399          * @msg: the message
400          *
401          * Emitted after receiving the complete message body. (For a
402          * server-side message, this means it has received the request
403          * body. For a client-side message, this means it has received
404          * the response body and is nearly done with the message.)
405          *
406          * See also soup_message_add_header_handler() and
407          * soup_message_add_status_code_handler(), which can be used
408          * to connect to a subset of emissions of this signal.
409          **/
410         signals[GOT_BODY] =
411                 g_signal_new ("got_body",
412                               G_OBJECT_CLASS_TYPE (object_class),
413                               G_SIGNAL_RUN_FIRST,
414                               G_STRUCT_OFFSET (SoupMessageClass, got_body),
415                               NULL, NULL,
416                               soup_marshal_NONE__NONE,
417                               G_TYPE_NONE, 0);
418
419         /**
420          * SoupMessage::content-sniffed:
421          * @msg: the message
422          * @type: the content type that we got from sniffing
423          * @params: (element-type utf8 utf8): a #GHashTable with the parameters
424          *
425          * This signal is emitted after %got-headers, and before the
426          * first %got-chunk. If content sniffing is disabled, or no
427          * content sniffing will be performed, due to the sniffer
428          * deciding to trust the Content-Type sent by the server, this
429          * signal is emitted immediately after %got_headers, and @type
430          * is %NULL.
431          *
432          * If the #SoupContentSniffer feature is enabled, and the
433          * sniffer decided to perform sniffing, the first %got_chunk
434          * emission may be delayed, so that the sniffer has enough
435          * data to correctly sniff the content. It notified the
436          * library user that the content has been sniffed, and allows
437          * it to change the header contents in the message, if
438          * desired.
439          *
440          * After this signal is emitted, the data that was spooled so
441          * that sniffing could be done is delivered on the first
442          * emission of %got_chunk.
443          *
444          * Since: 2.27.3
445          **/
446         signals[CONTENT_SNIFFED] =
447                 g_signal_new ("content_sniffed",
448                               G_OBJECT_CLASS_TYPE (object_class),
449                               G_SIGNAL_RUN_FIRST,
450                               0,
451                               NULL, NULL,
452                               soup_marshal_NONE__STRING_BOXED,
453                               G_TYPE_NONE, 2,
454                               G_TYPE_STRING,
455                               G_TYPE_HASH_TABLE);
456
457         /**
458          * SoupMessage::restarted:
459          * @msg: the message
460          *
461          * Emitted when a request that was already sent once is now
462          * being sent again (eg, because the first attempt received a
463          * redirection response, or because we needed to use
464          * authentication).
465          **/
466         signals[RESTARTED] =
467                 g_signal_new ("restarted",
468                               G_OBJECT_CLASS_TYPE (object_class),
469                               G_SIGNAL_RUN_FIRST,
470                               G_STRUCT_OFFSET (SoupMessageClass, restarted),
471                               NULL, NULL,
472                               soup_marshal_NONE__NONE,
473                               G_TYPE_NONE, 0);
474
475         /**
476          * SoupMessage::finished:
477          * @msg: the message
478          *
479          * Emitted when all HTTP processing is finished for a message.
480          * (After #SoupMessage::got_body for client-side messages, or
481          * after #SoupMessage::wrote_body for server-side messages.)
482          **/
483         signals[FINISHED] =
484                 g_signal_new ("finished",
485                               G_OBJECT_CLASS_TYPE (object_class),
486                               G_SIGNAL_RUN_FIRST,
487                               G_STRUCT_OFFSET (SoupMessageClass, finished),
488                               NULL, NULL,
489                               soup_marshal_NONE__NONE,
490                               G_TYPE_NONE, 0);
491
492         /* properties */
493         /**
494          * SOUP_MESSAGE_METHOD:
495          *
496          * Alias for the #SoupMessage:method property. (The message's
497          * HTTP method.)
498          **/
499         g_object_class_install_property (
500                 object_class, PROP_METHOD,
501                 g_param_spec_string (SOUP_MESSAGE_METHOD,
502                                      "Method",
503                                      "The message's HTTP method",
504                                      SOUP_METHOD_GET,
505                                      G_PARAM_READWRITE));
506         /**
507          * SOUP_MESSAGE_URI:
508          *
509          * Alias for the #SoupMessage:uri property. (The message's
510          * #SoupURI.)
511          **/
512         g_object_class_install_property (
513                 object_class, PROP_URI,
514                 g_param_spec_boxed (SOUP_MESSAGE_URI,
515                                     "URI",
516                                     "The message's Request-URI",
517                                     SOUP_TYPE_URI,
518                                     G_PARAM_READWRITE));
519         /**
520          * SOUP_MESSAGE_HTTP_VERSION:
521          *
522          * Alias for the #SoupMessage:http-version property. (The
523          * message's #SoupHTTPVersion.)
524          **/
525         g_object_class_install_property (
526                 object_class, PROP_HTTP_VERSION,
527                 g_param_spec_enum (SOUP_MESSAGE_HTTP_VERSION,
528                                    "HTTP Version",
529                                    "The HTTP protocol version to use",
530                                    SOUP_TYPE_HTTP_VERSION,
531                                    SOUP_HTTP_1_1,
532                                    G_PARAM_READWRITE));
533         /**
534          * SOUP_MESSAGE_FLAGS:
535          *
536          * Alias for the #SoupMessage:flags property. (The message's
537          * #SoupMessageFlags.)
538          **/
539         g_object_class_install_property (
540                 object_class, PROP_FLAGS,
541                 g_param_spec_flags (SOUP_MESSAGE_FLAGS,
542                                     "Flags",
543                                     "Various message options",
544                                     SOUP_TYPE_MESSAGE_FLAGS,
545                                     0,
546                                     G_PARAM_READWRITE));
547         /**
548          * SOUP_MESSAGE_SERVER_SIDE:
549          *
550          * Alias for the #SoupMessage:server-side property. (%TRUE if
551          * the message was created by #SoupServer.)
552          **/
553         g_object_class_install_property (
554                 object_class, PROP_SERVER_SIDE,
555                 g_param_spec_boolean (SOUP_MESSAGE_SERVER_SIDE,
556                                       "Server-side",
557                                       "Whether or not the message is server-side rather than client-side",
558                                       FALSE,
559                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
560         /**
561          * SOUP_MESSAGE_STATUS_CODE:
562          *
563          * Alias for the #SoupMessage:status-code property. (The
564          * message's HTTP response status code.)
565          **/
566         g_object_class_install_property (
567                 object_class, PROP_STATUS_CODE,
568                 g_param_spec_uint (SOUP_MESSAGE_STATUS_CODE,
569                                    "Status code",
570                                    "The HTTP response status code",
571                                    0, 599, 0,
572                                    G_PARAM_READWRITE));
573         /**
574          * SOUP_MESSAGE_REASON_PHRASE:
575          *
576          * Alias for the #SoupMessage:reason-phrase property. (The
577          * message's HTTP response reason phrase.)
578          **/
579         g_object_class_install_property (
580                 object_class, PROP_REASON_PHRASE,
581                 g_param_spec_string (SOUP_MESSAGE_REASON_PHRASE,
582                                      "Reason phrase",
583                                      "The HTTP response reason phrase",
584                                      NULL,
585                                      G_PARAM_READWRITE));
586         /**
587          * SOUP_MESSAGE_FIRST_PARTY:
588          *
589          * Alias for the #SoupMessage:first-party property. (The
590          * #SoupURI loaded in the application when the message was
591          * queued.)
592          *
593          * Since: 2.30
594          **/
595         /**
596          * SoupMessage:first-party:
597          *
598          * The #SoupURI loaded in the application when the message was
599          * queued.
600          *
601          * Since: 2.30
602          */
603         g_object_class_install_property (
604                 object_class, PROP_FIRST_PARTY,
605                 g_param_spec_boxed (SOUP_MESSAGE_FIRST_PARTY,
606                                     "First party",
607                                     "The URI loaded in the application when the message was requested.",
608                                     SOUP_TYPE_URI,
609                                     G_PARAM_READWRITE));
610         /**
611          * SOUP_MESSAGE_REQUEST_BODY:
612          *
613          * Alias for the #SoupMessage:request-body property. (The
614          * message's HTTP request body.)
615          **/
616         g_object_class_install_property (
617                 object_class, PROP_REQUEST_BODY,
618                 g_param_spec_boxed (SOUP_MESSAGE_REQUEST_BODY,
619                                     "Request Body",
620                                     "The HTTP request content",
621                                     SOUP_TYPE_MESSAGE_BODY,
622                                     G_PARAM_READABLE));
623         /**
624          * SOUP_MESSAGE_REQUEST_HEADERS:
625          *
626          * Alias for the #SoupMessage:request-headers property. (The
627          * message's HTTP request headers.)
628          **/
629         g_object_class_install_property (
630                 object_class, PROP_REQUEST_HEADERS,
631                 g_param_spec_boxed (SOUP_MESSAGE_REQUEST_HEADERS,
632                                     "Request Headers",
633                                     "The HTTP request headers",
634                                     SOUP_TYPE_MESSAGE_HEADERS,
635                                     G_PARAM_READABLE));
636         /**
637          * SOUP_MESSAGE_RESPONSE_BODY:
638          *
639          * Alias for the #SoupMessage:response-body property. (The
640          * message's HTTP response body.)
641          **/
642         g_object_class_install_property (
643                 object_class, PROP_RESPONSE_BODY,
644                 g_param_spec_boxed (SOUP_MESSAGE_RESPONSE_BODY,
645                                     "Response Body",
646                                     "The HTTP response content",
647                                     SOUP_TYPE_MESSAGE_BODY,
648                                     G_PARAM_READABLE));
649         /**
650          * SOUP_MESSAGE_RESPONSE_HEADERS:
651          *
652          * Alias for the #SoupMessage:response-headers property. (The
653          * message's HTTP response headers.)
654          **/
655         g_object_class_install_property (
656                 object_class, PROP_RESPONSE_HEADERS,
657                 g_param_spec_boxed (SOUP_MESSAGE_RESPONSE_HEADERS,
658                                     "Response Headers",
659                                      "The HTTP response headers",
660                                     SOUP_TYPE_MESSAGE_HEADERS,
661                                     G_PARAM_READABLE));
662         /**
663          * SOUP_MESSAGE_TLS_CERTIFICATE:
664          *
665          * Alias for the #SoupMessage:tls-certificate property. (The
666          * TLS certificate associated with the message, if any.)
667          *
668          * Since: 2.34
669          **/
670         /**
671          * SoupMessage:tls-certificate:
672          *
673          * The #GTlsCertificate associated with the message
674          *
675          * Since: 2.34
676          */      
677         g_object_class_install_property (
678                 object_class, PROP_TLS_CERTIFICATE,
679                 g_param_spec_object (SOUP_MESSAGE_TLS_CERTIFICATE,
680                                      "TLS Certificate",
681                                      "The TLS certificate associated with the message",
682                                      G_TYPE_TLS_CERTIFICATE,
683                                      G_PARAM_READWRITE));
684         /**
685          * SOUP_MESSAGE_TLS_ERRORS:
686          *
687          * Alias for the #SoupMessage:tls-errors property. (The
688          * verification errors on #SoupMessage:tls-certificate.)
689          *
690          * Since: 2.34
691          **/
692         /**
693          * SoupMessage:tls-certificate:
694          *
695          * The verification errors on #SoupMessage:tls-certificate
696          *
697          * Since: 2.34
698          */      
699         g_object_class_install_property (
700                 object_class, PROP_TLS_ERRORS,
701                 g_param_spec_flags (SOUP_MESSAGE_TLS_ERRORS,
702                                     "TLS Errors",
703                                     "The verification errors on the message's TLS certificate",
704                                     G_TYPE_TLS_CERTIFICATE_FLAGS, 0,
705                                     G_PARAM_READWRITE));
706 }
707
708 static void
709 set_property (GObject *object, guint prop_id,
710               const GValue *value, GParamSpec *pspec)
711 {
712         SoupMessage *msg = SOUP_MESSAGE (object);
713         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
714
715         switch (prop_id) {
716         case PROP_METHOD:
717                 msg->method = g_intern_string (g_value_get_string (value));
718                 break;
719         case PROP_URI:
720                 soup_message_set_uri (msg, g_value_get_boxed (value));
721                 break;
722         case PROP_HTTP_VERSION:
723                 soup_message_set_http_version (msg, g_value_get_enum (value));
724                 break;
725         case PROP_FLAGS:
726                 soup_message_set_flags (msg, g_value_get_flags (value));
727                 break;
728         case PROP_SERVER_SIDE:
729                 priv->server_side = g_value_get_boolean (value);
730                 if (priv->server_side) {
731                         soup_message_headers_set_encoding (msg->response_headers,
732                                                            SOUP_ENCODING_CONTENT_LENGTH);
733                 }
734                 break;
735         case PROP_STATUS_CODE:
736                 soup_message_set_status (msg, g_value_get_uint (value));
737                 break;
738         case PROP_REASON_PHRASE:
739                 soup_message_set_status_full (msg, msg->status_code,
740                                               g_value_get_string (value));
741                 break;
742         case PROP_FIRST_PARTY:
743                 soup_message_set_first_party (msg, g_value_get_boxed (value));
744                 break;
745         case PROP_TLS_CERTIFICATE:
746                 if (priv->tls_certificate)
747                         g_object_unref (priv->tls_certificate);
748                 priv->tls_certificate = g_value_dup_object (value);
749                 if (priv->tls_certificate && !priv->tls_errors)
750                         priv->msg_flags |= SOUP_MESSAGE_CERTIFICATE_TRUSTED;
751                 break;
752         case PROP_TLS_ERRORS:
753                 priv->tls_errors = g_value_get_flags (value);
754                 if (priv->tls_errors)
755                         priv->msg_flags &= ~SOUP_MESSAGE_CERTIFICATE_TRUSTED;
756                 else if (priv->tls_certificate)
757                         priv->msg_flags |= SOUP_MESSAGE_CERTIFICATE_TRUSTED;
758                 break;
759         default:
760                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
761                 break;
762         }
763 }
764
765 static void
766 get_property (GObject *object, guint prop_id,
767               GValue *value, GParamSpec *pspec)
768 {
769         SoupMessage *msg = SOUP_MESSAGE (object);
770         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
771
772         switch (prop_id) {
773         case PROP_METHOD:
774                 g_value_set_string (value, msg->method);
775                 break;
776         case PROP_URI:
777                 g_value_set_boxed (value, priv->uri);
778                 break;
779         case PROP_HTTP_VERSION:
780                 g_value_set_enum (value, priv->http_version);
781                 break;
782         case PROP_FLAGS:
783                 g_value_set_flags (value, priv->msg_flags);
784                 break;
785         case PROP_SERVER_SIDE:
786                 g_value_set_boolean (value, priv->server_side);
787                 break;
788         case PROP_STATUS_CODE:
789                 g_value_set_uint (value, msg->status_code);
790                 break;
791         case PROP_REASON_PHRASE:
792                 g_value_set_string (value, msg->reason_phrase);
793                 break;
794         case PROP_FIRST_PARTY:
795                 g_value_set_boxed (value, priv->first_party);
796                 break;
797         case PROP_REQUEST_BODY:
798                 g_value_set_boxed (value, msg->request_body);
799                 break;
800         case PROP_REQUEST_HEADERS:
801                 g_value_set_boxed (value, msg->request_headers);
802                 break;
803         case PROP_RESPONSE_BODY:
804                 g_value_set_boxed (value, msg->response_body);
805                 break;
806         case PROP_RESPONSE_HEADERS:
807                 g_value_set_boxed (value, msg->response_headers);
808                 break;
809         case PROP_TLS_CERTIFICATE:
810                 g_value_set_object (value, priv->tls_certificate);
811                 break;
812         case PROP_TLS_ERRORS:
813                 g_value_set_flags (value, priv->tls_errors);
814                 break;
815         default:
816                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
817                 break;
818         }
819 }
820
821
822 /**
823  * soup_message_new:
824  * @method: the HTTP method for the created request
825  * @uri_string: the destination endpoint (as a string)
826  * 
827  * Creates a new empty #SoupMessage, which will connect to @uri
828  *
829  * Return value: the new #SoupMessage (or %NULL if @uri could not
830  * be parsed).
831  */
832 SoupMessage *
833 soup_message_new (const char *method, const char *uri_string)
834 {
835         SoupMessage *msg;
836         SoupURI *uri;
837
838         g_return_val_if_fail (method != NULL, NULL);
839         g_return_val_if_fail (uri_string != NULL, NULL);
840
841         uri = soup_uri_new (uri_string);
842         if (!uri)
843                 return NULL;
844         if (!uri->host) {
845                 soup_uri_free (uri);
846                 return NULL;
847         }
848
849         msg = soup_message_new_from_uri (method, uri);
850         soup_uri_free (uri);
851         return msg;
852 }
853
854 /**
855  * soup_message_new_from_uri:
856  * @method: the HTTP method for the created request
857  * @uri: the destination endpoint (as a #SoupURI)
858  * 
859  * Creates a new empty #SoupMessage, which will connect to @uri
860  *
861  * Return value: the new #SoupMessage
862  */
863 SoupMessage *
864 soup_message_new_from_uri (const char *method, SoupURI *uri)
865 {
866         return g_object_new (SOUP_TYPE_MESSAGE,
867                              SOUP_MESSAGE_METHOD, method,
868                              SOUP_MESSAGE_URI, uri,
869                              NULL);
870 }
871
872 /**
873  * soup_message_set_request:
874  * @msg: the message
875  * @content_type: MIME Content-Type of the body
876  * @req_use: a #SoupMemoryUse describing how to handle @req_body
877  * @req_body: a data buffer containing the body of the message request.
878  * @req_length: the byte length of @req_body.
879  * 
880  * Convenience function to set the request body of a #SoupMessage. If
881  * @content_type is %NULL, the request body must be empty as well.
882  */
883 void
884 soup_message_set_request (SoupMessage    *msg,
885                           const char     *content_type,
886                           SoupMemoryUse   req_use,
887                           const char     *req_body,
888                           gsize           req_length)
889 {
890         g_return_if_fail (SOUP_IS_MESSAGE (msg));
891         g_return_if_fail (content_type != NULL || req_length == 0);
892
893         if (content_type) {
894                 soup_message_headers_replace (msg->request_headers,
895                                               "Content-Type", content_type);
896                 soup_message_body_append (msg->request_body, req_use,
897                                           req_body, req_length);
898         } else {
899                 soup_message_headers_remove (msg->request_headers,
900                                              "Content-Type");
901                 soup_message_body_truncate (msg->request_body);
902         }
903 }
904
905 /**
906  * soup_message_set_response:
907  * @msg: the message
908  * @content_type: (allow-none): MIME Content-Type of the body
909  * @resp_use: a #SoupMemoryUse describing how to handle @resp_body
910  * @resp_body: (array length=resp_length) (element-type guint8): a data buffer
911  * containing the body of the message response.
912  * @resp_length: the byte length of @resp_body.
913  * 
914  * Convenience function to set the response body of a #SoupMessage. If
915  * @content_type is %NULL, the response body must be empty as well.
916  */
917 void
918 soup_message_set_response (SoupMessage    *msg,
919                            const char     *content_type,
920                            SoupMemoryUse   resp_use,
921                            const char     *resp_body,
922                            gsize           resp_length)
923 {
924         g_return_if_fail (SOUP_IS_MESSAGE (msg));
925         g_return_if_fail (content_type != NULL || resp_length == 0);
926
927         if (content_type) {
928                 soup_message_headers_replace (msg->response_headers,
929                                               "Content-Type", content_type);
930                 soup_message_body_append (msg->response_body, resp_use,
931                                           resp_body, resp_length);
932         } else {
933                 soup_message_headers_remove (msg->response_headers,
934                                              "Content-Type");
935                 soup_message_body_truncate (msg->response_body);
936         }
937 }
938
939 /**
940  * soup_message_wrote_informational:
941  * @msg: a #SoupMessage
942  *
943  * Emits the %wrote_informational signal, indicating that the IO layer
944  * finished writing an informational (1xx) response for @msg.
945  **/
946 void
947 soup_message_wrote_informational (SoupMessage *msg)
948 {
949         g_signal_emit (msg, signals[WROTE_INFORMATIONAL], 0);
950 }
951
952 /**
953  * soup_message_wrote_headers:
954  * @msg: a #SoupMessage
955  *
956  * Emits the %wrote_headers signal, indicating that the IO layer
957  * finished writing the (non-informational) headers for @msg.
958  **/
959 void
960 soup_message_wrote_headers (SoupMessage *msg)
961 {
962         g_signal_emit (msg, signals[WROTE_HEADERS], 0);
963 }
964
965 /**
966  * soup_message_wrote_chunk:
967  * @msg: a #SoupMessage
968  *
969  * Emits the %wrote_chunk signal, indicating that the IO layer
970  * finished writing a chunk of @msg's body.
971  **/
972 void
973 soup_message_wrote_chunk (SoupMessage *msg)
974 {
975         g_signal_emit (msg, signals[WROTE_CHUNK], 0);
976 }
977
978 /**
979  * soup_message_wrote_body_data:
980  * @msg: a #SoupMessage
981  * @chunk: the data written
982  *
983  * Emits the %wrote_body_data signal, indicating that the IO layer
984  * finished writing a portion of @msg's body.
985  **/
986 void
987 soup_message_wrote_body_data (SoupMessage *msg, SoupBuffer *chunk)
988 {
989         g_signal_emit (msg, signals[WROTE_BODY_DATA], 0, chunk);
990 }
991
992 /**
993  * soup_message_wrote_body:
994  * @msg: a #SoupMessage
995  *
996  * Emits the %wrote_body signal, indicating that the IO layer finished
997  * writing the body for @msg.
998  **/
999 void
1000 soup_message_wrote_body (SoupMessage *msg)
1001 {
1002         g_signal_emit (msg, signals[WROTE_BODY], 0);
1003 }
1004
1005 /**
1006  * soup_message_got_informational:
1007  * @msg: a #SoupMessage
1008  *
1009  * Emits the %got_informational signal, indicating that the IO layer
1010  * read a complete informational (1xx) response for @msg.
1011  **/
1012 void
1013 soup_message_got_informational (SoupMessage *msg)
1014 {
1015         g_signal_emit (msg, signals[GOT_INFORMATIONAL], 0);
1016 }
1017
1018 /**
1019  * soup_message_got_headers:
1020  * @msg: a #SoupMessage
1021  *
1022  * Emits the %got_headers signal, indicating that the IO layer
1023  * finished reading the (non-informational) headers for @msg.
1024  **/
1025 void
1026 soup_message_got_headers (SoupMessage *msg)
1027 {
1028         g_signal_emit (msg, signals[GOT_HEADERS], 0);
1029 }
1030
1031 /**
1032  * soup_message_got_chunk:
1033  * @msg: a #SoupMessage
1034  * @chunk: the newly-read chunk
1035  *
1036  * Emits the %got_chunk signal, indicating that the IO layer finished
1037  * reading a chunk of @msg's body.
1038  **/
1039 void
1040 soup_message_got_chunk (SoupMessage *msg, SoupBuffer *chunk)
1041 {
1042         g_signal_emit (msg, signals[GOT_CHUNK], 0, chunk);
1043 }
1044
1045 static void
1046 got_body (SoupMessage *req)
1047 {
1048         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (req);
1049         SoupMessageBody *body;
1050
1051         body = priv->server_side ? req->request_body : req->response_body;
1052         if (soup_message_body_get_accumulate (body)) {
1053                 SoupBuffer *buffer;
1054
1055                 buffer = soup_message_body_flatten (body);
1056                 soup_buffer_free (buffer);
1057         }
1058 }
1059
1060 /**
1061  * soup_message_got_body:
1062  * @msg: a #SoupMessage
1063  *
1064  * Emits the %got_body signal, indicating that the IO layer finished
1065  * reading the body for @msg.
1066  **/
1067 void
1068 soup_message_got_body (SoupMessage *msg)
1069 {
1070         g_signal_emit (msg, signals[GOT_BODY], 0);
1071 }
1072
1073 /**
1074  * soup_message_content_sniffed:
1075  * @msg: a #SoupMessage
1076  * @type: a string with the sniffed content type
1077  * @params: a #GHashTable with the parameters
1078  *
1079  * Emits the %content_sniffed signal, indicating that the IO layer
1080  * finished sniffing the content type for @msg. If content sniffing
1081  * will not be performed, due to the sniffer deciding to trust the
1082  * Content-Type sent by the server, this signal is emitted immediately
1083  * after %got_headers, with %NULL as @content_type.
1084  **/
1085 void
1086 soup_message_content_sniffed (SoupMessage *msg, const char *content_type, GHashTable *params)
1087 {
1088         g_signal_emit (msg, signals[CONTENT_SNIFFED], 0, content_type, params);
1089 }
1090
1091 /**
1092  * soup_message_restarted:
1093  * @msg: a #SoupMessage
1094  *
1095  * Emits the %restarted signal, indicating that @msg should be
1096  * requeued.
1097  **/
1098 void
1099 soup_message_restarted (SoupMessage *msg)
1100 {
1101         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1102
1103         if (priv->msg_flags & SOUP_MESSAGE_CAN_REBUILD)
1104                 soup_message_body_truncate (msg->request_body);
1105
1106         g_signal_emit (msg, signals[RESTARTED], 0);
1107 }
1108
1109 /**
1110  * soup_message_finished:
1111  * @msg: a #SoupMessage
1112  *
1113  * Emits the %finished signal, indicating that @msg has been completely
1114  * processed.
1115  **/
1116 void
1117 soup_message_finished (SoupMessage *msg)
1118 {
1119         g_signal_emit (msg, signals[FINISHED], 0);
1120 }
1121
1122 static void
1123 header_handler_free (gpointer header_name, GClosure *closure)
1124 {
1125         g_free (header_name);
1126 }
1127
1128 static void
1129 header_handler_metamarshal (GClosure *closure, GValue *return_value,
1130                             guint n_param_values, const GValue *param_values,
1131                             gpointer invocation_hint, gpointer marshal_data)
1132 {
1133         SoupMessage *msg = g_value_get_object (&param_values[0]);
1134         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1135         const char *header_name = marshal_data;
1136         SoupMessageHeaders *hdrs;
1137
1138 #ifdef FIXME
1139         if (priv->io_status != SOUP_MESSAGE_IO_STATUS_RUNNING)
1140                 return;
1141 #endif
1142
1143         hdrs = priv->server_side ? msg->request_headers : msg->response_headers;
1144         if (soup_message_headers_get_one (hdrs, header_name)) {
1145                 closure->marshal (closure, return_value, n_param_values,
1146                                   param_values, invocation_hint,
1147                                   ((GCClosure *)closure)->callback);
1148         }
1149 }
1150
1151 /**
1152  * soup_message_add_header_handler:
1153  * @msg: a #SoupMessage
1154  * @signal: signal to connect the handler to.
1155  * @header: HTTP response header to match against
1156  * @callback: the header handler
1157  * @user_data: data to pass to @handler_cb
1158  *
1159  * Adds a signal handler to @msg for @signal, as with
1160  * g_signal_connect(), but with two differences: the @callback will
1161  * only be run if @msg has a header named @header, and it will only be
1162  * run if no earlier handler cancelled or requeued the message.
1163  *
1164  * If @signal is one of the "got" signals (eg, "got_headers"), or
1165  * "finished" or "restarted", then @header is matched against the
1166  * incoming message headers (that is, the #request_headers for a
1167  * client #SoupMessage, or the #response_headers for a server
1168  * #SoupMessage). If @signal is one of the "wrote" signals, then
1169  * @header is matched against the outgoing message headers.
1170  *
1171  * Return value: the handler ID from g_signal_connect()
1172  **/
1173 guint
1174 soup_message_add_header_handler (SoupMessage *msg,
1175                                  const char  *signal,
1176                                  const char  *header,
1177                                  GCallback    callback,
1178                                  gpointer     user_data)
1179 {
1180         GClosure *closure;
1181         char *header_name;
1182
1183         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
1184         g_return_val_if_fail (signal != NULL, 0);
1185         g_return_val_if_fail (header != NULL, 0);
1186         g_return_val_if_fail (callback != NULL, 0);
1187
1188         closure = g_cclosure_new (callback, user_data, NULL);
1189
1190         header_name = g_strdup (header);
1191         g_closure_set_meta_marshal (closure, header_name,
1192                                     header_handler_metamarshal);
1193         g_closure_add_finalize_notifier (closure, header_name,
1194                                          header_handler_free);
1195
1196         return g_signal_connect_closure (msg, signal, closure, FALSE);
1197 }
1198
1199 static void
1200 status_handler_metamarshal (GClosure *closure, GValue *return_value,
1201                             guint n_param_values, const GValue *param_values,
1202                             gpointer invocation_hint, gpointer marshal_data)
1203 {
1204         SoupMessage *msg = g_value_get_object (&param_values[0]);
1205         guint status = GPOINTER_TO_UINT (marshal_data);
1206
1207 #ifdef FIXME
1208         if (priv->io_status != SOUP_MESSAGE_IO_STATUS_RUNNING)
1209                 return;
1210 #endif
1211
1212         if (msg->status_code == status) {
1213                 closure->marshal (closure, return_value, n_param_values,
1214                                   param_values, invocation_hint,
1215                                   ((GCClosure *)closure)->callback);
1216         }
1217 }
1218
1219 /**
1220  * soup_message_add_status_code_handler:
1221  * @msg: a #SoupMessage
1222  * @signal: signal to connect the handler to.
1223  * @status_code: status code to match against
1224  * @callback: the header handler
1225  * @user_data: data to pass to @handler_cb
1226  *
1227  * Adds a signal handler to @msg for @signal, as with
1228  * g_signal_connect() but with two differences: the @callback will
1229  * only be run if @msg has the status @status_code, and it will only
1230  * be run if no earlier handler cancelled or requeued the message.
1231  *
1232  * @signal must be a signal that will be emitted after @msg's status
1233  * is set. For a client #SoupMessage, this means it can't be a "wrote"
1234  * signal. For a server #SoupMessage, this means it can't be a "got"
1235  * signal.
1236  *
1237  * Return value: the handler ID from g_signal_connect()
1238  **/
1239 guint
1240 soup_message_add_status_code_handler (SoupMessage *msg,
1241                                       const char  *signal,
1242                                       guint        status_code,
1243                                       GCallback    callback,
1244                                       gpointer     user_data)
1245 {
1246         GClosure *closure;
1247
1248         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
1249         g_return_val_if_fail (signal != NULL, 0);
1250         g_return_val_if_fail (callback != NULL, 0);
1251
1252         closure = g_cclosure_new (callback, user_data, NULL);
1253         g_closure_set_meta_marshal (closure, GUINT_TO_POINTER (status_code),
1254                                     status_handler_metamarshal);
1255
1256         return g_signal_connect_closure (msg, signal, closure, FALSE);
1257 }
1258
1259
1260 /**
1261  * soup_message_set_auth:
1262  * @msg: a #SoupMessage
1263  * @auth: a #SoupAuth, or %NULL
1264  *
1265  * Sets @msg to authenticate to its destination using @auth, which
1266  * must have already been fully authenticated. If @auth is %NULL, @msg
1267  * will not authenticate to its destination.
1268  **/
1269 void
1270 soup_message_set_auth (SoupMessage *msg, SoupAuth *auth)
1271 {
1272         SoupMessagePrivate *priv;
1273         char *token;
1274
1275         g_return_if_fail (SOUP_IS_MESSAGE (msg));
1276         g_return_if_fail (auth == NULL || SOUP_IS_AUTH (auth));
1277         g_return_if_fail (auth == NULL || soup_auth_is_authenticated (auth));
1278
1279         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1280
1281         if (priv->auth) {
1282                 g_object_unref (priv->auth);
1283                 soup_message_headers_remove (msg->request_headers,
1284                                              "Authorization");
1285         }
1286         priv->auth = auth;
1287         if (!priv->auth)
1288                 return;
1289
1290         g_object_ref (priv->auth);
1291         token = soup_auth_get_authorization (auth, msg);
1292         soup_message_headers_replace (msg->request_headers,
1293                                       "Authorization", token);
1294         g_free (token);
1295 }
1296
1297 /**
1298  * soup_message_get_auth:
1299  * @msg: a #SoupMessage
1300  *
1301  * Gets the #SoupAuth used by @msg for authentication.
1302  *
1303  * Return value: (transfer none): the #SoupAuth used by @msg for
1304  * authentication, or %NULL if @msg is unauthenticated.
1305  **/
1306 SoupAuth *
1307 soup_message_get_auth (SoupMessage *msg)
1308 {
1309         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1310
1311         return SOUP_MESSAGE_GET_PRIVATE (msg)->auth;
1312 }
1313
1314 /**
1315  * soup_message_set_proxy_auth:
1316  * @msg: a #SoupMessage
1317  * @auth: a #SoupAuth, or %NULL
1318  *
1319  * Sets @msg to authenticate to its proxy using @auth, which must have
1320  * already been fully authenticated. If @auth is %NULL, @msg will not
1321  * authenticate to its proxy.
1322  **/
1323 void
1324 soup_message_set_proxy_auth (SoupMessage *msg, SoupAuth *auth)
1325 {
1326         SoupMessagePrivate *priv;
1327         char *token;
1328
1329         g_return_if_fail (SOUP_IS_MESSAGE (msg));
1330         g_return_if_fail (auth == NULL || SOUP_IS_AUTH (auth));
1331         g_return_if_fail (auth == NULL || soup_auth_is_authenticated (auth));
1332
1333         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1334
1335         if (priv->proxy_auth) {
1336                 g_object_unref (priv->proxy_auth);
1337                 soup_message_headers_remove (msg->request_headers,
1338                                              "Proxy-Authorization");
1339         }
1340         priv->proxy_auth = auth;
1341         if (!priv->proxy_auth)
1342                 return;
1343
1344         g_object_ref (priv->proxy_auth);
1345         token = soup_auth_get_authorization (auth, msg);
1346         soup_message_headers_replace (msg->request_headers,
1347                                       "Proxy-Authorization", token);
1348         g_free (token);
1349 }
1350
1351 /**
1352  * soup_message_get_proxy_auth:
1353  * @msg: a #SoupMessage
1354  *
1355  * Gets the #SoupAuth used by @msg for authentication to its proxy..
1356  *
1357  * Return value: the #SoupAuth used by @msg for authentication to its
1358  * proxy, or %NULL if @msg isn't authenticated to its proxy.
1359  **/
1360 SoupAuth *
1361 soup_message_get_proxy_auth (SoupMessage *msg)
1362 {
1363         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1364
1365         return SOUP_MESSAGE_GET_PRIVATE (msg)->proxy_auth;
1366 }
1367
1368 /**
1369  * soup_message_cleanup_response:
1370  * @req: a #SoupMessage
1371  *
1372  * Cleans up all response data on @req, so that the request can be sent
1373  * again and receive a new response. (Eg, as a result of a redirect or
1374  * authorization request.)
1375  **/
1376 void
1377 soup_message_cleanup_response (SoupMessage *req)
1378 {
1379         SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (req);
1380
1381         soup_message_body_truncate (req->response_body);
1382         soup_message_headers_clear (req->response_headers);
1383         if (priv->server_side) {
1384                 soup_message_headers_set_encoding (req->response_headers,
1385                                                    SOUP_ENCODING_CONTENT_LENGTH);
1386         }
1387
1388         while (priv->decoders) {
1389                 g_object_unref (priv->decoders->data);
1390                 priv->decoders = g_slist_delete_link (priv->decoders, priv->decoders);
1391         }
1392         priv->msg_flags &= ~SOUP_MESSAGE_CONTENT_DECODED;
1393         priv->msg_flags &= ~SOUP_MESSAGE_CERTIFICATE_TRUSTED;
1394
1395         req->status_code = SOUP_STATUS_NONE;
1396         if (req->reason_phrase) {
1397                 g_free (req->reason_phrase);
1398                 req->reason_phrase = NULL;
1399         }
1400         priv->http_version = priv->orig_http_version;
1401
1402         if (priv->tls_certificate) {
1403                 g_object_unref (priv->tls_certificate);
1404                 priv->tls_certificate = NULL;
1405         }
1406         priv->tls_errors = 0;
1407
1408         g_object_notify (G_OBJECT (req), SOUP_MESSAGE_STATUS_CODE);
1409         g_object_notify (G_OBJECT (req), SOUP_MESSAGE_REASON_PHRASE);
1410         g_object_notify (G_OBJECT (req), SOUP_MESSAGE_HTTP_VERSION);
1411         g_object_notify (G_OBJECT (req), SOUP_MESSAGE_FLAGS);
1412         g_object_notify (G_OBJECT (req), SOUP_MESSAGE_TLS_CERTIFICATE);
1413         g_object_notify (G_OBJECT (req), SOUP_MESSAGE_TLS_ERRORS);
1414 }
1415
1416 /**
1417  * SoupMessageFlags:
1418  * @SOUP_MESSAGE_NO_REDIRECT: The session should not follow redirect
1419  *   (3xx) responses received by this message.
1420  * @SOUP_MESSAGE_CAN_REBUILD: The caller will rebuild the request
1421  *   body if the message is restarted; see
1422  *   soup_message_body_set_accumulate() for more details.
1423  * @SOUP_MESSAGE_OVERWRITE_CHUNKS: Deprecated: equivalent to calling
1424  *   soup_message_body_set_accumulate() on the incoming message body
1425  *   (ie, %response_body for a client-side request), passing %FALSE.
1426  * @SOUP_MESSAGE_CONTENT_DECODED: Set by #SoupContentDecoder to
1427  *   indicate that it has removed the Content-Encoding on a message (and
1428  *   so headers such as Content-Length may no longer accurately describe
1429  *   the body).
1430  * @SOUP_MESSAGE_CERTIFICATE_TRUSTED: if %TRUE after an https response
1431  *   has been received, indicates that the server's SSL certificate is
1432  *   trusted according to the session's CA.
1433  *
1434  * Various flags that can be set on a #SoupMessage to alter its
1435  * behavior.
1436  **/
1437
1438 /**
1439  * soup_message_set_flags:
1440  * @msg: a #SoupMessage
1441  * @flags: a set of #SoupMessageFlags values
1442  *
1443  * Sets the specified flags on @msg.
1444  **/
1445 void
1446 soup_message_set_flags (SoupMessage *msg, SoupMessageFlags flags)
1447 {
1448         SoupMessagePrivate *priv;
1449
1450         g_return_if_fail (SOUP_IS_MESSAGE (msg));
1451         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1452
1453         if ((priv->msg_flags ^ flags) & SOUP_MESSAGE_OVERWRITE_CHUNKS) {
1454                 soup_message_body_set_accumulate (
1455                         priv->server_side ? msg->request_body : msg->response_body,
1456                         !(flags & SOUP_MESSAGE_OVERWRITE_CHUNKS));
1457         }
1458
1459         priv->msg_flags = flags;
1460         g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_FLAGS);
1461 }
1462
1463 /**
1464  * soup_message_get_flags:
1465  * @msg: a #SoupMessage
1466  *
1467  * Gets the flags on @msg
1468  *
1469  * Return value: the flags
1470  **/
1471 SoupMessageFlags
1472 soup_message_get_flags (SoupMessage *msg)
1473 {
1474         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
1475
1476         return SOUP_MESSAGE_GET_PRIVATE (msg)->msg_flags;
1477 }
1478
1479 /**
1480  * SoupHTTPVersion:
1481  * @SOUP_HTTP_1_0: HTTP 1.0 (RFC 1945)
1482  * @SOUP_HTTP_1_1: HTTP 1.1 (RFC 2616)
1483  *
1484  * Indicates the HTTP protocol version being used.
1485  **/
1486
1487 /**
1488  * soup_message_set_http_version:
1489  * @msg: a #SoupMessage
1490  * @version: the HTTP version
1491  *
1492  * Sets the HTTP version on @msg. The default version is
1493  * %SOUP_HTTP_1_1. Setting it to %SOUP_HTTP_1_0 will prevent certain
1494  * functionality from being used.
1495  **/
1496 void
1497 soup_message_set_http_version (SoupMessage *msg, SoupHTTPVersion version)
1498 {
1499         SoupMessagePrivate *priv;
1500
1501         g_return_if_fail (SOUP_IS_MESSAGE (msg));
1502         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1503
1504         priv->http_version = version;
1505         if (msg->status_code == SOUP_STATUS_NONE)
1506                 priv->orig_http_version = version;
1507         g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_HTTP_VERSION);
1508 }
1509
1510 /**
1511  * soup_message_get_http_version:
1512  * @msg: a #SoupMessage
1513  *
1514  * Gets the HTTP version of @msg. This is the minimum of the
1515  * version from the request and the version from the response.
1516  *
1517  * Return value: the HTTP version
1518  **/
1519 SoupHTTPVersion
1520 soup_message_get_http_version (SoupMessage *msg)
1521 {
1522         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), SOUP_HTTP_1_0);
1523
1524         return SOUP_MESSAGE_GET_PRIVATE (msg)->http_version;
1525 }
1526
1527 /**
1528  * soup_message_is_keepalive:
1529  * @msg: a #SoupMessage
1530  *
1531  * Determines whether or not @msg's connection can be kept alive for
1532  * further requests after processing @msg, based on the HTTP version,
1533  * Connection header, etc.
1534  *
1535  * Return value: %TRUE or %FALSE.
1536  **/
1537 gboolean
1538 soup_message_is_keepalive (SoupMessage *msg)
1539 {
1540         const char *c_conn, *s_conn;
1541
1542         c_conn = soup_message_headers_get_list (msg->request_headers,
1543                                                 "Connection");
1544         s_conn = soup_message_headers_get_list (msg->response_headers,
1545                                                 "Connection");
1546
1547         if (msg->status_code == SOUP_STATUS_OK &&
1548             msg->method == SOUP_METHOD_CONNECT)
1549                 return TRUE;
1550
1551         /* Not persistent if the server sent a terminate-by-EOF response */
1552         if (soup_message_headers_get_encoding (msg->response_headers) == SOUP_ENCODING_EOF)
1553                 return FALSE;
1554
1555         if (SOUP_MESSAGE_GET_PRIVATE (msg)->http_version == SOUP_HTTP_1_0) {
1556                 /* In theory, HTTP/1.0 connections are only persistent
1557                  * if the client requests it, and the server agrees.
1558                  * But some servers do keep-alive even if the client
1559                  * doesn't request it. So ignore c_conn.
1560                  */
1561
1562                 if (!s_conn || !soup_header_contains (s_conn, "Keep-Alive"))
1563                         return FALSE;
1564         } else {
1565                 /* Normally persistent unless either side requested otherwise */
1566                 if (c_conn && soup_header_contains (c_conn, "close"))
1567                         return FALSE;
1568                 if (s_conn && soup_header_contains (s_conn, "close"))
1569                         return FALSE;
1570
1571                 return TRUE;
1572         }
1573
1574         return TRUE;
1575 }
1576
1577 /**
1578  * soup_message_set_uri:
1579  * @msg: a #SoupMessage
1580  * @uri: the new #SoupURI
1581  *
1582  * Sets @msg's URI to @uri. If @msg has already been sent and you want
1583  * to re-send it with the new URI, you need to call
1584  * soup_session_requeue_message().
1585  **/
1586 void
1587 soup_message_set_uri (SoupMessage *msg, SoupURI *uri)
1588 {
1589         SoupMessagePrivate *priv;
1590
1591         g_return_if_fail (SOUP_IS_MESSAGE (msg));
1592         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1593
1594         if (priv->uri)
1595                 soup_uri_free (priv->uri);
1596         if (priv->addr) {
1597                 g_object_unref (priv->addr);
1598                 priv->addr = NULL;
1599         }
1600         priv->uri = soup_uri_copy (uri);
1601
1602         g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_URI);
1603 }
1604
1605 /**
1606  * soup_message_get_uri:
1607  * @msg: a #SoupMessage
1608  *
1609  * Gets @msg's URI
1610  *
1611  * Return value: (transfer none): the URI @msg is targeted for.
1612  **/
1613 SoupURI *
1614 soup_message_get_uri (SoupMessage *msg)
1615 {
1616         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1617
1618         return SOUP_MESSAGE_GET_PRIVATE (msg)->uri;
1619 }
1620
1621 /**
1622  * soup_message_get_address:
1623  * @msg: a #SoupMessage
1624  *
1625  * Gets the address @msg's URI points to. After first setting the
1626  * URI on a message, this will be unresolved, although the message's
1627  * session will resolve it before sending the message.
1628  *
1629  * Return value: (transfer none): the address @msg's URI points to
1630  *
1631  * Since: 2.26
1632  **/
1633 SoupAddress *
1634 soup_message_get_address (SoupMessage *msg)
1635 {
1636         SoupMessagePrivate *priv;
1637
1638         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1639
1640         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1641         if (!priv->addr) {
1642                 priv->addr = soup_address_new (priv->uri->host,
1643                                                priv->uri->port);
1644         }
1645         return priv->addr;
1646 }
1647
1648 /**
1649  * soup_message_set_status:
1650  * @msg: a #SoupMessage
1651  * @status_code: an HTTP status code
1652  *
1653  * Sets @msg's status code to @status_code. If @status_code is a
1654  * known value, it will also set @msg's reason_phrase.
1655  **/
1656 void
1657 soup_message_set_status (SoupMessage *msg, guint status_code)
1658 {
1659         g_return_if_fail (SOUP_IS_MESSAGE (msg));
1660         g_return_if_fail (status_code != 0);
1661
1662         g_free (msg->reason_phrase);
1663
1664         msg->status_code = status_code;
1665         msg->reason_phrase = g_strdup (soup_status_get_phrase (status_code));
1666         g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_STATUS_CODE);
1667         g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_REASON_PHRASE);
1668 }
1669
1670 /**
1671  * soup_message_set_status_full:
1672  * @msg: a #SoupMessage
1673  * @status_code: an HTTP status code
1674  * @reason_phrase: a description of the status
1675  *
1676  * Sets @msg's status code and reason phrase.
1677  **/
1678 void
1679 soup_message_set_status_full (SoupMessage *msg,
1680                               guint        status_code,
1681                               const char  *reason_phrase)
1682 {
1683         g_return_if_fail (SOUP_IS_MESSAGE (msg));
1684         g_return_if_fail (status_code != 0);
1685         g_return_if_fail (reason_phrase != NULL);
1686
1687         g_free (msg->reason_phrase);
1688
1689         msg->status_code = status_code;
1690         msg->reason_phrase = g_strdup (reason_phrase);
1691         g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_STATUS_CODE);
1692         g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_REASON_PHRASE);
1693 }
1694
1695 /**
1696  * SoupChunkAllocator:
1697  * @msg: the #SoupMessage the chunk is being allocated for
1698  * @max_len: the maximum length that will be read, or 0.
1699  * @user_data: the data passed to soup_message_set_chunk_allocator()
1700  *
1701  * The prototype for a chunk allocation callback. This should allocate
1702  * a new #SoupBuffer and return it for the I/O layer to read message
1703  * body data off the network into.
1704  *
1705  * If @max_len is non-0, it indicates the maximum number of bytes that
1706  * could be read, based on what is known about the message size. Note
1707  * that this might be a very large number, and you should not simply
1708  * try to allocate that many bytes blindly. If @max_len is 0, that
1709  * means that libsoup does not know how many bytes remain to be read,
1710  * and the allocator should return a buffer of a size that it finds
1711  * convenient.
1712  *
1713  * If the allocator returns %NULL, the message will be paused. It is
1714  * up to the application to make sure that it gets unpaused when it
1715  * becomes possible to allocate a new buffer.
1716  *
1717  * Return value: the new buffer (or %NULL)
1718  **/
1719
1720 /**
1721  * soup_message_set_chunk_allocator:
1722  * @msg: a #SoupMessage
1723  * @allocator: the chunk allocator callback
1724  * @user_data: data to pass to @allocator
1725  * @destroy_notify: destroy notifier to free @user_data when @msg is
1726  * destroyed
1727  *
1728  * Sets an alternate chunk-allocation function to use when reading
1729  * @msg's body. Every time data is available to read, libsoup will
1730  * call @allocator, which should return a #SoupBuffer. (See
1731  * #SoupChunkAllocator for additional details.) Libsoup will then read
1732  * data from the network into that buffer, and update the buffer's
1733  * %length to indicate how much data it read.
1734  *
1735  * Generally, a custom chunk allocator would be used in conjunction
1736  * with soup_message_body_set_accumulate() %FALSE and
1737  * #SoupMessage::got_chunk, as part of a strategy to avoid unnecessary
1738  * copying of data. However, you cannot assume that every call to the
1739  * allocator will be followed by a call to your %got_chunk handler; if
1740  * an I/O error occurs, then the buffer will be unreffed without ever
1741  * having been used. If your buffer-allocation strategy requires
1742  * special cleanup, use soup_buffer_new_with_owner() rather than doing
1743  * the cleanup from the %got_chunk handler.
1744  *
1745  * The other thing to remember when using non-accumulating message
1746  * bodies is that the buffer passed to the %got_chunk handler will be
1747  * unreffed after the handler returns, just as it would be in the
1748  * non-custom-allocated case. If you want to hand the chunk data off
1749  * to some other part of your program to use later, you'll need to ref
1750  * the #SoupBuffer (or its owner, in the soup_buffer_new_with_owner()
1751  * case) to ensure that the data remains valid.
1752  **/
1753 void
1754 soup_message_set_chunk_allocator (SoupMessage *msg,
1755                                   SoupChunkAllocator allocator,
1756                                   gpointer user_data,
1757                                   GDestroyNotify destroy_notify)
1758 {
1759         SoupMessagePrivate *priv;
1760
1761         g_return_if_fail (SOUP_IS_MESSAGE (msg));
1762
1763         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1764
1765         if (priv->chunk_allocator_dnotify)
1766                 priv->chunk_allocator_dnotify (priv->chunk_allocator_data);
1767
1768         priv->chunk_allocator         = allocator;
1769         priv->chunk_allocator_data    = user_data;
1770         priv->chunk_allocator_dnotify = destroy_notify;
1771 }
1772
1773 /**
1774  * soup_message_disable_feature:
1775  * @msg: a #SoupMessage
1776  * @feature_type: the #GType of a #SoupSessionFeature
1777  *
1778  * This disables the actions of #SoupSessionFeature<!-- -->s with the
1779  * given @feature_type (or a subclass of that type) on @msg, so that
1780  * @msg is processed as though the feature(s) hadn't been added to the
1781  * session. Eg, passing #SOUP_TYPE_PROXY_RESOLVER for @feature_type
1782  * will disable proxy handling and cause @msg to be sent directly to
1783  * the indicated origin server, regardless of system proxy
1784  * configuration.
1785  *
1786  * You must call this before queueing @msg on a session; calling it on
1787  * a message that has already been queued is undefined. In particular,
1788  * you cannot call this on a message that is being requeued after a
1789  * redirect or authentication.
1790  *
1791  * Since: 2.28
1792  **/
1793 void
1794 soup_message_disable_feature (SoupMessage *msg, GType feature_type)
1795 {
1796         SoupMessagePrivate *priv;
1797
1798         g_return_if_fail (SOUP_IS_MESSAGE (msg));
1799
1800         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1801
1802         priv->disabled_features = g_slist_prepend (priv->disabled_features,
1803                                                    GSIZE_TO_POINTER (feature_type));
1804 }
1805
1806 gboolean
1807 soup_message_disables_feature (SoupMessage *msg, gpointer feature)
1808 {
1809         SoupMessagePrivate *priv;
1810         GSList *f;
1811
1812         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE);
1813
1814         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1815
1816         for (f = priv->disabled_features; f; f = f->next) {
1817                 if (G_TYPE_CHECK_INSTANCE_TYPE (feature, (GType) GPOINTER_TO_SIZE (f->data)))
1818                         return TRUE;
1819         }
1820         return FALSE;
1821 }
1822
1823 /**
1824  * soup_message_get_first_party:
1825  * @msg: a #SoupMessage
1826  * 
1827  * Returns: (transfer none): the @msg's first party #SoupURI
1828  * 
1829  * Since: 2.30
1830  **/
1831 SoupURI *
1832 soup_message_get_first_party (SoupMessage *msg)
1833 {
1834         SoupMessagePrivate *priv;
1835
1836         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1837
1838         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1839         return priv->first_party;
1840 }
1841
1842 /**
1843  * soup_message_set_first_party:
1844  * @msg: a #SoupMessage
1845  * @first_party: the #SoupURI for the @msg's first party
1846  * 
1847  * Sets @first_party as the main document #SoupURI for @msg. For
1848  * details of when and how this is used refer to the documentation for
1849  * #SoupCookieJarAcceptPolicy.
1850  *
1851  * Since: 2.30
1852  **/
1853 void
1854 soup_message_set_first_party (SoupMessage *msg,
1855                               SoupURI     *first_party)
1856 {
1857         SoupMessagePrivate *priv;
1858
1859         g_return_if_fail (SOUP_IS_MESSAGE (msg));
1860         g_return_if_fail (first_party != NULL);
1861
1862         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1863
1864         if (priv->first_party) {
1865                 if (soup_uri_equal (priv->first_party, first_party))
1866                         return;
1867
1868                 soup_uri_free (priv->first_party);
1869         }
1870
1871         priv->first_party = soup_uri_copy (first_party);
1872         g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_FIRST_PARTY);
1873 }
1874
1875 /**
1876  * soup_message_get_https_status:
1877  * @msg: a #SoupMessage
1878  * @certificate: (out) (transfer none): @msg's TLS certificate
1879  * @errors: (out): the verification status of @certificate
1880  *
1881  * If @msg is using https, this retrieves the #GTlsCertificate
1882  * associated with its connection, and the #GTlsCertificateFlags showing
1883  * what problems, if any, have been found with that certificate.
1884  *
1885  * Return value: %TRUE if @msg uses https, %FALSE if not
1886  *
1887  * Since: 2.34
1888  */
1889 gboolean
1890 soup_message_get_https_status (SoupMessage           *msg,
1891                                GTlsCertificate      **certificate,
1892                                GTlsCertificateFlags  *errors)
1893 {
1894         SoupMessagePrivate *priv;
1895
1896         g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE);
1897
1898         priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1899
1900         if (certificate)
1901                 *certificate = priv->tls_certificate;
1902         if (errors)
1903                 *errors = priv->tls_errors;
1904         return priv->tls_certificate != NULL;
1905 }