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-enum-types.h"
14 #include "soup-marshal.h"
15 #include "soup-message.h"
16 #include "soup-message-private.h"
17 #include "soup-misc.h"
21 * SECTION:soup-message
22 * @short_description: An HTTP request and response.
23 * @see_also: #SoupMessageHeaders, #SoupMessageBody
25 * A #SoupMessage represents an HTTP message that is being sent or
28 * For client-side usage, you would create a #SoupMessage with
29 * soup_message_new() or soup_message_new_from_uri(), set up its
30 * fields appropriate, and send it via a #SoupSession.
32 * For server-side usage, #SoupServer will create #SoupMessage<!--
33 * -->s automatically for incoming requests, which your application
34 * will receive via handlers.
36 * Note that libsoup's terminology here does not quite match the HTTP
37 * specification: in RFC 2616, an "HTTP-message" is
38 * <emphasis>either</emphasis> a Request, <emphasis>or</emphasis> a
39 * Response. In libsoup, a #SoupMessage combines both the request and
45 * @method: the HTTP method
46 * @status_code: the HTTP status code
47 * @reason_phrase: the status phrase associated with @status_code
48 * @request_body: the request body
49 * @request_headers: the request headers
50 * @response_body: the response body
51 * @response_headers: the response headers
53 * Represents an HTTP message being sent or received.
55 * @status_code will normally be a #SoupKnownStatusCode, eg,
56 * %SOUP_STATUS_OK, though of course it might actually be an unknown
57 * status code. @reason_phrase is the actual text returned from the
58 * server, which may or may not correspond to the "standard"
59 * description of @status_code. At any rate, it is almost certainly
60 * not localized, and not very descriptive even if it is in the user's
61 * language; you should not use @reason_phrase in user-visible
62 * messages. Rather, you should look at @status_code, and determine an
63 * end-user-appropriate message based on that and on what you were
66 * As described in the #SoupMessageBody documentation, the
67 * @request_body and @response_body %data fields will not necessarily
68 * be filled in at all times. When they are filled in, they will be
69 * terminated with a '\0' byte (which is not included in the %length),
70 * so you can use them as ordinary C strings (assuming that you know
71 * that the body doesn't have any other '\0' bytes).
73 * For a client-side #SoupMessage, @request_body's %data is usually
74 * filled in right before libsoup writes the request to the network,
75 * but you should not count on this; use soup_message_body_flatten()
76 * if you want to ensure that %data is filled in. @response_body's
77 * %data will be filled in before #SoupMessage::finished is emitted.
79 * For a server-side #SoupMessage, @request_body's %data will be
80 * filled in before #SoupMessage::got_body is emitted.
82 * To prevent the %data field from being filled in at all (eg, if you
83 * are handling the data from a #SoupMessage::got_chunk, and so don't
84 * need to see it all at the end), call
85 * soup_message_body_set_accumulate() on @response_body or
86 * @request_body as appropriate, passing %FALSE.
89 G_DEFINE_TYPE (SoupMessage, soup_message, G_TYPE_OBJECT)
110 static guint signals[LAST_SIGNAL] = { 0 };
124 PROP_REQUEST_HEADERS,
126 PROP_RESPONSE_HEADERS,
127 PROP_TLS_CERTIFICATE,
133 static void got_body (SoupMessage *req);
135 static void set_property (GObject *object, guint prop_id,
136 const GValue *value, GParamSpec *pspec);
137 static void get_property (GObject *object, guint prop_id,
138 GValue *value, GParamSpec *pspec);
141 soup_message_init (SoupMessage *msg)
143 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
145 priv->http_version = priv->orig_http_version = SOUP_HTTP_1_1;
147 msg->request_body = soup_message_body_new ();
148 msg->request_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_REQUEST);
149 msg->response_body = soup_message_body_new ();
150 msg->response_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE);
154 finalize (GObject *object)
156 SoupMessage *msg = SOUP_MESSAGE (object);
157 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
159 soup_message_io_cleanup (msg);
160 if (priv->chunk_allocator_dnotify)
161 priv->chunk_allocator_dnotify (priv->chunk_allocator_data);
164 soup_uri_free (priv->uri);
165 if (priv->first_party)
166 soup_uri_free (priv->first_party);
168 g_object_unref (priv->addr);
171 g_object_unref (priv->auth);
172 if (priv->proxy_auth)
173 g_object_unref (priv->proxy_auth);
175 g_slist_free (priv->disabled_features);
177 while (priv->decoders) {
178 g_object_unref (priv->decoders->data);
179 priv->decoders = g_slist_delete_link (priv->decoders, priv->decoders);
182 if (priv->tls_certificate)
183 g_object_unref (priv->tls_certificate);
185 soup_message_body_free (msg->request_body);
186 soup_message_headers_free (msg->request_headers);
187 soup_message_body_free (msg->response_body);
188 soup_message_headers_free (msg->response_headers);
190 g_free (msg->reason_phrase);
192 G_OBJECT_CLASS (soup_message_parent_class)->finalize (object);
196 soup_message_class_init (SoupMessageClass *message_class)
198 GObjectClass *object_class = G_OBJECT_CLASS (message_class);
200 g_type_class_add_private (message_class, sizeof (SoupMessagePrivate));
202 /* virtual method definition */
203 message_class->got_body = got_body;
205 /* virtual method override */
206 object_class->finalize = finalize;
207 object_class->set_property = set_property;
208 object_class->get_property = get_property;
213 * SoupMessage::wrote-informational:
216 * Emitted immediately after writing a 1xx (Informational)
217 * response for a (server-side) message.
219 signals[WROTE_INFORMATIONAL] =
220 g_signal_new ("wrote_informational",
221 G_OBJECT_CLASS_TYPE (object_class),
223 G_STRUCT_OFFSET (SoupMessageClass, wrote_informational),
225 soup_marshal_NONE__NONE,
229 * SoupMessage::wrote-headers:
232 * Emitted immediately after writing the headers for a
233 * message. (For a client-side message, this is after writing
234 * the request headers; for a server-side message, it is after
235 * writing the response headers.)
237 signals[WROTE_HEADERS] =
238 g_signal_new ("wrote_headers",
239 G_OBJECT_CLASS_TYPE (object_class),
241 G_STRUCT_OFFSET (SoupMessageClass, wrote_headers),
243 soup_marshal_NONE__NONE,
247 * SoupMessage::wrote-chunk:
250 * Emitted immediately after writing a body chunk for a message.
252 * Note that this signal is not parallel to
253 * #SoupMessage::got_chunk; it is emitted only when a complete
254 * chunk (added with soup_message_body_append() or
255 * soup_message_body_append_buffer()) has been written. To get
256 * more useful continuous progress information, use
257 * #SoupMessage::wrote_body_data.
259 signals[WROTE_CHUNK] =
260 g_signal_new ("wrote_chunk",
261 G_OBJECT_CLASS_TYPE (object_class),
263 G_STRUCT_OFFSET (SoupMessageClass, wrote_chunk),
265 soup_marshal_NONE__NONE,
269 * SoupMessage::wrote-body-data:
271 * @chunk: the data written
273 * Emitted immediately after writing a portion of the message
274 * body to the network.
276 * Unlike #SoupMessage::wrote_chunk, this is emitted after
277 * every successful write() call, not only after finishing a
282 signals[WROTE_BODY_DATA] =
283 g_signal_new ("wrote_body_data",
284 G_OBJECT_CLASS_TYPE (object_class),
286 0, /* FIXME after next ABI break */
288 soup_marshal_NONE__BOXED,
293 * SoupMessage::wrote-body:
296 * Emitted immediately after writing the complete body for a
297 * message. (For a client-side message, this means that
298 * libsoup is done writing and is now waiting for the response
299 * from the server. For a server-side message, this means that
300 * libsoup has finished writing the response and is nearly
301 * done with the message.)
303 signals[WROTE_BODY] =
304 g_signal_new ("wrote_body",
305 G_OBJECT_CLASS_TYPE (object_class),
307 G_STRUCT_OFFSET (SoupMessageClass, wrote_body),
309 soup_marshal_NONE__NONE,
313 * SoupMessage::got-informational:
316 * Emitted after receiving a 1xx (Informational) response for
317 * a (client-side) message. The response_headers will be
318 * filled in with the headers associated with the
319 * informational response; however, those header values will
320 * be erased after this signal is done.
322 * If you cancel or requeue @msg while processing this signal,
323 * then the current HTTP I/O will be stopped after this signal
324 * emission finished, and @msg's connection will be closed.
326 signals[GOT_INFORMATIONAL] =
327 g_signal_new ("got_informational",
328 G_OBJECT_CLASS_TYPE (object_class),
330 G_STRUCT_OFFSET (SoupMessageClass, got_informational),
332 soup_marshal_NONE__NONE,
336 * SoupMessage::got-headers:
339 * Emitted after receiving all message headers for a message.
340 * (For a client-side message, this is after receiving the
341 * Status-Line and response headers; for a server-side
342 * message, it is after receiving the Request-Line and request
345 * See also soup_message_add_header_handler() and
346 * soup_message_add_status_code_handler(), which can be used
347 * to connect to a subset of emissions of this signal.
349 * If you cancel or requeue @msg while processing this signal,
350 * then the current HTTP I/O will be stopped after this signal
351 * emission finished, and @msg's connection will be closed.
352 * (If you need to requeue a message--eg, after handling
353 * authentication or redirection--it is usually better to
354 * requeue it from a #SoupMessage::got_body handler rather
355 * than a #SoupMessage::got_header handler, so that the
356 * existing HTTP connection can be reused.)
358 signals[GOT_HEADERS] =
359 g_signal_new ("got_headers",
360 G_OBJECT_CLASS_TYPE (object_class),
362 G_STRUCT_OFFSET (SoupMessageClass, got_headers),
364 soup_marshal_NONE__NONE,
368 * SoupMessage::got-chunk:
370 * @chunk: the just-read chunk
372 * Emitted after receiving a chunk of a message body. Note
373 * that "chunk" in this context means any subpiece of the
374 * body, not necessarily the specific HTTP 1.1 chunks sent by
377 * If you cancel or requeue @msg while processing this signal,
378 * then the current HTTP I/O will be stopped after this signal
379 * emission finished, and @msg's connection will be closed.
382 g_signal_new ("got_chunk",
383 G_OBJECT_CLASS_TYPE (object_class),
385 G_STRUCT_OFFSET (SoupMessageClass, got_chunk),
387 soup_marshal_NONE__BOXED,
389 /* Use %G_SIGNAL_TYPE_STATIC_SCOPE so that
390 * the %SOUP_MEMORY_TEMPORARY buffers used
391 * by soup-message-io.c when emitting this
392 * signal don't get forcibly copied by
395 SOUP_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE);
398 * SoupMessage::got-body:
401 * Emitted after receiving the complete message body. (For a
402 * server-side message, this means it has received the request
403 * body. For a client-side message, this means it has received
404 * the response body and is nearly done with the message.)
406 * See also soup_message_add_header_handler() and
407 * soup_message_add_status_code_handler(), which can be used
408 * to connect to a subset of emissions of this signal.
411 g_signal_new ("got_body",
412 G_OBJECT_CLASS_TYPE (object_class),
414 G_STRUCT_OFFSET (SoupMessageClass, got_body),
416 soup_marshal_NONE__NONE,
420 * SoupMessage::content-sniffed:
422 * @type: the content type that we got from sniffing
423 * @params: (element-type utf8 utf8): a #GHashTable with the parameters
425 * This signal is emitted after %got-headers, and before the
426 * first %got-chunk. If content sniffing is disabled, or no
427 * content sniffing will be performed, due to the sniffer
428 * deciding to trust the Content-Type sent by the server, this
429 * signal is emitted immediately after %got_headers, and @type
432 * If the #SoupContentSniffer feature is enabled, and the
433 * sniffer decided to perform sniffing, the first %got_chunk
434 * emission may be delayed, so that the sniffer has enough
435 * data to correctly sniff the content. It notified the
436 * library user that the content has been sniffed, and allows
437 * it to change the header contents in the message, if
440 * After this signal is emitted, the data that was spooled so
441 * that sniffing could be done is delivered on the first
442 * emission of %got_chunk.
446 signals[CONTENT_SNIFFED] =
447 g_signal_new ("content_sniffed",
448 G_OBJECT_CLASS_TYPE (object_class),
452 soup_marshal_NONE__STRING_BOXED,
458 * SoupMessage::restarted:
461 * Emitted when a request that was already sent once is now
462 * being sent again (eg, because the first attempt received a
463 * redirection response, or because we needed to use
467 g_signal_new ("restarted",
468 G_OBJECT_CLASS_TYPE (object_class),
470 G_STRUCT_OFFSET (SoupMessageClass, restarted),
472 soup_marshal_NONE__NONE,
476 * SoupMessage::finished:
479 * Emitted when all HTTP processing is finished for a message.
480 * (After #SoupMessage::got_body for client-side messages, or
481 * after #SoupMessage::wrote_body for server-side messages.)
484 g_signal_new ("finished",
485 G_OBJECT_CLASS_TYPE (object_class),
487 G_STRUCT_OFFSET (SoupMessageClass, finished),
489 soup_marshal_NONE__NONE,
494 * SOUP_MESSAGE_METHOD:
496 * Alias for the #SoupMessage:method property. (The message's
499 g_object_class_install_property (
500 object_class, PROP_METHOD,
501 g_param_spec_string (SOUP_MESSAGE_METHOD,
503 "The message's HTTP method",
509 * Alias for the #SoupMessage:uri property. (The message's
512 g_object_class_install_property (
513 object_class, PROP_URI,
514 g_param_spec_boxed (SOUP_MESSAGE_URI,
516 "The message's Request-URI",
520 * SOUP_MESSAGE_HTTP_VERSION:
522 * Alias for the #SoupMessage:http-version property. (The
523 * message's #SoupHTTPVersion.)
525 g_object_class_install_property (
526 object_class, PROP_HTTP_VERSION,
527 g_param_spec_enum (SOUP_MESSAGE_HTTP_VERSION,
529 "The HTTP protocol version to use",
530 SOUP_TYPE_HTTP_VERSION,
534 * SOUP_MESSAGE_FLAGS:
536 * Alias for the #SoupMessage:flags property. (The message's
537 * #SoupMessageFlags.)
539 g_object_class_install_property (
540 object_class, PROP_FLAGS,
541 g_param_spec_flags (SOUP_MESSAGE_FLAGS,
543 "Various message options",
544 SOUP_TYPE_MESSAGE_FLAGS,
548 * SOUP_MESSAGE_SERVER_SIDE:
550 * Alias for the #SoupMessage:server-side property. (%TRUE if
551 * the message was created by #SoupServer.)
553 g_object_class_install_property (
554 object_class, PROP_SERVER_SIDE,
555 g_param_spec_boolean (SOUP_MESSAGE_SERVER_SIDE,
557 "Whether or not the message is server-side rather than client-side",
559 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
561 * SOUP_MESSAGE_STATUS_CODE:
563 * Alias for the #SoupMessage:status-code property. (The
564 * message's HTTP response status code.)
566 g_object_class_install_property (
567 object_class, PROP_STATUS_CODE,
568 g_param_spec_uint (SOUP_MESSAGE_STATUS_CODE,
570 "The HTTP response status code",
574 * SOUP_MESSAGE_REASON_PHRASE:
576 * Alias for the #SoupMessage:reason-phrase property. (The
577 * message's HTTP response reason phrase.)
579 g_object_class_install_property (
580 object_class, PROP_REASON_PHRASE,
581 g_param_spec_string (SOUP_MESSAGE_REASON_PHRASE,
583 "The HTTP response reason phrase",
587 * SOUP_MESSAGE_FIRST_PARTY:
589 * Alias for the #SoupMessage:first-party property. (The
590 * #SoupURI loaded in the application when the message was
596 * SoupMessage:first-party:
598 * The #SoupURI loaded in the application when the message was
603 g_object_class_install_property (
604 object_class, PROP_FIRST_PARTY,
605 g_param_spec_boxed (SOUP_MESSAGE_FIRST_PARTY,
607 "The URI loaded in the application when the message was requested.",
611 * SOUP_MESSAGE_REQUEST_BODY:
613 * Alias for the #SoupMessage:request-body property. (The
614 * message's HTTP request body.)
616 g_object_class_install_property (
617 object_class, PROP_REQUEST_BODY,
618 g_param_spec_boxed (SOUP_MESSAGE_REQUEST_BODY,
620 "The HTTP request content",
621 SOUP_TYPE_MESSAGE_BODY,
624 * SOUP_MESSAGE_REQUEST_HEADERS:
626 * Alias for the #SoupMessage:request-headers property. (The
627 * message's HTTP request headers.)
629 g_object_class_install_property (
630 object_class, PROP_REQUEST_HEADERS,
631 g_param_spec_boxed (SOUP_MESSAGE_REQUEST_HEADERS,
633 "The HTTP request headers",
634 SOUP_TYPE_MESSAGE_HEADERS,
637 * SOUP_MESSAGE_RESPONSE_BODY:
639 * Alias for the #SoupMessage:response-body property. (The
640 * message's HTTP response body.)
642 g_object_class_install_property (
643 object_class, PROP_RESPONSE_BODY,
644 g_param_spec_boxed (SOUP_MESSAGE_RESPONSE_BODY,
646 "The HTTP response content",
647 SOUP_TYPE_MESSAGE_BODY,
650 * SOUP_MESSAGE_RESPONSE_HEADERS:
652 * Alias for the #SoupMessage:response-headers property. (The
653 * message's HTTP response headers.)
655 g_object_class_install_property (
656 object_class, PROP_RESPONSE_HEADERS,
657 g_param_spec_boxed (SOUP_MESSAGE_RESPONSE_HEADERS,
659 "The HTTP response headers",
660 SOUP_TYPE_MESSAGE_HEADERS,
663 * SOUP_MESSAGE_TLS_CERTIFICATE:
665 * Alias for the #SoupMessage:tls-certificate property. (The
666 * TLS certificate associated with the message, if any.)
671 * SoupMessage:tls-certificate:
673 * The #GTlsCertificate associated with the message
677 g_object_class_install_property (
678 object_class, PROP_TLS_CERTIFICATE,
679 g_param_spec_object (SOUP_MESSAGE_TLS_CERTIFICATE,
681 "The TLS certificate associated with the message",
682 G_TYPE_TLS_CERTIFICATE,
685 * SOUP_MESSAGE_TLS_ERRORS:
687 * Alias for the #SoupMessage:tls-errors property. (The
688 * verification errors on #SoupMessage:tls-certificate.)
693 * SoupMessage:tls-certificate:
695 * The verification errors on #SoupMessage:tls-certificate
699 g_object_class_install_property (
700 object_class, PROP_TLS_ERRORS,
701 g_param_spec_flags (SOUP_MESSAGE_TLS_ERRORS,
703 "The verification errors on the message's TLS certificate",
704 G_TYPE_TLS_CERTIFICATE_FLAGS, 0,
709 set_property (GObject *object, guint prop_id,
710 const GValue *value, GParamSpec *pspec)
712 SoupMessage *msg = SOUP_MESSAGE (object);
713 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
717 msg->method = g_intern_string (g_value_get_string (value));
720 soup_message_set_uri (msg, g_value_get_boxed (value));
722 case PROP_HTTP_VERSION:
723 soup_message_set_http_version (msg, g_value_get_enum (value));
726 soup_message_set_flags (msg, g_value_get_flags (value));
728 case PROP_SERVER_SIDE:
729 priv->server_side = g_value_get_boolean (value);
730 if (priv->server_side) {
731 soup_message_headers_set_encoding (msg->response_headers,
732 SOUP_ENCODING_CONTENT_LENGTH);
735 case PROP_STATUS_CODE:
736 soup_message_set_status (msg, g_value_get_uint (value));
738 case PROP_REASON_PHRASE:
739 soup_message_set_status_full (msg, msg->status_code,
740 g_value_get_string (value));
742 case PROP_FIRST_PARTY:
743 soup_message_set_first_party (msg, g_value_get_boxed (value));
745 case PROP_TLS_CERTIFICATE:
746 if (priv->tls_certificate)
747 g_object_unref (priv->tls_certificate);
748 priv->tls_certificate = g_value_dup_object (value);
749 if (priv->tls_certificate && !priv->tls_errors)
750 priv->msg_flags |= SOUP_MESSAGE_CERTIFICATE_TRUSTED;
752 case PROP_TLS_ERRORS:
753 priv->tls_errors = g_value_get_flags (value);
754 if (priv->tls_errors)
755 priv->msg_flags &= ~SOUP_MESSAGE_CERTIFICATE_TRUSTED;
756 else if (priv->tls_certificate)
757 priv->msg_flags |= SOUP_MESSAGE_CERTIFICATE_TRUSTED;
760 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
766 get_property (GObject *object, guint prop_id,
767 GValue *value, GParamSpec *pspec)
769 SoupMessage *msg = SOUP_MESSAGE (object);
770 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
774 g_value_set_string (value, msg->method);
777 g_value_set_boxed (value, priv->uri);
779 case PROP_HTTP_VERSION:
780 g_value_set_enum (value, priv->http_version);
783 g_value_set_flags (value, priv->msg_flags);
785 case PROP_SERVER_SIDE:
786 g_value_set_boolean (value, priv->server_side);
788 case PROP_STATUS_CODE:
789 g_value_set_uint (value, msg->status_code);
791 case PROP_REASON_PHRASE:
792 g_value_set_string (value, msg->reason_phrase);
794 case PROP_FIRST_PARTY:
795 g_value_set_boxed (value, priv->first_party);
797 case PROP_REQUEST_BODY:
798 g_value_set_boxed (value, msg->request_body);
800 case PROP_REQUEST_HEADERS:
801 g_value_set_boxed (value, msg->request_headers);
803 case PROP_RESPONSE_BODY:
804 g_value_set_boxed (value, msg->response_body);
806 case PROP_RESPONSE_HEADERS:
807 g_value_set_boxed (value, msg->response_headers);
809 case PROP_TLS_CERTIFICATE:
810 g_value_set_object (value, priv->tls_certificate);
812 case PROP_TLS_ERRORS:
813 g_value_set_flags (value, priv->tls_errors);
816 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
824 * @method: the HTTP method for the created request
825 * @uri_string: the destination endpoint (as a string)
827 * Creates a new empty #SoupMessage, which will connect to @uri
829 * Return value: the new #SoupMessage (or %NULL if @uri could not
833 soup_message_new (const char *method, const char *uri_string)
838 g_return_val_if_fail (method != NULL, NULL);
839 g_return_val_if_fail (uri_string != NULL, NULL);
841 uri = soup_uri_new (uri_string);
849 msg = soup_message_new_from_uri (method, uri);
855 * soup_message_new_from_uri:
856 * @method: the HTTP method for the created request
857 * @uri: the destination endpoint (as a #SoupURI)
859 * Creates a new empty #SoupMessage, which will connect to @uri
861 * Return value: the new #SoupMessage
864 soup_message_new_from_uri (const char *method, SoupURI *uri)
866 return g_object_new (SOUP_TYPE_MESSAGE,
867 SOUP_MESSAGE_METHOD, method,
868 SOUP_MESSAGE_URI, uri,
873 * soup_message_set_request:
875 * @content_type: MIME Content-Type of the body
876 * @req_use: a #SoupMemoryUse describing how to handle @req_body
877 * @req_body: a data buffer containing the body of the message request.
878 * @req_length: the byte length of @req_body.
880 * Convenience function to set the request body of a #SoupMessage. If
881 * @content_type is %NULL, the request body must be empty as well.
884 soup_message_set_request (SoupMessage *msg,
885 const char *content_type,
886 SoupMemoryUse req_use,
887 const char *req_body,
890 g_return_if_fail (SOUP_IS_MESSAGE (msg));
891 g_return_if_fail (content_type != NULL || req_length == 0);
894 soup_message_headers_replace (msg->request_headers,
895 "Content-Type", content_type);
896 soup_message_body_append (msg->request_body, req_use,
897 req_body, req_length);
899 soup_message_headers_remove (msg->request_headers,
901 soup_message_body_truncate (msg->request_body);
906 * soup_message_set_response:
908 * @content_type: (allow-none): MIME Content-Type of the body
909 * @resp_use: a #SoupMemoryUse describing how to handle @resp_body
910 * @resp_body: (array length=resp_length) (element-type guint8): a data buffer
911 * containing the body of the message response.
912 * @resp_length: the byte length of @resp_body.
914 * Convenience function to set the response body of a #SoupMessage. If
915 * @content_type is %NULL, the response body must be empty as well.
918 soup_message_set_response (SoupMessage *msg,
919 const char *content_type,
920 SoupMemoryUse resp_use,
921 const char *resp_body,
924 g_return_if_fail (SOUP_IS_MESSAGE (msg));
925 g_return_if_fail (content_type != NULL || resp_length == 0);
928 soup_message_headers_replace (msg->response_headers,
929 "Content-Type", content_type);
930 soup_message_body_append (msg->response_body, resp_use,
931 resp_body, resp_length);
933 soup_message_headers_remove (msg->response_headers,
935 soup_message_body_truncate (msg->response_body);
940 * soup_message_wrote_informational:
941 * @msg: a #SoupMessage
943 * Emits the %wrote_informational signal, indicating that the IO layer
944 * finished writing an informational (1xx) response for @msg.
947 soup_message_wrote_informational (SoupMessage *msg)
949 g_signal_emit (msg, signals[WROTE_INFORMATIONAL], 0);
953 * soup_message_wrote_headers:
954 * @msg: a #SoupMessage
956 * Emits the %wrote_headers signal, indicating that the IO layer
957 * finished writing the (non-informational) headers for @msg.
960 soup_message_wrote_headers (SoupMessage *msg)
962 g_signal_emit (msg, signals[WROTE_HEADERS], 0);
966 * soup_message_wrote_chunk:
967 * @msg: a #SoupMessage
969 * Emits the %wrote_chunk signal, indicating that the IO layer
970 * finished writing a chunk of @msg's body.
973 soup_message_wrote_chunk (SoupMessage *msg)
975 g_signal_emit (msg, signals[WROTE_CHUNK], 0);
979 * soup_message_wrote_body_data:
980 * @msg: a #SoupMessage
981 * @chunk: the data written
983 * Emits the %wrote_body_data signal, indicating that the IO layer
984 * finished writing a portion of @msg's body.
987 soup_message_wrote_body_data (SoupMessage *msg, SoupBuffer *chunk)
989 g_signal_emit (msg, signals[WROTE_BODY_DATA], 0, chunk);
993 * soup_message_wrote_body:
994 * @msg: a #SoupMessage
996 * Emits the %wrote_body signal, indicating that the IO layer finished
997 * writing the body for @msg.
1000 soup_message_wrote_body (SoupMessage *msg)
1002 g_signal_emit (msg, signals[WROTE_BODY], 0);
1006 * soup_message_got_informational:
1007 * @msg: a #SoupMessage
1009 * Emits the %got_informational signal, indicating that the IO layer
1010 * read a complete informational (1xx) response for @msg.
1013 soup_message_got_informational (SoupMessage *msg)
1015 g_signal_emit (msg, signals[GOT_INFORMATIONAL], 0);
1019 * soup_message_got_headers:
1020 * @msg: a #SoupMessage
1022 * Emits the %got_headers signal, indicating that the IO layer
1023 * finished reading the (non-informational) headers for @msg.
1026 soup_message_got_headers (SoupMessage *msg)
1028 g_signal_emit (msg, signals[GOT_HEADERS], 0);
1032 * soup_message_got_chunk:
1033 * @msg: a #SoupMessage
1034 * @chunk: the newly-read chunk
1036 * Emits the %got_chunk signal, indicating that the IO layer finished
1037 * reading a chunk of @msg's body.
1040 soup_message_got_chunk (SoupMessage *msg, SoupBuffer *chunk)
1042 g_signal_emit (msg, signals[GOT_CHUNK], 0, chunk);
1046 got_body (SoupMessage *req)
1048 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (req);
1049 SoupMessageBody *body;
1051 body = priv->server_side ? req->request_body : req->response_body;
1052 if (soup_message_body_get_accumulate (body)) {
1055 buffer = soup_message_body_flatten (body);
1056 soup_buffer_free (buffer);
1061 * soup_message_got_body:
1062 * @msg: a #SoupMessage
1064 * Emits the %got_body signal, indicating that the IO layer finished
1065 * reading the body for @msg.
1068 soup_message_got_body (SoupMessage *msg)
1070 g_signal_emit (msg, signals[GOT_BODY], 0);
1074 * soup_message_content_sniffed:
1075 * @msg: a #SoupMessage
1076 * @type: a string with the sniffed content type
1077 * @params: a #GHashTable with the parameters
1079 * Emits the %content_sniffed signal, indicating that the IO layer
1080 * finished sniffing the content type for @msg. If content sniffing
1081 * will not be performed, due to the sniffer deciding to trust the
1082 * Content-Type sent by the server, this signal is emitted immediately
1083 * after %got_headers, with %NULL as @content_type.
1086 soup_message_content_sniffed (SoupMessage *msg, const char *content_type, GHashTable *params)
1088 g_signal_emit (msg, signals[CONTENT_SNIFFED], 0, content_type, params);
1092 * soup_message_restarted:
1093 * @msg: a #SoupMessage
1095 * Emits the %restarted signal, indicating that @msg should be
1099 soup_message_restarted (SoupMessage *msg)
1101 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1103 if (priv->msg_flags & SOUP_MESSAGE_CAN_REBUILD)
1104 soup_message_body_truncate (msg->request_body);
1106 g_signal_emit (msg, signals[RESTARTED], 0);
1110 * soup_message_finished:
1111 * @msg: a #SoupMessage
1113 * Emits the %finished signal, indicating that @msg has been completely
1117 soup_message_finished (SoupMessage *msg)
1119 g_signal_emit (msg, signals[FINISHED], 0);
1123 header_handler_free (gpointer header_name, GClosure *closure)
1125 g_free (header_name);
1129 header_handler_metamarshal (GClosure *closure, GValue *return_value,
1130 guint n_param_values, const GValue *param_values,
1131 gpointer invocation_hint, gpointer marshal_data)
1133 SoupMessage *msg = g_value_get_object (¶m_values[0]);
1134 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1135 const char *header_name = marshal_data;
1136 SoupMessageHeaders *hdrs;
1139 if (priv->io_status != SOUP_MESSAGE_IO_STATUS_RUNNING)
1143 hdrs = priv->server_side ? msg->request_headers : msg->response_headers;
1144 if (soup_message_headers_get_one (hdrs, header_name)) {
1145 closure->marshal (closure, return_value, n_param_values,
1146 param_values, invocation_hint,
1147 ((GCClosure *)closure)->callback);
1152 * soup_message_add_header_handler:
1153 * @msg: a #SoupMessage
1154 * @signal: signal to connect the handler to.
1155 * @header: HTTP response header to match against
1156 * @callback: the header handler
1157 * @user_data: data to pass to @handler_cb
1159 * Adds a signal handler to @msg for @signal, as with
1160 * g_signal_connect(), but with two differences: the @callback will
1161 * only be run if @msg has a header named @header, and it will only be
1162 * run if no earlier handler cancelled or requeued the message.
1164 * If @signal is one of the "got" signals (eg, "got_headers"), or
1165 * "finished" or "restarted", then @header is matched against the
1166 * incoming message headers (that is, the #request_headers for a
1167 * client #SoupMessage, or the #response_headers for a server
1168 * #SoupMessage). If @signal is one of the "wrote" signals, then
1169 * @header is matched against the outgoing message headers.
1171 * Return value: the handler ID from g_signal_connect()
1174 soup_message_add_header_handler (SoupMessage *msg,
1183 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
1184 g_return_val_if_fail (signal != NULL, 0);
1185 g_return_val_if_fail (header != NULL, 0);
1186 g_return_val_if_fail (callback != NULL, 0);
1188 closure = g_cclosure_new (callback, user_data, NULL);
1190 header_name = g_strdup (header);
1191 g_closure_set_meta_marshal (closure, header_name,
1192 header_handler_metamarshal);
1193 g_closure_add_finalize_notifier (closure, header_name,
1194 header_handler_free);
1196 return g_signal_connect_closure (msg, signal, closure, FALSE);
1200 status_handler_metamarshal (GClosure *closure, GValue *return_value,
1201 guint n_param_values, const GValue *param_values,
1202 gpointer invocation_hint, gpointer marshal_data)
1204 SoupMessage *msg = g_value_get_object (¶m_values[0]);
1205 guint status = GPOINTER_TO_UINT (marshal_data);
1208 if (priv->io_status != SOUP_MESSAGE_IO_STATUS_RUNNING)
1212 if (msg->status_code == status) {
1213 closure->marshal (closure, return_value, n_param_values,
1214 param_values, invocation_hint,
1215 ((GCClosure *)closure)->callback);
1220 * soup_message_add_status_code_handler:
1221 * @msg: a #SoupMessage
1222 * @signal: signal to connect the handler to.
1223 * @status_code: status code to match against
1224 * @callback: the header handler
1225 * @user_data: data to pass to @handler_cb
1227 * Adds a signal handler to @msg for @signal, as with
1228 * g_signal_connect() but with two differences: the @callback will
1229 * only be run if @msg has the status @status_code, and it will only
1230 * be run if no earlier handler cancelled or requeued the message.
1232 * @signal must be a signal that will be emitted after @msg's status
1233 * is set. For a client #SoupMessage, this means it can't be a "wrote"
1234 * signal. For a server #SoupMessage, this means it can't be a "got"
1237 * Return value: the handler ID from g_signal_connect()
1240 soup_message_add_status_code_handler (SoupMessage *msg,
1248 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
1249 g_return_val_if_fail (signal != NULL, 0);
1250 g_return_val_if_fail (callback != NULL, 0);
1252 closure = g_cclosure_new (callback, user_data, NULL);
1253 g_closure_set_meta_marshal (closure, GUINT_TO_POINTER (status_code),
1254 status_handler_metamarshal);
1256 return g_signal_connect_closure (msg, signal, closure, FALSE);
1261 * soup_message_set_auth:
1262 * @msg: a #SoupMessage
1263 * @auth: a #SoupAuth, or %NULL
1265 * Sets @msg to authenticate to its destination using @auth, which
1266 * must have already been fully authenticated. If @auth is %NULL, @msg
1267 * will not authenticate to its destination.
1270 soup_message_set_auth (SoupMessage *msg, SoupAuth *auth)
1272 SoupMessagePrivate *priv;
1275 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1276 g_return_if_fail (auth == NULL || SOUP_IS_AUTH (auth));
1277 g_return_if_fail (auth == NULL || soup_auth_is_authenticated (auth));
1279 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1282 g_object_unref (priv->auth);
1283 soup_message_headers_remove (msg->request_headers,
1290 g_object_ref (priv->auth);
1291 token = soup_auth_get_authorization (auth, msg);
1292 soup_message_headers_replace (msg->request_headers,
1293 "Authorization", token);
1298 * soup_message_get_auth:
1299 * @msg: a #SoupMessage
1301 * Gets the #SoupAuth used by @msg for authentication.
1303 * Return value: (transfer none): the #SoupAuth used by @msg for
1304 * authentication, or %NULL if @msg is unauthenticated.
1307 soup_message_get_auth (SoupMessage *msg)
1309 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1311 return SOUP_MESSAGE_GET_PRIVATE (msg)->auth;
1315 * soup_message_set_proxy_auth:
1316 * @msg: a #SoupMessage
1317 * @auth: a #SoupAuth, or %NULL
1319 * Sets @msg to authenticate to its proxy using @auth, which must have
1320 * already been fully authenticated. If @auth is %NULL, @msg will not
1321 * authenticate to its proxy.
1324 soup_message_set_proxy_auth (SoupMessage *msg, SoupAuth *auth)
1326 SoupMessagePrivate *priv;
1329 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1330 g_return_if_fail (auth == NULL || SOUP_IS_AUTH (auth));
1331 g_return_if_fail (auth == NULL || soup_auth_is_authenticated (auth));
1333 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1335 if (priv->proxy_auth) {
1336 g_object_unref (priv->proxy_auth);
1337 soup_message_headers_remove (msg->request_headers,
1338 "Proxy-Authorization");
1340 priv->proxy_auth = auth;
1341 if (!priv->proxy_auth)
1344 g_object_ref (priv->proxy_auth);
1345 token = soup_auth_get_authorization (auth, msg);
1346 soup_message_headers_replace (msg->request_headers,
1347 "Proxy-Authorization", token);
1352 * soup_message_get_proxy_auth:
1353 * @msg: a #SoupMessage
1355 * Gets the #SoupAuth used by @msg for authentication to its proxy..
1357 * Return value: the #SoupAuth used by @msg for authentication to its
1358 * proxy, or %NULL if @msg isn't authenticated to its proxy.
1361 soup_message_get_proxy_auth (SoupMessage *msg)
1363 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1365 return SOUP_MESSAGE_GET_PRIVATE (msg)->proxy_auth;
1369 * soup_message_cleanup_response:
1370 * @req: a #SoupMessage
1372 * Cleans up all response data on @req, so that the request can be sent
1373 * again and receive a new response. (Eg, as a result of a redirect or
1374 * authorization request.)
1377 soup_message_cleanup_response (SoupMessage *req)
1379 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (req);
1381 soup_message_body_truncate (req->response_body);
1382 soup_message_headers_clear (req->response_headers);
1383 if (priv->server_side) {
1384 soup_message_headers_set_encoding (req->response_headers,
1385 SOUP_ENCODING_CONTENT_LENGTH);
1388 while (priv->decoders) {
1389 g_object_unref (priv->decoders->data);
1390 priv->decoders = g_slist_delete_link (priv->decoders, priv->decoders);
1392 priv->msg_flags &= ~SOUP_MESSAGE_CONTENT_DECODED;
1393 priv->msg_flags &= ~SOUP_MESSAGE_CERTIFICATE_TRUSTED;
1395 req->status_code = SOUP_STATUS_NONE;
1396 if (req->reason_phrase) {
1397 g_free (req->reason_phrase);
1398 req->reason_phrase = NULL;
1400 priv->http_version = priv->orig_http_version;
1402 if (priv->tls_certificate) {
1403 g_object_unref (priv->tls_certificate);
1404 priv->tls_certificate = NULL;
1406 priv->tls_errors = 0;
1408 g_object_notify (G_OBJECT (req), SOUP_MESSAGE_STATUS_CODE);
1409 g_object_notify (G_OBJECT (req), SOUP_MESSAGE_REASON_PHRASE);
1410 g_object_notify (G_OBJECT (req), SOUP_MESSAGE_HTTP_VERSION);
1411 g_object_notify (G_OBJECT (req), SOUP_MESSAGE_FLAGS);
1412 g_object_notify (G_OBJECT (req), SOUP_MESSAGE_TLS_CERTIFICATE);
1413 g_object_notify (G_OBJECT (req), SOUP_MESSAGE_TLS_ERRORS);
1418 * @SOUP_MESSAGE_NO_REDIRECT: The session should not follow redirect
1419 * (3xx) responses received by this message.
1420 * @SOUP_MESSAGE_CAN_REBUILD: The caller will rebuild the request
1421 * body if the message is restarted; see
1422 * soup_message_body_set_accumulate() for more details.
1423 * @SOUP_MESSAGE_OVERWRITE_CHUNKS: Deprecated: equivalent to calling
1424 * soup_message_body_set_accumulate() on the incoming message body
1425 * (ie, %response_body for a client-side request), passing %FALSE.
1426 * @SOUP_MESSAGE_CONTENT_DECODED: Set by #SoupContentDecoder to
1427 * indicate that it has removed the Content-Encoding on a message (and
1428 * so headers such as Content-Length may no longer accurately describe
1430 * @SOUP_MESSAGE_CERTIFICATE_TRUSTED: if %TRUE after an https response
1431 * has been received, indicates that the server's SSL certificate is
1432 * trusted according to the session's CA.
1434 * Various flags that can be set on a #SoupMessage to alter its
1439 * soup_message_set_flags:
1440 * @msg: a #SoupMessage
1441 * @flags: a set of #SoupMessageFlags values
1443 * Sets the specified flags on @msg.
1446 soup_message_set_flags (SoupMessage *msg, SoupMessageFlags flags)
1448 SoupMessagePrivate *priv;
1450 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1451 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1453 if ((priv->msg_flags ^ flags) & SOUP_MESSAGE_OVERWRITE_CHUNKS) {
1454 soup_message_body_set_accumulate (
1455 priv->server_side ? msg->request_body : msg->response_body,
1456 !(flags & SOUP_MESSAGE_OVERWRITE_CHUNKS));
1459 priv->msg_flags = flags;
1460 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_FLAGS);
1464 * soup_message_get_flags:
1465 * @msg: a #SoupMessage
1467 * Gets the flags on @msg
1469 * Return value: the flags
1472 soup_message_get_flags (SoupMessage *msg)
1474 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
1476 return SOUP_MESSAGE_GET_PRIVATE (msg)->msg_flags;
1481 * @SOUP_HTTP_1_0: HTTP 1.0 (RFC 1945)
1482 * @SOUP_HTTP_1_1: HTTP 1.1 (RFC 2616)
1484 * Indicates the HTTP protocol version being used.
1488 * soup_message_set_http_version:
1489 * @msg: a #SoupMessage
1490 * @version: the HTTP version
1492 * Sets the HTTP version on @msg. The default version is
1493 * %SOUP_HTTP_1_1. Setting it to %SOUP_HTTP_1_0 will prevent certain
1494 * functionality from being used.
1497 soup_message_set_http_version (SoupMessage *msg, SoupHTTPVersion version)
1499 SoupMessagePrivate *priv;
1501 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1502 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1504 priv->http_version = version;
1505 if (msg->status_code == SOUP_STATUS_NONE)
1506 priv->orig_http_version = version;
1507 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_HTTP_VERSION);
1511 * soup_message_get_http_version:
1512 * @msg: a #SoupMessage
1514 * Gets the HTTP version of @msg. This is the minimum of the
1515 * version from the request and the version from the response.
1517 * Return value: the HTTP version
1520 soup_message_get_http_version (SoupMessage *msg)
1522 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), SOUP_HTTP_1_0);
1524 return SOUP_MESSAGE_GET_PRIVATE (msg)->http_version;
1528 * soup_message_is_keepalive:
1529 * @msg: a #SoupMessage
1531 * Determines whether or not @msg's connection can be kept alive for
1532 * further requests after processing @msg, based on the HTTP version,
1533 * Connection header, etc.
1535 * Return value: %TRUE or %FALSE.
1538 soup_message_is_keepalive (SoupMessage *msg)
1540 const char *c_conn, *s_conn;
1542 c_conn = soup_message_headers_get_list (msg->request_headers,
1544 s_conn = soup_message_headers_get_list (msg->response_headers,
1547 if (msg->status_code == SOUP_STATUS_OK &&
1548 msg->method == SOUP_METHOD_CONNECT)
1551 /* Not persistent if the server sent a terminate-by-EOF response */
1552 if (soup_message_headers_get_encoding (msg->response_headers) == SOUP_ENCODING_EOF)
1555 if (SOUP_MESSAGE_GET_PRIVATE (msg)->http_version == SOUP_HTTP_1_0) {
1556 /* In theory, HTTP/1.0 connections are only persistent
1557 * if the client requests it, and the server agrees.
1558 * But some servers do keep-alive even if the client
1559 * doesn't request it. So ignore c_conn.
1562 if (!s_conn || !soup_header_contains (s_conn, "Keep-Alive"))
1565 /* Normally persistent unless either side requested otherwise */
1566 if (c_conn && soup_header_contains (c_conn, "close"))
1568 if (s_conn && soup_header_contains (s_conn, "close"))
1578 * soup_message_set_uri:
1579 * @msg: a #SoupMessage
1580 * @uri: the new #SoupURI
1582 * Sets @msg's URI to @uri. If @msg has already been sent and you want
1583 * to re-send it with the new URI, you need to call
1584 * soup_session_requeue_message().
1587 soup_message_set_uri (SoupMessage *msg, SoupURI *uri)
1589 SoupMessagePrivate *priv;
1591 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1592 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1595 soup_uri_free (priv->uri);
1597 g_object_unref (priv->addr);
1600 priv->uri = soup_uri_copy (uri);
1602 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_URI);
1606 * soup_message_get_uri:
1607 * @msg: a #SoupMessage
1611 * Return value: (transfer none): the URI @msg is targeted for.
1614 soup_message_get_uri (SoupMessage *msg)
1616 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1618 return SOUP_MESSAGE_GET_PRIVATE (msg)->uri;
1622 * soup_message_get_address:
1623 * @msg: a #SoupMessage
1625 * Gets the address @msg's URI points to. After first setting the
1626 * URI on a message, this will be unresolved, although the message's
1627 * session will resolve it before sending the message.
1629 * Return value: (transfer none): the address @msg's URI points to
1634 soup_message_get_address (SoupMessage *msg)
1636 SoupMessagePrivate *priv;
1638 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1640 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1642 priv->addr = soup_address_new (priv->uri->host,
1649 * soup_message_set_status:
1650 * @msg: a #SoupMessage
1651 * @status_code: an HTTP status code
1653 * Sets @msg's status code to @status_code. If @status_code is a
1654 * known value, it will also set @msg's reason_phrase.
1657 soup_message_set_status (SoupMessage *msg, guint status_code)
1659 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1660 g_return_if_fail (status_code != 0);
1662 g_free (msg->reason_phrase);
1664 msg->status_code = status_code;
1665 msg->reason_phrase = g_strdup (soup_status_get_phrase (status_code));
1666 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_STATUS_CODE);
1667 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_REASON_PHRASE);
1671 * soup_message_set_status_full:
1672 * @msg: a #SoupMessage
1673 * @status_code: an HTTP status code
1674 * @reason_phrase: a description of the status
1676 * Sets @msg's status code and reason phrase.
1679 soup_message_set_status_full (SoupMessage *msg,
1681 const char *reason_phrase)
1683 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1684 g_return_if_fail (status_code != 0);
1685 g_return_if_fail (reason_phrase != NULL);
1687 g_free (msg->reason_phrase);
1689 msg->status_code = status_code;
1690 msg->reason_phrase = g_strdup (reason_phrase);
1691 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_STATUS_CODE);
1692 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_REASON_PHRASE);
1696 * SoupChunkAllocator:
1697 * @msg: the #SoupMessage the chunk is being allocated for
1698 * @max_len: the maximum length that will be read, or 0.
1699 * @user_data: the data passed to soup_message_set_chunk_allocator()
1701 * The prototype for a chunk allocation callback. This should allocate
1702 * a new #SoupBuffer and return it for the I/O layer to read message
1703 * body data off the network into.
1705 * If @max_len is non-0, it indicates the maximum number of bytes that
1706 * could be read, based on what is known about the message size. Note
1707 * that this might be a very large number, and you should not simply
1708 * try to allocate that many bytes blindly. If @max_len is 0, that
1709 * means that libsoup does not know how many bytes remain to be read,
1710 * and the allocator should return a buffer of a size that it finds
1713 * If the allocator returns %NULL, the message will be paused. It is
1714 * up to the application to make sure that it gets unpaused when it
1715 * becomes possible to allocate a new buffer.
1717 * Return value: the new buffer (or %NULL)
1721 * soup_message_set_chunk_allocator:
1722 * @msg: a #SoupMessage
1723 * @allocator: the chunk allocator callback
1724 * @user_data: data to pass to @allocator
1725 * @destroy_notify: destroy notifier to free @user_data when @msg is
1728 * Sets an alternate chunk-allocation function to use when reading
1729 * @msg's body. Every time data is available to read, libsoup will
1730 * call @allocator, which should return a #SoupBuffer. (See
1731 * #SoupChunkAllocator for additional details.) Libsoup will then read
1732 * data from the network into that buffer, and update the buffer's
1733 * %length to indicate how much data it read.
1735 * Generally, a custom chunk allocator would be used in conjunction
1736 * with soup_message_body_set_accumulate() %FALSE and
1737 * #SoupMessage::got_chunk, as part of a strategy to avoid unnecessary
1738 * copying of data. However, you cannot assume that every call to the
1739 * allocator will be followed by a call to your %got_chunk handler; if
1740 * an I/O error occurs, then the buffer will be unreffed without ever
1741 * having been used. If your buffer-allocation strategy requires
1742 * special cleanup, use soup_buffer_new_with_owner() rather than doing
1743 * the cleanup from the %got_chunk handler.
1745 * The other thing to remember when using non-accumulating message
1746 * bodies is that the buffer passed to the %got_chunk handler will be
1747 * unreffed after the handler returns, just as it would be in the
1748 * non-custom-allocated case. If you want to hand the chunk data off
1749 * to some other part of your program to use later, you'll need to ref
1750 * the #SoupBuffer (or its owner, in the soup_buffer_new_with_owner()
1751 * case) to ensure that the data remains valid.
1754 soup_message_set_chunk_allocator (SoupMessage *msg,
1755 SoupChunkAllocator allocator,
1757 GDestroyNotify destroy_notify)
1759 SoupMessagePrivate *priv;
1761 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1763 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1765 if (priv->chunk_allocator_dnotify)
1766 priv->chunk_allocator_dnotify (priv->chunk_allocator_data);
1768 priv->chunk_allocator = allocator;
1769 priv->chunk_allocator_data = user_data;
1770 priv->chunk_allocator_dnotify = destroy_notify;
1774 * soup_message_disable_feature:
1775 * @msg: a #SoupMessage
1776 * @feature_type: the #GType of a #SoupSessionFeature
1778 * This disables the actions of #SoupSessionFeature<!-- -->s with the
1779 * given @feature_type (or a subclass of that type) on @msg, so that
1780 * @msg is processed as though the feature(s) hadn't been added to the
1781 * session. Eg, passing #SOUP_TYPE_PROXY_RESOLVER for @feature_type
1782 * will disable proxy handling and cause @msg to be sent directly to
1783 * the indicated origin server, regardless of system proxy
1786 * You must call this before queueing @msg on a session; calling it on
1787 * a message that has already been queued is undefined. In particular,
1788 * you cannot call this on a message that is being requeued after a
1789 * redirect or authentication.
1794 soup_message_disable_feature (SoupMessage *msg, GType feature_type)
1796 SoupMessagePrivate *priv;
1798 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1800 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1802 priv->disabled_features = g_slist_prepend (priv->disabled_features,
1803 GSIZE_TO_POINTER (feature_type));
1807 soup_message_disables_feature (SoupMessage *msg, gpointer feature)
1809 SoupMessagePrivate *priv;
1812 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE);
1814 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1816 for (f = priv->disabled_features; f; f = f->next) {
1817 if (G_TYPE_CHECK_INSTANCE_TYPE (feature, (GType) GPOINTER_TO_SIZE (f->data)))
1824 * soup_message_get_first_party:
1825 * @msg: a #SoupMessage
1827 * Returns: (transfer none): the @msg's first party #SoupURI
1832 soup_message_get_first_party (SoupMessage *msg)
1834 SoupMessagePrivate *priv;
1836 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1838 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1839 return priv->first_party;
1843 * soup_message_set_first_party:
1844 * @msg: a #SoupMessage
1845 * @first_party: the #SoupURI for the @msg's first party
1847 * Sets @first_party as the main document #SoupURI for @msg. For
1848 * details of when and how this is used refer to the documentation for
1849 * #SoupCookieJarAcceptPolicy.
1854 soup_message_set_first_party (SoupMessage *msg,
1855 SoupURI *first_party)
1857 SoupMessagePrivate *priv;
1859 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1860 g_return_if_fail (first_party != NULL);
1862 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1864 if (priv->first_party) {
1865 if (soup_uri_equal (priv->first_party, first_party))
1868 soup_uri_free (priv->first_party);
1871 priv->first_party = soup_uri_copy (first_party);
1872 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_FIRST_PARTY);
1876 * soup_message_get_https_status:
1877 * @msg: a #SoupMessage
1878 * @certificate: (out) (transfer none): @msg's TLS certificate
1879 * @errors: (out): the verification status of @certificate
1881 * If @msg is using https, this retrieves the #GTlsCertificate
1882 * associated with its connection, and the #GTlsCertificateFlags showing
1883 * what problems, if any, have been found with that certificate.
1885 * Return value: %TRUE if @msg uses https, %FALSE if not
1890 soup_message_get_https_status (SoupMessage *msg,
1891 GTlsCertificate **certificate,
1892 GTlsCertificateFlags *errors)
1894 SoupMessagePrivate *priv;
1896 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE);
1898 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1901 *certificate = priv->tls_certificate;
1903 *errors = priv->tls_errors;
1904 return priv->tls_certificate != NULL;