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-auth.h"
12 #include "soup-enum-types.h"
13 #include "soup-marshal.h"
14 #include "soup-message.h"
15 #include "soup-message-private.h"
16 #include "soup-misc.h"
20 * SECTION:soup-message
21 * @short_description: An HTTP request and response.
22 * @see_also: #SoupMessageHeaders, #SoupMessageBody
28 * @method: the HTTP method
29 * @status_code: the HTTP status code
30 * @reason_phrase: the status phrase associated with @status_code
31 * @request_body: the request body
32 * @request_headers: the request headers
33 * @response_body: the response body
34 * @response_headers: the response headers
36 * Represents an HTTP message being sent or received.
38 * As described in the #SoupMessageBody documentation, the
39 * @request_body and @response_body %data fields will not necessarily
40 * be filled in at all times. When they are filled in, they will be
41 * terminated with a '\0' byte (which is not included in the %length),
42 * so you can use them as ordinary C strings (assuming that you know
43 * that the body doesn't have any other '\0' bytes).
45 * For a client-side #SoupMessage, @request_body's %data is usually
46 * filled in right before libsoup writes the request to the network,
47 * but you should not count on this; use soup_message_body_flatten()
48 * if you want to ensure that %data is filled in. @response_body's
49 * %data will be filled in before #SoupMessage::finished is emitted,
50 * unless you set the %SOUP_MESSAGE_OVERWRITE_CHUNKS flag.
52 * For a server-side #SoupMessage, @request_body's %data will be
53 * filled in before #SoupMessage::got_body is emitted.
56 G_DEFINE_TYPE (SoupMessage, soup_message, G_TYPE_OBJECT)
75 static guint signals[LAST_SIGNAL] = { 0 };
90 static void got_body (SoupMessage *req);
91 static void restarted (SoupMessage *req);
92 static void finished (SoupMessage *req);
94 static void set_property (GObject *object, guint prop_id,
95 const GValue *value, GParamSpec *pspec);
96 static void get_property (GObject *object, guint prop_id,
97 GValue *value, GParamSpec *pspec);
100 soup_message_init (SoupMessage *msg)
102 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
104 priv->io_status = SOUP_MESSAGE_IO_STATUS_IDLE;
105 priv->http_version = SOUP_HTTP_1_1;
107 msg->request_body = soup_message_body_new ();
108 msg->request_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_REQUEST);
109 msg->response_body = soup_message_body_new ();
110 msg->response_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE);
114 finalize (GObject *object)
116 SoupMessage *msg = SOUP_MESSAGE (object);
117 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
119 soup_message_io_cleanup (msg);
122 soup_uri_free (priv->uri);
125 g_object_unref (priv->auth);
126 if (priv->proxy_auth)
127 g_object_unref (priv->proxy_auth);
129 soup_message_body_free (msg->request_body);
130 soup_message_headers_free (msg->request_headers);
131 soup_message_body_free (msg->response_body);
132 soup_message_headers_free (msg->response_headers);
134 g_free ((char *) msg->reason_phrase);
136 G_OBJECT_CLASS (soup_message_parent_class)->finalize (object);
140 soup_message_class_init (SoupMessageClass *message_class)
142 GObjectClass *object_class = G_OBJECT_CLASS (message_class);
144 g_type_class_add_private (message_class, sizeof (SoupMessagePrivate));
146 /* virtual method definition */
147 message_class->got_body = got_body;
148 message_class->restarted = restarted;
149 message_class->finished = finished;
151 /* virtual method override */
152 object_class->finalize = finalize;
153 object_class->set_property = set_property;
154 object_class->get_property = get_property;
159 * SoupMessage::wrote-informational:
162 * Emitted immediately after writing a 1xx (Informational)
163 * response for a (server-side) message.
165 signals[WROTE_INFORMATIONAL] =
166 g_signal_new ("wrote_informational",
167 G_OBJECT_CLASS_TYPE (object_class),
169 G_STRUCT_OFFSET (SoupMessageClass, wrote_informational),
171 soup_marshal_NONE__NONE,
175 * SoupMessage::wrote-headers:
178 * Emitted immediately after writing the headers for a
179 * message. (For a client-side message, this is after writing
180 * the request headers; for a server-side message, it is after
181 * writing the response headers.)
183 signals[WROTE_HEADERS] =
184 g_signal_new ("wrote_headers",
185 G_OBJECT_CLASS_TYPE (object_class),
187 G_STRUCT_OFFSET (SoupMessageClass, wrote_headers),
189 soup_marshal_NONE__NONE,
193 * SoupMessage::wrote-chunk:
196 * Emitted immediately after writing a body chunk for a message.
198 signals[WROTE_CHUNK] =
199 g_signal_new ("wrote_chunk",
200 G_OBJECT_CLASS_TYPE (object_class),
202 G_STRUCT_OFFSET (SoupMessageClass, wrote_chunk),
204 soup_marshal_NONE__NONE,
208 * SoupMessage::wrote-body:
211 * Emitted immediately after writing the complete body for a
212 * message. (For a client-side message, this means that
213 * libsoup is done writing and is now waiting for the response
214 * from the server. For a server-side message, this means that
215 * libsoup has finished writing the response and is nearly
216 * done with the message.)
218 signals[WROTE_BODY] =
219 g_signal_new ("wrote_body",
220 G_OBJECT_CLASS_TYPE (object_class),
222 G_STRUCT_OFFSET (SoupMessageClass, wrote_body),
224 soup_marshal_NONE__NONE,
228 * SoupMessage::got-informational:
231 * Emitted after receiving a 1xx (Informational) response for
232 * a (client-side) message. The response_headers will be
233 * filled in with the headers associated with the
234 * informational response; however, those header values will
235 * be erased after this signal is done.
237 * If you cancel or requeue @msg while processing this signal,
238 * then the current HTTP I/O will be stopped after this signal
239 * emission finished, and @msg's connection will be closed.
241 signals[GOT_INFORMATIONAL] =
242 g_signal_new ("got_informational",
243 G_OBJECT_CLASS_TYPE (object_class),
245 G_STRUCT_OFFSET (SoupMessageClass, got_informational),
247 soup_marshal_NONE__NONE,
251 * SoupMessage::got-headers:
254 * Emitted after receiving all message headers for a message.
255 * (For a client-side message, this is after receiving the
256 * Status-Line and response headers; for a server-side
257 * message, it is after receiving the Request-Line and request
260 * See also soup_message_add_header_handler() and
261 * soup_message_add_status_code_handler(), which can be used
262 * to connect to a subset of emissions of this signal.
264 * If you cancel or requeue @msg while processing this signal,
265 * then the current HTTP I/O will be stopped after this signal
266 * emission finished, and @msg's connection will be closed.
267 * (If you need to requeue a message--eg, after handling
268 * authentication or redirection--it is usually better to
269 * requeue it from a #SoupMessage::got_body handler rather
270 * than a #SoupMessage::got_header handler, so that the
271 * existing HTTP connection can be reused.)
273 signals[GOT_HEADERS] =
274 g_signal_new ("got_headers",
275 G_OBJECT_CLASS_TYPE (object_class),
277 G_STRUCT_OFFSET (SoupMessageClass, got_headers),
279 soup_marshal_NONE__NONE,
283 * SoupMessage::got-chunk:
285 * @chunk: the just-read chunk
287 * Emitted after receiving a chunk of a message body. Note
288 * that "chunk" in this context means any subpiece of the
289 * body, not necessarily the specific HTTP 1.1 chunks sent by
292 * If you cancel or requeue @msg while processing this signal,
293 * then the current HTTP I/O will be stopped after this signal
294 * emission finished, and @msg's connection will be closed.
297 g_signal_new ("got_chunk",
298 G_OBJECT_CLASS_TYPE (object_class),
300 G_STRUCT_OFFSET (SoupMessageClass, got_chunk),
302 soup_marshal_NONE__BOXED,
307 * SoupMessage::got-body:
310 * Emitted after receiving the complete message body. (For a
311 * server-side message, this means it has received the request
312 * body. For a client-side message, this means it has received
313 * the response body and is nearly done with the message.)
315 * See also soup_message_add_header_handler() and
316 * soup_message_add_status_code_handler(), which can be used
317 * to connect to a subset of emissions of this signal.
320 g_signal_new ("got_body",
321 G_OBJECT_CLASS_TYPE (object_class),
323 G_STRUCT_OFFSET (SoupMessageClass, got_body),
325 soup_marshal_NONE__NONE,
329 * SoupMessage::restarted:
332 * Emitted when a request that was already sent once is now
333 * being sent again (eg, because the first attempt received a
334 * redirection response, or because we needed to use
338 g_signal_new ("restarted",
339 G_OBJECT_CLASS_TYPE (object_class),
341 G_STRUCT_OFFSET (SoupMessageClass, restarted),
343 soup_marshal_NONE__NONE,
347 * SoupMessage::finished:
350 * Emitted when all HTTP processing is finished for a message.
351 * (After #SoupMessage::got_body for client-side messages, or
352 * after #SoupMessage::wrote_body for server-side messages.)
355 g_signal_new ("finished",
356 G_OBJECT_CLASS_TYPE (object_class),
358 G_STRUCT_OFFSET (SoupMessageClass, finished),
360 soup_marshal_NONE__NONE,
364 g_object_class_install_property (
365 object_class, PROP_METHOD,
366 g_param_spec_string (SOUP_MESSAGE_METHOD,
368 "The message's HTTP method",
371 g_object_class_install_property (
372 object_class, PROP_URI,
373 g_param_spec_boxed (SOUP_MESSAGE_URI,
375 "The message's Request-URI",
378 g_object_class_install_property (
379 object_class, PROP_HTTP_VERSION,
380 g_param_spec_enum (SOUP_MESSAGE_HTTP_VERSION,
382 "The HTTP protocol version to use",
383 SOUP_TYPE_HTTP_VERSION,
386 g_object_class_install_property (
387 object_class, PROP_FLAGS,
388 g_param_spec_flags (SOUP_MESSAGE_FLAGS,
390 "Various message options",
391 SOUP_TYPE_MESSAGE_FLAGS,
394 g_object_class_install_property (
395 object_class, PROP_STATUS_CODE,
396 g_param_spec_uint (SOUP_MESSAGE_STATUS_CODE,
398 "The HTTP response status code",
401 g_object_class_install_property (
402 object_class, PROP_REASON_PHRASE,
403 g_param_spec_string (SOUP_MESSAGE_REASON_PHRASE,
405 "The HTTP response reason phrase",
411 set_property (GObject *object, guint prop_id,
412 const GValue *value, GParamSpec *pspec)
414 SoupMessage *msg = SOUP_MESSAGE (object);
418 msg->method = g_intern_string (g_value_get_string (value));
421 soup_message_set_uri (msg, g_value_get_boxed (value));
423 case PROP_HTTP_VERSION:
424 soup_message_set_http_version (msg, g_value_get_enum (value));
427 soup_message_set_flags (msg, g_value_get_flags (value));
429 case PROP_STATUS_CODE:
430 soup_message_set_status (msg, g_value_get_uint (value));
432 case PROP_REASON_PHRASE:
433 soup_message_set_status_full (msg, msg->status_code,
434 g_value_get_string (value));
442 get_property (GObject *object, guint prop_id,
443 GValue *value, GParamSpec *pspec)
445 SoupMessage *msg = SOUP_MESSAGE (object);
446 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
450 g_value_set_string (value, msg->method);
453 g_value_set_boxed (value, priv->uri);
455 case PROP_HTTP_VERSION:
456 g_value_set_enum (value, priv->http_version);
459 g_value_set_flags (value, priv->msg_flags);
461 case PROP_STATUS_CODE:
462 g_value_set_uint (value, msg->status_code);
464 case PROP_REASON_PHRASE:
465 g_value_set_string (value, msg->reason_phrase);
475 * @method: the HTTP method for the created request
476 * @uri_string: the destination endpoint (as a string)
478 * Creates a new empty #SoupMessage, which will connect to @uri
480 * Return value: the new #SoupMessage (or %NULL if @uri could not
484 soup_message_new (const char *method, const char *uri_string)
489 g_return_val_if_fail (method != NULL, NULL);
490 g_return_val_if_fail (uri_string != NULL, NULL);
492 uri = soup_uri_new (uri_string);
500 msg = soup_message_new_from_uri (method, uri);
506 * soup_message_new_from_uri:
507 * @method: the HTTP method for the created request
508 * @uri: the destination endpoint (as a #SoupURI)
510 * Creates a new empty #SoupMessage, which will connect to @uri
512 * Return value: the new #SoupMessage
515 soup_message_new_from_uri (const char *method, SoupURI *uri)
517 return g_object_new (SOUP_TYPE_MESSAGE,
518 SOUP_MESSAGE_METHOD, method,
519 SOUP_MESSAGE_URI, uri,
524 * soup_message_set_request:
526 * @content_type: MIME Content-Type of the body
527 * @req_use: a #SoupMemoryUse describing how to handle @req_body
528 * @req_body: a data buffer containing the body of the message request.
529 * @req_length: the byte length of @req_body.
531 * Convenience function to set the request body of a #SoupMessage. If
532 * @content_type is %NULL, the request body must be empty as well.
535 soup_message_set_request (SoupMessage *msg,
536 const char *content_type,
537 SoupMemoryUse req_use,
538 const char *req_body,
541 g_return_if_fail (SOUP_IS_MESSAGE (msg));
542 g_return_if_fail (content_type != NULL || req_length == 0);
545 soup_message_headers_replace (msg->request_headers,
546 "Content-Type", content_type);
547 soup_message_body_append (msg->request_body, req_use,
548 req_body, req_length);
550 soup_message_headers_remove (msg->request_headers,
552 soup_message_body_truncate (msg->request_body);
557 * soup_message_set_response:
559 * @content_type: MIME Content-Type of the body
560 * @resp_use: a #SoupMemoryUse describing how to handle @resp_body
561 * @resp_body: a data buffer containing the body of the message response.
562 * @resp_length: the byte length of @resp_body.
564 * Convenience function to set the response body of a #SoupMessage. If
565 * @content_type is %NULL, the response body must be empty as well.
568 soup_message_set_response (SoupMessage *msg,
569 const char *content_type,
570 SoupMemoryUse resp_use,
571 const char *resp_body,
574 g_return_if_fail (SOUP_IS_MESSAGE (msg));
575 g_return_if_fail (content_type != NULL || resp_length == 0);
578 soup_message_headers_replace (msg->response_headers,
579 "Content-Type", content_type);
580 soup_message_body_append (msg->response_body, resp_use,
581 resp_body, resp_length);
583 soup_message_headers_remove (msg->response_headers,
585 soup_message_body_truncate (msg->response_body);
590 * soup_message_wrote_informational:
591 * @msg: a #SoupMessage
593 * Emits the %wrote_informational signal, indicating that the IO layer
594 * finished writing an informational (1xx) response for @msg.
597 soup_message_wrote_informational (SoupMessage *msg)
599 g_signal_emit (msg, signals[WROTE_INFORMATIONAL], 0);
603 * soup_message_wrote_headers:
604 * @msg: a #SoupMessage
606 * Emits the %wrote_headers signal, indicating that the IO layer
607 * finished writing the (non-informational) headers for @msg.
610 soup_message_wrote_headers (SoupMessage *msg)
612 g_signal_emit (msg, signals[WROTE_HEADERS], 0);
616 * soup_message_wrote_chunk:
617 * @msg: a #SoupMessage
619 * Emits the %wrote_chunk signal, indicating that the IO layer
620 * finished writing a chunk of @msg's body.
623 soup_message_wrote_chunk (SoupMessage *msg)
625 g_signal_emit (msg, signals[WROTE_CHUNK], 0);
629 * soup_message_wrote_body:
630 * @msg: a #SoupMessage
632 * Emits the %wrote_body signal, indicating that the IO layer finished
633 * writing the body for @msg.
636 soup_message_wrote_body (SoupMessage *msg)
638 g_signal_emit (msg, signals[WROTE_BODY], 0);
642 * soup_message_got_informational:
643 * @msg: a #SoupMessage
645 * Emits the %got_informational signal, indicating that the IO layer
646 * read a complete informational (1xx) response for @msg.
649 soup_message_got_informational (SoupMessage *msg)
651 g_signal_emit (msg, signals[GOT_INFORMATIONAL], 0);
655 * soup_message_got_headers:
656 * @msg: a #SoupMessage
658 * Emits the %got_headers signal, indicating that the IO layer
659 * finished reading the (non-informational) headers for @msg.
662 soup_message_got_headers (SoupMessage *msg)
664 g_signal_emit (msg, signals[GOT_HEADERS], 0);
668 * soup_message_got_chunk:
669 * @msg: a #SoupMessage
670 * @chunk: the newly-read chunk
672 * Emits the %got_chunk signal, indicating that the IO layer finished
673 * reading a chunk of @msg's body.
676 soup_message_got_chunk (SoupMessage *msg, SoupBuffer *chunk)
678 g_signal_emit (msg, signals[GOT_CHUNK], 0, chunk);
682 got_body (SoupMessage *req)
684 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (req);
686 if (!(priv->msg_flags & SOUP_MESSAGE_OVERWRITE_CHUNKS)) {
689 /* Figure out *which* body we read, and flatten it. */
690 if (req->status_code == 0)
691 buffer = soup_message_body_flatten (req->request_body);
693 buffer = soup_message_body_flatten (req->response_body);
694 soup_buffer_free (buffer);
699 * soup_message_got_body:
700 * @msg: a #SoupMessage
702 * Emits the %got_body signal, indicating that the IO layer finished
703 * reading the body for @msg.
706 soup_message_got_body (SoupMessage *msg)
708 g_signal_emit (msg, signals[GOT_BODY], 0);
712 restarted (SoupMessage *req)
714 soup_message_io_stop (req);
718 * soup_message_restarted:
719 * @msg: a #SoupMessage
721 * Emits the %restarted signal, indicating that @msg should be
725 soup_message_restarted (SoupMessage *msg)
727 g_signal_emit (msg, signals[RESTARTED], 0);
731 finished (SoupMessage *req)
733 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (req);
735 soup_message_io_stop (req);
736 priv->io_status = SOUP_MESSAGE_IO_STATUS_FINISHED;
740 * soup_message_finished:
741 * @msg: a #SoupMessage
743 * Emits the %finished signal, indicating that @msg has been completely
747 soup_message_finished (SoupMessage *msg)
749 g_signal_emit (msg, signals[FINISHED], 0);
753 header_handler_free (gpointer header_name, GClosure *closure)
755 g_free (header_name);
759 header_handler_metamarshal (GClosure *closure, GValue *return_value,
760 guint n_param_values, const GValue *param_values,
761 gpointer invocation_hint, gpointer marshal_data)
763 SoupMessage *msg = g_value_get_object (¶m_values[0]);
764 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
765 const char *header_name = marshal_data;
766 SoupMessageHeaders *hdrs;
768 if (priv->io_status != SOUP_MESSAGE_IO_STATUS_RUNNING)
771 /* If status_code is SOUP_STATUS_NONE, we're still processing
772 * the request side; if it's not, we're processing the
775 hdrs = (msg->status_code == SOUP_STATUS_NONE) ?
776 msg->request_headers : msg->response_headers;
778 if (soup_message_headers_get (hdrs, header_name)) {
779 closure->marshal (closure, return_value, n_param_values,
780 param_values, invocation_hint,
781 ((GCClosure *)closure)->callback);
786 * soup_message_add_header_handler:
787 * @msg: a #SoupMessage
788 * @signal: signal to connect the handler to.
789 * @header: HTTP response header to match against
790 * @callback: the header handler
791 * @user_data: data to pass to @handler_cb
793 * Adds a signal handler to @msg for @signal, as with
794 * g_signal_connect(), but with two differences: the @callback will
795 * only be run if @msg has a header named @header, and it will only be
796 * run if no earlier handler cancelled or requeued the message.
798 * If @signal is one of the "got" signals (eg, "got_headers"), or
799 * "finished" or "restarted", then @header is matched against the
800 * incoming message headers (that is, the #request_headers for a
801 * client #SoupMessage, or the #response_headers for a server
802 * #SoupMessage). If @signal is one of the "wrote" signals, then
803 * @header is matched against the outgoing message headers.
805 * Return value: the handler ID from g_signal_connect()
808 soup_message_add_header_handler (SoupMessage *msg,
814 SoupMessagePrivate *priv;
818 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
819 g_return_val_if_fail (signal != NULL, 0);
820 g_return_val_if_fail (header != NULL, 0);
821 g_return_val_if_fail (callback != NULL, 0);
823 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
825 closure = g_cclosure_new (callback, user_data, NULL);
827 header_name = g_strdup (header);
828 g_closure_set_meta_marshal (closure, header_name,
829 header_handler_metamarshal);
830 g_closure_add_finalize_notifier (closure, header_name,
831 header_handler_free);
833 return g_signal_connect_closure (msg, signal, closure, FALSE);
837 status_handler_metamarshal (GClosure *closure, GValue *return_value,
838 guint n_param_values, const GValue *param_values,
839 gpointer invocation_hint, gpointer marshal_data)
841 SoupMessage *msg = g_value_get_object (¶m_values[0]);
842 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
843 guint status = GPOINTER_TO_UINT (marshal_data);
845 if (priv->io_status != SOUP_MESSAGE_IO_STATUS_RUNNING)
848 if (msg->status_code == status) {
849 closure->marshal (closure, return_value, n_param_values,
850 param_values, invocation_hint,
851 ((GCClosure *)closure)->callback);
856 * soup_message_add_status_code_handler:
857 * @msg: a #SoupMessage
858 * @signal: signal to connect the handler to.
859 * @status_code: status code to match against
860 * @callback: the header handler
861 * @user_data: data to pass to @handler_cb
863 * Adds a signal handler to @msg for @signal, as with
864 * g_signal_connect() but with two differences: the @callback will
865 * only be run if @msg has the status @status_code, and it will only
866 * be run if no earlier handler cancelled or requeued the message.
868 * @signal must be a signal that will be emitted after @msg's status
869 * is set. For a client #SoupMessage, this means it can't be a "wrote"
870 * signal. For a server #SoupMessage, this means it can't be a "got"
873 * Return value: the handler ID from g_signal_connect()
876 soup_message_add_status_code_handler (SoupMessage *msg,
884 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
885 g_return_val_if_fail (signal != NULL, 0);
886 g_return_val_if_fail (callback != NULL, 0);
888 closure = g_cclosure_new (callback, user_data, NULL);
889 g_closure_set_meta_marshal (closure, GUINT_TO_POINTER (status_code),
890 status_handler_metamarshal);
892 return g_signal_connect_closure (msg, signal, closure, FALSE);
897 * soup_message_set_auth:
898 * @msg: a #SoupMessage
899 * @auth: a #SoupAuth, or %NULL
901 * Sets @msg to authenticate to its destination using @auth, which
902 * must have already been fully authenticated. If @auth is %NULL, @msg
903 * will not authenticate to its destination.
906 soup_message_set_auth (SoupMessage *msg, SoupAuth *auth)
908 SoupMessagePrivate *priv;
911 g_return_if_fail (SOUP_IS_MESSAGE (msg));
912 g_return_if_fail (auth == NULL || SOUP_IS_AUTH (auth));
913 g_return_if_fail (auth == NULL || soup_auth_is_authenticated (auth));
915 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
918 g_object_unref (priv->auth);
919 soup_message_headers_remove (msg->request_headers,
926 g_object_ref (priv->auth);
927 token = soup_auth_get_authorization (auth, msg);
928 soup_message_headers_append (msg->request_headers,
929 "Authorization", token);
934 * soup_message_get_auth:
935 * @msg: a #SoupMessage
937 * Gets the #SoupAuth used by @msg for authentication.
939 * Return value: the #SoupAuth used by @msg for authentication, or
940 * %NULL if @msg is unauthenticated.
943 soup_message_get_auth (SoupMessage *msg)
945 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
947 return SOUP_MESSAGE_GET_PRIVATE (msg)->auth;
951 * soup_message_set_proxy_auth:
952 * @msg: a #SoupMessage
953 * @auth: a #SoupAuth, or %NULL
955 * Sets @msg to authenticate to its proxy using @auth, which must have
956 * already been fully authenticated. If @auth is %NULL, @msg will not
957 * authenticate to its proxy.
960 soup_message_set_proxy_auth (SoupMessage *msg, SoupAuth *auth)
962 SoupMessagePrivate *priv;
965 g_return_if_fail (SOUP_IS_MESSAGE (msg));
966 g_return_if_fail (auth == NULL || SOUP_IS_AUTH (auth));
967 g_return_if_fail (auth == NULL || soup_auth_is_authenticated (auth));
969 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
971 if (priv->proxy_auth) {
972 g_object_unref (priv->proxy_auth);
973 soup_message_headers_remove (msg->request_headers,
974 "Proxy-Authorization");
976 priv->proxy_auth = auth;
977 if (!priv->proxy_auth)
980 g_object_ref (priv->proxy_auth);
981 token = soup_auth_get_authorization (auth, msg);
982 soup_message_headers_append (msg->request_headers,
983 "Proxy-Authorization", token);
988 * soup_message_get_proxy_auth:
989 * @msg: a #SoupMessage
991 * Gets the #SoupAuth used by @msg for authentication to its proxy..
993 * Return value: the #SoupAuth used by @msg for authentication to its
994 * proxy, or %NULL if @msg isn't authenticated to its proxy.
997 soup_message_get_proxy_auth (SoupMessage *msg)
999 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1001 return SOUP_MESSAGE_GET_PRIVATE (msg)->proxy_auth;
1005 * soup_message_cleanup_response:
1006 * @req: a #SoupMessage
1008 * Cleans up all response data on @req, so that the request can be sent
1009 * again and receive a new response. (Eg, as a result of a redirect or
1010 * authorization request.)
1013 soup_message_cleanup_response (SoupMessage *req)
1015 soup_message_body_truncate (req->response_body);
1016 soup_message_headers_clear (req->response_headers);
1018 req->status_code = SOUP_STATUS_NONE;
1019 if (req->reason_phrase) {
1020 g_free ((char *) req->reason_phrase);
1021 req->reason_phrase = NULL;
1023 g_object_notify (G_OBJECT (req), SOUP_MESSAGE_STATUS_CODE);
1024 g_object_notify (G_OBJECT (req), SOUP_MESSAGE_REASON_PHRASE);
1029 * @SOUP_MESSAGE_NO_REDIRECT: The session should not follow redirect
1030 * (3xx) responses received by this message.
1031 * @SOUP_MESSAGE_OVERWRITE_CHUNKS: Each chunk of the response will be
1032 * freed after its corresponding %got_chunk signal is emitted, meaning
1033 * %response will still be empty after the message is complete. You
1034 * can use this to save memory if you expect the response to be large
1035 * and you are able to process it a chunk at a time.
1037 * Various flags that can be set on a #SoupMessage to alter its
1042 * soup_message_set_flags:
1043 * @msg: a #SoupMessage
1044 * @flags: a set of #SoupMessageFlags values
1046 * Sets the specified flags on @msg.
1049 soup_message_set_flags (SoupMessage *msg, SoupMessageFlags flags)
1051 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1053 SOUP_MESSAGE_GET_PRIVATE (msg)->msg_flags = flags;
1054 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_FLAGS);
1058 * soup_message_get_flags:
1059 * @msg: a #SoupMessage
1061 * Gets the flags on @msg
1063 * Return value: the flags
1066 soup_message_get_flags (SoupMessage *msg)
1068 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
1070 return SOUP_MESSAGE_GET_PRIVATE (msg)->msg_flags;
1075 * @SOUP_HTTP_1_0: HTTP 1.0 (RFC 1945)
1076 * @SOUP_HTTP_1_1: HTTP 1.1 (RFC 2616)
1078 * Indicates the HTTP protocol version being used.
1082 * soup_message_set_http_version:
1083 * @msg: a #SoupMessage
1084 * @version: the HTTP version
1086 * Sets the HTTP version on @msg. The default version is
1087 * %SOUP_HTTP_1_1. Setting it to %SOUP_HTTP_1_0 will prevent certain
1088 * functionality from being used.
1091 soup_message_set_http_version (SoupMessage *msg, SoupHTTPVersion version)
1093 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1095 SOUP_MESSAGE_GET_PRIVATE (msg)->http_version = version;
1096 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_HTTP_VERSION);
1100 * soup_message_get_http_version:
1101 * @msg: a #SoupMessage
1103 * Gets the HTTP version of @msg. This is the minimum of the
1104 * version from the request and the version from the response.
1106 * Return value: the HTTP version
1109 soup_message_get_http_version (SoupMessage *msg)
1111 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), SOUP_HTTP_1_0);
1113 return SOUP_MESSAGE_GET_PRIVATE (msg)->http_version;
1117 * soup_message_is_keepalive:
1118 * @msg: a #SoupMessage
1120 * Determines whether or not @msg's connection can be kept alive for
1121 * further requests after processing @msg, based on the HTTP version,
1122 * Connection header, etc.
1124 * Return value: %TRUE or %FALSE.
1127 soup_message_is_keepalive (SoupMessage *msg)
1129 const char *c_conn, *s_conn;
1131 c_conn = soup_message_headers_get (msg->request_headers, "Connection");
1132 s_conn = soup_message_headers_get (msg->response_headers, "Connection");
1134 if (msg->status_code == SOUP_STATUS_OK &&
1135 msg->method == SOUP_METHOD_CONNECT)
1138 if (SOUP_MESSAGE_GET_PRIVATE (msg)->http_version == SOUP_HTTP_1_0) {
1139 /* Only persistent if the client requested keepalive
1140 * and the server agreed.
1143 if (!c_conn || !s_conn)
1145 if (soup_header_contains (c_conn, "Keep-Alive") ||
1146 soup_header_contains (s_conn, "Keep-Alive"))
1151 /* Normally persistent unless either side requested otherwise */
1152 if (c_conn && soup_header_contains (c_conn, "close"))
1154 if (s_conn && soup_header_contains (s_conn, "close"))
1157 /* But not if the server sent a terminate-by-EOF response */
1158 if (soup_message_headers_get_encoding (msg->response_headers) == SOUP_ENCODING_EOF)
1166 * soup_message_set_uri:
1167 * @msg: a #SoupMessage
1168 * @uri: the new #SoupURI
1170 * Sets @msg's URI to @uri. If @msg has already been sent and you want
1171 * to re-send it with the new URI, you need to call
1172 * soup_session_requeue_message().
1175 soup_message_set_uri (SoupMessage *msg, SoupURI *uri)
1177 SoupMessagePrivate *priv;
1179 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1180 priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1183 soup_uri_free (priv->uri);
1184 priv->uri = soup_uri_copy (uri);
1186 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_URI);
1190 * soup_message_get_uri:
1191 * @msg: a #SoupMessage
1195 * Return value: the URI @msg is targeted for.
1198 soup_message_get_uri (SoupMessage *msg)
1200 g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
1202 return SOUP_MESSAGE_GET_PRIVATE (msg)->uri;
1206 * soup_message_set_status:
1207 * @msg: a #SoupMessage
1208 * @status_code: an HTTP status code
1210 * Sets @msg's status code to @status_code. If @status_code is a
1211 * known value, it will also set @msg's reason_phrase.
1214 soup_message_set_status (SoupMessage *msg, guint status_code)
1216 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1217 g_return_if_fail (status_code != 0);
1219 g_free ((char *) msg->reason_phrase);
1221 msg->status_code = status_code;
1222 msg->reason_phrase = g_strdup (soup_status_get_phrase (status_code));
1223 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_STATUS_CODE);
1224 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_REASON_PHRASE);
1228 * soup_message_set_status_full:
1229 * @msg: a #SoupMessage
1230 * @status_code: an HTTP status code
1231 * @reason_phrase: a description of the status
1233 * Sets @msg's status code and reason phrase.
1236 soup_message_set_status_full (SoupMessage *msg,
1238 const char *reason_phrase)
1240 g_return_if_fail (SOUP_IS_MESSAGE (msg));
1241 g_return_if_fail (status_code != 0);
1242 g_return_if_fail (reason_phrase != NULL);
1244 g_free ((char *) msg->reason_phrase);
1246 msg->status_code = status_code;
1247 msg->reason_phrase = g_strdup (reason_phrase);
1248 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_STATUS_CODE);
1249 g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_REASON_PHRASE);
1253 soup_message_set_io_status (SoupMessage *msg,
1254 SoupMessageIOStatus status)
1256 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1258 priv->io_status = status;
1262 soup_message_get_io_status (SoupMessage *msg)
1264 SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
1266 return priv->io_status;