<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="http://docbook.org/xml/5.1/rng/docbook.rng" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="http://docbook.org/xml/5.1/sch/docbook.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<sect1 xmlns="http://docbook.org/ns/docbook" 
    xmlns:xlink="http://www.w3.org/1999/xlink" version="5.1">
  <title>Advanced Usage</title>
  <sect2>
    <title>Customizing Session Options</title>
    <para>When you create the session with <link linkend="soup-session-new-with-options"><function>soup_session_new_with_options()</function></link>,
    you can specify various additional options. See the <link
linkend="SoupSession"><type>SoupSession</type> documentation</link> for more details but these may be interesting:
    <link linkend="SoupSession:max-conns"><literal>SoupSession:max-conns</literal></link> and <link linkend="SoupSession:max-conns-per-host"><literal>SoupSession:max-conns-per-host</literal></link>,
    <link linkend="SoupSession:user-agent"><literal>SoupSession:user-agent</literal></link>, <link linkend="SoupSession:timeout"><literal>SoupSession:timeout</literal></link>,
    <link linkend="SoupSession:accept-language"><literal>SoupSession:accept-language</literal></link> and <link linkend="SoupSession:accept-language-auto"><literal>SoupSession:accept-language-auto</literal></link></para>
  </sect2>
  <sect2>
    <title>Adding Session Features</title>
	<para>Additional session functionality is provided as <link
linkend="SoupSessionFeature"><type>SoupSessionFeature</type></link>s,
which can be added to or removed from a session.</para>

	<para>One such feature is <link linkend="SoupContentDecoder"><type>SoupContentDecoder</type></link>
    which is added by default. This advertises to servers that the
client supports compression, and automatically decompresses compressed
responses.
</para>
<para>
Some other available features that you can add include:
</para>

<variablelist>
    <varlistentry>
	<term><link linkend="SoupLogger"><type>SoupLogger</type></link></term>
	<listitem><para>
	    A debugging aid, which logs all of libsoup's HTTP traffic
	    to <literal>stdout</literal> (or another place you specify).
	</para></listitem>
    </varlistentry>
    <varlistentry>
	<term>
	    <link linkend="SoupCookieJar"><type>SoupCookieJar</type></link>,
	    <link linkend="SoupCookieJarText"><type>SoupCookieJarText</type></link>,
	    and <link linkend="SoupCookieJarDB"><type>SoupCookieJarDB</type></link>
	</term>
	<listitem><para>
	    Support for HTTP cookies. <type>SoupCookieJar</type>
	    provides non-persistent cookie storage, while
	    <type>SoupCookieJarText</type> uses a text file to keep
	    track of cookies between sessions, and
	    <type>SoupCookieJarDB</type> uses a
	    <application>SQLite</application> database.
	</para></listitem>
    </varlistentry>
    <varlistentry>
	<term><link linkend="SoupContentSniffer"><type>SoupContentSniffer</type></link></term>
	<listitem><para>
	    Uses the HTML5 sniffing rules to attempt to
	    determine the Content-Type of a response when the
	    server does not identify the Content-Type, or appears to
	    have provided an incorrect one. 
	</para></listitem>
    </varlistentry>
</variablelist>

<para>
Use the <link
linkend="soup-session-add-feature-by-type"><function>soup_session_add_feature_by_type()</function></link> function to
add features that don't require any configuration (such as <link
linkend="SoupContentSniffer"><type>SoupContentSniffer</type></link>),
and the <link
linkend="soup-session-add-feature"><function>soup_session_add_feature()</function></link>function to add features that must be
constructed first (such as <link
linkend="SoupLogger"><type>SoupLogger</type></link>). For example, an
application might do something like the following:
</para>

<informalexample><programlisting><![CDATA[session = soup_session_new ();
soup_session_add_feature_by_type (session, SOUP_TYPE_CONTENT_SNIFFER);

if (debug_level) {
    SoupLogger *logger = soup_logger_new (debug_level);
    soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger));
    g_object_unref (logger);
}]]></programlisting></informalexample>

    <para>You can also remove features by calling <link
linkend="soup-session-remove-feature"><function>soup_session_remove_feature()</function></link> or
<link
linkend="soup-session-remove-feature-by-type"><function>soup_session_remove_feature_by_type()</function></link></para>.

    <para>See the <link linkend="additional-features">Additional Features</link> section for other features.
    </para>
  </sect2>
  <sect2>
    <title>Using a proxy</title>
    <para>By default libsoup tries to respect the default proxy (as best as <link
linkend="g-proxy-resolver-get-default"><function>g_proxy_resolver_get_default()</function></link> knows), however you can set
    a custom one or disable it outright using the <link linkend="SoupSession:proxy-resolver"><literal>SoupSession:proxy-resolver</literal></link>
    property. For example:</para>
<informalexample><programlisting><![CDATA[
{
    GProxyResolver *resolver = g_simple_proxy_resolver_new ("https://my-proxy-example.org", NULL);
    SoupSession *session = soup_session_new_with_options ("proxy-resolver", resolver, NULL);
    g_object_unref (resolver);
}]]>
</programlisting></informalexample>
  </sect2>
  <sect2>
    <title>Using the SoupMessage API</title>
    <para>The <type>SoupMessage</type> type contains all the state for a request and response pair that you send and recieve
    to a server. For many more complex tasks you will have to create one of these and send it with the <function>soup_session_send()</function>
    function. For example this sends a request with the <literal>HEAD</literal> method:
    </para>
<informalexample><programlisting><![CDATA[
{
    SoupSession *session = soup_session_new ();
    SoupMessage *msg = soup_message_new (SOUP_METHOD_HEAD, "https://example.org");

    // This allows you to also customize the request headers:
    SoupMessageHeaders *request_headers = soup_message_get_request_headers (msg);
    soup_message_headers_replace (request_headers, "Foo", "Bar");

    GInputStream *in_stream = soup_session_send (session, msg, NULL, NULL);
    if (in_stream) {
        g_print ("Message was sent and recived a response of %u (%s)\n",
                 soup_message_get_status (msg), soup_message_get_reason_phrase (msg));
        // You can also inspect the response headers via soup_message_get_response_headers();
        g_object_unref (in_stream);
    }

    g_object_unref (msg);
    g_object_unref (session);
}]]>
</programlisting></informalexample>
  </sect2>
  <sect2>
    <title>Handling authentication</title>
<informalexample><programlisting><![CDATA[
static gboolean
authenticate_callback (SoupMessage *msg, SoupAuth *auth, gboolean retrying, gpointer user_data)
{
    if (retrying) {
        // Maybe don't try again if our password failed
        return FALSE;
    }

    soup_auth_authenticate (auth, "username", "password");

    // Returning TRUE means we have or *will* handle it.
    // soup_auth_authenticate() or soup_auth_cancel() can be called later
    // for example after showing a prompt to the user or loading the password
    // from a keyring.
    return TRUE;
}

int main (int argc, char **argv)
{
    SoupSession *session = soup_session_new ();
    SoupMessage *msg = soup_message_new (SOUP_METHOD_GET, "https://example.org");
    g_signal_connect (msg, "authenticate", G_CALLBACK (authenticate_callback), NULL);
    GInputStream *in_stream = soup_session_send (session, msg, NULL, NULL);

    if (in_stream) {
        g_object_unref (in_stream);
    }

    return 0;
}]]>
</programlisting></informalexample>
  </sect2>
</sect1>