[libsoup] SoupSession: update docs (and some semantics) for plain SoupSession



commit 967dcc28f43cd47a75b7ff2c069807edb9929400
Author: Dan Winship <danw gnome org>
Date:   Fri Dec 14 09:54:36 2012 -0500

    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.

 docs/reference/Makefile.am              |    3 +-
 docs/reference/libsoup-2.4-docs.sgml    |    1 +
 docs/reference/libsoup-2.4-sections.txt |    3 +
 docs/reference/session-porting.xml      |  163 ++++++++++++++++
 libsoup/libsoup-2.4.sym                 |    2 +
 libsoup/soup-content-decoder.c          |   23 ++-
 libsoup/soup-proxy-resolver-default.c   |    9 +
 libsoup/soup-session-async.c            |   32 ++--
 libsoup/soup-session-async.h            |    2 +
 libsoup/soup-session-sync.c             |   46 ++----
 libsoup/soup-session-sync.h             |    2 +
 libsoup/soup-session.c                  |  310 ++++++++++++++++++++++---------
 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 7e6c180..74a6d92 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 95ff9c9..f19848f 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 f359597..963cbce 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 0000000..680f75a
--- /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 7080ac5..8ec30b1 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 8aac8a8..bce78c0 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 0fc8780..ee3b102 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 c416646..b935348 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 9fb9cfe..15b0ebf 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 f6ae968..374f22b 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 845e01c..0ddda22 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 43e5f6b..0a86630 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 40f1a8d..a69c071 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)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]