summaryrefslogtreecommitdiff
path: root/libsoup/soup-message.c
diff options
context:
space:
mode:
Diffstat (limited to 'libsoup/soup-message.c')
-rw-r--r--libsoup/soup-message.c537
1 files changed, 306 insertions, 231 deletions
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index 3e1112e1..23fd8b08 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -5,13 +5,11 @@
* Copyright (C) 2000-2003, Ximian, Inc.
*/
-//#include <stdlib.h>
-//#include <string.h>
+#include <string.h>
#include "soup-message.h"
#include "soup.h"
#include "soup-connection.h"
-#include "soup-marshal.h"
#include "soup-message-private.h"
/**
@@ -22,9 +20,16 @@
* A #SoupMessage represents an HTTP message that is being sent or
* received.
*
- * For client-side usage, you would create a #SoupMessage with
+ * For client-side usage, if you are using the traditional
+ * #SoupSession APIs (soup_session_queue_message() and
+ * soup_session_send_message()), you would create a #SoupMessage with
* soup_message_new() or soup_message_new_from_uri(), set up its
- * fields appropriate, and send it via a #SoupSession.
+ * fields appropriately, and send it. If you are using the newer
+ * #SoupRequest API, you would create a request with
+ * soup_session_request_http() or soup_session_request_http_uri(), and
+ * the returned #SoupRequestHTTP will already have an associated
+ * #SoupMessage that you can retrieve via
+ * soup_request_http_get_message().
*
* For server-side usage, #SoupServer will create #SoupMessage<!--
* -->s automatically for incoming requests, which your application
@@ -49,7 +54,7 @@
*
* Represents an HTTP message being sent or received.
*
- * @status_code will normally be a #SoupKnownStatusCode, eg,
+ * @status_code will normally be a #SoupStatus value, eg,
* %SOUP_STATUS_OK, though of course it might actually be an unknown
* status code. @reason_phrase is the actual text returned from the
* server, which may or may not correspond to the "standard"
@@ -62,17 +67,22 @@
*
* As described in the #SoupMessageBody documentation, the
* @request_body and @response_body <literal>data</literal> fields
- * will not necessarily be filled in at all times. When they are
- * filled in, they will be terminated with a '\0' byte (which is not
- * included in the <literal>length</literal>), so you can use them as
- * ordinary C strings (assuming that you know that the body doesn't
- * have any other '\0' bytes).
- *
- * For a client-side #SoupMessage, @request_body's %data is usually
- * filled in right before libsoup writes the request to the network,
- * but you should not count on this; use soup_message_body_flatten()
- * if you want to ensure that %data is filled in. @response_body's
- * %data will be filled in before #SoupMessage::finished is emitted.
+ * will not necessarily be filled in at all times. When the body
+ * fields are filled in, they will be terminated with a '\0' byte
+ * (which is not included in the <literal>length</literal>), so you
+ * can use them as ordinary C strings (assuming that you know that the
+ * body doesn't have any other '\0' bytes).
+ *
+ * For a client-side #SoupMessage, @request_body's
+ * <literal>data</literal> is usually filled in right before libsoup
+ * writes the request to the network, but you should not count on
+ * this; use soup_message_body_flatten() if you want to ensure that
+ * <literal>data</literal> is filled in. If you are not using
+ * #SoupRequest to read the response, then @response_body's
+ * <literal>data</literal> will be filled in before
+ * #SoupMessage::finished is emitted. (If you are using #SoupRequest,
+ * then the message body is not accumulated by default, so
+ * @response_body's <literal>data</literal> will always be %NULL.)
*
* For a server-side #SoupMessage, @request_body's %data will be
* filled in before #SoupMessage::got_body is emitted.
@@ -121,11 +131,14 @@ enum {
PROP_REASON_PHRASE,
PROP_FIRST_PARTY,
PROP_REQUEST_BODY,
+ PROP_REQUEST_BODY_DATA,
PROP_REQUEST_HEADERS,
PROP_RESPONSE_BODY,
+ PROP_RESPONSE_BODY_DATA,
PROP_RESPONSE_HEADERS,
PROP_TLS_CERTIFICATE,
PROP_TLS_ERRORS,
+ PROP_PRIORITY,
LAST_PROP
};
@@ -136,6 +149,7 @@ soup_message_init (SoupMessage *msg)
SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
priv->http_version = priv->orig_http_version = SOUP_HTTP_1_1;
+ priv->priority = SOUP_MESSAGE_PRIORITY_NORMAL;
msg->request_body = soup_message_body_new ();
msg->request_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_REQUEST);
@@ -162,8 +176,6 @@ soup_message_finalize (GObject *object)
g_slist_free (priv->disabled_features);
- g_slist_free_full (priv->decoders, g_object_unref);
-
g_clear_object (&priv->tls_certificate);
soup_message_body_free (msg->request_body);
@@ -229,6 +241,9 @@ soup_message_set_property (GObject *object, guint prop_id,
else if (priv->tls_certificate)
priv->msg_flags |= SOUP_MESSAGE_CERTIFICATE_TRUSTED;
break;
+ case PROP_PRIORITY:
+ priv->priority = g_value_get_enum (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -241,6 +256,7 @@ soup_message_get_property (GObject *object, guint prop_id,
{
SoupMessage *msg = SOUP_MESSAGE (object);
SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
+ SoupBuffer *buf;
switch (prop_id) {
case PROP_METHOD:
@@ -270,12 +286,22 @@ soup_message_get_property (GObject *object, guint prop_id,
case PROP_REQUEST_BODY:
g_value_set_boxed (value, msg->request_body);
break;
+ case PROP_REQUEST_BODY_DATA:
+ buf = soup_message_body_flatten (msg->request_body);
+ g_value_take_boxed (value, soup_buffer_get_as_bytes (buf));
+ soup_buffer_free (buf);
+ break;
case PROP_REQUEST_HEADERS:
g_value_set_boxed (value, msg->request_headers);
break;
case PROP_RESPONSE_BODY:
g_value_set_boxed (value, msg->response_body);
break;
+ case PROP_RESPONSE_BODY_DATA:
+ buf = soup_message_body_flatten (msg->response_body);
+ g_value_take_boxed (value, soup_buffer_get_as_bytes (buf));
+ soup_buffer_free (buf);
+ break;
case PROP_RESPONSE_HEADERS:
g_value_set_boxed (value, msg->response_headers);
break;
@@ -285,6 +311,9 @@ soup_message_get_property (GObject *object, guint prop_id,
case PROP_TLS_ERRORS:
g_value_set_flags (value, priv->tls_errors);
break;
+ case PROP_PRIORITY:
+ g_value_set_enum (value, priv->priority);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -292,12 +321,12 @@ soup_message_get_property (GObject *object, guint prop_id,
}
static void
-soup_message_real_got_body (SoupMessage *req)
+soup_message_real_got_body (SoupMessage *msg)
{
- SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (req);
+ SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
SoupMessageBody *body;
- body = priv->server_side ? req->request_body : req->response_body;
+ body = priv->server_side ? msg->request_body : msg->response_body;
if (soup_message_body_get_accumulate (body)) {
SoupBuffer *buffer;
@@ -336,7 +365,7 @@ soup_message_class_init (SoupMessageClass *message_class)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (SoupMessageClass, wrote_informational),
NULL, NULL,
- _soup_marshal_NONE__NONE,
+ NULL,
G_TYPE_NONE, 0);
/**
@@ -354,7 +383,7 @@ soup_message_class_init (SoupMessageClass *message_class)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (SoupMessageClass, wrote_headers),
NULL, NULL,
- _soup_marshal_NONE__NONE,
+ NULL,
G_TYPE_NONE, 0);
/**
@@ -376,7 +405,7 @@ soup_message_class_init (SoupMessageClass *message_class)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (SoupMessageClass, wrote_chunk),
NULL, NULL,
- _soup_marshal_NONE__NONE,
+ NULL,
G_TYPE_NONE, 0);
/**
@@ -391,7 +420,7 @@ soup_message_class_init (SoupMessageClass *message_class)
* every successful write() call, not only after finishing a
* complete "chunk".
*
- * Since: 2.4.1
+ * Since: 2.24
**/
signals[WROTE_BODY_DATA] =
g_signal_new ("wrote_body_data",
@@ -399,7 +428,7 @@ soup_message_class_init (SoupMessageClass *message_class)
G_SIGNAL_RUN_FIRST,
0, /* FIXME after next ABI break */
NULL, NULL,
- _soup_marshal_NONE__BOXED,
+ NULL,
G_TYPE_NONE, 1,
SOUP_TYPE_BUFFER);
@@ -420,7 +449,7 @@ soup_message_class_init (SoupMessageClass *message_class)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (SoupMessageClass, wrote_body),
NULL, NULL,
- _soup_marshal_NONE__NONE,
+ NULL,
G_TYPE_NONE, 0);
/**
@@ -443,7 +472,7 @@ soup_message_class_init (SoupMessageClass *message_class)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (SoupMessageClass, got_informational),
NULL, NULL,
- _soup_marshal_NONE__NONE,
+ NULL,
G_TYPE_NONE, 0);
/**
@@ -475,7 +504,7 @@ soup_message_class_init (SoupMessageClass *message_class)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (SoupMessageClass, got_headers),
NULL, NULL,
- _soup_marshal_NONE__NONE,
+ NULL,
G_TYPE_NONE, 0);
/**
@@ -498,7 +527,7 @@ soup_message_class_init (SoupMessageClass *message_class)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (SoupMessageClass, got_chunk),
NULL, NULL,
- _soup_marshal_NONE__BOXED,
+ NULL,
G_TYPE_NONE, 1,
/* Use %G_SIGNAL_TYPE_STATIC_SCOPE so that
* the %SOUP_MEMORY_TEMPORARY buffers used
@@ -527,7 +556,7 @@ soup_message_class_init (SoupMessageClass *message_class)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (SoupMessageClass, got_body),
NULL, NULL,
- _soup_marshal_NONE__NONE,
+ NULL,
G_TYPE_NONE, 0);
/**
@@ -556,7 +585,7 @@ soup_message_class_init (SoupMessageClass *message_class)
* that sniffing could be done is delivered on the first
* emission of #SoupMessage::got-chunk.
*
- * Since: 2.27.3
+ * Since: 2.28
**/
signals[CONTENT_SNIFFED] =
g_signal_new ("content_sniffed",
@@ -564,7 +593,7 @@ soup_message_class_init (SoupMessageClass *message_class)
G_SIGNAL_RUN_FIRST,
0,
NULL, NULL,
- _soup_marshal_NONE__STRING_BOXED,
+ NULL,
G_TYPE_NONE, 2,
G_TYPE_STRING,
G_TYPE_HASH_TABLE);
@@ -584,7 +613,7 @@ soup_message_class_init (SoupMessageClass *message_class)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (SoupMessageClass, restarted),
NULL, NULL,
- _soup_marshal_NONE__NONE,
+ NULL,
G_TYPE_NONE, 0);
/**
@@ -601,7 +630,7 @@ soup_message_class_init (SoupMessageClass *message_class)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (SoupMessageClass, finished),
NULL, NULL,
- _soup_marshal_NONE__NONE,
+ NULL,
G_TYPE_NONE, 0);
/**
@@ -768,6 +797,28 @@ soup_message_class_init (SoupMessageClass *message_class)
SOUP_TYPE_MESSAGE_BODY,
G_PARAM_READABLE));
/**
+ * SOUP_MESSAGE_REQUEST_BODY_DATA:
+ *
+ * Alias for the #SoupMessage:request-body-data property. (The
+ * message's HTTP request body, as a #GBytes.)
+ *
+ * Since: 2.46
+ **/
+ /**
+ * SoupMessage:request-body-data:
+ *
+ * The message's HTTP request body, as a #GBytes.
+ *
+ * Since: 2.46
+ **/
+ g_object_class_install_property (
+ object_class, PROP_REQUEST_BODY_DATA,
+ g_param_spec_boxed (SOUP_MESSAGE_REQUEST_BODY_DATA,
+ "Request Body Data",
+ "The HTTP request body",
+ G_TYPE_BYTES,
+ G_PARAM_READABLE));
+ /**
* SOUP_MESSAGE_REQUEST_HEADERS:
*
* Alias for the #SoupMessage:request-headers property. (The
@@ -794,6 +845,28 @@ soup_message_class_init (SoupMessageClass *message_class)
SOUP_TYPE_MESSAGE_BODY,
G_PARAM_READABLE));
/**
+ * SOUP_MESSAGE_RESPONSE_BODY_DATA:
+ *
+ * Alias for the #SoupMessage:response-body-data property. (The
+ * message's HTTP response body, as a #GBytes.)
+ *
+ * Since: 2.46
+ **/
+ /**
+ * SoupMessage:response-body-data:
+ *
+ * The message's HTTP response body, as a #GBytes.
+ *
+ * Since: 2.46
+ **/
+ g_object_class_install_property (
+ object_class, PROP_RESPONSE_BODY_DATA,
+ g_param_spec_boxed (SOUP_MESSAGE_RESPONSE_BODY_DATA,
+ "Response Body Data",
+ "The HTTP response body",
+ G_TYPE_BYTES,
+ G_PARAM_READABLE));
+ /**
* SOUP_MESSAGE_RESPONSE_HEADERS:
*
* Alias for the #SoupMessage:response-headers property. (The
@@ -850,6 +923,22 @@ soup_message_class_init (SoupMessageClass *message_class)
"The verification errors on the message's TLS certificate",
G_TYPE_TLS_CERTIFICATE_FLAGS, 0,
G_PARAM_READWRITE));
+ /**
+ * SOUP_MESSAGE_PRIORITY:
+ *
+ * Sets the priority of the #SoupMessage. See
+ * soup_message_set_priority() for further details.
+ *
+ * Since: 2.44
+ **/
+ g_object_class_install_property (
+ object_class, PROP_PRIORITY,
+ g_param_spec_enum (SOUP_MESSAGE_PRIORITY,
+ "Priority",
+ "The priority of the message",
+ SOUP_TYPE_MESSAGE_PRIORITY,
+ SOUP_MESSAGE_PRIORITY_NORMAL,
+ G_PARAM_READWRITE));
}
@@ -906,9 +995,10 @@ soup_message_new_from_uri (const char *method, SoupURI *uri)
/**
* soup_message_set_request:
* @msg: the message
- * @content_type: MIME Content-Type of the body
+ * @content_type: (allow-none): MIME Content-Type of the body
* @req_use: a #SoupMemoryUse describing how to handle @req_body
- * @req_body: a data buffer containing the body of the message request.
+ * @req_body: (allow-none) (array length=req_length) (element-type guint8):
+ * a data buffer containing the body of the message request.
* @req_length: the byte length of @req_body.
*
* Convenience function to set the request body of a #SoupMessage. If
@@ -925,6 +1015,8 @@ soup_message_set_request (SoupMessage *msg,
g_return_if_fail (content_type != NULL || req_length == 0);
if (content_type) {
+ g_warn_if_fail (strchr (content_type, '/') != NULL);
+
soup_message_headers_replace (msg->request_headers,
"Content-Type", content_type);
soup_message_body_append (msg->request_body, req_use,
@@ -941,8 +1033,8 @@ soup_message_set_request (SoupMessage *msg,
* @msg: the message
* @content_type: (allow-none): MIME Content-Type of the body
* @resp_use: a #SoupMemoryUse describing how to handle @resp_body
- * @resp_body: (array length=resp_length) (element-type guint8): a data buffer
- * containing the body of the message response.
+ * @resp_body: (allow-none) (array length=resp_length) (element-type guint8):
+ * a data buffer containing the body of the message response.
* @resp_length: the byte length of @resp_body.
*
* Convenience function to set the response body of a #SoupMessage. If
@@ -959,6 +1051,8 @@ soup_message_set_response (SoupMessage *msg,
g_return_if_fail (content_type != NULL || resp_length == 0);
if (content_type) {
+ g_warn_if_fail (strchr (content_type, '/') != NULL);
+
soup_message_headers_replace (msg->response_headers,
"Content-Type", content_type);
soup_message_body_append (msg->response_body, resp_use,
@@ -970,150 +1064,66 @@ soup_message_set_response (SoupMessage *msg,
}
}
-/**
- * soup_message_wrote_informational:
- * @msg: a #SoupMessage
- *
- * Emits the %wrote_informational signal, indicating that the IO layer
- * finished writing an informational (1xx) response for @msg.
- **/
void
soup_message_wrote_informational (SoupMessage *msg)
{
g_signal_emit (msg, signals[WROTE_INFORMATIONAL], 0);
}
-/**
- * soup_message_wrote_headers:
- * @msg: a #SoupMessage
- *
- * Emits the %wrote_headers signal, indicating that the IO layer
- * finished writing the (non-informational) headers for @msg.
- **/
void
soup_message_wrote_headers (SoupMessage *msg)
{
g_signal_emit (msg, signals[WROTE_HEADERS], 0);
}
-/**
- * soup_message_wrote_chunk:
- * @msg: a #SoupMessage
- *
- * Emits the %wrote_chunk signal, indicating that the IO layer
- * finished writing a chunk of @msg's body.
- **/
void
soup_message_wrote_chunk (SoupMessage *msg)
{
g_signal_emit (msg, signals[WROTE_CHUNK], 0);
}
-/**
- * soup_message_wrote_body_data:
- * @msg: a #SoupMessage
- * @chunk: the data written
- *
- * Emits the %wrote_body_data signal, indicating that the IO layer
- * finished writing a portion of @msg's body.
- **/
void
soup_message_wrote_body_data (SoupMessage *msg, SoupBuffer *chunk)
{
g_signal_emit (msg, signals[WROTE_BODY_DATA], 0, chunk);
}
-/**
- * soup_message_wrote_body:
- * @msg: a #SoupMessage
- *
- * Emits the %wrote_body signal, indicating that the IO layer finished
- * writing the body for @msg.
- **/
void
soup_message_wrote_body (SoupMessage *msg)
{
g_signal_emit (msg, signals[WROTE_BODY], 0);
}
-/**
- * soup_message_got_informational:
- * @msg: a #SoupMessage
- *
- * Emits the #SoupMessage::got_informational signal, indicating that
- * the IO layer read a complete informational (1xx) response for @msg.
- **/
void
soup_message_got_informational (SoupMessage *msg)
{
g_signal_emit (msg, signals[GOT_INFORMATIONAL], 0);
}
-/**
- * soup_message_got_headers:
- * @msg: a #SoupMessage
- *
- * Emits the #SoupMessage::got_headers signal, indicating that the IO
- * layer finished reading the (non-informational) headers for @msg.
- **/
void
soup_message_got_headers (SoupMessage *msg)
{
g_signal_emit (msg, signals[GOT_HEADERS], 0);
}
-/**
- * soup_message_got_chunk:
- * @msg: a #SoupMessage
- * @chunk: the newly-read chunk
- *
- * Emits the #SoupMessage::got_chunk signal, indicating that the IO
- * layer finished reading a chunk of @msg's body.
- **/
void
soup_message_got_chunk (SoupMessage *msg, SoupBuffer *chunk)
{
g_signal_emit (msg, signals[GOT_CHUNK], 0, chunk);
}
-/**
- * soup_message_got_body:
- * @msg: a #SoupMessage
- *
- * Emits the #SoupMessage::got_body signal, indicating that the IO
- * layer finished reading the body for @msg.
- **/
void
soup_message_got_body (SoupMessage *msg)
{
g_signal_emit (msg, signals[GOT_BODY], 0);
}
-/**
- * soup_message_content_sniffed:
- * @msg: a #SoupMessage
- * @content_type: a string with the sniffed content type
- * @params: a #GHashTable with the parameters
- *
- * Emits the %content_sniffed signal, indicating that the IO layer
- * finished sniffing the content type for @msg. If content sniffing
- * will not be performed, due to the sniffer deciding to trust the
- * Content-Type sent by the server, this signal is emitted immediately
- * after #SoupMessage::got_headers, with %NULL as @content_type.
- **/
void
soup_message_content_sniffed (SoupMessage *msg, const char *content_type, GHashTable *params)
{
g_signal_emit (msg, signals[CONTENT_SNIFFED], 0, content_type, params);
}
-/**
- * soup_message_restarted:
- * @msg: a #SoupMessage
- *
- * Emits the %restarted signal, indicating that @msg should be
- * requeued.
- **/
void
soup_message_restarted (SoupMessage *msg)
{
@@ -1125,13 +1135,6 @@ soup_message_restarted (SoupMessage *msg)
g_signal_emit (msg, signals[RESTARTED], 0);
}
-/**
- * soup_message_finished:
- * @msg: a #SoupMessage
- *
- * Emits the %finished signal, indicating that @msg has been completely
- * processed.
- **/
void
soup_message_finished (SoupMessage *msg)
{
@@ -1163,11 +1166,6 @@ header_handler_metamarshal (GClosure *closure, GValue *return_value,
const char *header_name = marshal_data;
SoupMessageHeaders *hdrs;
-#ifdef FIXME
- if (priv->io_status != SOUP_MESSAGE_IO_STATUS_RUNNING)
- return;
-#endif
-
hdrs = priv->server_side ? msg->request_headers : msg->response_headers;
if (soup_message_headers_get_one (hdrs, header_name)) {
closure->marshal (closure, return_value, n_param_values,
@@ -1185,16 +1183,11 @@ header_handler_metamarshal (GClosure *closure, GValue *return_value,
* @user_data: data to pass to @handler_cb
*
* Adds a signal handler to @msg for @signal, as with
- * g_signal_connect(), but with two differences: the @callback will
- * only be run if @msg has a header named @header, and it will only be
- * run if no earlier handler cancelled or requeued the message.
- *
- * If @signal is one of the "got" signals (eg, "got_headers"), or
- * "finished" or "restarted", then @header is matched against the
- * incoming message headers (that is, the #request_headers for a
- * client #SoupMessage, or the #response_headers for a server
- * #SoupMessage). If @signal is one of the "wrote" signals, then
- * @header is matched against the outgoing message headers.
+ * g_signal_connect(), but the @callback will only be run if @msg's
+ * incoming messages headers (that is, the
+ * <literal>request_headers</literal> for a client #SoupMessage, or
+ * the <literal>response_headers</literal> for a server #SoupMessage)
+ * contain a header named @header.
*
* Return value: the handler ID from g_signal_connect()
**/
@@ -1232,11 +1225,6 @@ status_handler_metamarshal (GClosure *closure, GValue *return_value,
SoupMessage *msg = g_value_get_object (&param_values[0]);
guint status = GPOINTER_TO_UINT (marshal_data);
-#ifdef FIXME
- if (priv->io_status != SOUP_MESSAGE_IO_STATUS_RUNNING)
- return;
-#endif
-
if (msg->status_code == status) {
closure->marshal (closure, return_value, n_param_values,
param_values, invocation_hint,
@@ -1253,9 +1241,8 @@ status_handler_metamarshal (GClosure *closure, GValue *return_value,
* @user_data: data to pass to @handler_cb
*
* Adds a signal handler to @msg for @signal, as with
- * g_signal_connect() but with two differences: the @callback will
- * only be run if @msg has the status @status_code, and it will only
- * be run if no earlier handler cancelled or requeued the message.
+ * g_signal_connect(), but the @callback will only be run if @msg has
+ * the status @status_code.
*
* @signal must be a signal that will be emitted after @msg's status
* is set. For a client #SoupMessage, this means it can't be a "wrote"
@@ -1285,15 +1272,6 @@ soup_message_add_status_code_handler (SoupMessage *msg,
}
-/**
- * soup_message_set_auth:
- * @msg: a #SoupMessage
- * @auth: a #SoupAuth, or %NULL
- *
- * Sets @msg to authenticate to its destination using @auth, which
- * must have already been fully authenticated. If @auth is %NULL, @msg
- * will not authenticate to its destination.
- **/
void
soup_message_set_auth (SoupMessage *msg, SoupAuth *auth)
{
@@ -1302,7 +1280,6 @@ soup_message_set_auth (SoupMessage *msg, SoupAuth *auth)
g_return_if_fail (SOUP_IS_MESSAGE (msg));
g_return_if_fail (auth == NULL || SOUP_IS_AUTH (auth));
- g_return_if_fail (auth == NULL || soup_auth_is_authenticated (auth));
priv = SOUP_MESSAGE_GET_PRIVATE (msg);
@@ -1317,20 +1294,13 @@ soup_message_set_auth (SoupMessage *msg, SoupAuth *auth)
g_object_ref (priv->auth);
token = soup_auth_get_authorization (auth, msg);
- soup_message_headers_replace (msg->request_headers,
- "Authorization", token);
- g_free (token);
+ if (token) {
+ soup_message_headers_replace (msg->request_headers,
+ "Authorization", token);
+ g_free (token);
+ }
}
-/**
- * soup_message_get_auth:
- * @msg: a #SoupMessage
- *
- * Gets the #SoupAuth used by @msg for authentication.
- *
- * Return value: (transfer none): the #SoupAuth used by @msg for
- * authentication, or %NULL if @msg is unauthenticated.
- **/
SoupAuth *
soup_message_get_auth (SoupMessage *msg)
{
@@ -1339,15 +1309,6 @@ soup_message_get_auth (SoupMessage *msg)
return SOUP_MESSAGE_GET_PRIVATE (msg)->auth;
}
-/**
- * soup_message_set_proxy_auth:
- * @msg: a #SoupMessage
- * @auth: a #SoupAuth, or %NULL
- *
- * Sets @msg to authenticate to its proxy using @auth, which must have
- * already been fully authenticated. If @auth is %NULL, @msg will not
- * authenticate to its proxy.
- **/
void
soup_message_set_proxy_auth (SoupMessage *msg, SoupAuth *auth)
{
@@ -1356,7 +1317,6 @@ soup_message_set_proxy_auth (SoupMessage *msg, SoupAuth *auth)
g_return_if_fail (SOUP_IS_MESSAGE (msg));
g_return_if_fail (auth == NULL || SOUP_IS_AUTH (auth));
- g_return_if_fail (auth == NULL || soup_auth_is_authenticated (auth));
priv = SOUP_MESSAGE_GET_PRIVATE (msg);
@@ -1376,15 +1336,6 @@ soup_message_set_proxy_auth (SoupMessage *msg, SoupAuth *auth)
g_free (token);
}
-/**
- * soup_message_get_proxy_auth:
- * @msg: a #SoupMessage
- *
- * Gets the #SoupAuth used by @msg for authentication to its proxy..
- *
- * Return value: the #SoupAuth used by @msg for authentication to its
- * proxy, or %NULL if @msg isn't authenticated to its proxy.
- **/
SoupAuth *
soup_message_get_proxy_auth (SoupMessage *msg)
{
@@ -1393,43 +1344,54 @@ soup_message_get_proxy_auth (SoupMessage *msg)
return SOUP_MESSAGE_GET_PRIVATE (msg)->proxy_auth;
}
+SoupConnection *
+soup_message_get_connection (SoupMessage *msg)
+{
+ return SOUP_MESSAGE_GET_PRIVATE (msg)->connection;
+}
+
+void
+soup_message_set_connection (SoupMessage *msg,
+ SoupConnection *conn)
+{
+ SOUP_MESSAGE_GET_PRIVATE (msg)->connection = conn;
+}
+
/**
* soup_message_cleanup_response:
- * @req: a #SoupMessage
+ * @msg: a #SoupMessage
*
- * Cleans up all response data on @req, so that the request can be sent
+ * Cleans up all response data on @msg, so that the request can be sent
* again and receive a new response. (Eg, as a result of a redirect or
* authorization request.)
**/
void
-soup_message_cleanup_response (SoupMessage *req)
+soup_message_cleanup_response (SoupMessage *msg)
{
- SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (req);
+ SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
- soup_message_body_truncate (req->response_body);
- soup_message_headers_clear (req->response_headers);
+ soup_message_body_truncate (msg->response_body);
+ soup_message_headers_clear (msg->response_headers);
if (priv->server_side) {
- soup_message_headers_set_encoding (req->response_headers,
+ soup_message_headers_set_encoding (msg->response_headers,
SOUP_ENCODING_CONTENT_LENGTH);
}
- g_slist_free_full (priv->decoders, g_object_unref);
- priv->decoders = NULL;
priv->msg_flags &= ~SOUP_MESSAGE_CONTENT_DECODED;
- req->status_code = SOUP_STATUS_NONE;
- if (req->reason_phrase) {
- g_free (req->reason_phrase);
- req->reason_phrase = NULL;
+ msg->status_code = SOUP_STATUS_NONE;
+ if (msg->reason_phrase) {
+ g_free (msg->reason_phrase);
+ msg->reason_phrase = NULL;
}
priv->http_version = priv->orig_http_version;
- g_object_notify (G_OBJECT (req), SOUP_MESSAGE_STATUS_CODE);
- g_object_notify (G_OBJECT (req), SOUP_MESSAGE_REASON_PHRASE);
- g_object_notify (G_OBJECT (req), SOUP_MESSAGE_HTTP_VERSION);
- g_object_notify (G_OBJECT (req), SOUP_MESSAGE_FLAGS);
- g_object_notify (G_OBJECT (req), SOUP_MESSAGE_TLS_CERTIFICATE);
- g_object_notify (G_OBJECT (req), SOUP_MESSAGE_TLS_ERRORS);
+ g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_STATUS_CODE);
+ g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_REASON_PHRASE);
+ g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_HTTP_VERSION);
+ g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_FLAGS);
+ g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_TLS_CERTIFICATE);
+ g_object_notify (G_OBJECT (msg), SOUP_MESSAGE_TLS_ERRORS);
}
/**
@@ -1450,10 +1412,15 @@ soup_message_cleanup_response (SoupMessage *req)
* @SOUP_MESSAGE_CERTIFICATE_TRUSTED: if set after an https response
* has been received, indicates that the server's SSL certificate is
* trusted according to the session's CA.
- * @SOUP_MESSAGE_NEW_CONNECTION: The message should be sent on a
- * newly-created connection, not reusing an existing persistent
- * connection. Note that messages with non-idempotent
- * #SoupMessage:method<!-- -->s behave this way by default.
+ * @SOUP_MESSAGE_NEW_CONNECTION: Requests that the message should be
+ * sent on a newly-created connection, not reusing an existing
+ * persistent connection. Note that messages with non-idempotent
+ * #SoupMessage:method<!-- -->s behave this way by default, unless
+ * #SOUP_MESSAGE_IDEMPOTENT is set.
+ * @SOUP_MESSAGE_IDEMPOTENT: The message is considered idempotent,
+ * regardless its #SoupMessage:method, and allows reuse of existing
+ * idle connections, instead of always requiring a new one, unless
+ * #SOUP_MESSAGE_NEW_CONNECTION is set.
*
* Various flags that can be set on a #SoupMessage to alter its
* behavior.
@@ -1739,6 +1706,9 @@ soup_message_set_status_full (SoupMessage *msg,
* becomes possible to allocate a new buffer.
*
* Return value: the new buffer (or %NULL)
+ *
+ * Deprecated: Use #SoupRequest if you want to read into your
+ * own buffers.
**/
/**
@@ -1750,11 +1720,13 @@ soup_message_set_status_full (SoupMessage *msg,
* destroyed
*
* Sets an alternate chunk-allocation function to use when reading
- * @msg's body. Every time data is available to read, libsoup will
- * call @allocator, which should return a #SoupBuffer. (See
- * #SoupChunkAllocator for additional details.) Libsoup will then read
- * data from the network into that buffer, and update the buffer's
- * <literal>length</literal> to indicate how much data it read.
+ * @msg's body when using the traditional (ie,
+ * non-#SoupRequest<!-- -->-based) API. Every time data is available
+ * to read, libsoup will call @allocator, which should return a
+ * #SoupBuffer. (See #SoupChunkAllocator for additional details.)
+ * Libsoup will then read data from the network into that buffer, and
+ * update the buffer's <literal>length</literal> to indicate how much
+ * data it read.
*
* Generally, a custom chunk allocator would be used in conjunction
* with soup_message_body_set_accumulate() %FALSE and
@@ -1775,6 +1747,10 @@ soup_message_set_status_full (SoupMessage *msg,
* you'll need to ref the #SoupBuffer (or its owner, in the
* soup_buffer_new_with_owner() case) to ensure that the data remains
* valid.
+ *
+ * Deprecated: #SoupRequest provides a much simpler API that lets you
+ * read the response directly into your own buffers without needing to
+ * mess with callbacks, pausing/unpausing, etc.
**/
void
soup_message_set_chunk_allocator (SoupMessage *msg,
@@ -1804,10 +1780,8 @@ soup_message_set_chunk_allocator (SoupMessage *msg,
* This disables the actions of #SoupSessionFeature<!-- -->s with the
* given @feature_type (or a subclass of that type) on @msg, so that
* @msg is processed as though the feature(s) hadn't been added to the
- * session. Eg, passing #SOUP_TYPE_PROXY_URI_RESOLVER for @feature_type
- * will disable proxy handling and cause @msg to be sent directly to
- * the indicated origin server, regardless of system proxy
- * configuration.
+ * session. Eg, passing #SOUP_TYPE_CONTENT_SNIFFER for @feature_type
+ * will disable Content-Type sniffing on the message.
*
* You must call this before queueing @msg on a session; calling it on
* a message that has already been queued is undefined. In particular,
@@ -1934,11 +1908,13 @@ soup_message_set_https_status (SoupMessage *msg, SoupConnection *conn)
* @certificate: (out) (transfer none): @msg's TLS certificate
* @errors: (out): the verification status of @certificate
*
- * If @msg is using https, this retrieves the #GTlsCertificate
- * associated with its connection, and the #GTlsCertificateFlags showing
- * what problems, if any, have been found with that certificate.
+ * If @msg is using https (or attempted to use https but got
+ * %SOUP_STATUS_SSL_FAILED), this retrieves the #GTlsCertificate
+ * associated with its connection, and the #GTlsCertificateFlags
+ * showing what problems, if any, have been found with that
+ * certificate.
*
- * Return value: %TRUE if @msg uses https, %FALSE if not
+ * Return value: %TRUE if @msg used/attempted https, %FALSE if not
*
* Since: 2.34
*/
@@ -1994,3 +1970,102 @@ soup_message_set_redirect (SoupMessage *msg, guint status_code,
g_free (location_str);
soup_uri_free (location);
}
+
+void
+soup_message_set_soup_request (SoupMessage *msg,
+ SoupRequest *req)
+{
+ SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
+
+ priv->request = req;
+}
+
+/**
+ * soup_message_get_soup_request:
+ * @msg: a #SoupMessage
+ *
+ * If @msg is associated with a #SoupRequest, this returns that
+ * request. Otherwise it returns %NULL.
+ *
+ * Return value: (transfer none): @msg's associated #SoupRequest
+ *
+ * Since: 2.42
+ */
+SoupRequest *
+soup_message_get_soup_request (SoupMessage *msg)
+{
+ SoupMessagePrivate *priv;
+
+ g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
+
+ priv = SOUP_MESSAGE_GET_PRIVATE (msg);
+ return priv->request;
+}
+
+/**
+ * SoupMessagePriority:
+ * @SOUP_MESSAGE_PRIORITY_VERY_LOW: The lowest priority, the messages
+ * with this priority will be the last ones to be attended.
+ * @SOUP_MESSAGE_PRIORITY_LOW: Use this for low priority messages, a
+ * #SoupMessage with the default priority will be processed first.
+ * @SOUP_MESSAGE_PRIORITY_NORMAL: The default priotity, this is the
+ * priority assigned to the #SoupMessage by default.
+ * @SOUP_MESSAGE_PRIORITY_HIGH: High priority, a #SoupMessage with
+ * this priority will be processed before the ones with the default
+ * priority.
+ * @SOUP_MESSAGE_PRIORITY_VERY_HIGH: The highest priority, use this
+ * for very urgent #SoupMessage as they will be the first ones to be
+ * attended.
+ *
+ * Priorities that can be set on a #SoupMessage to instruct the
+ * message queue to process it before any other message with lower
+ * priority.
+ **/
+
+/**
+ * soup_message_set_priority:
+ * @msg: a #SoupMessage
+ * @priority: the #SoupMessagePriority
+ *
+ * Sets the priority of a message. Note that this won't have any
+ * effect unless used before the message is added to the session's
+ * message processing queue.
+ *
+ * The message will be placed just before any other previously added
+ * message with lower priority (messages with the same priority are
+ * processed on a FIFO basis).
+ *
+ * Setting priorities does not currently work with #SoupSessionSync
+ * (or with synchronous messages on a plain #SoupSession) because in
+ * the synchronous/blocking case, priority ends up being determined
+ * semi-randomly by thread scheduling.
+ *
+ * Since: 2.44
+ */
+void
+soup_message_set_priority (SoupMessage *msg,
+ SoupMessagePriority priority)
+{
+ g_return_if_fail (SOUP_IS_MESSAGE (msg));
+
+ g_object_set (msg, SOUP_MESSAGE_PRIORITY, priority, NULL);
+}
+
+/**
+ * soup_message_get_priority:
+ * @msg: a #SoupMessage
+ *
+ * Retrieves the #SoupMessagePriority. If not set this value defaults
+ * to #SOUP_MESSAGE_PRIORITY_NORMAL.
+ *
+ * Return value: the priority of the message.
+ *
+ * Since: 2.44
+ */
+SoupMessagePriority
+soup_message_get_priority (SoupMessage *msg)
+{
+ g_return_val_if_fail (SOUP_IS_MESSAGE (msg), SOUP_MESSAGE_PRIORITY_NORMAL);
+
+ return SOUP_MESSAGE_GET_PRIVATE (msg)->priority;
+}