1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * soup-message.c: HTTP request/response
5 * Copyright (C) 2000-2003, Ximian, Inc.
11 #include "soup-address.h"
12 #include "soup-auth.h"
13 #include "soup-connection.h"
14 #include "soup-enum-types.h"
15 #include "soup-marshal.h"
16 #include "soup-message.h"
17 #include "soup-message-private.h"
18 #include "soup-misc.h"
19 #include "soup-socket.h"
23 * SECTION:soup-message
24 * @short_description: An HTTP request and response.
25 * @see_also: #SoupMessageHeaders, #SoupMessageBody
27 * A #SoupMessage represents an HTTP message that is being sent or
30 * For client-side usage, you would create a #SoupMessage with
31 * soup_message_new() or soup_message_new_from_uri(), set up its
32 * fields appropriate, and send it via a #SoupSession.
34 * For server-side usage, #SoupServer will create #SoupMessage<!--
35 * -->s automatically for incoming requests, which your application
36 * will receive via handlers.
38 * Note that libsoup's terminology here does not quite match the HTTP
39 * specification: in RFC 2616, an "HTTP-message" is
40 * <emphasis>either</emphasis> a Request, <emphasis>or</emphasis> a
41 * Response. In libsoup, a #SoupMessage combines both the request and
47 * @method: the HTTP method
48 * @status_code: the HTTP status code
49 * @reason_phrase: the status phrase associated with @status_code
50 * @request_body: the request body
51 * @request_headers: the request headers
52 * @response_body: the response body
53 * @response_headers: the response headers
55 * Represents an HTTP message being sent or received.
57 * @status_code will normally be a #SoupKnownStatusCode, eg,
58 * %SOUP_STATUS_OK, though of course it might actually be an unknown
59 * status code. @reason_phrase is the actual text returned from the
60 * server, which may or may not correspond to the "standard"
61 * description of @status_code. At any rate, it is almost certainly
62 * not localized, and not very descriptive even if it is in the user's
63 * language; you should not use @reason_phrase in user-visible
64 * messages. Rather, you should look at @status_code, and determine an
65 * end-user-appropriate message based on that and on what you were
68 * As described in the #SoupMessageBody documentation, the
69 * @request_body and @response_body <literal>data</literal> fields
70 * will not necessarily be filled in at all times. When they are
71 * filled in, they will be terminated with a '\0' byte (which is not
72 * included in the <literal>length</literal>), so you can use them as
73 * ordinary C strings (assuming that you know that the body doesn't
74 * have any other '\0' bytes).
76 * For a client-side #SoupMessage, @request_body's %data is usually
77 * filled in right before libsoup writes the request to the network,
78 * but you should not count on this; use soup_message_body_flatten()
79 * if you want to ensure that %data is filled in. @response_body's
80 * %data will be filled in before #SoupMessage::finished is emitted.
82 * For a server-side #SoupMessage, @request_body's %data will be
83 * filled in before #SoupMessage::got_body is emitted.
85 * To prevent the %data field from being filled in at all (eg, if you
86 * are handling the data from a #SoupMessage::got_chunk, and so don't
87 * need to see it all at the end), call
88 * soup_message_body_set_accumulate() on @response_body or
89 * @request_body as appropriate, passing %FALSE.
92 G_DEFINE_TYPE (SoupMessage, soup_message, G_TYPE_OBJECT)
115 static guint signals[LAST_SIGNAL] = { 0 };
129 PROP_REQUEST_HEADERS,
131 PROP_RESPONSE_HEADERS,
132 PROP_TLS_CERTIFICATE,
138 static void got_body (SoupMessage *req);
140 static void set_property (GObject *object, guint prop_id,
141 const GValue *value, GParamSpec *pspec);
142 static void get_property (GObject *object, guint prop_id,
143 GValue *value, GParamSpec *pspec);
146 soup_message_init (SoupMessage *msg)
148 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
150 priv->http_version = priv->orig_http_version = SOUP_HTTP_1_1;
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);
159 finalize (GObject *object)
161 SoupMessage *msg = SOUP_MESSAGE (object);
162 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
164 soup_message_io_cleanup (msg);
165 if (priv->chunk_allocator_dnotify)
166 priv->chunk_allocator_dnotify (priv->chunk_allocator_data);
169 soup_uri_free (priv->uri);
170 if (priv->first_party)
171 soup_uri_free (priv->first_party);
173 g_object_unref (priv->addr);
176 g_object_unref (priv->auth);
177 if (priv->proxy_auth)
178 g_object_unref (priv->proxy_auth);
180 g_slist_free (priv->disabled_features);
182 while (priv->decoders) {
183 g_object_unref (priv->decoders->data);
184 priv->decoders = g_slist_delete_link (priv->decoders, priv->decoders);
187 if (priv->tls_certificate)
188 g_object_unref (priv->tls_certificate);
190 soup_message_body_free (msg->request_body);
191 soup_message_headers_free (msg->request_headers);
192 soup_message_body_free (msg->response_body);
193 soup_message_headers_free (msg->response_headers);
195 g_free (msg->reason_phrase);
197 G_OBJECT_CLASS (soup_message_parent_class)->finalize (object);
201 soup_message_class_init (SoupMessageClass *message_class)
203 GObjectClass *object_class = G_OBJECT_CLASS (message_class);
205 g_type_class_add_private (message_class, sizeof (SoupMessagePrivate));
207 /* virtual method definition */
208 message_class->got_body = got_body;
210 /* virtual method override */
211 object_class->finalize = finalize;
212 object_class->set_property = set_property;
213 object_class->get_property = get_property;
218 * SoupMessage::wrote-informational:
221 * Emitted immediately after writing a 1xx (Informational)
222 * response for a (server-side) message.
224 signals[WROTE_INFORMATIONAL] =
225 g_signal_new ("wrote_informational",
226 G_OBJECT_CLASS_TYPE (object_class),
228 G_STRUCT_OFFSET (SoupMessageClass, wrote_informational),
230 _soup_marshal_NONE__NONE,
234 * SoupMessage::wrote-headers:
237 * Emitted immediately after writing the headers for a
238 * message. (For a client-side message, this is after writing
239 * the request headers; for a server-side message, it is after
240 * writing the response headers.)
242 signals[WROTE_HEADERS] =
243 g_signal_new ("wrote_headers",
244 G_OBJECT_CLASS_TYPE (object_class),
246 G_STRUCT_OFFSET (SoupMessageClass, wrote_headers),
248 _soup_marshal_NONE__NONE,
252 * SoupMessage::wrote-chunk:
255 * Emitted immediately after writing a body chunk for a message.
257 * Note that this signal is not parallel to
258 * #SoupMessage::got_chunk; it is emitted only when a complete
259 * chunk (added with soup_message_body_append() or
260 * soup_message_body_append_buffer()) has been written. To get
261 * more useful continuous progress information, use
262 * #SoupMessage::wrote_body_data.
264 signals[WROTE_CHUNK] =
265 g_signal_new ("wrote_chunk",
266 G_OBJECT_CLASS_TYPE (object_class),
268 G_STRUCT_OFFSET (SoupMessageClass, wrote_chunk),
270 _soup_marshal_NONE__NONE,
274 * SoupMessage::wrote-body-data:
276 * @chunk: the data written
278 * Emitted immediately after writing a portion of the message
279 * body to the network.
281 * Unlike #SoupMessage::wrote_chunk, this is emitted after
282 * every successful write() call, not only after finishing a
287 signals[WROTE_BODY_DATA] =
288 g_signal_new ("wrote_body_data",
289 G_OBJECT_CLASS_TYPE (object_class),
291 0, /* FIXME after next ABI break */
293 _soup_marshal_NONE__BOXED,
298 * SoupMessage::wrote-body:
301 * Emitted immediately after writing the complete body for a
302 * message. (For a client-side message, this means that
303 * libsoup is done writing and is now waiting for the response
304 * from the server. For a server-side message, this means that
305 * libsoup has finished writing the response and is nearly
306 * done with the message.)
308 signals[WROTE_BODY] =
309 g_signal_new ("wrote_body",
310 G_OBJECT_CLASS_TYPE (object_class),
312 G_STRUCT_OFFSET (SoupMessageClass, wrote_body),
314 _soup_marshal_NONE__NONE,
318 * SoupMessage::got-informational:
321 * Emitted after receiving a 1xx (Informational) response for
322 * a (client-side) message. The response_headers will be
323 * filled in with the headers associated with the
324 * informational response; however, those header values will
325 * be erased after this signal is done.
327 * If you cancel or requeue @msg while processing this signal,
328 * then the current HTTP I/O will be stopped after this signal
329 * emission finished, and @msg's connection will be closed.
331 signals[GOT_INFORMATIONAL] =
332 g_signal_new ("got_informational",
333 G_OBJECT_CLASS_TYPE (object_class),
335 G_STRUCT_OFFSET (SoupMessageClass, got_informational),
337 _soup_marshal_NONE__NONE,
341 * SoupMessage::got-headers:
344 * Emitted after receiving all message headers for a message.
345 * (For a client-side message, this is after receiving the
346 * Status-Line and response headers; for a server-side
347 * message, it is after receiving the Request-Line and request
350 * See also soup_message_add_header_handler() and
351 * soup_message_add_status_code_handler(), which can be used
352 * to connect to a subset of emissions of this signal.
354 * If you cancel or requeue @msg while processing this signal,
355 * then the current HTTP I/O will be stopped after this signal
356 * emission finished, and @msg's connection will be closed.
357 * (If you need to requeue a message--eg, after handling
358 * authentication or redirection--it is usually better to
359 * requeue it from a #SoupMessage::got_body handler rather
360 * than a #SoupMessage::got_headers handler, so that the
361 * existing HTTP connection can be reused.)
363 signals[GOT_HEADERS] =
364 g_signal_new ("got_headers",
365 G_OBJECT_CLASS_TYPE (object_class),
367 G_STRUCT_OFFSET (SoupMessageClass, got_headers),
369 _soup_marshal_NONE__NONE,
373 * SoupMessage::got-chunk:
375 * @chunk: the just-read chunk
377 * Emitted after receiving a chunk of a message body. Note
378 * that "chunk" in this context means any subpiece of the
379 * body, not necessarily the specific HTTP 1.1 chunks sent by
382 * If you cancel or requeue @msg while processing this signal,
383 * then the current HTTP I/O will be stopped after this signal
384 * emission finished, and @msg's connection will be closed.
387 g_signal_new ("got_chunk",
388 G_OBJECT_CLASS_TYPE (object_class),
390 G_STRUCT_OFFSET (SoupMessageClass, got_chunk),
392 _soup_marshal_NONE__BOXED,
394 /* Use %G_SIGNAL_TYPE_STATIC_SCOPE so that
395 * the %SOUP_MEMORY_TEMPORARY buffers used
396 * by soup-message-io.c when emitting this
397 * signal don't get forcibly copied by
400 SOUP_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE);
403 * SoupMessage::got-body:
406 * Emitted after receiving the complete message body. (For a
407 * server-side message, this means it has received the request
408 * body. For a client-side message, this means it has received
409 * the response body and is nearly done with the message.)
411 * See also soup_message_add_header_handler() and
412 * soup_message_add_status_code_handler(), which can be used
413 * to connect to a subset of emissions of this signal.
416 g_signal_new ("got_body",
417 G_OBJECT_CLASS_TYPE (object_class),
419 G_STRUCT_OFFSET (SoupMessageClass, got_body),
421 _soup_marshal_NONE__NONE,
425 * SoupMessage::content-sniffed:
427 * @type: the content type that we got from sniffing
428 * @params: (element-type utf8 utf8): a #GHashTable with the parameters
430 * This signal is emitted after #SoupMessage::got-headers, and
431 * before the first #SoupMessage::got-chunk. If content
432 * sniffing is disabled, or no content sniffing will be
433 * performed, due to the sniffer deciding to trust the
434 * Content-Type sent by the server, this signal is emitted
435 * immediately after #SoupMessage::got-headers, and @type is
438 * If the #SoupContentSniffer feature is enabled, and the
439 * sniffer decided to perform sniffing, the first
440 * #SoupMessage::got-chunk emission may be delayed, so that the
441 * sniffer has enough data to correctly sniff the content. It
442 * notified the library user that the content has been
443 * sniffed, and allows it to change the header contents in the
444 * message, if desired.
446 * After this signal is emitted, the data that was spooled so
447 * that sniffing could be done is delivered on the first
448 * emission of #SoupMessage::got-chunk.
452 signals[CONTENT_SNIFFED] =
453 g_signal_new ("content_sniffed",
454 G_OBJECT_CLASS_TYPE (object_class),
458 _soup_marshal_NONE__STRING_BOXED,
464 * SoupMessage::restarted:
467 * Emitted when a request that was already sent once is now
468 * being sent again (eg, because the first attempt received a
469 * redirection response, or because we needed to use
473 g_signal_new ("restarted",
474 G_OBJECT_CLASS_TYPE (object_class),
476 G_STRUCT_OFFSET (SoupMessageClass, restarted),
478 _soup_marshal_NONE__NONE,
482 * SoupMessage::finished:
485 * Emitted when all HTTP processing is finished for a message.
486 * (After #SoupMessage::got_body for client-side messages, or
487 * after #SoupMessage::wrote_body for server-side messages.)
490 g_signal_new ("finished",
491 G_OBJECT_CLASS_TYPE (object_class),
493 G_STRUCT_OFFSET (SoupMessageClass, finished),
495 _soup_marshal_NONE__NONE,
499 * SoupMessage::network-event:
501 * @event: the network event
502 * @connection: the current state of the network connection
504 * Emitted to indicate that some network-related event
505 * related to @msg has occurred. This essentially proxies the
506 * #GSocketClient::event signal, but only for events that
507 * occur while @msg "owns" the connection; if @msg is sent on
508 * an existing persistent connection, then this signal will
509 * not be emitted. (If you want to force the message to be
510 * sent on a new connection, set the
511 * %SOUP_MESSAGE_NEW_CONNECTION flag on it.)
513 * See #GSocketClient::event for more information on what
514 * the different values of @event correspond to, and what
515 * @connection will be in each case.
519 signals[NETWORK_EVENT] =
520 g_signal_new ("network_event",
521 G_OBJECT_CLASS_TYPE (object_class),
527 G_TYPE_SOCKET_CLIENT_EVENT,
532 * SOUP_MESSAGE_METHOD:
534 * Alias for the #SoupMessage:method property. (The message's
537 g_object_class_install_property (
538 object_class, PROP_METHOD,
539 g_param_spec_string (SOUP_MESSAGE_METHOD,
541 "The message's HTTP method",
547 * Alias for the #SoupMessage:uri property. (The message's
550 g_object_class_install_property (
551 object_class, PROP_URI,
552 g_param_spec_boxed (SOUP_MESSAGE_URI,
554 "The message's Request-URI",
558 * SOUP_MESSAGE_HTTP_VERSION:
560 * Alias for the #SoupMessage:http-version property. (The
561 * message's #SoupHTTPVersion.)
563 g_object_class_install_property (
564 object_class, PROP_HTTP_VERSION,
565 g_param_spec_enum (SOUP_MESSAGE_HTTP_VERSION,
567 "The HTTP protocol version to use",
568 SOUP_TYPE_HTTP_VERSION,
572 * SOUP_MESSAGE_FLAGS:
574 * Alias for the #SoupMessage:flags property. (The message's
575 * #SoupMessageFlags.)
577 g_object_class_install_property (
578 object_class, PROP_FLAGS,
579 g_param_spec_flags (SOUP_MESSAGE_FLAGS,
581 "Various message options",
582 SOUP_TYPE_MESSAGE_FLAGS,
586 * SOUP_MESSAGE_SERVER_SIDE:
588 * Alias for the #SoupMessage:server-side property. (%TRUE if
589 * the message was created by #SoupServer.)
591 g_object_class_install_property (
592 object_class, PROP_SERVER_SIDE,
593 g_param_spec_boolean (SOUP_MESSAGE_SERVER_SIDE,
595 "Whether or not the message is server-side rather than client-side",
597 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
599 * SOUP_MESSAGE_STATUS_CODE:
601 * Alias for the #SoupMessage:status-code property. (The
602 * message's HTTP response status code.)
604 g_object_class_install_property (
605 object_class, PROP_STATUS_CODE,
606 g_param_spec_uint (SOUP_MESSAGE_STATUS_CODE,
608 "The HTTP response status code",
612 * SOUP_MESSAGE_REASON_PHRASE:
614 * Alias for the #SoupMessage:reason-phrase property. (The
615 * message's HTTP response reason phrase.)
617 g_object_class_install_property (
618 object_class, PROP_REASON_PHRASE,
619 g_param_spec_string (SOUP_MESSAGE_REASON_PHRASE,
621 "The HTTP response reason phrase",
625 * SOUP_MESSAGE_FIRST_PARTY:
627 * Alias for the #SoupMessage:first-party property. (The
628 * #SoupURI loaded in the application when the message was
634 * SoupMessage:first-party:
636 * The #SoupURI loaded in the application when the message was
641 g_object_class_install_property (
642 object_class, PROP_FIRST_PARTY,
643 g_param_spec_boxed (SOUP_MESSAGE_FIRST_PARTY,
645 "The URI loaded in the application when the message was requested.",
649 * SOUP_MESSAGE_REQUEST_BODY:
651 * Alias for the #SoupMessage:request-body property. (The
652 * message's HTTP request body.)
654 g_object_class_install_property (
655 object_class, PROP_REQUEST_BODY,
656 g_param_spec_boxed (SOUP_MESSAGE_REQUEST_BODY,
658 "The HTTP request content",
659 SOUP_TYPE_MESSAGE_BODY,
662 * SOUP_MESSAGE_REQUEST_HEADERS:
664 * Alias for the #SoupMessage:request-headers property. (The
665 * message's HTTP request headers.)
667 g_object_class_install_property (
668 object_class, PROP_REQUEST_HEADERS,
669 g_param_spec_boxed (SOUP_MESSAGE_REQUEST_HEADERS,
671 "The HTTP request headers",
672 SOUP_TYPE_MESSAGE_HEADERS,
675 * SOUP_MESSAGE_RESPONSE_BODY:
677 * Alias for the #SoupMessage:response-body property. (The
678 * message's HTTP response body.)
680 g_object_class_install_property (
681 object_class, PROP_RESPONSE_BODY,
682 g_param_spec_boxed (SOUP_MESSAGE_RESPONSE_BODY,
684 "The HTTP response content",
685 SOUP_TYPE_MESSAGE_BODY,
688 * SOUP_MESSAGE_RESPONSE_HEADERS:
690 * Alias for the #SoupMessage:response-headers property. (The
691 * message's HTTP response headers.)
693 g_object_class_install_property (
694 object_class, PROP_RESPONSE_HEADERS,
695 g_param_spec_boxed (SOUP_MESSAGE_RESPONSE_HEADERS,
697 "The HTTP response headers",
698 SOUP_TYPE_MESSAGE_HEADERS,
701 * SOUP_MESSAGE_TLS_CERTIFICATE:
703 * Alias for the #SoupMessage:tls-certificate property. (The
704 * TLS certificate associated with the message, if any.)
709 * SoupMessage:tls-certificate:
711 * The #GTlsCertificate associated with the message
715 g_object_class_install_property (
716 object_class, PROP_TLS_CERTIFICATE,
717 g_param_spec_object (SOUP_MESSAGE_TLS_CERTIFICATE,
719 "The TLS certificate associated with the message",
720 G_TYPE_TLS_CERTIFICATE,
723 * SOUP_MESSAGE_TLS_ERRORS:
725 * Alias for the #SoupMessage:tls-errors property. (The
726 * verification errors on #SoupMessage:tls-certificate.)
731 * SoupMessage:tls-errors:
733 * The verification errors on #SoupMessage:tls-certificate
737 g_object_class_install_property (
738 object_class, PROP_TLS_ERRORS,
739 g_param_spec_flags (SOUP_MESSAGE_TLS_ERRORS,
741 "The verification errors on the message's TLS certificate",
742 G_TYPE_TLS_CERTIFICATE_FLAGS, 0,
747 set_property (GObject *object, guint prop_id,
748 const GValue *value, GParamSpec *pspec)
750 SoupMessage *msg = SOUP_MESSAGE (object);
751 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
755 msg->method = g_intern_string (g_value_get_string (value));
758 soup_message_set_uri (msg, g_value_get_boxed (value));
760 case PROP_HTTP_VERSION:
761 soup_message_set_http_version (msg, g_value_get_enum (value));
764 soup_message_set_flags (msg, g_value_get_flags (value));
766 case PROP_SERVER_SIDE:
767 priv->server_side = g_value_get_boolean (value);
768 if (priv->server_side) {
769 soup_message_headers_set_encoding (msg->response_headers,
770 SOUP_ENCODING_CONTENT_LENGTH);
773 case PROP_STATUS_CODE:
774 soup_message_set_status (msg, g_value_get_uint (value));
776 case PROP_REASON_PHRASE:
777 soup_message_set_status_full (msg, msg->status_code,
778 g_value_get_string (value));
780 case PROP_FIRST_PARTY:
781 soup_message_set_first_party (msg, g_value_get_boxed (value));
783 case PROP_TLS_CERTIFICATE:
784 if (priv->tls_certificate)
785 g_object_unref (priv->tls_certificate);
786 priv->tls_certificate = g_value_dup_object (value);
787 if (priv->tls_errors)
788 priv->msg_flags &= ~SOUP_MESSAGE_CERTIFICATE_TRUSTED;
789 else if (priv->tls_certificate)
790 priv->msg_flags |= SOUP_MESSAGE_CERTIFICATE_TRUSTED;
792 case PROP_TLS_ERRORS:
793 priv->tls_errors = g_value_get_flags (value);
794 if (priv->tls_errors)
795 priv->msg_flags &= ~SOUP_MESSAGE_CERTIFICATE_TRUSTED;
796 else if (priv->tls_certificate)
797 priv->msg_flags |= SOUP_MESSAGE_CERTIFICATE_TRUSTED;
800 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
806 get_property (GObject *object, guint prop_id,
807 GValue *value, GParamSpec *pspec)
809 SoupMessage *msg = SOUP_MESSAGE (object);
810 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
814 g_value_set_string (value, msg->method);
817 g_value_set_boxed (value, priv->uri);
819 case PROP_HTTP_VERSION:
820 g_value_set_enum (value, priv->http_version);
823 g_value_set_flags (value, priv->msg_flags);
825 case PROP_SERVER_SIDE:
826 g_value_set_boolean (value, priv->server_side);
828 case PROP_STATUS_CODE:
829 g_value_set_uint (value, msg->status_code);
831 case PROP_REASON_PHRASE:
832 g_value_set_string (value, msg->reason_phrase);
834 case PROP_FIRST_PARTY:
835 g_value_set_boxed (value, priv->first_party);
837 case PROP_REQUEST_BODY:
838 g_value_set_boxed (value, msg->request_body);
840 case PROP_REQUEST_HEADERS:
841 g_value_set_boxed (value, msg->request_headers);
843 case PROP_RESPONSE_BODY:
844 g_value_set_boxed (value, msg->response_body);
846 case PROP_RESPONSE_HEADERS:
847 g_value_set_boxed (value, msg->response_headers);
849 case PROP_TLS_CERTIFICATE:
850 g_value_set_object (value, priv->tls_certificate);
852 case PROP_TLS_ERRORS:
853 g_value_set_flags (value, priv->tls_errors);
856 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
864 * @method: the HTTP method for the created request
865 * @uri_string: the destination endpoint (as a string)
867 * Creates a new empty #SoupMessage, which will connect to @uri
869 * Return value: the new #SoupMessage (or %NULL if @uri could not
873 soup_message_new (const char *method, const char *uri_string)
878 g_return_val_if_fail (method != NULL, NULL);
879 g_return_val_if_fail (uri_string != NULL, NULL);
881 uri = soup_uri_new (uri_string);
889 msg = soup_message_new_from_uri (method, uri);
895 * soup_message_new_from_uri:
896 * @method: the HTTP method for the created request
897 * @uri: the destination endpoint (as a #SoupURI)
899 * Creates a new empty #SoupMessage, which will connect to @uri
901 * Return value: the new #SoupMessage
904 soup_message_new_from_uri (const char *method, SoupURI *uri)
906 return g_object_new (SOUP_TYPE_MESSAGE,
907 SOUP_MESSAGE_METHOD, method,
908 SOUP_MESSAGE_URI, uri,
913 * soup_message_set_request:
915 * @content_type: MIME Content-Type of the body
916 * @req_use: a #SoupMemoryUse describing how to handle @req_body
917 * @req_body: a data buffer containing the body of the message request.
918 * @req_length: the byte length of @req_body.
920 * Convenience function to set the request body of a #SoupMessage. If
921 * @content_type is %NULL, the request body must be empty as well.
924 soup_message_set_request (SoupMessage *msg,
925 const char *content_type,
926 SoupMemoryUse req_use,
927 const char *req_body,
930 g_return_if_fail (SOUP_IS_MESSAGE (msg));
931 g_return_if_fail (content_type != NULL || req_length == 0);
934 soup_message_headers_replace (msg->request_headers,
935 "Content-Type", content_type);
936 soup_message_body_append (msg->request_body, req_use,
937 req_body, req_length);
939 soup_message_headers_remove (msg->request_headers,
941 soup_message_body_truncate (msg->request_body);
946 * soup_message_set_response:
948 * @content_type: (allow-none): MIME Content-Type of the body
949 * @resp_use: a #SoupMemoryUse describing how to handle @resp_body
950 * @resp_body: (array length=resp_length) (element-type guint8): a data buffer
951 * containing the body of the message response.
952 * @resp_length: the byte length of @resp_body.
954 * Convenience function to set the response body of a #SoupMessage. If
955 * @content_type is %NULL, the response body must be empty as well.
958 soup_message_set_response (SoupMessage *msg,
959 const char *content_type,
960 SoupMemoryUse resp_use,
961 const char *resp_body,
964 g_return_if_fail (SOUP_IS_MESSAGE (msg));
965 g_return_if_fail (content_type != NULL || resp_length == 0);
968 soup_message_headers_replace (msg->response_headers,
969 "Content-Type", content_type);
970 soup_message_body_append (msg->response_body, resp_use,
971 resp_body, resp_length);
973 soup_message_headers_remove (msg->response_headers,
975 soup_message_body_truncate (msg->response_body);
980 * soup_message_wrote_informational:
981 * @msg: a #SoupMessage
983 * Emits the %wrote_informational signal, indicating that the IO layer
984 * finished writing an informational (1xx) response for @msg.
987 soup_message_wrote_informational (SoupMessage *msg)
989 g_signal_emit (msg, signals[WROTE_INFORMATIONAL], 0);
993 * soup_message_wrote_headers:
994 * @msg: a #SoupMessage
996 * Emits the %wrote_headers signal, indicating that the IO layer
997 * finished writing the (non-informational) headers for @msg.
1000 soup_message_wrote_headers (SoupMessage *msg)
1002 g_signal_emit (msg, signals[WROTE_HEADERS], 0);
1006 * soup_message_wrote_chunk:
1007 * @msg: a #SoupMessage
1009 * Emits the %wrote_chunk signal, indicating that the IO layer
1010 * finished writing a chunk of @msg's body.
1013 soup_message_wrote_chunk (SoupMessage *msg)
1015 g_signal_emit (msg, signals[WROTE_CHUNK], 0);
1019 * soup_message_wrote_body_data:
1020 * @msg: a #SoupMessage
1021 * @chunk: the data written
1023 * Emits the %wrote_body_data signal, indicating that the IO layer
1024 * finished writing a portion of @msg's body.
1027 soup_message_wrote_body_data (SoupMessage *msg, SoupBuffer *chunk)
1029 g_signal_emit (msg, signals[WROTE_BODY_DATA], 0, chunk);
1033 * soup_message_wrote_body:
1034 * @msg: a #SoupMessage
1036 * Emits the %wrote_body signal, indicating that the IO layer finished
1037 * writing the body for @msg.
1040 soup_message_wrote_body (SoupMessage *msg)
1042 g_signal_emit (msg, signals[WROTE_BODY], 0);
1046 * soup_message_got_informational:
1047 * @msg: a #SoupMessage
1049 * Emits the #SoupMessage::got_informational signal, indicating that
1050 * the IO layer read a complete informational (1xx) response for @msg.
1053 soup_message_got_informational (SoupMessage *msg)
1055 g_signal_emit (msg, signals[GOT_INFORMATIONAL], 0);
1059 * soup_message_got_headers:
1060 * @msg: a #SoupMessage
1062 * Emits the #SoupMessage::got_headers signal, indicating that the IO
1063 * layer finished reading the (non-informational) headers for @msg.
1066 soup_message_got_headers (SoupMessage *msg)
1068 g_signal_emit (msg, signals[GOT_HEADERS], 0);
1072 * soup_message_got_chunk:
1073 * @msg: a #SoupMessage
1074 * @chunk: the newly-read chunk
1076 * Emits the #SoupMessage::got_chunk signal, indicating that the IO
1077 * layer finished reading a chunk of @msg's body.
1080 soup_message_got_chunk (SoupMessage *msg, SoupBuffer *chunk)
1082 g_signal_emit (msg, signals[GOT_CHUNK], 0, chunk);
1086 got_body (SoupMessage *req)
1088 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (req);
1089 SoupMessageBody *body;
1091 body = priv->server_side ? req->request_body : req->response_body;
1092 if (soup_message_body_get_accumulate (body)) {
1095 buffer = soup_message_body_flatten (body);
1096 soup_buffer_free (buffer);
1101 * soup_message_got_body:
1102 * @msg: a #SoupMessage
1104 * Emits the #SoupMessage::got_body signal, indicating that the IO
1105 * layer finished reading the body for @msg.
1108 soup_message_got_body (SoupMessage *msg)
1110 g_signal_emit (msg, signals[GOT_BODY], 0);
1114 * soup_message_content_sniffed:
1115 * @msg: a #SoupMessage
1116 * @content_type: a string with the sniffed content type
1117 * @params: a #GHashTable with the parameters
1119 * Emits the %content_sniffed signal, indicating that the IO layer
1120 * finished sniffing the content type for @msg. If content sniffing
1121 * will not be performed, due to the sniffer deciding to trust the
1122 * Content-Type sent by the server, this signal is emitted immediately
1123 * after #SoupMessage::got_headers, with %NULL as @content_type.
1126 soup_message_content_sniffed (SoupMessage *msg, const char *content_type, GHashTable *params)
1128 g_signal_emit (msg, signals[CONTENT_SNIFFED], 0, content_type, params);
1132 * soup_message_restarted:
1133 * @msg: a #SoupMessage
1135 * Emits the %restarted signal, indicating that @msg should be
1139 soup_message_restarted (SoupMessage *msg)
1141 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1143 if (priv->msg_flags & SOUP_MESSAGE_CAN_REBUILD)
1144 soup_message_body_truncate (msg->request_body);
1146 g_signal_emit (msg, signals[RESTARTED], 0);
1150 * soup_message_finished:
1151 * @msg: a #SoupMessage
1153 * Emits the %finished signal, indicating that @msg has been completely
1157 soup_message_finished (SoupMessage *msg)
1159 g_signal_emit (msg, signals[FINISHED], 0);
1163 soup_message_network_event (SoupMessage *msg,
1164 GSocketClientEvent event,
1165 GIOStream *connection)
1167 g_signal_emit (msg, signals[NETWORK_EVENT], 0,
1172 header_handler_free (gpointer header_name, GClosure *closure)
1174 g_free (header_name);
1178 header_handler_metamarshal (GClosure *closure, GValue *return_value,
1179 guint n_param_values, const GValue *param_values,
1180 gpointer invocation_hint, gpointer marshal_data)
1182 SoupMessage *msg = g_value_get_object (¶m_values[0]);
1183 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1184 const char *header_name = marshal_data;
1185 SoupMessageHeaders *hdrs;
1188 if (priv->io_status != SOUP_MESSAGE_IO_STATUS_RUNNING)
1192 hdrs = priv->server_side ? msg->request_headers : msg->response_headers;
1193 if (soup_message_headers_get_one (hdrs, header_name)) {
1194 closure->marshal (closure, return_value, n_param_values,
1195 param_values, invocation_hint,
1196 ((GCClosure *)closure)->callback);
1201 * soup_message_add_header_handler: (skip)
1202 * @msg: a #SoupMessage
1203 * @signal: signal to connect the handler to.
1204 * @header: HTTP response header to match against
1205 * @callback: the header handler
1206 * @user_data: data to pass to @handler_cb
1208 * Adds a signal handler to @msg for @signal, as with
1209 * g_signal_connect(), but with two differences: the @callback will
1210 * only be run if @msg has a header named @header, and it will only be
1211 * run if no earlier handler cancelled or requeued the message.
1213 * If @signal is one of the "got" signals (eg, "got_headers"), or
1214 * "finished" or "restarted", then @header is matched against the
1215 * incoming message headers (that is, the #request_headers for a
1216 * client #SoupMessage, or the #response_headers for a server
1217 * #SoupMessage). If @signal is one of the "wrote" signals, then
1218 * @header is matched against the outgoing message headers.
1220 * Return value: the handler ID from g_signal_connect()
1223 soup_message_add_header_handler (SoupMessage *msg,
1232 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
1233 g_return_val_if_fail (signal != NULL, 0);
1234 g_return_val_if_fail (header != NULL, 0);
1235 g_return_val_if_fail (callback != NULL, 0);
1237 closure = g_cclosure_new (callback, user_data, NULL);
1239 header_name = g_strdup (header);
1240 g_closure_set_meta_marshal (closure, header_name,
1241 header_handler_metamarshal);
1242 g_closure_add_finalize_notifier (closure, header_name,
1243 header_handler_free);
1245 return g_signal_connect_closure (msg, signal, closure, FALSE);
1249 status_handler_metamarshal (GClosure *closure, GValue *return_value,
1250 guint n_param_values, const GValue *param_values,
1251 gpointer invocation_hint, gpointer marshal_data)
1253 SoupMessage *msg = g_value_get_object (¶m_values[0]);
1254 guint status = GPOINTER_TO_UINT (marshal_data);
1257 if (priv->io_status != SOUP_MESSAGE_IO_STATUS_RUNNING)
1261 if (msg->status_code == status) {
1262 closure->marshal (closure, return_value, n_param_values,
1263 param_values, invocation_hint,
1264 ((GCClosure *)closure)->callback);
1269 * soup_message_add_status_code_handler: (skip)
1270 * @msg: a #SoupMessage
1271 * @signal: signal to connect the handler to.
1272 * @status_code: status code to match against
1273 * @callback: the header handler
1274 * @user_data: data to pass to @handler_cb
1276 * Adds a signal handler to @msg for @signal, as with
1277 * g_signal_connect() but with two differences: the @callback will
1278 * only be run if @msg has the status @status_code, and it will only
1279 * be run if no earlier handler cancelled or requeued the message.
1281 * @signal must be a signal that will be emitted after @msg's status
1282 * is set. For a client #SoupMessage, this means it can't be a "wrote"
1283 * signal. For a server #SoupMessage, this means it can't be a "got"
1286 * Return value: the handler ID from g_signal_connect()
1289 soup_message_add_status_code_handler (SoupMessage *msg,
1297 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
1298 g_return_val_if_fail (signal != NULL, 0);
1299 g_return_val_if_fail (callback != NULL, 0);
1301 closure = g_cclosure_new (callback, user_data, NULL);
1302 g_closure_set_meta_marshal (closure, GUINT_TO_POINTER (status_code),
1303 status_handler_metamarshal);
1305 return g_signal_connect_closure (msg, signal, closure, FALSE);
1310 * soup_message_set_auth:
1311 * @msg: a #SoupMessage
1312 * @auth: a #SoupAuth, or %NULL
1314 * Sets @msg to authenticate to its destination using @auth, which
1315 * must have already been fully authenticated. If @auth is %NULL, @msg
1316 * will not authenticate to its destination.
1319 soup_message_set_auth (SoupMessage *msg, SoupAuth *auth)
1321 SoupMessagePrivate *priv;
1324 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1325 g_return_if_fail (auth == NULL || SOUP_IS_AUTH (auth));
1326 g_return_if_fail (auth == NULL || soup_auth_is_authenticated (auth));
1328 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1331 g_object_unref (priv->auth);
1332 soup_message_headers_remove (msg->request_headers,
1339 g_object_ref (priv->auth);
1340 token = soup_auth_get_authorization (auth, msg);
1341 soup_message_headers_replace (msg->request_headers,
1342 "Authorization", token);
1347 * soup_message_get_auth:
1348 * @msg: a #SoupMessage
1350 * Gets the #SoupAuth used by @msg for authentication.
1352 * Return value: (transfer none): the #SoupAuth used by @msg for
1353 * authentication, or %NULL if @msg is unauthenticated.
1356 soup_message_get_auth (SoupMessage *msg)
1358 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1360 return SOUP_MESSAGE_GET_PRIVATE (msg)->auth;
1364 * soup_message_set_proxy_auth:
1365 * @msg: a #SoupMessage
1366 * @auth: a #SoupAuth, or %NULL
1368 * Sets @msg to authenticate to its proxy using @auth, which must have
1369 * already been fully authenticated. If @auth is %NULL, @msg will not
1370 * authenticate to its proxy.
1373 soup_message_set_proxy_auth (SoupMessage *msg, SoupAuth *auth)
1375 SoupMessagePrivate *priv;
1378 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1379 g_return_if_fail (auth == NULL || SOUP_IS_AUTH (auth));
1380 g_return_if_fail (auth == NULL || soup_auth_is_authenticated (auth));
1382 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1384 if (priv->proxy_auth) {
1385 g_object_unref (priv->proxy_auth);
1386 soup_message_headers_remove (msg->request_headers,
1387 "Proxy-Authorization");
1389 priv->proxy_auth = auth;
1390 if (!priv->proxy_auth)
1393 g_object_ref (priv->proxy_auth);
1394 token = soup_auth_get_authorization (auth, msg);
1395 soup_message_headers_replace (msg->request_headers,
1396 "Proxy-Authorization", token);
1401 * soup_message_get_proxy_auth:
1402 * @msg: a #SoupMessage
1404 * Gets the #SoupAuth used by @msg for authentication to its proxy..
1406 * Return value: the #SoupAuth used by @msg for authentication to its
1407 * proxy, or %NULL if @msg isn't authenticated to its proxy.
1410 soup_message_get_proxy_auth (SoupMessage *msg)
1412 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1414 return SOUP_MESSAGE_GET_PRIVATE (msg)->proxy_auth;
1418 * soup_message_cleanup_response:
1419 * @req: a #SoupMessage
1421 * Cleans up all response data on @req, so that the request can be sent
1422 * again and receive a new response. (Eg, as a result of a redirect or
1423 * authorization request.)
1426 soup_message_cleanup_response (SoupMessage *req)
1428 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (req);
1430 soup_message_body_truncate (req->response_body);
1431 soup_message_headers_clear (req->response_headers);
1432 if (priv->server_side) {
1433 soup_message_headers_set_encoding (req->response_headers,
1434 SOUP_ENCODING_CONTENT_LENGTH);
1437 while (priv->decoders) {
1438 g_object_unref (priv->decoders->data);
1439 priv->decoders = g_slist_delete_link (priv->decoders, priv->decoders);
1441 priv->msg_flags &= ~SOUP_MESSAGE_CONTENT_DECODED;
1443 req->status_code = SOUP_STATUS_NONE;
1444 if (req->reason_phrase) {
1445 g_free (req->reason_phrase);
1446 req->reason_phrase = NULL;
1448 priv->http_version = priv->orig_http_version;
1450 g_object_notify (G_OBJECT (req), SOUP_MESSAGE_STATUS_CODE);
1451 g_object_notify (G_OBJECT (req), SOUP_MESSAGE_REASON_PHRASE);
1452 g_object_notify (G_OBJECT (req), SOUP_MESSAGE_HTTP_VERSION);
1453 g_object_notify (G_OBJECT (req), SOUP_MESSAGE_FLAGS);
1454 g_object_notify (G_OBJECT (req), SOUP_MESSAGE_TLS_CERTIFICATE);
1455 g_object_notify (G_OBJECT (req), SOUP_MESSAGE_TLS_ERRORS);
1460 * @SOUP_MESSAGE_NO_REDIRECT: The session should not follow redirect
1461 * (3xx) responses received by this message.
1462 * @SOUP_MESSAGE_CAN_REBUILD: The caller will rebuild the request
1463 * body if the message is restarted; see
1464 * soup_message_body_set_accumulate() for more details.
1465 * @SOUP_MESSAGE_OVERWRITE_CHUNKS: Deprecated: equivalent to calling
1466 * soup_message_body_set_accumulate() on the incoming message body
1467 * (ie, #SoupMessage:response_body for a client-side request),
1469 * @SOUP_MESSAGE_CONTENT_DECODED: Set by #SoupContentDecoder to
1470 * indicate that it has removed the Content-Encoding on a message (and
1471 * so headers such as Content-Length may no longer accurately describe
1473 * @SOUP_MESSAGE_CERTIFICATE_TRUSTED: if set after an https response
1474 * has been received, indicates that the server's SSL certificate is
1475 * trusted according to the session's CA.
1476 * @SOUP_MESSAGE_NEW_CONNECTION: The message should be sent on a
1477 * newly-created connection, not reusing an existing persistent
1478 * connection. Note that messages with non-idempotent
1479 * #SoupMessage:method<!-- -->s behave this way by default.
1481 * Various flags that can be set on a #SoupMessage to alter its
1486 * soup_message_set_flags:
1487 * @msg: a #SoupMessage
1488 * @flags: a set of #SoupMessageFlags values
1490 * Sets the specified flags on @msg.
1493 soup_message_set_flags (SoupMessage *msg, SoupMessageFlags flags)
1495 SoupMessagePrivate *priv;
1497 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1498 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1500 if ((priv->msg_flags ^ flags) & SOUP_MESSAGE_OVERWRITE_CHUNKS) {
1501 soup_message_body_set_accumulate (
1502 priv->server_side ? msg->request_body : msg->response_body,
1503 !(flags & SOUP_MESSAGE_OVERWRITE_CHUNKS));
1506 priv->msg_flags = flags;
1507 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_FLAGS);
1511 * soup_message_get_flags:
1512 * @msg: a #SoupMessage
1514 * Gets the flags on @msg
1516 * Return value: the flags
1519 soup_message_get_flags (SoupMessage *msg)
1521 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
1523 return SOUP_MESSAGE_GET_PRIVATE (msg)->msg_flags;
1528 * @SOUP_HTTP_1_0: HTTP 1.0 (RFC 1945)
1529 * @SOUP_HTTP_1_1: HTTP 1.1 (RFC 2616)
1531 * Indicates the HTTP protocol version being used.
1535 * soup_message_set_http_version:
1536 * @msg: a #SoupMessage
1537 * @version: the HTTP version
1539 * Sets the HTTP version on @msg. The default version is
1540 * %SOUP_HTTP_1_1. Setting it to %SOUP_HTTP_1_0 will prevent certain
1541 * functionality from being used.
1544 soup_message_set_http_version (SoupMessage *msg, SoupHTTPVersion version)
1546 SoupMessagePrivate *priv;
1548 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1549 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1551 priv->http_version = version;
1552 if (msg->status_code == SOUP_STATUS_NONE)
1553 priv->orig_http_version = version;
1554 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_HTTP_VERSION);
1558 * soup_message_get_http_version:
1559 * @msg: a #SoupMessage
1561 * Gets the HTTP version of @msg. This is the minimum of the
1562 * version from the request and the version from the response.
1564 * Return value: the HTTP version
1567 soup_message_get_http_version (SoupMessage *msg)
1569 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), SOUP_HTTP_1_0);
1571 return SOUP_MESSAGE_GET_PRIVATE (msg)->http_version;
1575 * soup_message_is_keepalive:
1576 * @msg: a #SoupMessage
1578 * Determines whether or not @msg's connection can be kept alive for
1579 * further requests after processing @msg, based on the HTTP version,
1580 * Connection header, etc.
1582 * Return value: %TRUE or %FALSE.
1585 soup_message_is_keepalive (SoupMessage *msg)
1587 const char *c_conn, *s_conn;
1589 c_conn = soup_message_headers_get_list (msg->request_headers,
1591 s_conn = soup_message_headers_get_list (msg->response_headers,
1594 if (msg->status_code == SOUP_STATUS_OK &&
1595 msg->method == SOUP_METHOD_CONNECT)
1598 /* Not persistent if the server sent a terminate-by-EOF response */
1599 if (soup_message_headers_get_encoding (msg->response_headers) == SOUP_ENCODING_EOF)
1602 if (SOUP_MESSAGE_GET_PRIVATE (msg)->http_version == SOUP_HTTP_1_0) {
1603 /* In theory, HTTP/1.0 connections are only persistent
1604 * if the client requests it, and the server agrees.
1605 * But some servers do keep-alive even if the client
1606 * doesn't request it. So ignore c_conn.
1609 if (!s_conn || !soup_header_contains (s_conn, "Keep-Alive"))
1612 /* Normally persistent unless either side requested otherwise */
1613 if (c_conn && soup_header_contains (c_conn, "close"))
1615 if (s_conn && soup_header_contains (s_conn, "close"))
1625 * soup_message_set_uri:
1626 * @msg: a #SoupMessage
1627 * @uri: the new #SoupURI
1629 * Sets @msg's URI to @uri. If @msg has already been sent and you want
1630 * to re-send it with the new URI, you need to call
1631 * soup_session_requeue_message().
1634 soup_message_set_uri (SoupMessage *msg, SoupURI *uri)
1636 SoupMessagePrivate *priv;
1638 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1639 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1642 soup_uri_free (priv->uri);
1644 g_object_unref (priv->addr);
1647 priv->uri = soup_uri_copy (uri);
1649 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_URI);
1653 * soup_message_get_uri:
1654 * @msg: a #SoupMessage
1658 * Return value: (transfer none): the URI @msg is targeted for.
1661 soup_message_get_uri (SoupMessage *msg)
1663 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1665 return SOUP_MESSAGE_GET_PRIVATE (msg)->uri;
1669 * soup_message_get_address:
1670 * @msg: a #SoupMessage
1672 * Gets the address @msg's URI points to. After first setting the
1673 * URI on a message, this will be unresolved, although the message's
1674 * session will resolve it before sending the message.
1676 * Return value: (transfer none): the address @msg's URI points to
1681 soup_message_get_address (SoupMessage *msg)
1683 SoupMessagePrivate *priv;
1685 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1687 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1689 priv->addr = soup_address_new (priv->uri->host,
1696 * soup_message_set_status:
1697 * @msg: a #SoupMessage
1698 * @status_code: an HTTP status code
1700 * Sets @msg's status code to @status_code. If @status_code is a
1701 * known value, it will also set @msg's reason_phrase.
1704 soup_message_set_status (SoupMessage *msg, guint status_code)
1706 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1707 g_return_if_fail (status_code != 0);
1709 g_free (msg->reason_phrase);
1711 msg->status_code = status_code;
1712 msg->reason_phrase = g_strdup (soup_status_get_phrase (status_code));
1713 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_STATUS_CODE);
1714 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_REASON_PHRASE);
1718 * soup_message_set_status_full:
1719 * @msg: a #SoupMessage
1720 * @status_code: an HTTP status code
1721 * @reason_phrase: a description of the status
1723 * Sets @msg's status code and reason phrase.
1726 soup_message_set_status_full (SoupMessage *msg,
1728 const char *reason_phrase)
1730 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1731 g_return_if_fail (status_code != 0);
1732 g_return_if_fail (reason_phrase != NULL);
1734 g_free (msg->reason_phrase);
1736 msg->status_code = status_code;
1737 msg->reason_phrase = g_strdup (reason_phrase);
1738 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_STATUS_CODE);
1739 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_REASON_PHRASE);
1743 * SoupChunkAllocator:
1744 * @msg: the #SoupMessage the chunk is being allocated for
1745 * @max_len: the maximum length that will be read, or 0.
1746 * @user_data: the data passed to soup_message_set_chunk_allocator()
1748 * The prototype for a chunk allocation callback. This should allocate
1749 * a new #SoupBuffer and return it for the I/O layer to read message
1750 * body data off the network into.
1752 * If @max_len is non-0, it indicates the maximum number of bytes that
1753 * could be read, based on what is known about the message size. Note
1754 * that this might be a very large number, and you should not simply
1755 * try to allocate that many bytes blindly. If @max_len is 0, that
1756 * means that libsoup does not know how many bytes remain to be read,
1757 * and the allocator should return a buffer of a size that it finds
1760 * If the allocator returns %NULL, the message will be paused. It is
1761 * up to the application to make sure that it gets unpaused when it
1762 * becomes possible to allocate a new buffer.
1764 * Return value: the new buffer (or %NULL)
1768 * soup_message_set_chunk_allocator:
1769 * @msg: a #SoupMessage
1770 * @allocator: the chunk allocator callback
1771 * @user_data: data to pass to @allocator
1772 * @destroy_notify: destroy notifier to free @user_data when @msg is
1775 * Sets an alternate chunk-allocation function to use when reading
1776 * @msg's body. Every time data is available to read, libsoup will
1777 * call @allocator, which should return a #SoupBuffer. (See
1778 * #SoupChunkAllocator for additional details.) Libsoup will then read
1779 * data from the network into that buffer, and update the buffer's
1780 * <literal>length</literal> to indicate how much data it read.
1782 * Generally, a custom chunk allocator would be used in conjunction
1783 * with soup_message_body_set_accumulate() %FALSE and
1784 * #SoupMessage::got_chunk, as part of a strategy to avoid unnecessary
1785 * copying of data. However, you cannot assume that every call to the
1786 * allocator will be followed by a call to your
1787 * #SoupMessage::got_chunk handler; if an I/O error occurs, then the
1788 * buffer will be unreffed without ever having been used. If your
1789 * buffer-allocation strategy requires special cleanup, use
1790 * soup_buffer_new_with_owner() rather than doing the cleanup from the
1791 * #SoupMessage::got_chunk handler.
1793 * The other thing to remember when using non-accumulating message
1794 * bodies is that the buffer passed to the #SoupMessage::got_chunk
1795 * handler will be unreffed after the handler returns, just as it
1796 * would be in the non-custom-allocated case. If you want to hand the
1797 * chunk data off to some other part of your program to use later,
1798 * you'll need to ref the #SoupBuffer (or its owner, in the
1799 * soup_buffer_new_with_owner() case) to ensure that the data remains
1803 soup_message_set_chunk_allocator (SoupMessage *msg,
1804 SoupChunkAllocator allocator,
1806 GDestroyNotify destroy_notify)
1808 SoupMessagePrivate *priv;
1810 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1812 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1814 if (priv->chunk_allocator_dnotify)
1815 priv->chunk_allocator_dnotify (priv->chunk_allocator_data);
1817 priv->chunk_allocator = allocator;
1818 priv->chunk_allocator_data = user_data;
1819 priv->chunk_allocator_dnotify = destroy_notify;
1823 * soup_message_disable_feature:
1824 * @msg: a #SoupMessage
1825 * @feature_type: the #GType of a #SoupSessionFeature
1827 * This disables the actions of #SoupSessionFeature<!-- -->s with the
1828 * given @feature_type (or a subclass of that type) on @msg, so that
1829 * @msg is processed as though the feature(s) hadn't been added to the
1830 * session. Eg, passing #SOUP_TYPE_PROXY_URI_RESOLVER for @feature_type
1831 * will disable proxy handling and cause @msg to be sent directly to
1832 * the indicated origin server, regardless of system proxy
1835 * You must call this before queueing @msg on a session; calling it on
1836 * a message that has already been queued is undefined. In particular,
1837 * you cannot call this on a message that is being requeued after a
1838 * redirect or authentication.
1843 soup_message_disable_feature (SoupMessage *msg, GType feature_type)
1845 SoupMessagePrivate *priv;
1847 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1849 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1851 priv->disabled_features = g_slist_prepend (priv->disabled_features,
1852 GSIZE_TO_POINTER (feature_type));
1856 soup_message_disables_feature (SoupMessage *msg, gpointer feature)
1858 SoupMessagePrivate *priv;
1861 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE);
1863 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1865 for (f = priv->disabled_features; f; f = f->next) {
1866 if (G_TYPE_CHECK_INSTANCE_TYPE (feature, (GType) GPOINTER_TO_SIZE (f->data)))
1873 * soup_message_get_first_party:
1874 * @msg: a #SoupMessage
1876 * Gets @msg's first-party #SoupURI
1878 * Returns: (transfer none): the @msg's first party #SoupURI
1883 soup_message_get_first_party (SoupMessage *msg)
1885 SoupMessagePrivate *priv;
1887 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1889 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1890 return priv->first_party;
1894 * soup_message_set_first_party:
1895 * @msg: a #SoupMessage
1896 * @first_party: the #SoupURI for the @msg's first party
1898 * Sets @first_party as the main document #SoupURI for @msg. For
1899 * details of when and how this is used refer to the documentation for
1900 * #SoupCookieJarAcceptPolicy.
1905 soup_message_set_first_party (SoupMessage *msg,
1906 SoupURI *first_party)
1908 SoupMessagePrivate *priv;
1910 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1911 g_return_if_fail (first_party != NULL);
1913 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1915 if (priv->first_party) {
1916 if (soup_uri_equal (priv->first_party, first_party))
1919 soup_uri_free (priv->first_party);
1922 priv->first_party = soup_uri_copy (first_party);
1923 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_FIRST_PARTY);
1927 soup_message_set_https_status (SoupMessage *msg, SoupConnection *conn)
1931 sock = conn ? soup_connection_get_socket (conn) : NULL;
1932 if (sock && soup_socket_is_ssl (sock)) {
1933 GTlsCertificate *certificate;
1934 GTlsCertificateFlags errors;
1937 SOUP_SOCKET_TLS_CERTIFICATE, &certificate,
1938 SOUP_SOCKET_TLS_ERRORS, &errors,
1941 SOUP_MESSAGE_TLS_CERTIFICATE, certificate,
1942 SOUP_MESSAGE_TLS_ERRORS, errors,
1945 g_object_unref (certificate);
1948 SOUP_MESSAGE_TLS_CERTIFICATE, NULL,
1949 SOUP_MESSAGE_TLS_ERRORS, 0,
1955 * soup_message_get_https_status:
1956 * @msg: a #SoupMessage
1957 * @certificate: (out) (transfer none): @msg's TLS certificate
1958 * @errors: (out): the verification status of @certificate
1960 * If @msg is using https, this retrieves the #GTlsCertificate
1961 * associated with its connection, and the #GTlsCertificateFlags showing
1962 * what problems, if any, have been found with that certificate.
1964 * Return value: %TRUE if @msg uses https, %FALSE if not
1969 soup_message_get_https_status (SoupMessage *msg,
1970 GTlsCertificate **certificate,
1971 GTlsCertificateFlags *errors)
1973 SoupMessagePrivate *priv;
1975 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE);
1977 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1980 *certificate = priv->tls_certificate;
1982 *errors = priv->tls_errors;
1983 return priv->tls_certificate != NULL;
1987 * soup_message_set_redirect:
1988 * @msg: a #SoupMessage
1989 * @status_code: a 3xx status code
1990 * @redirect_uri: the URI to redirect @msg to
1992 * Sets @msg's status_code to @status_code and adds a Location header
1993 * pointing to @redirect_uri. Use this from a #SoupServer when you
1994 * want to redirect the client to another URI.
1996 * @redirect_uri can be a relative URI, in which case it is
1997 * interpreted relative to @msg's current URI. In particular, if
1998 * @redirect_uri is just a path, it will replace the path
1999 * <emphasis>and query</emphasis> of @msg's URI.
2004 soup_message_set_redirect (SoupMessage *msg, guint status_code,
2005 const char *redirect_uri)
2010 location = soup_uri_new_with_base (soup_message_get_uri (msg), redirect_uri);
2011 g_return_if_fail (location != NULL);
2013 soup_message_set_status (msg, status_code);
2014 location_str = soup_uri_to_string (location, FALSE);
2015 soup_message_headers_replace (msg->response_headers, "Location",
2017 g_free (location_str);
2018 soup_uri_free (location);