diff options
author | Dan Winship <danw@gnome.org> | 2012-12-14 09:54:36 -0500 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2012-12-28 11:26:46 -0500 |
commit | 967dcc28f43cd47a75b7ff2c069807edb9929400 (patch) | |
tree | 55f7a6fbaa6b5077c3073cfbed5693f104881478 | |
parent | 2357f3501718967003914da4f1f7659b6593aa0d (diff) | |
download | libsoup-967dcc28f43cd47a75b7ff2c069807edb9929400.tar.gz |
SoupSession: update docs (and some semantics) for plain SoupSession
Update the docs to reflect the changes in plain SoupSessions vs its
traditional subclasses. And while we're there, add a few new ones
(including making soup_session_queue_message() and
soup_session_send_message() work on plain SoupSession.
-rw-r--r-- | docs/reference/Makefile.am | 3 | ||||
-rw-r--r-- | docs/reference/libsoup-2.4-docs.sgml | 1 | ||||
-rw-r--r-- | docs/reference/libsoup-2.4-sections.txt | 3 | ||||
-rw-r--r-- | docs/reference/session-porting.xml | 163 | ||||
-rw-r--r-- | libsoup/libsoup-2.4.sym | 2 | ||||
-rw-r--r-- | libsoup/soup-content-decoder.c | 23 | ||||
-rw-r--r-- | libsoup/soup-proxy-resolver-default.c | 9 | ||||
-rw-r--r-- | libsoup/soup-session-async.c | 32 | ||||
-rw-r--r-- | libsoup/soup-session-async.h | 2 | ||||
-rw-r--r-- | libsoup/soup-session-sync.c | 46 | ||||
-rw-r--r-- | libsoup/soup-session-sync.h | 2 | ||||
-rw-r--r-- | libsoup/soup-session.c | 310 | ||||
-rw-r--r-- | libsoup/soup-session.h | 9 |
13 files changed, 463 insertions, 142 deletions
diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am index 7e6c180b..74a6d925 100644 --- a/docs/reference/Makefile.am +++ b/docs/reference/Makefile.am @@ -52,7 +52,8 @@ HTML_IMAGES = content_files = \ build-howto.xml \ client-howto.xml \ - server-howto.xml + server-howto.xml \ + session-porting.xml # Other files to distribute. extra_files = diff --git a/docs/reference/libsoup-2.4-docs.sgml b/docs/reference/libsoup-2.4-docs.sgml index 95ff9c98..f19848f5 100644 --- a/docs/reference/libsoup-2.4-docs.sgml +++ b/docs/reference/libsoup-2.4-docs.sgml @@ -11,6 +11,7 @@ <xi:include href="build-howto.xml"/> <xi:include href="client-howto.xml"/> <xi:include href="server-howto.xml"/> + <xi:include href="session-porting.xml"/> </chapter> <chapter> diff --git a/docs/reference/libsoup-2.4-sections.txt b/docs/reference/libsoup-2.4-sections.txt index f3595973..963cbce1 100644 --- a/docs/reference/libsoup-2.4-sections.txt +++ b/docs/reference/libsoup-2.4-sections.txt @@ -388,6 +388,9 @@ SoupAddressClass <TITLE>SoupSession</TITLE> SoupSession <SUBSECTION> +soup_session_new +soup_session_new_with_options +<SUBSECTION> soup_session_request soup_session_request_uri soup_session_request_http diff --git a/docs/reference/session-porting.xml b/docs/reference/session-porting.xml new file mode 100644 index 00000000..680f75aa --- /dev/null +++ b/docs/reference/session-porting.xml @@ -0,0 +1,163 @@ +<?xml version="1.0"?> +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> +<refentry id="libsoup-session-porting"> +<refmeta> +<refentrytitle>Porting to the new SoupSession</refentrytitle> +<manvolnum>3</manvolnum> +<refmiscinfo>LIBSOUP Library</refmiscinfo> +</refmeta> + +<refnamediv> +<refname>Porting to the new SoupSession</refname><refpurpose>Notes on +porting from SoupSessionAsync and SoupSessionSync to SoupSession</refpurpose> +</refnamediv> + +<refsect2 id="intro"> +<title>Introduction</title> + +<para> +As of libsoup 2.42, <link +linkend="SoupSession"><type>SoupSession</type></link> is no longer an +abstract class, and the base <type>SoupSession</type> class is now +preferred over its traditional subclasses, <link +linkend="SoupSessionAsync"><type>SoupSessionAsync</type></link> and +<link linkend="SoupSessionSync"><type>SoupSessionSync</type></link>. +</para> + +<para> +There are several changes in behavior between the old and new sessions +to be aware of. +</para> + +</refsect2> + +<refsect2 id="defaults"> +<title>Different defaults</title> + +<para> +The new <link linkend="SoupSession"><type>SoupSession</type></link> +has different (and hopefully better) defaults than <link +linkend="SoupSessionAsync"><type>SoupSessionAsync</type></link> and +<link linkend="SoupSessionSync"><type>SoupSessionSync</type></link>: +</para> + +<itemizedlist> + <listitem> + <para> + The system TLS/SSL certificate database is used by default to + validate https certificates, and sites with invalid certificates + will refuse to load with a + <link linkend="SOUP-STATUS-SSL-FAILED:CAPS"><literal>SOUP_STATUS_SSL_FAILED</literal></link> + error. + </para> + <para> + You can still override the CA database as before, by setting the + <link linkend="SoupSession--ssl-ca-file"><type>"ssl-ca-file"</type></link> + property, although the + <link linkend="SoupSession--tls-database"><type>"tls-database"</type></link> + property is preferred, since it allows you to do proper error + handling. + </para> + <para> + If you want to accept all certificates, set + <link linkend="SoupSession--ssl-strict"><type>"ssl-strict"</type></link> to + <literal>FALSE</literal>. Note that libsoup will still check + certificates, it will just continue with the HTTP request even + if the certificate fails to validate. You can use + <link linkend="soup-message-get-https-status"><function>soup_message_get_https_status()</function></link> + to look at the certificate after the fact. + </para> + </listitem> + <listitem> + <para> + The + <link linkend="SoupSession--timeout"><type>"timeout"</type></link> + and + <link linkend="SoupSession--idle-timeout"><type>"idle-timeout"</type></link> + properties both default to 60 seconds. + </para> + </listitem> + <listitem> + <para> + The + <link linkend="SoupSession--http-aliases"><type>"http-aliases"</type></link> + property defaults to <literal>NULL</literal>, meaning that URI + schemes like "<literal>webcal</literal>" and + "<literal>dav</literal>" (and "<literal>ftp</literal>") are not + considered to be aliases for "<literal>http</literal>", and so + libsoup will not accept requests for such URIs, and will not + follow redirects to such URIs. + </para> + </listitem> + <listitem> + <para> + Every session gets a + <link linkend="SoupProxyResolverDefault"><type>SoupProxyResolverDefault</type></link> + and a + <link linkend="SoupContentDecoder"><type>SoupContentDecoder</type></link> + attached to it by default, meaning that it will automatically + use the user's system proxy configuration, and will handle (and + request) "gzip"- and "deflate"-encoded response bodies. + </para> + </listitem> +</itemizedlist> + +</refsect2> + +<refsect2 id="apis"> +<title>Differences in SoupMessage-sending APIs</title> + +<para> +<type>SoupSessionAsync</type> always uses asynchronous I/O, and +<type>SoupSessionSync</type> always uses blocking I/O, regardless of +the operation. In the new <type>SoupSession</type>, <link +linkend="soup-session-queue-message"><function>soup_session_queue_message()</function></link> +uses asynchronous I/O (like <type>SoupSessionAsync</type>), and <link +linkend="soup-session-send-message"><function>soup_session_send_message()</function></link> +uses blocking I/O (like <type>SoupSessionSync</type>). There is no API +on the plain <type>SoupSession</type> that simulates the effect of +calling <function>soup_session_send_message()</function> on a +<type>SoupSessionAsync</type> (ie, running the main loop internally), +or of calling <function>soup_session_queue_message()</function> on a +<type>SoupSessionSync</type> (ie, automatically sending the request in +another thread). +</para> + +</refsect2> + +<refsect2 id="async"> +<title>Differences in Asynchronous I/O</title> + +<para> +As compared to <link +linkend="SoupSessionAsync"><type>SoupSessionAsync</type></link>, <link +linkend="SoupSession"><type>SoupSession</type></link> behaves more +like gio with respect to asynchronous I/O. +</para> + +<para> +In particular, the <link +linkend="SoupSession--async-context"><type>"async-context"</type></link> +and <link +linkend="SoupSession--use-thread-context"><type>"use-thread-context"</type></link> +properties are now effectively unused, and the session always queues +asynchronous requests in the <link +linkend="GMainContext"><type>GMainContext</type></link> that was is +the thread default when the asynchronous operation is started. Session +bookkeeping tasks (like closing idle connections) happen in the +context that was thread default when the session was created. +</para> + +<para> +Additionally, <link +linkend="soup-session-cancel-message"><function>soup_session_cancel_message()</function></link> +now acts asynchronously when you cancel an asynchronous request; +rather than having the request's callback be called from inside +<function>soup_session_cancel_message()</function>, it just gets called +when you need return to the main loop. +</para> + +</refsect2> + +</refentry> diff --git a/libsoup/libsoup-2.4.sym b/libsoup/libsoup-2.4.sym index 7080ac5b..8ec30b14 100644 --- a/libsoup/libsoup-2.4.sym +++ b/libsoup/libsoup-2.4.sym @@ -368,6 +368,8 @@ soup_session_get_feature_for_message soup_session_get_features soup_session_get_type soup_session_has_feature +soup_session_new +soup_session_new_with_options soup_session_pause_message soup_session_prefetch_dns soup_session_prepare_for_uri diff --git a/libsoup/soup-content-decoder.c b/libsoup/soup-content-decoder.c index 8aac8a8a..bce78c01 100644 --- a/libsoup/soup-content-decoder.c +++ b/libsoup/soup-content-decoder.c @@ -18,15 +18,18 @@ * SECTION:soup-content-decoder * @short_description: Content-Encoding handler * - * #SoupContentDecoder handles the "Accept-Encoding" header on - * outgoing messages, and the "Content-Encoding" header on incoming - * ones. If you add it to a session with soup_session_add_feature() or - * soup_session_add_feature_by_type(), the session will automatically - * use Content-Encoding as appropriate. + * #SoupContentDecoder handles adding the "Accept-Encoding" header on + * outgoing messages, and processing the "Content-Encoding" header on + * incoming ones. Currently it supports the "gzip" and "deflate" + * content codings. * - * (Note that currently there is no way to (automatically) use - * Content-Encoding when sending a request body, or to pick specific - * encoding types to support.) + * If you are using a plain #SoupSession (ie, not #SoupSessionAsync or + * #SoupSessionSync), then a #SoupContentDecoder will automatically be + * added to the session by default. (You can use + * %SOUP_SESSION_REMOVE_FEATURE_BY_TYPE at construct time if you don't + * want this.) If you are using one of the deprecated #SoupSession + * subclasses, you can add a #SoupContentDecoder to your session with + * soup_session_add_feature() or soup_session_add_feature_by_type(). * * If #SoupContentDecoder successfully decodes the Content-Encoding, * it will set the %SOUP_MESSAGE_CONTENT_DECODED flag on the message, @@ -40,6 +43,10 @@ * will be decoded (and the %SOUP_MESSAGE_CONTENT_DECODED flag will * not be set). * + * (Note that currently there is no way to (automatically) use + * Content-Encoding when sending a request body, or to pick specific + * encoding types to support.) + * * Since: 2.30 **/ diff --git a/libsoup/soup-proxy-resolver-default.c b/libsoup/soup-proxy-resolver-default.c index 0fc8780c..ee3b102b 100644 --- a/libsoup/soup-proxy-resolver-default.c +++ b/libsoup/soup-proxy-resolver-default.c @@ -19,6 +19,15 @@ * #SoupProxyResolverDefault is a #SoupProxyURIResolver implementation * that uses the default gio GProxyResolver to resolve proxies. * + * If you are using a plain #SoupSession (ie, not #SoupSessionAsync or + * #SoupSessionSync), then a #SoupProxyResolverDefault will + * automatically be added to the session. (You can use + * %SOUP_SESSION_REMOVE_FEATURE_BY_TYPE at construct time if you don't + * want this.) If you are using one of the deprecated #SoupSession + * subclasses, you can add a #SoupProxyResolverDefault to your session + * with soup_session_add_feature() or + * soup_session_add_feature_by_type(). + * * Since: 2.34 */ diff --git a/libsoup/soup-session-async.c b/libsoup/soup-session-async.c index c416646d..b9353480 100644 --- a/libsoup/soup-session-async.c +++ b/libsoup/soup-session-async.c @@ -18,11 +18,16 @@ /** * SECTION:soup-session-async - * @short_description: Soup session for asynchronous (main-loop-based) I/O. + * @short_description: (Deprecated) SoupSession for asynchronous + * (main-loop-based) I/O. * * #SoupSessionAsync is an implementation of #SoupSession that uses - * non-blocking I/O via the glib main loop. It is intended for use in - * single-threaded programs. + * non-blocking I/O via the glib main loop for all I/O. + * + * As of libsoup 2.42, this is deprecated in favor of the plain + * #SoupSession class (which uses both asynchronous and synchronous + * I/O, depending on the API used). See the <link + * linkend="libsoup-session-porting">porting guide</link>. **/ G_DEFINE_TYPE (SoupSessionAsync, soup_session_async, SOUP_TYPE_SESSION) @@ -38,6 +43,10 @@ soup_session_async_init (SoupSessionAsync *sa) * Creates an asynchronous #SoupSession with the default options. * * Return value: the new session. + * + * Deprecated: #SoupSessionAsync is deprecated; use a plain + * #SoupSession, created with soup_session_new(). See the <link + * linkend="libsoup-session-porting">porting guide</link>. **/ SoupSession * soup_session_async_new (void) @@ -53,6 +62,10 @@ soup_session_async_new (void) * Creates an asynchronous #SoupSession with the specified options. * * Return value: the new session. + * + * Deprecated: #SoupSessionAsync is deprecated; use a plain + * #SoupSession, created with soup_session_new_with_options(). See the + * <link linkend="libsoup-session-porting">porting guide</link>. **/ SoupSession * soup_session_async_new_with_options (const char *optname1, ...) @@ -68,18 +81,6 @@ soup_session_async_new_with_options (const char *optname1, ...) return session; } -static void -soup_session_async_queue_message (SoupSession *session, SoupMessage *msg, - SoupSessionCallback callback, gpointer user_data) -{ - SoupMessageQueueItem *item; - - item = soup_session_append_queue_item (session, msg, TRUE, FALSE, - callback, user_data); - soup_session_kick_queue (session); - soup_message_queue_item_unref (item); -} - static guint soup_session_async_send_message (SoupSession *session, SoupMessage *msg) { @@ -137,7 +138,6 @@ soup_session_async_class_init (SoupSessionAsyncClass *soup_session_async_class) SoupSessionClass *session_class = SOUP_SESSION_CLASS (soup_session_async_class); /* virtual method override */ - session_class->queue_message = soup_session_async_queue_message; session_class->send_message = soup_session_async_send_message; session_class->cancel_message = soup_session_async_cancel_message; } diff --git a/libsoup/soup-session-async.h b/libsoup/soup-session-async.h index 9fb9cfe0..15b0ebfd 100644 --- a/libsoup/soup-session-async.h +++ b/libsoup/soup-session-async.h @@ -35,9 +35,11 @@ typedef struct { GType soup_session_async_get_type (void); +#ifndef LIBSOUP_DISABLE_DEPRECATED SoupSession *soup_session_async_new (void); SoupSession *soup_session_async_new_with_options (const char *optname1, ...) G_GNUC_NULL_TERMINATED; +#endif G_END_DECLS diff --git a/libsoup/soup-session-sync.c b/libsoup/soup-session-sync.c index f6ae9682..374f22bd 100644 --- a/libsoup/soup-session-sync.c +++ b/libsoup/soup-session-sync.c @@ -17,27 +17,16 @@ /** * SECTION:soup-session-sync - * @short_description: Soup session for blocking I/O in multithreaded - * programs. + * @short_description: (Deprecated) SoupSession for blocking I/O in + * multithreaded programs. * * #SoupSessionSync is an implementation of #SoupSession that uses * synchronous I/O, intended for use in multi-threaded programs. * - * You can use #SoupSessionSync from multiple threads concurrently. - * Eg, you can send a #SoupMessage in one thread, and then while - * waiting for the response, send another #SoupMessage from another - * thread. You can also send a message from one thread and then call - * soup_session_cancel_message() on it from any other thread (although - * you need to be careful to avoid race conditions, where the message - * finishes and is then unreffed by the sending thread just before you - * cancel it). - * - * However, the majority of other types and methods in libsoup are not - * MT-safe. In particular, you <emphasis>cannot</emphasis> modify or - * examine a #SoupMessage while it is being transmitted by - * #SoupSessionSync in another thread. Once a message has been handed - * off to #SoupSessionSync, it can only be manipulated from its signal - * handler callbacks, until I/O is complete. + * As of libsoup 2.42, this is deprecated in favor of the plain + * #SoupSession class (which uses both asynchronous and synchronous + * I/O, depending on the API used). See the <link + * linkend="libsoup-session-porting">porting guide</link>. **/ G_DEFINE_TYPE (SoupSessionSync, soup_session_sync, SOUP_TYPE_SESSION) @@ -53,6 +42,10 @@ soup_session_sync_init (SoupSessionSync *ss) * Creates an synchronous #SoupSession with the default options. * * Return value: the new session. + * + * Deprecated: #SoupSessionSync is deprecated; use a plain + * #SoupSession, created with soup_session_new(). See the <link + * linkend="libsoup-session-porting">porting guide</link>. **/ SoupSession * soup_session_sync_new (void) @@ -68,6 +61,10 @@ soup_session_sync_new (void) * Creates an synchronous #SoupSession with the specified options. * * Return value: the new session. + * + * Deprecated: #SoupSessionSync is deprecated; use a plain + * #SoupSession, created with soup_session_new_with_options(). See the + * <link linkend="libsoup-session-porting">porting guide</link>. **/ SoupSession * soup_session_sync_new_with_options (const char *optname1, ...) @@ -122,20 +119,6 @@ soup_session_sync_queue_message (SoupSession *session, SoupMessage *msg, g_thread_unref (thread); } -static guint -soup_session_sync_send_message (SoupSession *session, SoupMessage *msg) -{ - SoupMessageQueueItem *item; - guint status; - - item = soup_session_append_queue_item (session, msg, FALSE, FALSE, - NULL, NULL); - soup_session_process_queue_item (session, item, NULL, TRUE); - status = msg->status_code; - soup_message_queue_item_unref (item); - return status; -} - static void soup_session_sync_class_init (SoupSessionSyncClass *session_sync_class) { @@ -143,5 +126,4 @@ soup_session_sync_class_init (SoupSessionSyncClass *session_sync_class) /* virtual method override */ session_class->queue_message = soup_session_sync_queue_message; - session_class->send_message = soup_session_sync_send_message; } diff --git a/libsoup/soup-session-sync.h b/libsoup/soup-session-sync.h index 845e01c3..0ddda226 100644 --- a/libsoup/soup-session-sync.h +++ b/libsoup/soup-session-sync.h @@ -35,9 +35,11 @@ typedef struct { GType soup_session_sync_get_type (void); +#ifndef LIBSOUP_DISABLE_DEPRECATED SoupSession *soup_session_sync_new (void); SoupSession *soup_session_sync_new_with_options (const char *optname1, ...) G_GNUC_NULL_TERMINATED; +#endif G_END_DECLS diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c index 43e5f6be..0a866300 100644 --- a/libsoup/soup-session.c +++ b/libsoup/soup-session.c @@ -32,7 +32,8 @@ * #SoupSession is the object that controls client-side HTTP. A * #SoupSession encapsulates all of the state that libsoup is keeping * on behalf of your program; cached HTTP connections, authentication - * information, etc. + * information, etc. It also keeps track of various global options + * and features that you are using. * * Most applications will only need a single #SoupSession; the primary * reason you might need multiple sessions is if you need to have @@ -43,12 +44,16 @@ * one session for the first user, and a second session for the other * user.) * - * #SoupSession itself is an abstract class, with two subclasses. If - * you are using the glib main loop, you will generally want to use - * #SoupSessionAsync, which uses non-blocking I/O and callbacks. On - * the other hand, if your application is threaded and you want to do - * synchronous I/O in a separate thread from the UI, use - * #SoupSessionSync. + * In the past, #SoupSession was an abstract class, and users needed + * to choose between #SoupSessionAsync (which always uses + * #GMainLoop<!-- -->-based I/O), or #SoupSessionSync (which always uses + * blocking I/O and can be used from multiple threads simultaneously). + * This is no longer necessary; you can (and should) use a plain + * #SoupSession, which supports both synchronous and asynchronous use. + * (When using a plain #SoupSession, soup_session_queue_message() + * behaves like it traditionally did on a #SoupSessionAsync, and + * soup_session_send_message() behaves like it traditionally did on a + * #SoupSessionSync.) **/ static void @@ -746,6 +751,47 @@ soup_session_get_property (GObject *object, guint prop_id, } } +/** + * soup_session_new: + * + * Creates a #SoupSession with the default options. + * + * Return value: the new session. + * + * Since: 2.42 + */ +SoupSession * +soup_session_new (void) +{ + return g_object_new (SOUP_TYPE_SESSION, NULL); +} + +/** + * soup_session_new_with_options: + * @optname1: name of first property to set + * @...: value of @optname1, followed by additional property/value pairs + * + * Creates a #SoupSession with the specified options. + * + * Return value: the new session. + * + * Since: 2.42 + */ +SoupSession * +soup_session_new_with_options (const char *optname1, + ...) +{ + SoupSession *session; + va_list ap; + + va_start (ap, optname1); + session = (SoupSession *)g_object_new_valist (SOUP_TYPE_SESSION, + optname1, ap); + va_end (ap); + + return session; +} + static gboolean uri_is_http (SoupSessionPrivate *priv, SoupURI *uri) { @@ -793,12 +839,12 @@ uri_is_https (SoupSessionPrivate *priv, SoupURI *uri) * soup_session_get_async_context: * @session: a #SoupSession * - * Gets @session's async_context. This does not add a ref to the - * context, so you will need to ref it yourself if you want it to - * outlive its session. + * Gets @session's #SoupSession:async-context. This does not add a ref + * to the context, so you will need to ref it yourself if you want it + * to outlive its session. * - * If #SoupSession:use-thread-context is true, this will return the - * current thread-default main context. + * For a modern #SoupSession, this will always just return the + * thread-default #GMainContext, and so is not especially useful. * * Return value: (transfer none): @session's #GMainContext, which may * be %NULL @@ -1623,7 +1669,7 @@ get_connection_for_host (SoupSession *session, SOUP_CONNECTION_PROXY_RESOLVER, soup_session_get_feature (session, SOUP_TYPE_PROXY_URI_RESOLVER), SOUP_CONNECTION_SSL, uri_is_https (priv, soup_message_get_uri (item->msg)), SOUP_CONNECTION_SSL_CREDENTIALS, priv->tlsdb, - SOUP_CONNECTION_SSL_STRICT, (priv->tlsdb != NULL) && priv->ssl_strict, + SOUP_CONNECTION_SSL_STRICT, priv->ssl_strict && (priv->tlsdb != NULL || SOUP_IS_PLAIN_SESSION (session)), SOUP_CONNECTION_ASYNC_CONTEXT, priv->async_context, SOUP_CONNECTION_USE_THREAD_CONTEXT, priv->use_thread_context, SOUP_CONNECTION_TIMEOUT, priv->io_timeout, @@ -1887,6 +1933,18 @@ idle_run_queue (gpointer user_data) * qv. **/ +static void +soup_session_real_queue_message (SoupSession *session, SoupMessage *msg, + SoupSessionCallback callback, gpointer user_data) +{ + SoupMessageQueueItem *item; + + item = soup_session_append_queue_item (session, msg, TRUE, FALSE, + callback, user_data); + soup_session_kick_queue (session); + soup_message_queue_item_unref (item); +} + /** * soup_session_queue_message: * @session: a #SoupSession @@ -1895,20 +1953,27 @@ idle_run_queue (gpointer user_data) * be called after the message completes or when an unrecoverable error occurs. * @user_data: (allow-none): a pointer passed to @callback. * - * Queues the message @msg for sending. All messages are processed - * while the glib main loop runs. If @msg has been processed before, - * any resources related to the time it was last sent are freed. + * Queues the message @msg for asynchronously sending the request and + * receiving a response in the current thread-default #GMainContext. + * If @msg has been processed before, any resources related to the + * time it was last sent are freed. * * Upon message completion, the callback specified in @callback will - * be invoked (in the thread associated with @session's async - * context). If after returning from this callback the message has not + * be invoked. If after returning from this callback the message has not * been requeued, @msg will be unreffed. + * + * (The behavior above applies to a plain #SoupSession; if you are + * using #SoupSessionAsync or #SoupSessionSync, then the #GMainContext + * that is used depends on the settings of #SoupSession:async-context + * and #SoupSession:use-thread-context, and for #SoupSessionSync, the + * message will actually be sent and processed in another thread, with + * only the final callback occurring in the indicated #GMainContext.) */ void soup_session_queue_message (SoupSession *session, SoupMessage *msg, SoupSessionCallback callback, gpointer user_data) { - g_return_if_fail (SOUP_IS_SESSION_ASYNC (session) || SOUP_IS_SESSION_SYNC (session)); + g_return_if_fail (SOUP_IS_SESSION (session)); g_return_if_fail (SOUP_IS_MESSAGE (msg)); SOUP_SESSION_GET_CLASS (session)->queue_message (session, msg, @@ -1948,6 +2013,20 @@ soup_session_requeue_message (SoupSession *session, SoupMessage *msg) SOUP_SESSION_GET_CLASS (session)->requeue_message (session, msg); } +static guint +soup_session_real_send_message (SoupSession *session, SoupMessage *msg) +{ + SoupMessageQueueItem *item; + guint status; + + item = soup_session_append_queue_item (session, msg, FALSE, FALSE, + NULL, NULL); + soup_session_process_queue_item (session, item, NULL, TRUE); + status = msg->status_code; + soup_message_queue_item_unref (item); + return status; +} + /** * soup_session_send_message: * @session: a #SoupSession @@ -1957,14 +2036,20 @@ soup_session_requeue_message (SoupSession *session, SoupMessage *msg) * transfer is finished successfully or there is an unrecoverable * error. * - * @msg is not freed upon return. + * Unlike with soup_session_queue_message(), @msg is not freed upon + * return. + * + * (Note that if you call this method on a #SoupSessionAsync, it will + * still use asynchronous I/O internally, running the glib main loop + * to process the message, which may also cause other events to be + * processed.) * * Return value: the HTTP status code of the response */ guint soup_session_send_message (SoupSession *session, SoupMessage *msg) { - g_return_val_if_fail (SOUP_IS_SESSION_ASYNC (session) || SOUP_IS_SESSION_SYNC (session), SOUP_STATUS_MALFORMED); + g_return_val_if_fail (SOUP_IS_SESSION (session), SOUP_STATUS_MALFORMED); g_return_val_if_fail (SOUP_IS_MESSAGE (msg), SOUP_STATUS_MALFORMED); return SOUP_SESSION_GET_CLASS (session)->send_message (session, msg); @@ -2105,7 +2190,7 @@ soup_session_real_cancel_message (SoupSession *session, SoupMessage *msg, guint * may call this at any time after handing @msg off to @session; if * @session has started sending the request but has not yet received * the complete response, then it will close the request's connection. - * Note that with non-idempotent requests (eg, + * Note that with requests that have side effects (eg, * <literal>POST</literal>, <literal>PUT</literal>, * <literal>DELETE</literal>) it is possible that you might cancel the * request after the server acts on it, but before it returns a @@ -2116,9 +2201,12 @@ soup_session_real_cancel_message (SoupSession *session, SoupMessage *msg, guint * The response headers, on the other hand, will always be either * empty or complete. * - * For messages queued with soup_session_queue_message() (and - * cancelled from the same thread), the callback will be invoked - * before soup_session_cancel_message() returns. + * Beware that with the deprecated #SoupSessionAsync, messages queued + * with soup_session_queue_message() will have their callbacks invoked + * before soup_session_cancel_message() returns. The plain + * #SoupSession does not have this behavior; cancelling an + * asynchronous message will merely queue its callback to be run after + * returning to the main loop. **/ void soup_session_cancel_message (SoupSession *session, SoupMessage *msg, @@ -2203,6 +2291,12 @@ soup_session_real_flush_queue (SoupSession *session) * * Cancels all pending requests in @session and closes all idle * persistent connections. + * + * The message cancellation has the same semantics as with + * soup_session_cancel_message(); asynchronous requests on a + * #SoupSessionAsync will have their callback called before + * soup_session_abort() returns. Requests on a plain #SoupSession will + * not. **/ void soup_session_abort (SoupSession *session) @@ -2268,10 +2362,6 @@ prefetch_uri (SoupSession *session, SoupURI *uri, * proxy address, etc.) in order to work more quickly once the URI is * actually requested. * - * This method acts asynchronously, in @session's - * #SoupSession:async_context. If you are using #SoupSessionSync and do - * not have a main loop running, then you can't use this method. - * * Since: 2.30 * * Deprecated: 2.38: use soup_session_prefetch_dns() instead @@ -2306,10 +2396,6 @@ soup_session_prepare_for_uri (SoupSession *session, SoupURI *uri) * resolution. @callback will still be invoked in this case, with a * status of %SOUP_STATUS_CANCELLED. * -* This method acts asynchronously, in @session's -* #SoupSession:async_context. If you are using #SoupSessionSync and do -* not have a main loop running, then you can't use this method. -* * Since: 2.38 **/ void @@ -2341,6 +2427,10 @@ soup_session_prefetch_dns (SoupSession *session, const char *hostname, * feature to the session at construct time by using the * %SOUP_SESSION_ADD_FEATURE property. * + * Note that a #SoupProxyResolverDefault and a #SoupContentDecoder are + * added to the session by default (unless you are using one of the + * deprecated session subclasses). + * * Since: 2.24 **/ void @@ -2375,6 +2465,10 @@ soup_session_add_feature (SoupSession *session, SoupSessionFeature *feature) * You can also add a feature to the session at construct time by * using the %SOUP_SESSION_ADD_FEATURE_BY_TYPE property. * + * Note that a #SoupProxyResolverDefault and a #SoupContentDecoder are + * added to the session by default (unless you are using one of the + * deprecated session subclasses). + * * Since: 2.24 **/ void @@ -2642,6 +2736,8 @@ soup_session_class_init (SoupSessionClass *session_class) g_type_class_add_private (session_class, sizeof (SoupSessionPrivate)); /* virtual method definition */ + session_class->queue_message = soup_session_real_queue_message; + session_class->send_message = soup_session_real_send_message; session_class->requeue_message = soup_session_real_requeue_message; session_class->cancel_message = soup_session_real_cancel_message; session_class->flush_queue = soup_session_real_flush_queue; @@ -2838,10 +2934,22 @@ soup_session_class_init (SoupSessionClass *session_class) /* properties */ /** + * SoupSession:proxy-uri: + * + * An http proxy to use for all http and https requests in + * this session. Setting this will remove any + * #SoupProxyURIResolver features that have been added to the + * session. + * + * Note that #SoupProxyResolverDefault will handle looking up + * the user's proxy settings for you; you should only use + * #SoupSession:proxy-uri if you need to override the user's + * normal proxy settings. + */ + /** * SOUP_SESSION_PROXY_URI: * - * Alias for the #SoupSession:proxy-uri property. (The HTTP - * proxy to use for this session.) + * Alias for the #SoupSession:proxy-uri property, qv. **/ g_object_class_install_property ( object_class, PROP_PROXY_URI, @@ -2853,8 +2961,7 @@ soup_session_class_init (SoupSessionClass *session_class) /** * SOUP_SESSION_MAX_CONNS: * - * Alias for the #SoupSession:max-conns property. (The maximum - * number of connections that the session can open at once.) + * Alias for the #SoupSession:max-conns property, qv. **/ g_object_class_install_property ( object_class, PROP_MAX_CONNS, @@ -2868,9 +2975,7 @@ soup_session_class_init (SoupSessionClass *session_class) /** * SOUP_SESSION_MAX_CONNS_PER_HOST: * - * Alias for the #SoupSession:max-conns-per-host property. - * (The maximum number of connections that the session can - * open at once to a given host.) + * Alias for the #SoupSession:max-conns-per-host property, qv. **/ g_object_class_install_property ( object_class, PROP_MAX_CONNS_PER_HOST, @@ -2893,13 +2998,17 @@ soup_session_class_init (SoupSessionClass *session_class) * if you want to ensure that all future connections will have * this timeout value. * + * Note that the default value of 60 seconds only applies to + * plain #SoupSessions. If you are using #SoupSessionAsync or + * #SoupSessionSync, the default value is 0 (meaning idle + * connections will never time out). + * * Since: 2.24 **/ /** * SOUP_SESSION_IDLE_TIMEOUT: * - * Alias for the #SoupSession:idle-timeout property. (The idle - * connection lifetime.) + * Alias for the #SoupSession:idle-timeout property, qv. * * Since: 2.24 **/ @@ -2908,7 +3017,7 @@ soup_session_class_init (SoupSessionClass *session_class) g_param_spec_uint (SOUP_SESSION_IDLE_TIMEOUT, "Idle Timeout", "Connection lifetime when idle", - 0, G_MAXUINT, 0, + 0, G_MAXUINT, 60, G_PARAM_READWRITE)); /** * SoupSession:use-ntlm: @@ -2921,8 +3030,7 @@ soup_session_class_init (SoupSessionClass *session_class) /** * SOUP_SESSION_USE_NTLM: * - * Alias for the #SoupSession:use-ntlm property. (Whether or - * not to use NTLM authentication.) + * Alias for the #SoupSession:use-ntlm property, qv. **/ g_object_class_install_property ( object_class, PROP_USE_NTLM, @@ -2936,17 +3044,19 @@ soup_session_class_init (SoupSessionClass *session_class) * * File containing SSL CA certificates. * - * Deprecated: use #SoupSession:ssl-use-system-ca-file or - * #SoupSession:tls-database instead + * If the specified file does not exist or cannot be read, + * then libsoup will print a warning, and then behave as + * though it had read in a empty CA file, meaning that all SSL + * certificates will be considered invalid. + * + * Deprecated: use #SoupSession:ssl-use-system-ca-file, or + * else #SoupSession:tls-database with a #GTlsFileDatabase + * (which allows you to do explicit error handling). **/ /** * SOUP_SESSION_SSL_CA_FILE: * - * Alias for the #SoupSession:ssl-ca-file property. (File - * containing SSL CA certificates.). - * - * Deprecated: use #SoupSession:ssl-use-system-ca-file or - * #SoupSession:tls-database instead + * Alias for the #SoupSession:ssl-ca-file property, qv. **/ g_object_class_install_property ( object_class, PROP_SSL_CA_FILE, @@ -2978,6 +3088,11 @@ soup_session_class_init (SoupSessionClass *session_class) * See #SoupSession:ssl-strict for more information on how * https certificate validation is handled. * + * Note that the default value of %TRUE only applies to plain + * #SoupSessions. If you are using #SoupSessionAsync or + * #SoupSessionSync, the default value is %FALSE, for backward + * compatibility. + * * Since: 2.38 **/ g_object_class_install_property ( @@ -2985,7 +3100,7 @@ soup_session_class_init (SoupSessionClass *session_class) g_param_spec_boolean (SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, "Use system CA file", "Use the system certificate database", - FALSE, + TRUE, G_PARAM_READWRITE)); /** * SOUP_SESSION_TLS_DATABASE: @@ -3008,6 +3123,12 @@ soup_session_class_init (SoupSessionClass *session_class) * See #SoupSession:ssl-strict for more information on how * https certificate validation is handled. * + * If you are using a plain #SoupSession then + * #SoupSession:ssl-use-system-ca-file will be %TRUE by + * default, and so this property will be a copy of the system + * CA database. If you are using #SoupSessionAsync or + * #SoupSessionSync, this property will be %NULL by default. + * * Since: 2.38 **/ g_object_class_install_property ( @@ -3042,9 +3163,13 @@ soup_session_class_init (SoupSessionClass *session_class) * accept invalid certificates after giving some sort of * warning.) * - * If the session has no CA file or TLS database, then all - * certificates are always accepted, and this property has no - * effect. + * For a plain #SoupSession, if the session has no CA file or + * TLS database, and this property is %TRUE, then all + * certificates will be rejected. However, beware that the + * deprecated #SoupSession subclasses (#SoupSessionAsync and + * #SoupSessionSync) have the opposite behavior: if there is + * no CA file or TLS database, then all certificates are always + * accepted, and this property has no effect. * * Since: 2.30 */ @@ -3056,10 +3181,26 @@ soup_session_class_init (SoupSessionClass *session_class) TRUE, G_PARAM_READWRITE)); /** + * SoupSession:async-context: + * + * The #GMainContext that miscellaneous session-related + * asynchronous callbacks are invoked on. (Eg, setting + * #SoupSession:idle-timeout will add a timeout source on this + * context.) + * + * For a plain #SoupSession, this property is always set to + * the #GMainContext that is the thread-default at the time + * the session was created, and cannot be overridden. For the + * deprecated #SoupSession subclasses, the default value is + * %NULL, meaning to use the global default #GMainContext. + * + * If #SoupSession:use-thread-context is %FALSE, this context + * will also be used for asynchronous HTTP I/O. + */ + /** * SOUP_SESSION_ASYNC_CONTEXT: * - * Alias for the #SoupSession:async-context property. (The - * session's #GMainContext.) + * Alias for the #SoupSession:async-context property, qv. */ g_object_class_install_property ( object_class, PROP_ASYNC_CONTEXT, @@ -3077,13 +3218,11 @@ soup_session_class_init (SoupSessionClass *session_class) /** * SoupSession:use-thread-context: * - * If set, asynchronous operations in this session will run in + * If %TRUE (which it always is on a plain #SoupSession), + * asynchronous HTTP requests in this session will run in * whatever the thread-default #GMainContext is at the time - * they are started, rather than always occurring in a context - * fixed at the session's construction time. "Bookkeeping" - * tasks (like expiring idle connections) will happen in the - * context that was thread-default at the time the session was - * created. + * they are started, rather than always occurring in + * #SoupSession:async-context. * * Since: 2.38 */ @@ -3106,12 +3245,20 @@ soup_session_class_init (SoupSessionClass *session_class) * ones. You can call soup_session_abort() after setting this * if you want to ensure that all future connections will have * this timeout value. + * + * Note that the default value of 60 seconds only applies to + * plain #SoupSessions. If you are using #SoupSessionAsync or + * #SoupSessionSync, the default value is 0 (meaning socket I/O + * will not time out). + * + * Not to be confused with #SoupSession:idle-timeout (which is + * the length of time that idle persistent connections will be + * kept open). */ /** * SOUP_SESSION_TIMEOUT: * - * Alias for the #SoupSession:timeout property. (The timeout - * in seconds for socket I/O operations.) + * Alias for the #SoupSession:timeout property, qv. **/ g_object_class_install_property ( object_class, PROP_TIMEOUT, @@ -3225,8 +3372,7 @@ soup_session_class_init (SoupSessionClass *session_class) /** * SOUP_SESSION_ADD_FEATURE: (skip) * - * Alias for the #SoupSession:add-feature property. (Shortcut - * for calling soup_session_add_feature(). + * Alias for the #SoupSession:add-feature property, qv. * * Since: 2.24 **/ @@ -3248,8 +3394,7 @@ soup_session_class_init (SoupSessionClass *session_class) /** * SOUP_SESSION_ADD_FEATURE_BY_TYPE: (skip) * - * Alias for the #SoupSession:add-feature-by-type property. - * (Shortcut for calling soup_session_add_feature_by_type(). + * Alias for the #SoupSession:add-feature-by-type property, qv. * * Since: 2.24 **/ @@ -3271,9 +3416,8 @@ soup_session_class_init (SoupSessionClass *session_class) /** * SOUP_SESSION_REMOVE_FEATURE_BY_TYPE: (skip) * - * Alias for the #SoupSession:remove-feature-by-type - * property. (Shortcut for calling - * soup_session_remove_feature_by_type(). + * Alias for the #SoupSession:remove-feature-by-type property, + * qv. * * Since: 2.24 **/ @@ -3292,14 +3436,14 @@ soup_session_class_init (SoupSessionClass *session_class) * <literal>"dav"</literal>, than a URI of * <literal>dav://example.com/path</literal> would be treated * identically to <literal>http://example.com/path</literal>. - * If the value is %NULL, then only "http" is recognized as - * meaning "http". * - * For backward-compatibility reasons, the default value for - * this property is an array containing the single element - * <literal>"*"</literal>, a special value which means that - * any scheme except "https" is considered to be an alias for - * "http". + * In a plain #SoupSession, the default value is %NULL, + * meaning that only "http" is recognized as meaning "http". + * In #SoupSessionAsync and #SoupSessionSync, for backward + * compatibility, the default value is an array containing the + * single element <literal>"*"</literal>, a special value + * which means that any scheme except "https" is considered to + * be an alias for "http". * * See also #SoupSession:https-aliases. * @@ -3308,8 +3452,7 @@ soup_session_class_init (SoupSessionClass *session_class) /** * SOUP_SESSION_HTTP_ALIASES: * - * Alias for the #SoupSession:http-aliases property. (URI - * schemes that will be considered aliases for "http".) + * Alias for the #SoupSession:http-aliases property, qv. * * Since: 2.38 */ @@ -3335,8 +3478,7 @@ soup_session_class_init (SoupSessionClass *session_class) /** * SOUP_SESSION_HTTPS_ALIASES: * - * Alias for the #SoupSession:https-aliases property. (URI - * schemes that will be considered aliases for "https".) + * Alias for the #SoupSession:https-aliases property, qv. * * Since: 2.38 **/ diff --git a/libsoup/soup-session.h b/libsoup/soup-session.h index 40f1a8d5..a69c0717 100644 --- a/libsoup/soup-session.h +++ b/libsoup/soup-session.h @@ -81,7 +81,12 @@ GType soup_session_get_type (void); #define SOUP_SESSION_HTTP_ALIASES "http-aliases" #define SOUP_SESSION_HTTPS_ALIASES "https-aliases" -GMainContext *soup_session_get_async_context(SoupSession *session); +SOUP_AVAILABLE_IN_2_42 +SoupSession *soup_session_new (void); + +SOUP_AVAILABLE_IN_2_42 +SoupSession *soup_session_new_with_options (const char *optname1, + ...) G_GNUC_NULL_TERMINATED; void soup_session_queue_message (SoupSession *session, SoupMessage *msg, @@ -103,6 +108,8 @@ void soup_session_cancel_message (SoupSession *session, guint status_code); void soup_session_abort (SoupSession *session); +GMainContext *soup_session_get_async_context(SoupSession *session); + #ifndef LIBSOUP_DISABLE_DEPRECATED /* SOUP_AVAILABLE_IN_2_30 -- this trips up gtkdoc-scan */ SOUP_DEPRECATED_IN_2_38_FOR (soup_session_prefetch_dns) |