<?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"?>
<chapter xmlns="http://docbook.org/ns/docbook"
    xmlns:xlink="http://www.w3.org/1999/xlink" version="5.1">
   <title>Migrating from libsoup 2</title>
    <sect2>
        <title>Removed APIs</title>
        <para>This is a list of APIs that have been removed:<itemizedlist>
                <listitem>
                    <para>XML-RPC support</para>
                </listitem>
                <listitem>
                    <para>Handling of <literal>file://</literal> and <literal>data://</literal>
                        URIs</para>
                    <para>You should use <link
linkend="GFile"><type>GFile</type></link> for the former and <link
linkend="soup-uri-decode-data-uri"><function>soup_uri_decode_data_uri()</function></link> for the
                        latter.</para>
                </listitem>
                <listitem>
                    <para>Define aliases for property names</para>
                    <para>You must use the string name of properties directly which works in libsoup
                        2 already.</para>
                </listitem>
                <listitem>
                    <para><literal>SoupSession:add-feature</literal> and <literal>SoupSession:add-feature-by-type</literal></para>
                    <para>You must call <link linkend="soup-session-add-feature"><function>soup_session_add_feature()</function></link> and
                        <link linkend="soup-session-add-feature-by-type"><function>soup_session_add_feature_by_type()</function></link> directly.</para>
                </listitem>
                <listitem>
                    <para><type>SoupRequest</type></para>
                    <para>You should use <link linkend="soup-session-send"><function>soup_session_send()</function></link> or
                        <link linkend="soup-session-send-async"><function>soup_session_send_async()</function></link> methods.</para>
                </listitem>
                <listitem>
                    <para><type>SoupAddress</type> has been replaced with <link linkend="GInetAddress"><type>GInetAddress</type></link>
                        and <link linkend="GNetworkAddress"><type>GNetworkAddress</type></link></para>
                </listitem>
                <listitem>
                    <para><type>SoupSocket</type> has been removed</para>
                </listitem>
                <listitem>
                    <para><type>SoupProxyResolverDefault</type> is replaced by
                        <link linkend="g-proxy-resolver-get-default"><function>g_proxy_resolver_get_default()</function></link></para>
                </listitem>
                <listitem>
                    <para><type>SoupBuffer</type> has been replaced by <link linkend="GBytes"><type>GBytes</type></link> and <link linkend="GByteArray"><type>GByteArray</type></link></para>
                </listitem>
                <listitem>
                    <para><type>SoupDate</type> has been replaced by <link linkend="GDateTime"><type>GDateTime</type></link></para>
                </listitem>
                <listitem>
                    <para><literal>SoupSession:ssl-strict</literal> has been removed in favor of using the <link linkend="SoupMessage-accept-certificate"><literal>SoupMessage:accept-certificate</literal></link> signal.</para>
                </listitem>
                <listitem>
                    <para><literal>soup_session_cancel_message()</literal> has been removed</para>
                    <para>Instead you pass a <link linkend="GCancellable"><type>GCancellable</type></link> to APIs and call <link linkend="g_cancellable_cancel"><function>g_cancellable_cancel()</function></link>.</para>
                </listitem>
            </itemizedlist></para>
    </sect2>
  <sect2>
    <title>Moved authenticate signal</title>
        <para>The <literal>SoupSession::authenticate</literal> signal has been replaced by
            <link linkend="SoupMessage-authenticate"><literal>SoupMessage::authenticate</literal></link>. It now allows returning <literal>TRUE</literal> to signifiy
            if you will handle authentication which allows for asynchronous handling.</para>
  </sect2>
  <sect2>
        <title>Structs are private</title>
        <para>You can no longer directly access various structs such as SoupMessage. These are now
            accessed by getters and setters. See below for direct conversions:<informaltable>
                <tgroup cols="2">
                    <colspec colname="c1" colnum="1" colwidth="1*"/>
                    <colspec colname="c2" colnum="2" colwidth="1*"/>
                    <thead>
                        <row>
                            <entry>Struct field</entry>
                            <entry>Getter/Setter function</entry>
                        </row>
                    </thead>
                    <tbody>
                        <row>
                            <entry>SoupMessage.method</entry>
                            <entry><link linkend="soup-message-get-method"><function>soup_message_get_method()</function></link></entry>
                        </row>
                        <row>
                            <entry>SoupMessage.status_code</entry>
                            <entry><link linkend="soup-message-get-status"><function>soup_message_get_status()</function></link></entry>
                        </row>
                        <row>
                            <entry>SoupMessage.reason_phrase</entry>
                            <entry><link linkend="soup-message-get-reason-phrase"><function>soup_message_get_reason_phrase()</function></link></entry>
                        </row>
                        <row>
                            <entry>SoupMessage.uri</entry>
                            <entry><link linkend="soup-message-get-uri"><function>soup_message_get_uri()</function></link>, <link linkend="soup-message-set-uri"><function>soup_message_set_uri()</function></link></entry>
                        </row>
                        <row>
                            <entry>SoupMessage.request_headers</entry>
                            <entry><link linkend="soup-message-get-request-headers"><function>soup_message_get_request_headers()</function></link></entry>
                        </row>
                        <row>
                            <entry>SoupMessage.response_headers</entry>
                            <entry><link linkend="soup-message-get-response-headers"><function>soup_message_get_response_headers()</function></link></entry>
                        </row>
                        <row>
                            <entry>SoupMessage.request_body</entry>
                            <entry><link linkend="soup-message-set-request-body"><function>soup_message_set_request_body()</function></link>,
                                <link linkend="soup-message-set-request-body-from-bytes"><function>soup_message_set_request_body_from_bytes()</function></link></entry>
                        </row>
                        <row>
                            <entry>SoupMessage.response_body</entry>
                            <entry>See <link linkend="io-stream-based">section on IO</link> </entry>
                        </row>
                    </tbody>
                </tgroup>
            </informaltable></para>
        <para>Similar struct changes exist for <link linkend="SoupCookie"><type>SoupCookie</type></link> but have very straightforward
            replacements.</para>
    </sect2>
    <sect2>
        <title>URI type changed</title>
        <para>The <type>SoupURI</type> type has been replaced with the <link linkend="GUri"><type>GUri</type></link> type which has some
            implications.</para>
        <para>Creating a <link linkend="GUri"><type>GUri</type></link> is generally as simple as <code>g_uri_parse (uri,
                SOUP_HTTP_URI_FLAGS, NULL)</code>. You may want to add
                <literal>G_URI_FLAGS_PARSE_RELAXED</literal> to accept input that used to be
            considered valid.</para>
        <para>Note that unlike <type>SoupURI</type> <link linkend="GUri"><type>GUri</type></link> is an immutable type so you cannot change the contents
            of one after it has been constructed. We provide <link linkend="soup_copy_uri"><function>soup_copy_uri()</function></link> to aid in modifying them.</para>
        <para>The equivalent behavior to <code>soup_uri_to_string (uri, FALSE)</code> is
                <code>g_uri_to_string_partial (uri, G_URI_HIDE_PASSWORD)</code>.</para>
        <para>Since GUri does not provide any function to check for equality
                <link linkend="soup_uri_equal"><function>soup_uri_equal()</function></link> still exists.</para>
        <para>Sending a <literal>OPTIONS</literal> message with a path of <literal>*</literal> is no
            longer a valid URI and has been replaced with SoupMessage:options-ping.</para>
    </sect2>
    <sect2>
        <title>Status codes no longer used for internal errors</title>
        <para>Previously <link linkend="SoupStatus"><type>SoupStatus</type></link> was used to hold libsoup errors
                (<code>SOUP_STATUS_IS_TRANSPORT_ERROR()</code>). Now all of these errors are
            propagated up through the normal <link linkend="GError"><type>GError</type></link> method on the various APIs to send messages.
            Here is a mapping chart between the status codes and new errors:<informaltable>
                <tgroup cols="2">
                    <colspec colname="c1" colnum="1" colwidth="1*"/>
                    <colspec colname="newCol4" colnum="2" colwidth="1*"/>
                    <thead>
                        <row>
                            <entry>Old Status Codes</entry>
                            <entry>New GError</entry>
                        </row>
                    </thead>
                    <tbody>
                        <row>
                            <entry><code>SOUP_STATUS_CANCELLED</code></entry>
                            <entry><link linkend="G-IO-ERROR-CANCELLED:CAPS"><code>G_IO_ERROR_CANCELLED</code></link></entry>
                        </row>
                        <row>
                            <entry><code>SOUP_STATUS_MALFORMED</code></entry>
                            <entry><link linkend="SOUP-SESSION-ERROR-PARSING:CAPS"><code>SOUP_SESSION_ERROR_PARSING</code></link>, <link linkend="SOUP-SESSION-ERROR-ENCODING:CAPS"><code>SOUP_SESSION_ERROR_ENCODING</code></link></entry>
                        </row>
                        <row>
                            <entry><code>SOUP_STATUS_TOO_MANY_REDIRECTS</code></entry>
                            <entry><link linkend="SOUP-SESSION-ERROR-TOO-MANY-REDIRECTS:CAPS"><code>SOUP_SESSION_ERROR_TOO_MANY_REDIRECTS</code></link></entry>
                        </row>
                    </tbody>
                </tgroup>
            </informaltable></para>
    </sect2>
    <sect2 id="io-stream-based">
        <title>All IO is now GIOStream-based</title>
        <para>Previously there were ways to allow libsoup to read data into buffers and for you to
            read from those buffers such as <literal>SoupMessage:response-body</literal>,
            <literal>SoupMessage:response-body-data</literal>, and <literal>SoupMessage::got-chunk</literal>.</para>
        <para>libsoup no longer stores a buffer of data for you to read from and instead it returns
            a <link linkend="GInputStream"><type>GInputStream</type></link> which you read from using normal GIO APIs.</para>
        <para>If you want to simply request a buffer and nothing more you can use the
                <link linkend="soup_session_send_and_read"><function>soup_session_send_and_read()</function></link> or
                <link linkend="soup_session_send_and_read_async"><function>soup_session_send_and_read_async()</function></link> APIs.</para>
        <para>This also applies to writing data where you can set a <link linkend="GInputStream"><type>GInputStream</type></link> using
                <link linkend="soup_message_set_request_body"><function>soup_message_set_request_body()</function></link> or use the convenience API
                <link linkend="soup_message_set_request_body_from_bytes"><function>soup_message_set_request_body_from_bytes()</function></link> to use a GBytes
            buffer.</para>
    </sect2>
    <sect2 id="threading">
        <title>Clarification on thread-safety</title>
        <para>In libsoup 2 there was an attempt at making various APIs of the library thread-safe. However this was never well tested, maintained, or documented.</para>
        <para>In libsoup 3 it now behaves in line with other GObject libraries. Once you create a <link linkend="SoupSession"><type>SoupSession</type></link> all usage of that
            session must happen on the same thread. You may create seperate sessions per thread but in most use-cases you should be using the async APIs which handle non-blocking IO for you.</para>
    </sect2>
</chapter>

