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