<?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>
      The new
      <link linkend="SoupSession--proxy-resolver"><type>"proxy-resolver"</type></link>
      property is now initialized to the default
      <link linkend="GProxyResolver"><type>GProxyResolver</type></link>,
      meaning that it will automatically use the user's system proxy
      configuration. This replaces the use of the
      <link linkend="SoupProxyResolverDefault"><type>SoupProxyResolverDefault</type></link>,
      session feature in earlier releases. You can set this property to
      <literal>NULL</literal> if you don't want to use proxies, and the
      <link linkend="SoupSession--proxy-uri"><type>"proxy-uri"</type></link>
      property still works if you want to use a single proxy for all requests.
    </para>
  </listitem>
  <listitem>
    <para>
      Every session gets a
      <link linkend="SoupContentDecoder"><type>SoupContentDecoder</type></link>
      attached to it by default, meaning that it will automatically
      handle (and request) "gzip"- and "deflate"-encoded response
      bodies.
    </para>
  </listitem>
</itemizedlist>

</refsect2>

<refsect2 id="behavior">
<title>Differences in feature behavior</title>

<para>
If you are using NTLM authentication, the new <type>SoupSession</type>
behaves slightly differently from the old session types.
</para>

<para>
First, the deprecated <link
linkend="SOUP-SESSION-USE-NTLM:CAPS"><literal>SOUP_SESSION_USE_NTLM</literal></link>
property is no longer supported. If you want to add support for NTLM
to a session, call <link
linkend="soup-session-add-feature-by-type"><function>soup_session_add_feature_by_type()</function></link>,
passing <link
linkend="SOUP-TYPE-AUTH-NTLM:CAPS"><literal>SOUP_TYPE_AUTH_NTLM</literal></link>.
</para>

<para>
Second, with the old session types, enabling NTLM would cause all
(otherwise-unauthenticated) requests to be sent with an NTLM request
in the <literal>Authorization</literal> header. That is, libsoup would
assume that all servers supported NTLM, and would attempt to begin
negotiating NTLM authentication before the server ever returned a 401
response. With the plain <type>SoupSession</type>, this no longer
happens. If you want the old behavior, you need to call <link
linkend="soup-auth-manager-use-auth"><function>soup_auth_manager_use_auth()</function></link>
for each host to "preload" the NTLM authentication:
</para>

<informalexample><programlisting>
	SoupAuthManager *auth_manager;
	SoupAuth *auth;
	SoupURI *uri;

	auth_manager = SOUP_AUTH_MANAGER (soup_session_get_feature (session, SOUP_TYPE_AUTH_MANAGER));
	auth = g_object_new (SOUP_TYPE_AUTH_NTLM, NULL);
	uri = soup_uri_new ("http://ntlm-using-host.example.com/");
	soup_auth_manager_use_auth (auth_manager, uri, auth);
	g_object_unref (auth);
	soup_uri_free (auth);
</programlisting></informalexample>

</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>
