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-message.h"
13 #include "soup-connection.h"
14 #include "soup-marshal.h"
15 #include "soup-message-private.h"
18 * SECTION:soup-message
19 * @short_description: An HTTP request and response.
20 * @see_also: #SoupMessageHeaders, #SoupMessageBody
22 * A #SoupMessage represents an HTTP message that is being sent or
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().
36 * For server-side usage, #SoupServer will create #SoupMessage<!--
37 * -->s automatically for incoming requests, which your application
38 * will receive via handlers.
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
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
57 * Represents an HTTP message being sent or received.
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
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).
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.)
89 * For a server-side #SoupMessage, @request_body's %data will be
90 * filled in before #SoupMessage::got_body is emitted.
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.
99 G_DEFINE_TYPE (SoupMessage, soup_message, G_TYPE_OBJECT)
122 static guint signals[LAST_SIGNAL] = { 0 };
136 PROP_REQUEST_HEADERS,
138 PROP_RESPONSE_HEADERS,
139 PROP_TLS_CERTIFICATE,
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 soup_message_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);
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);
172 g_clear_object (&priv->auth);
173 g_clear_object (&priv->proxy_auth);
175 g_slist_free (priv->disabled_features);
177 g_clear_object (&priv->tls_certificate);
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);
184 g_free (msg->reason_phrase);
186 G_OBJECT_CLASS (soup_message_parent_class)->finalize (object);
190 soup_message_set_property (GObject *object, guint prop_id,
191 const GValue *value, GParamSpec *pspec)
193 SoupMessage *msg = SOUP_MESSAGE (object);
194 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
198 msg->method = g_intern_string (g_value_get_string (value));
201 soup_message_set_uri (msg, g_value_get_boxed (value));
203 case PROP_HTTP_VERSION:
204 soup_message_set_http_version (msg, g_value_get_enum (value));
207 soup_message_set_flags (msg, g_value_get_flags (value));
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);
216 case PROP_STATUS_CODE:
217 soup_message_set_status (msg, g_value_get_uint (value));
219 case PROP_REASON_PHRASE:
220 soup_message_set_status_full (msg, msg->status_code,
221 g_value_get_string (value));
223 case PROP_FIRST_PARTY:
224 soup_message_set_first_party (msg, g_value_get_boxed (value));
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;
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;
243 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
249 soup_message_get_property (GObject *object, guint prop_id,
250 GValue *value, GParamSpec *pspec)
252 SoupMessage *msg = SOUP_MESSAGE (object);
253 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
257 g_value_set_string (value, msg->method);
260 g_value_set_boxed (value, priv->uri);
262 case PROP_HTTP_VERSION:
263 g_value_set_enum (value, priv->http_version);
266 g_value_set_flags (value, priv->msg_flags);
268 case PROP_SERVER_SIDE:
269 g_value_set_boolean (value, priv->server_side);
271 case PROP_STATUS_CODE:
272 g_value_set_uint (value, msg->status_code);
274 case PROP_REASON_PHRASE:
275 g_value_set_string (value, msg->reason_phrase);
277 case PROP_FIRST_PARTY:
278 g_value_set_boxed (value, priv->first_party);
280 case PROP_REQUEST_BODY:
281 g_value_set_boxed (value, msg->request_body);
283 case PROP_REQUEST_HEADERS:
284 g_value_set_boxed (value, msg->request_headers);
286 case PROP_RESPONSE_BODY:
287 g_value_set_boxed (value, msg->response_body);
289 case PROP_RESPONSE_HEADERS:
290 g_value_set_boxed (value, msg->response_headers);
292 case PROP_TLS_CERTIFICATE:
293 g_value_set_object (value, priv->tls_certificate);
295 case PROP_TLS_ERRORS:
296 g_value_set_flags (value, priv->tls_errors);
299 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
305 soup_message_real_got_body (SoupMessage *msg)
307 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
308 SoupMessageBody *body;
310 body = priv->server_side ? msg->request_body : msg->response_body;
311 if (soup_message_body_get_accumulate (body)) {
314 buffer = soup_message_body_flatten (body);
315 soup_buffer_free (buffer);
320 soup_message_class_init (SoupMessageClass *message_class)
322 GObjectClass *object_class = G_OBJECT_CLASS (message_class);
324 g_type_class_add_private (message_class, sizeof (SoupMessagePrivate));
326 /* virtual method definition */
327 message_class->got_body = soup_message_real_got_body;
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;
337 * SoupMessage::wrote-informational:
340 * Emitted immediately after writing a 1xx (Informational)
341 * response for a (server-side) message.
343 signals[WROTE_INFORMATIONAL] =
344 g_signal_new ("wrote_informational",
345 G_OBJECT_CLASS_TYPE (object_class),
347 G_STRUCT_OFFSET (SoupMessageClass, wrote_informational),
349 _soup_marshal_NONE__NONE,
353 * SoupMessage::wrote-headers:
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.)
361 signals[WROTE_HEADERS] =
362 g_signal_new ("wrote_headers",
363 G_OBJECT_CLASS_TYPE (object_class),
365 G_STRUCT_OFFSET (SoupMessageClass, wrote_headers),
367 _soup_marshal_NONE__NONE,
371 * SoupMessage::wrote-chunk:
374 * Emitted immediately after writing a body chunk for a message.
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.
383 signals[WROTE_CHUNK] =
384 g_signal_new ("wrote_chunk",
385 G_OBJECT_CLASS_TYPE (object_class),
387 G_STRUCT_OFFSET (SoupMessageClass, wrote_chunk),
389 _soup_marshal_NONE__NONE,
393 * SoupMessage::wrote-body-data:
395 * @chunk: the data written
397 * Emitted immediately after writing a portion of the message
398 * body to the network.
400 * Unlike #SoupMessage::wrote_chunk, this is emitted after
401 * every successful write() call, not only after finishing a
406 signals[WROTE_BODY_DATA] =
407 g_signal_new ("wrote_body_data",
408 G_OBJECT_CLASS_TYPE (object_class),
410 0, /* FIXME after next ABI break */
412 _soup_marshal_NONE__BOXED,
417 * SoupMessage::wrote-body:
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.)
427 signals[WROTE_BODY] =
428 g_signal_new ("wrote_body",
429 G_OBJECT_CLASS_TYPE (object_class),
431 G_STRUCT_OFFSET (SoupMessageClass, wrote_body),
433 _soup_marshal_NONE__NONE,
437 * SoupMessage::got-informational:
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.
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.
450 signals[GOT_INFORMATIONAL] =
451 g_signal_new ("got_informational",
452 G_OBJECT_CLASS_TYPE (object_class),
454 G_STRUCT_OFFSET (SoupMessageClass, got_informational),
456 _soup_marshal_NONE__NONE,
460 * SoupMessage::got-headers:
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
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.
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.)
482 signals[GOT_HEADERS] =
483 g_signal_new ("got_headers",
484 G_OBJECT_CLASS_TYPE (object_class),
486 G_STRUCT_OFFSET (SoupMessageClass, got_headers),
488 _soup_marshal_NONE__NONE,
492 * SoupMessage::got-chunk:
494 * @chunk: the just-read chunk
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
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.
506 g_signal_new ("got_chunk",
507 G_OBJECT_CLASS_TYPE (object_class),
509 G_STRUCT_OFFSET (SoupMessageClass, got_chunk),
511 _soup_marshal_NONE__BOXED,
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
519 SOUP_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE);
522 * SoupMessage::got-body:
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.)
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.
535 g_signal_new ("got_body",
536 G_OBJECT_CLASS_TYPE (object_class),
538 G_STRUCT_OFFSET (SoupMessageClass, got_body),
540 _soup_marshal_NONE__NONE,
544 * SoupMessage::content-sniffed:
546 * @type: the content type that we got from sniffing
547 * @params: (element-type utf8 utf8): a #GHashTable with the parameters
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
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.
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.
571 signals[CONTENT_SNIFFED] =
572 g_signal_new ("content_sniffed",
573 G_OBJECT_CLASS_TYPE (object_class),
577 _soup_marshal_NONE__STRING_BOXED,
583 * SoupMessage::restarted:
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
592 g_signal_new ("restarted",
593 G_OBJECT_CLASS_TYPE (object_class),
595 G_STRUCT_OFFSET (SoupMessageClass, restarted),
597 _soup_marshal_NONE__NONE,
601 * SoupMessage::finished:
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.)
609 g_signal_new ("finished",
610 G_OBJECT_CLASS_TYPE (object_class),
612 G_STRUCT_OFFSET (SoupMessageClass, finished),
614 _soup_marshal_NONE__NONE,
618 * SoupMessage::network-event:
620 * @event: the network event
621 * @connection: the current state of the network connection
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.)
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.
638 signals[NETWORK_EVENT] =
639 g_signal_new ("network_event",
640 G_OBJECT_CLASS_TYPE (object_class),
646 G_TYPE_SOCKET_CLIENT_EVENT,
651 * SOUP_MESSAGE_METHOD:
653 * Alias for the #SoupMessage:method property. (The message's
656 g_object_class_install_property (
657 object_class, PROP_METHOD,
658 g_param_spec_string (SOUP_MESSAGE_METHOD,
660 "The message's HTTP method",
666 * Alias for the #SoupMessage:uri property. (The message's
669 g_object_class_install_property (
670 object_class, PROP_URI,
671 g_param_spec_boxed (SOUP_MESSAGE_URI,
673 "The message's Request-URI",
677 * SOUP_MESSAGE_HTTP_VERSION:
679 * Alias for the #SoupMessage:http-version property. (The
680 * message's #SoupHTTPVersion.)
682 g_object_class_install_property (
683 object_class, PROP_HTTP_VERSION,
684 g_param_spec_enum (SOUP_MESSAGE_HTTP_VERSION,
686 "The HTTP protocol version to use",
687 SOUP_TYPE_HTTP_VERSION,
691 * SOUP_MESSAGE_FLAGS:
693 * Alias for the #SoupMessage:flags property. (The message's
694 * #SoupMessageFlags.)
696 g_object_class_install_property (
697 object_class, PROP_FLAGS,
698 g_param_spec_flags (SOUP_MESSAGE_FLAGS,
700 "Various message options",
701 SOUP_TYPE_MESSAGE_FLAGS,
705 * SOUP_MESSAGE_SERVER_SIDE:
707 * Alias for the #SoupMessage:server-side property. (%TRUE if
708 * the message was created by #SoupServer.)
710 g_object_class_install_property (
711 object_class, PROP_SERVER_SIDE,
712 g_param_spec_boolean (SOUP_MESSAGE_SERVER_SIDE,
714 "Whether or not the message is server-side rather than client-side",
716 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
718 * SOUP_MESSAGE_STATUS_CODE:
720 * Alias for the #SoupMessage:status-code property. (The
721 * message's HTTP response status code.)
723 g_object_class_install_property (
724 object_class, PROP_STATUS_CODE,
725 g_param_spec_uint (SOUP_MESSAGE_STATUS_CODE,
727 "The HTTP response status code",
731 * SOUP_MESSAGE_REASON_PHRASE:
733 * Alias for the #SoupMessage:reason-phrase property. (The
734 * message's HTTP response reason phrase.)
736 g_object_class_install_property (
737 object_class, PROP_REASON_PHRASE,
738 g_param_spec_string (SOUP_MESSAGE_REASON_PHRASE,
740 "The HTTP response reason phrase",
744 * SOUP_MESSAGE_FIRST_PARTY:
746 * Alias for the #SoupMessage:first-party property. (The
747 * #SoupURI loaded in the application when the message was
753 * SoupMessage:first-party:
755 * The #SoupURI loaded in the application when the message was
760 g_object_class_install_property (
761 object_class, PROP_FIRST_PARTY,
762 g_param_spec_boxed (SOUP_MESSAGE_FIRST_PARTY,
764 "The URI loaded in the application when the message was requested.",
768 * SOUP_MESSAGE_REQUEST_BODY:
770 * Alias for the #SoupMessage:request-body property. (The
771 * message's HTTP request body.)
773 g_object_class_install_property (
774 object_class, PROP_REQUEST_BODY,
775 g_param_spec_boxed (SOUP_MESSAGE_REQUEST_BODY,
777 "The HTTP request content",
778 SOUP_TYPE_MESSAGE_BODY,
781 * SOUP_MESSAGE_REQUEST_HEADERS:
783 * Alias for the #SoupMessage:request-headers property. (The
784 * message's HTTP request headers.)
786 g_object_class_install_property (
787 object_class, PROP_REQUEST_HEADERS,
788 g_param_spec_boxed (SOUP_MESSAGE_REQUEST_HEADERS,
790 "The HTTP request headers",
791 SOUP_TYPE_MESSAGE_HEADERS,
794 * SOUP_MESSAGE_RESPONSE_BODY:
796 * Alias for the #SoupMessage:response-body property. (The
797 * message's HTTP response body.)
799 g_object_class_install_property (
800 object_class, PROP_RESPONSE_BODY,
801 g_param_spec_boxed (SOUP_MESSAGE_RESPONSE_BODY,
803 "The HTTP response content",
804 SOUP_TYPE_MESSAGE_BODY,
807 * SOUP_MESSAGE_RESPONSE_HEADERS:
809 * Alias for the #SoupMessage:response-headers property. (The
810 * message's HTTP response headers.)
812 g_object_class_install_property (
813 object_class, PROP_RESPONSE_HEADERS,
814 g_param_spec_boxed (SOUP_MESSAGE_RESPONSE_HEADERS,
816 "The HTTP response headers",
817 SOUP_TYPE_MESSAGE_HEADERS,
820 * SOUP_MESSAGE_TLS_CERTIFICATE:
822 * Alias for the #SoupMessage:tls-certificate property. (The
823 * TLS certificate associated with the message, if any.)
828 * SoupMessage:tls-certificate:
830 * The #GTlsCertificate associated with the message
834 g_object_class_install_property (
835 object_class, PROP_TLS_CERTIFICATE,
836 g_param_spec_object (SOUP_MESSAGE_TLS_CERTIFICATE,
838 "The TLS certificate associated with the message",
839 G_TYPE_TLS_CERTIFICATE,
842 * SOUP_MESSAGE_TLS_ERRORS:
844 * Alias for the #SoupMessage:tls-errors property. (The
845 * verification errors on #SoupMessage:tls-certificate.)
850 * SoupMessage:tls-errors:
852 * The verification errors on #SoupMessage:tls-certificate
856 g_object_class_install_property (
857 object_class, PROP_TLS_ERRORS,
858 g_param_spec_flags (SOUP_MESSAGE_TLS_ERRORS,
860 "The verification errors on the message's TLS certificate",
861 G_TYPE_TLS_CERTIFICATE_FLAGS, 0,
868 * @method: the HTTP method for the created request
869 * @uri_string: the destination endpoint (as a string)
871 * Creates a new empty #SoupMessage, which will connect to @uri
873 * Return value: the new #SoupMessage (or %NULL if @uri could not
877 soup_message_new (const char *method, const char *uri_string)
882 g_return_val_if_fail (method != NULL, NULL);
883 g_return_val_if_fail (uri_string != NULL, NULL);
885 uri = soup_uri_new (uri_string);
893 msg = soup_message_new_from_uri (method, uri);
899 * soup_message_new_from_uri:
900 * @method: the HTTP method for the created request
901 * @uri: the destination endpoint (as a #SoupURI)
903 * Creates a new empty #SoupMessage, which will connect to @uri
905 * Return value: the new #SoupMessage
908 soup_message_new_from_uri (const char *method, SoupURI *uri)
910 return g_object_new (SOUP_TYPE_MESSAGE,
911 SOUP_MESSAGE_METHOD, method,
912 SOUP_MESSAGE_URI, uri,
917 * soup_message_set_request:
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.
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.
928 soup_message_set_request (SoupMessage *msg,
929 const char *content_type,
930 SoupMemoryUse req_use,
931 const char *req_body,
934 g_return_if_fail (SOUP_IS_MESSAGE (msg));
935 g_return_if_fail (content_type != NULL || req_length == 0);
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);
943 soup_message_headers_remove (msg->request_headers,
945 soup_message_body_truncate (msg->request_body);
950 * soup_message_set_response:
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.
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.
962 soup_message_set_response (SoupMessage *msg,
963 const char *content_type,
964 SoupMemoryUse resp_use,
965 const char *resp_body,
968 g_return_if_fail (SOUP_IS_MESSAGE (msg));
969 g_return_if_fail (content_type != NULL || resp_length == 0);
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);
977 soup_message_headers_remove (msg->response_headers,
979 soup_message_body_truncate (msg->response_body);
984 soup_message_wrote_informational (SoupMessage *msg)
986 g_signal_emit (msg, signals[WROTE_INFORMATIONAL], 0);
990 soup_message_wrote_headers (SoupMessage *msg)
992 g_signal_emit (msg, signals[WROTE_HEADERS], 0);
996 soup_message_wrote_chunk (SoupMessage *msg)
998 g_signal_emit (msg, signals[WROTE_CHUNK], 0);
1002 soup_message_wrote_body_data (SoupMessage *msg, SoupBuffer *chunk)
1004 g_signal_emit (msg, signals[WROTE_BODY_DATA], 0, chunk);
1008 soup_message_wrote_body (SoupMessage *msg)
1010 g_signal_emit (msg, signals[WROTE_BODY], 0);
1014 soup_message_got_informational (SoupMessage *msg)
1016 g_signal_emit (msg, signals[GOT_INFORMATIONAL], 0);
1020 soup_message_got_headers (SoupMessage *msg)
1022 g_signal_emit (msg, signals[GOT_HEADERS], 0);
1026 soup_message_got_chunk (SoupMessage *msg, SoupBuffer *chunk)
1028 g_signal_emit (msg, signals[GOT_CHUNK], 0, chunk);
1032 soup_message_got_body (SoupMessage *msg)
1034 g_signal_emit (msg, signals[GOT_BODY], 0);
1038 soup_message_content_sniffed (SoupMessage *msg, const char *content_type, GHashTable *params)
1040 g_signal_emit (msg, signals[CONTENT_SNIFFED], 0, content_type, params);
1044 soup_message_restarted (SoupMessage *msg)
1046 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1048 if (priv->msg_flags & SOUP_MESSAGE_CAN_REBUILD)
1049 soup_message_body_truncate (msg->request_body);
1051 g_signal_emit (msg, signals[RESTARTED], 0);
1055 soup_message_finished (SoupMessage *msg)
1057 g_signal_emit (msg, signals[FINISHED], 0);
1061 soup_message_network_event (SoupMessage *msg,
1062 GSocketClientEvent event,
1063 GIOStream *connection)
1065 g_signal_emit (msg, signals[NETWORK_EVENT], 0,
1070 header_handler_free (gpointer header_name, GClosure *closure)
1072 g_free (header_name);
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)
1080 SoupMessage *msg = g_value_get_object (¶m_values[0]);
1081 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1082 const char *header_name = marshal_data;
1083 SoupMessageHeaders *hdrs;
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);
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
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.
1108 * Return value: the handler ID from g_signal_connect()
1111 soup_message_add_header_handler (SoupMessage *msg,
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);
1125 closure = g_cclosure_new (callback, user_data, NULL);
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);
1133 return g_signal_connect_closure (msg, signal, closure, FALSE);
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)
1141 SoupMessage *msg = g_value_get_object (¶m_values[0]);
1142 guint status = GPOINTER_TO_UINT (marshal_data);
1144 if (msg->status_code == status) {
1145 closure->marshal (closure, return_value, n_param_values,
1146 param_values, invocation_hint,
1147 ((GCClosure *)closure)->callback);
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
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.
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"
1168 * Return value: the handler ID from g_signal_connect()
1171 soup_message_add_status_code_handler (SoupMessage *msg,
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);
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);
1187 return g_signal_connect_closure (msg, signal, closure, FALSE);
1192 soup_message_set_auth (SoupMessage *msg, SoupAuth *auth)
1194 SoupMessagePrivate *priv;
1197 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1198 g_return_if_fail (auth == NULL || SOUP_IS_AUTH (auth));
1200 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1203 g_object_unref (priv->auth);
1204 soup_message_headers_remove (msg->request_headers,
1211 g_object_ref (priv->auth);
1212 token = soup_auth_get_authorization (auth, msg);
1214 soup_message_headers_replace (msg->request_headers,
1215 "Authorization", token);
1221 soup_message_get_auth (SoupMessage *msg)
1223 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1225 return SOUP_MESSAGE_GET_PRIVATE (msg)->auth;
1229 soup_message_set_proxy_auth (SoupMessage *msg, SoupAuth *auth)
1231 SoupMessagePrivate *priv;
1234 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1235 g_return_if_fail (auth == NULL || SOUP_IS_AUTH (auth));
1237 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1239 if (priv->proxy_auth) {
1240 g_object_unref (priv->proxy_auth);
1241 soup_message_headers_remove (msg->request_headers,
1242 "Proxy-Authorization");
1244 priv->proxy_auth = auth;
1245 if (!priv->proxy_auth)
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);
1256 soup_message_get_proxy_auth (SoupMessage *msg)
1258 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1260 return SOUP_MESSAGE_GET_PRIVATE (msg)->proxy_auth;
1264 soup_message_get_connection (SoupMessage *msg)
1266 return SOUP_MESSAGE_GET_PRIVATE (msg)->connection;
1270 soup_message_set_connection (SoupMessage *msg,
1271 SoupConnection *conn)
1273 SOUP_MESSAGE_GET_PRIVATE (msg)->connection = conn;
1277 * soup_message_cleanup_response:
1278 * @msg: a #SoupMessage
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.)
1285 soup_message_cleanup_response (SoupMessage *msg)
1287 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
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);
1296 priv->msg_flags &= ~SOUP_MESSAGE_CONTENT_DECODED;
1298 msg->status_code = SOUP_STATUS_NONE;
1299 if (msg->reason_phrase) {
1300 g_free (msg->reason_phrase);
1301 msg->reason_phrase = NULL;
1303 priv->http_version = priv->orig_http_version;
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);
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),
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
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.
1341 * Various flags that can be set on a #SoupMessage to alter its
1346 * soup_message_set_flags:
1347 * @msg: a #SoupMessage
1348 * @flags: a set of #SoupMessageFlags values
1350 * Sets the specified flags on @msg.
1353 soup_message_set_flags (SoupMessage *msg, SoupMessageFlags flags)
1355 SoupMessagePrivate *priv;
1357 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1358 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
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));
1366 priv->msg_flags = flags;
1367 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_FLAGS);
1371 * soup_message_get_flags:
1372 * @msg: a #SoupMessage
1374 * Gets the flags on @msg
1376 * Return value: the flags
1379 soup_message_get_flags (SoupMessage *msg)
1381 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
1383 return SOUP_MESSAGE_GET_PRIVATE (msg)->msg_flags;
1388 * @SOUP_HTTP_1_0: HTTP 1.0 (RFC 1945)
1389 * @SOUP_HTTP_1_1: HTTP 1.1 (RFC 2616)
1391 * Indicates the HTTP protocol version being used.
1395 * soup_message_set_http_version:
1396 * @msg: a #SoupMessage
1397 * @version: the HTTP version
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.
1404 soup_message_set_http_version (SoupMessage *msg, SoupHTTPVersion version)
1406 SoupMessagePrivate *priv;
1408 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1409 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
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);
1418 * soup_message_get_http_version:
1419 * @msg: a #SoupMessage
1421 * Gets the HTTP version of @msg. This is the minimum of the
1422 * version from the request and the version from the response.
1424 * Return value: the HTTP version
1427 soup_message_get_http_version (SoupMessage *msg)
1429 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), SOUP_HTTP_1_0);
1431 return SOUP_MESSAGE_GET_PRIVATE (msg)->http_version;
1435 * soup_message_is_keepalive:
1436 * @msg: a #SoupMessage
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.
1442 * Return value: %TRUE or %FALSE.
1445 soup_message_is_keepalive (SoupMessage *msg)
1447 const char *c_conn, *s_conn;
1449 c_conn = soup_message_headers_get_list (msg->request_headers,
1451 s_conn = soup_message_headers_get_list (msg->response_headers,
1454 if (msg->status_code == SOUP_STATUS_OK &&
1455 msg->method == SOUP_METHOD_CONNECT)
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)
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.
1469 if (!s_conn || !soup_header_contains (s_conn, "Keep-Alive"))
1472 /* Normally persistent unless either side requested otherwise */
1473 if (c_conn && soup_header_contains (c_conn, "close"))
1475 if (s_conn && soup_header_contains (s_conn, "close"))
1485 * soup_message_set_uri:
1486 * @msg: a #SoupMessage
1487 * @uri: the new #SoupURI
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().
1494 soup_message_set_uri (SoupMessage *msg, SoupURI *uri)
1496 SoupMessagePrivate *priv;
1498 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1499 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1502 soup_uri_free (priv->uri);
1504 g_object_unref (priv->addr);
1507 priv->uri = soup_uri_copy (uri);
1509 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_URI);
1513 * soup_message_get_uri:
1514 * @msg: a #SoupMessage
1518 * Return value: (transfer none): the URI @msg is targeted for.
1521 soup_message_get_uri (SoupMessage *msg)
1523 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1525 return SOUP_MESSAGE_GET_PRIVATE (msg)->uri;
1529 * soup_message_get_address:
1530 * @msg: a #SoupMessage
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.
1536 * Return value: (transfer none): the address @msg's URI points to
1541 soup_message_get_address (SoupMessage *msg)
1543 SoupMessagePrivate *priv;
1545 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1547 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1549 priv->addr = soup_address_new (priv->uri->host,
1556 * soup_message_set_status:
1557 * @msg: a #SoupMessage
1558 * @status_code: an HTTP status code
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.
1564 soup_message_set_status (SoupMessage *msg, guint status_code)
1566 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1567 g_return_if_fail (status_code != 0);
1569 g_free (msg->reason_phrase);
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);
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
1583 * Sets @msg's status code and reason phrase.
1586 soup_message_set_status_full (SoupMessage *msg,
1588 const char *reason_phrase)
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);
1594 g_free (msg->reason_phrase);
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);
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()
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.
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
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.
1624 * Return value: the new buffer (or %NULL)
1626 * Deprecated: Use #SoupRequest if you want to read into your
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
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
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.
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
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.
1672 soup_message_set_chunk_allocator (SoupMessage *msg,
1673 SoupChunkAllocator allocator,
1675 GDestroyNotify destroy_notify)
1677 SoupMessagePrivate *priv;
1679 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1681 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1683 if (priv->chunk_allocator_dnotify)
1684 priv->chunk_allocator_dnotify (priv->chunk_allocator_data);
1686 priv->chunk_allocator = allocator;
1687 priv->chunk_allocator_data = user_data;
1688 priv->chunk_allocator_dnotify = destroy_notify;
1692 * soup_message_disable_feature:
1693 * @msg: a #SoupMessage
1694 * @feature_type: the #GType of a #SoupSessionFeature
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
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.
1712 soup_message_disable_feature (SoupMessage *msg, GType feature_type)
1714 SoupMessagePrivate *priv;
1716 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1718 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1720 priv->disabled_features = g_slist_prepend (priv->disabled_features,
1721 GSIZE_TO_POINTER (feature_type));
1725 soup_message_disables_feature (SoupMessage *msg, gpointer feature)
1727 SoupMessagePrivate *priv;
1730 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE);
1732 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1734 for (f = priv->disabled_features; f; f = f->next) {
1735 if (G_TYPE_CHECK_INSTANCE_TYPE (feature, (GType) GPOINTER_TO_SIZE (f->data)))
1742 * soup_message_get_first_party:
1743 * @msg: a #SoupMessage
1745 * Gets @msg's first-party #SoupURI
1747 * Returns: (transfer none): the @msg's first party #SoupURI
1752 soup_message_get_first_party (SoupMessage *msg)
1754 SoupMessagePrivate *priv;
1756 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1758 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1759 return priv->first_party;
1763 * soup_message_set_first_party:
1764 * @msg: a #SoupMessage
1765 * @first_party: the #SoupURI for the @msg's first party
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.
1774 soup_message_set_first_party (SoupMessage *msg,
1775 SoupURI *first_party)
1777 SoupMessagePrivate *priv;
1779 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1780 g_return_if_fail (first_party != NULL);
1782 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1784 if (priv->first_party) {
1785 if (soup_uri_equal (priv->first_party, first_party))
1788 soup_uri_free (priv->first_party);
1791 priv->first_party = soup_uri_copy (first_party);
1792 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_FIRST_PARTY);
1796 soup_message_set_https_status (SoupMessage *msg, SoupConnection *conn)
1800 sock = conn ? soup_connection_get_socket (conn) : NULL;
1801 if (sock && soup_socket_is_ssl (sock)) {
1802 GTlsCertificate *certificate;
1803 GTlsCertificateFlags errors;
1806 SOUP_SOCKET_TLS_CERTIFICATE, &certificate,
1807 SOUP_SOCKET_TLS_ERRORS, &errors,
1810 SOUP_MESSAGE_TLS_CERTIFICATE, certificate,
1811 SOUP_MESSAGE_TLS_ERRORS, errors,
1814 g_object_unref (certificate);
1817 SOUP_MESSAGE_TLS_CERTIFICATE, NULL,
1818 SOUP_MESSAGE_TLS_ERRORS, 0,
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
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.
1833 * Return value: %TRUE if @msg uses https, %FALSE if not
1838 soup_message_get_https_status (SoupMessage *msg,
1839 GTlsCertificate **certificate,
1840 GTlsCertificateFlags *errors)
1842 SoupMessagePrivate *priv;
1844 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE);
1846 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1849 *certificate = priv->tls_certificate;
1851 *errors = priv->tls_errors;
1852 return priv->tls_certificate != NULL;
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
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.
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.
1873 soup_message_set_redirect (SoupMessage *msg, guint status_code,
1874 const char *redirect_uri)
1879 location = soup_uri_new_with_base (soup_message_get_uri (msg), redirect_uri);
1880 g_return_if_fail (location != NULL);
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",
1886 g_free (location_str);
1887 soup_uri_free (location);
1891 soup_message_set_soup_request (SoupMessage *msg,
1894 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1896 priv->request = req;
1900 * soup_message_get_soup_request:
1901 * @msg: a #SoupMessage
1903 * If @msg is associated with a #SoupRequest, this returns that
1904 * request. Otherwise it returns %NULL.
1906 * Return value: @msg's associated #SoupRequest
1911 soup_message_get_soup_request (SoupMessage *msg)
1913 SoupMessagePrivate *priv;
1915 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1917 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1918 return priv->request;