summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2013-12-11 11:44:31 +0100
committerDan Winship <danw@gnome.org>2013-12-11 11:44:31 +0100
commitc2d0f8d19eb25f21838a1ddfd4baab1c0218ac9c (patch)
treee93807bee7aa35b9792922d6e1649a4860f3c800
parentdd3e2f4d9be661a5fae96c81618fb25c438916da (diff)
downloadlibsoup-c2d0f8d19eb25f21838a1ddfd4baab1c0218ac9c.tar.gz
docs: Update client-side tutorial for 2.42, document request APIs
-rw-r--r--docs/reference/Makefile.am1
-rw-r--r--docs/reference/client-howto.xml406
-rw-r--r--docs/reference/libsoup-2.4-docs.sgml1
-rw-r--r--docs/reference/libsoup-2.4-sections.txt1
-rw-r--r--docs/reference/request-howto.xml184
5 files changed, 391 insertions, 202 deletions
diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am
index 36e77006..a11ce395 100644
--- a/docs/reference/Makefile.am
+++ b/docs/reference/Makefile.am
@@ -53,6 +53,7 @@ HTML_IMAGES =
content_files = \
build-howto.xml \
client-howto.xml \
+ request-howto.xml \
server-howto.xml \
session-porting.xml
diff --git a/docs/reference/client-howto.xml b/docs/reference/client-howto.xml
index 3cf5a4e1..d4d0f37b 100644
--- a/docs/reference/client-howto.xml
+++ b/docs/reference/client-howto.xml
@@ -3,16 +3,26 @@
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
<refentry id="libsoup-client-howto">
<refmeta>
-<refentrytitle>Soup Client Basics</refentrytitle>
+<refentrytitle>libsoup Client Basics</refentrytitle>
<manvolnum>3</manvolnum>
<refmiscinfo>LIBSOUP Library</refmiscinfo>
</refmeta>
<refnamediv>
-<refname>Soup Client Basics</refname><refpurpose>Client-side tutorial</refpurpose>
+<refname>libsoup Client Basics</refname><refpurpose>Client-side tutorial</refpurpose>
</refnamediv>
<refsect2>
+<para>
+This section explains how to use <application>libsoup</application> as
+an HTTP client using several new APIs introduced in version 2.42. If
+you want to be compatible with older versions of
+<application>libsoup</application>, consult the documentation for that
+version.
+</para>
+</refsect2>
+
+<refsect2>
<title>Creating a <type>SoupSession</type></title>
<para>
@@ -24,35 +34,8 @@ authentication information, etc.
</para>
<para>
-There are two subclasses of <link
-linkend="SoupSession"><type>SoupSession</type></link> that you can use, with
-slightly different behavior:
-</para>
-
-<itemizedlist>
- <listitem><para>
- <link linkend="SoupSessionAsync"><type>SoupSessionAsync</type></link>,
- which uses callbacks and the glib main loop to provide
- asynchronous I/O.
- </para></listitem>
-
- <listitem><para>
- <link linkend="SoupSessionSync"><type>SoupSessionSync</type></link>,
- which uses blocking I/O rather than callbacks, making it more
- suitable for threaded applications.
- </para></listitem>
-</itemizedlist>
-
-<para>
-If you want to do a mix of mainloop-based and blocking I/O, you will
-need to create two different session objects.
-</para>
-
-<para>
-When you create the session (with <link
-linkend="soup-session-async-new-with-options"><function>soup_session_async_new_with_options</function></link>
-or <link
-linkend="soup-session-sync-new-with-options"><function>soup_session_sync_new_with_options</function></link>),
+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:
</para>
@@ -64,7 +47,7 @@ you can specify various additional options:
the session will have open at one time. (Once it reaches
this limit, it will either close idle connections, or
wait for existing connections to free up before starting
- new requests.)
+ new requests.) The default value is 10.
</para></listitem>
</varlistentry>
<varlistentry>
@@ -72,44 +55,61 @@ you can specify various additional options:
<listitem><para>
Allows you to set the maximum total number of connections
the session will have open <emphasis>to a single
- host</emphasis> at one time.
+ host</emphasis> at one time. The default value is 2.
</para></listitem>
</varlistentry>
<varlistentry>
- <term><link linkend="SOUP-SESSION-USE-NTLM:CAPS"><literal>SOUP_SESSION_USE_NTLM</literal></link></term>
+ <term><link linkend="SOUP-SESSION-USER-AGENT:CAPS"><literal>SOUP_SESSION_USER_AGENT</literal></link></term>
<listitem><para>
- If <literal>TRUE</literal>, then Microsoft NTLM
- authentication will be used if available (and will be
- preferred to HTTP Basic or Digest authentication).
- If <literal>FALSE</literal>, NTLM authentication won't be
- used, even if it's the only authentication type available.
- (NTLM works differently from the standard HTTP
- authentication types, so it needs to be handled
- specially.)
+ Allows you to set a User-Agent string that will be sent
+ on all outgoing requests.
</para></listitem>
</varlistentry>
<varlistentry>
- <term><link linkend="SOUP-SESSION-SSL-CA-FILE:CAPS"><literal>SOUP_SESSION_SSL_CA_FILE</literal></link></term>
+ <term><link linkend="SOUP-SESSION-ACCEPT-LANGUAGE:CAPS"><literal>SOUP_SESSION_ACCEPT_LANGUAGE</literal></link>
+ and <link linkend="SOUP-SESSION-ACCEPT-LANGUAGE-AUTO:CAPS"><literal>SOUP_SESSION_ACCEPT_LANGUAGE_AUTO</literal></link></term>
<listitem><para>
- Points to a file containing certificates for recognized
- SSL Certificate Authorities. If this is set, then HTTPS
- connections will be checked against these authorities, and
- rejected if they can't be verified. (Otherwise all SSL
- certificates will be accepted automatically.)
+ Allow you to set an Accept-Language header on all outgoing
+ requests. <literal>SOUP_SESSION_ACCEPT_LANGUAGE</literal>
+ takes a list of language tags to use, while
+ <literal>SOUP_SESSION_ACCEPT_LANGUAGE_AUTO</literal>
+ automatically generates the list from the user's locale
+ settings.
</para></listitem>
</varlistentry>
<varlistentry>
- <term><link linkend="SOUP-SESSION-ASYNC-CONTEXT:CAPS"><literal>SOUP_SESSION_ASYNC_CONTEXT</literal></link></term>
+ <term><link linkend="SOUP-SESSION-HTTP-ALIASES:CAPS"><literal>SOUP_SESSION_HTTP_ALIASES</literal></link>
+ and <link linkend="SOUP-SESSION-HTTPS-ALIASES:CAPS"><literal>SOUP_SESSION_HTTPS_ALIASES</literal></link></term>
<listitem><para>
- A <link
- linkend="GMainContext"><type>GMainContext</type></link>
- which the session will use for asynchronous operations.
- This can be set if you want to use a
- <type>SoupSessionAsync</type> in a thread other than the
- main thread.
+ Allow you to tell the session to recognize additional URI
+ schemes as aliases for "<literal>http</literal>" or
+ <literal>https</literal>. You can set this if you are
+ using URIs with schemes like "<literal>dav</literal>" or
+ "<literal>webcal</literal>" (and in particular, you need
+ to set this if the server you are talking to might return
+ redirects with such a scheme).
</para></listitem>
</varlistentry>
<varlistentry>
+ <term><link linkend="SOUP-SESSION-PROXY-RESOLVER:CAPS"><literal>SOUP_SESSION_PROXY_RESOLVER</literal></link> and <link linkend="SOUP-SESSION-PROXY-URI:CAPS"><literal>SOUP_SESSION_PROXY_URI</literal></link></term>
+ <listitem>
+ <para>
+ <link linkend="SOUP-SESSION-PROXY-RESOLVER:CAPS"><literal>SOUP_SESSION_PROXY_RESOLVER</literal></link>
+ specifies a <link
+ linkend="GProxyResolver"><type>GProxyResolver</type></link>
+ to use to determine the HTTP proxies to use. By default,
+ this is set to the resolver returned by <link
+ linkend="g-proxy-resolver-get-default"><function>g_proxy_resolver_get_default</function></link>,
+ so you do not need to set it yourself.
+ </para>
+ <para>
+ Alternatively, if you want all requests to go through a
+ single proxy, you can set <link
+ linkend="SOUP-SESSION-PROXY-URI:CAPS"><literal>SOUP_SESSION_PROXY_URI</literal></link>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><link linkend="SOUP-SESSION-ADD-FEATURE:CAPS"><literal>SOUP_SESSION_ADD_FEATURE</literal></link> and <link linkend="SOUP-SESSION-ADD-FEATURE-BY-TYPE:CAPS"><literal>SOUP_SESSION_ADD_FEATURE_BY_TYPE</literal></link></term>
<listitem><para>
These allow you to specify <link
@@ -121,10 +121,15 @@ you can specify various additional options:
</variablelist>
<para>
+Other properties are also available; see the <link
+linked="SoupSession"><type>SoupSession</type></link> documentation for
+more details.
+</para>
+
+<para>
If you don't need to specify any options, you can just use <link
-linkend="soup-session-async-new"><function>soup_session_async_new</function></link> or
-<link linkend="soup-session-sync-new"><function>soup_session_sync_new</function></link>,
-which take no arguments.
+linkend="soup-session-new"><function>soup_session_new</function></link>,
+which takes no arguments.
</para>
</refsect2>
@@ -143,8 +148,19 @@ options at session-construction-time, or afterward via the <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>
-functions. Some of the features available in
-<application>libsoup</application> are:
+functions.
+</para>
+
+<para>
+A <link
+linkend="SoupContentDecoder"><type>SoupContentDecoder</type></link> is
+added for you automatically. 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>
@@ -156,26 +172,27 @@ functions. Some of the features available in
</para></listitem>
</varlistentry>
<varlistentry>
- <term><link linkend="SoupCookieJar"><type>SoupCookieJar</type></link> and <link linkend="SoupCookieJarText"><type>SoupCookieJarText</type></link></term>
+ <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.
- </para></listitem>
- </varlistentry>
- <varlistentry>
- <term><link linkend="SoupProxyResolverDefault"><type>SoupProxyResolverDefault</type></link></term>
- <listitem><para>
- A feature that automatically determines the correct HTTP
- proxy to use for requests.
+ track of cookies between sessions, and
+ <type>SoupCookieJarDB</type> uses a
+ <application>SQLite</application> database.
</para></listitem>
</varlistentry>
<varlistentry>
- <term><link linkend="SoupCookieJarDB"><type>SoupCookieJarDB</type></link></term>
+ <term><link linkend="SoupContentSniffer"><type>SoupContentSniffer</type></link></term>
<listitem><para>
- Support for HTTP cookies stored in an
- <application>SQLite</application> database.
+ 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>
@@ -183,7 +200,7 @@ functions. Some of the features available in
<para>
Use the "add_feature_by_type" property/function to add features that
don't require any configuration (such as <link
-linkend="SoupProxyResolverDefault"><type>SoupProxyResolverDefault</type></link>),
+linkend="SoupContentSniffer"><type>SoupContentSniffer</type></link>),
and the "add_feature" property/function to add features that must be
constructed first (such as <link
linkend="SoupLogger"><type>SoupLogger</type></link>). For example, an
@@ -191,11 +208,10 @@ application might do something like the following:
</para>
<informalexample><programlisting>
- session = soup_session_async_new_with_options (
-#ifdef HAVE_LIBSOUP_GNOME
- SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_PROXY_RESOLVER_DEFAULT,
-#endif
+ session = soup_session_new_with_options (
+ SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_CONTENT_SNIFFER,
NULL);
+
if (debug_level) {
SoupLogger *logger;
@@ -211,7 +227,7 @@ application might do something like the following:
<title>Creating and Sending SoupMessages</title>
<para>
-Once you have a session, you do HTTP traffic using <link
+Once you have a session, you send HTTP requests using <link
linkend="SoupMessage"><type>SoupMessage</type></link>. In the simplest
case, you only need to create the message and it's ready to send:
</para>
@@ -235,7 +251,7 @@ request headers and body of the message:
msg = soup_message_new ("POST", "http://example.com/form.cgi");
soup_message_set_request (msg, "application/x-www-form-urlencoded",
- SOUP_MEMORY_COPY, formdata, strlen (formdata));
+ SOUP_MEMORY_COPY, formdata, strlen (formdata));
soup_message_headers_append (msg->request_headers, "Referer", referring_url);
</programlisting></informalexample>
@@ -262,28 +278,56 @@ flag.
<para>
To send a message and wait for the response, use <link
-linkend="soup-session-send-message"><function>soup_session_send_message</function></link>:
+linkend="soup-session-send"><function>soup_session_send</function></link>:
</para>
<informalexample><programlisting>
- guint status;
+ GInputStream *stream;
+ GError *error = NULL;
- status = soup_session_send_message (session, msg);
+ stream = soup_session_send (session, msg, cancellable, &amp;error);
</programlisting></informalexample>
<para>
-(If you use <function>soup_session_send_message</function> with a
-<link linkend="SoupSessionAsync"><type>SoupSessionAsync</type></link>,
-it will run the main loop itself until the message is complete.)
+At the point when <function>soup_session_send</function> returns, the
+request will have been sent, and the response headers read back in;
+you can examine the message's <structfield>status_code</structfield>,
+<structfield>reason_phrase</structfield>, and
+<structfield>response_headers</structfield> fields to see the response
+metadata. To get the response body, read from the returned <link
+linkend="GInputStream"><type>GInputStream</type></link>, and close it
+when you are done.
</para>
<para>
-The return value from <function>soup_session_send_message</function>
-is a <link linkend="libsoup-2.4-soup-status">libsoup status code</link>,
-indicating either a transport error that prevented the message from
-being sent, or the HTTP status that was returned by the server in
-response to the message. (The status is also available as
-<literal>msg->status_code</literal>.)
+Note that <function>soup_session_send</function> only returns an error
+if a transport-level problem occurs (eg, it could not connect to the
+host, or the request was cancelled). Use the message's
+<structfield>status_code</structfield> field to determine whether the
+request was successful or not at the HTTP level (ie, "<literal>200
+OK</literal>" vs "<literal>401 Bad Request</literal>").
+</para>
+
+<para>
+If you would prefer to have <application>libsoup</application> gather
+the response body for you and then return it all at once, you can use
+the older
+<link linkend="soup-session-send-message"><function>soup_session_send_message</function></link>
+API:
+</para>
+
+<informalexample><programlisting>
+ guint status;
+
+ status = soup_session_send_message (session, msg);
+</programlisting></informalexample>
+
+<para>
+In this case, the response body will be available in the message's
+<structfield>response_body</structfield> field, and transport-level
+errors will be indicated in the <structfield>status_code</structfield>
+field via special pseudo-HTTP-status codes like <link
+linkend="SOUP-STATUS-CANT-CONNECT:CAPS"><literal>SOUP_STATUS_CANT_CONNECT</literal></link>.
</para>
</refsect3>
@@ -293,51 +337,63 @@ response to the message. (The status is also available as
<para>
To send a message asynchronously, use <link
-linkend="soup-session-queue-message"><function>soup_session_queue_message</function></link>:
+linkend="soup-session-send-async"><function>soup_session_send_async</function></link>:
</para>
<informalexample><programlisting>
+{
...
- soup_session_queue_message (session, msg, my_callback, my_callback_data);
+ soup_session_send_async (session, msg, cancellable, my_callback, my_callback_data);
...
}
static void
-my_callback (SoupSession *session, SoupMessage *msg, gpointer user_data)
+my_callback (GObject *object, GAsyncResult *result, gpointer user_data)
{
- /* Handle the response here */
+ GInputStream *stream;
+ GError *error = NULL;
+
+ stream = soup_session_send_finish (SOUP_SESSION (object), result, &amp;error);
+ ...
}
</programlisting></informalexample>
<para>
The message will be added to the session's queue, and eventually (when
control is returned back to the main loop), it will be sent and the
-response be will be read. When the message is complete,
-<literal>callback</literal> will be invoked, along with the data you
-passed to <function>soup_session_queue_message</function>.
+response be will be read. When the message has been sent, and its
+headers received, the callback will be invoked, in the standard
+<link linkend="GAsyncReadyCallback"><type>GAsyncReadyCallback</type></link>
+style.
</para>
<para>
-<link
-linkend="soup-session-queue-message"><function>soup_session_queue_message</function></link>
-steals a reference to the message object, and unrefs it after the last
-callback is invoked on it. So in the usual case, messages sent
-asynchronously will be automatically freed for you without you needing
-to do anything. (Of course, this wouldn't work when using the synchronous
-API, since you will usually need continue working with the message
-after calling <link
-linkend="soup-session-send-message"><function>soup_session_send_message</function></link>,
-so in that case, you must unref it explicitly when you are done with
-it.)
+As with synchronous sending, there is also an alternate API, <link
+linkend="soup-session-queue-message"><function>soup_session_queue_message</function></link>,
+in which your callback is not invoked until the response has been
+completely read:
</para>
+<informalexample><programlisting>
+{
+ ...
+ soup_session_queue_message (session, msg, my_callback, my_callback_data);
+ ...
+}
+
+static void
+my_callback (SoupSession *session, SoupMessage *msg, gpointer user_data)
+{
+ /* msg->response_body contains the response */
+}
+</programlisting></informalexample>
+
<para>
-(If you use <link
+<link
linkend="soup-session-queue-message"><function>soup_session_queue_message</function></link>
-with a <link
-linkend="SoupSessionSync"><type>SoupSessionSync</type></link>, the
-message will be sent in another thread, with the callback eventually
-being invoked in the session's <link linkend="SOUP-SESSION-ASYNC-CONTEXT:CAPS"><literal>SOUP_SESSION_ASYNC_CONTEXT</literal></link>.)
+is slightly unusual in that it steals a reference to the message
+object, and unrefs it after the last callback is invoked on it. So
+when using this API, you should not unref the message yourself.
</para>
</refsect3>
@@ -348,19 +404,17 @@ being invoked in the session's <link linkend="SOUP-SESSION-ASYNC-CONTEXT:CAPS"><
<title>Processing the Response</title>
<para>
-Once you have received the response from the server, synchronously or
-asynchronously, you can look at the response fields in the
-<literal>SoupMessage</literal> to decide what to do next. The
-<structfield>status_code</structfield> and
+Once you have received the initial response from the server,
+synchronously or asynchronously, streaming or not, you can look at the
+response fields in the <literal>SoupMessage</literal> to decide what
+to do next. The <structfield>status_code</structfield> and
<structfield>reason_phrase</structfield> fields contain the numeric
status and textual status response from the server.
<structfield>response_headers</structfield> contains the response
headers, which you can investigate using <link
-linkend="soup-message-headers-get"><function>soup_message_headers_get</function></link> and
-<link
- linkend="soup-message-headers-foreach"><function>soup_message_headers_foreach</function></link>.
-The response body (if any) is in the
-<structfield>response_body</structfield> field.
+linkend="soup-message-headers-get"><function>soup_message_headers_get</function></link>
+and <link
+linkend="soup-message-headers-foreach"><function>soup_message_headers_foreach</function></link>.
</para>
<para>
@@ -383,41 +437,6 @@ headers much better than functions like
</refsect2>
<refsect2>
-<title>Intermediate/Automatic Processing</title>
-
-<para>
-You can also connect to various <type>SoupMessage</type> signals to do
-processing at intermediate stages of HTTP I/O. Eg, the <link
-linkend="SoupMessage-got-chunk"><literal>got-chunk</literal></link>
-signal is emitted as each piece of the response body is read (allowing
-you to provide progress information when receiving a large response,
-for example). <type>SoupMessage</type> also provides two convenience
-methods, <link
-linkend="soup-message-add-header-handler"><function>soup_message_add_header_handler</function></link>,
-and <link
-linkend="soup-message-add-status-code-handler"><function>soup_message_add_status_code_handler</function></link>,
-which allow you to set up a signal handler that will only be invoked
-for messages with certain response headers or status codes.
-<type>SoupSession</type> uses this internally to handle authentication
-and redirection.
-</para>
-
-<para>
-When using the synchronous API, the callbacks and signal handlers will
-be invoked during the call to <link
-linkend="soup-session-send-message"><function>soup_session_send_message</function></link>.
-</para>
-
-<para>
-To automatically set up handlers on all messages sent via a session,
-you can connect to the session's <link
-linkend="SoupSession-request-started"><literal>request_started</literal></link>
-signal, and add handlers to each message from there.
-</para>
-
-</refsect2>
-
-<refsect2>
<title>Handling Authentication</title>
<para>
@@ -467,38 +486,39 @@ linkend="soup-session-unpause-message"><function>soup_session_unpause_message</f
to resume the paused message.
</para>
+<para>
+By default, NTLM authentication is not enabled. To add NTLM support to
+a session, call:
+</para>
+
+<informalexample><programlisting>
+ soup_session_add_feature_by_type (session, SOUP_TYPE_AUTH_NTLM);
+</programlisting></informalexample>
+
+<para>
+(You can also disable Basic or Digest authentication by calling <link
+linkend="soup-session-remove-feature-by-type"><function>soup_session_remove_feature_by_type</function></link>
+on <link linkend="SOUP-TYPE-AUTH-BASIC:CAPS"><literal>SOUP_TYPE_AUTH_BASIC</literal></link>
+or <link linkend="SOUP-TYPE-AUTH-DIGEST:CAPS"><literal>SOUP_TYPE_AUTH_DIGEST</literal></link>.)
+</para>
+
</refsect2>
<refsect2>
<title>Multi-threaded usage</title>
<para>
-The only explicitly thread-safe operations in
-<application>libsoup</application> are <link
-linkend="SoupSessionSync"><type>SoupSessionSync</type></link>'s
-implementations of the <link
-linkend="SoupSession"><type>SoupSession</type></link> methods. So
-after creating a <type>SoupSessionSync</type>, you can call <link
-linkend="soup-session-send-message"><function>soup_session_send_message</function></link>
-and <link
-linkend="soup-session-cancel-message"><function>soup_session_cancel_message</function></link>
-on it from any thread. But, eg, while the session is processing a
-message, you should not call any <link
-linkend="SoupMessage"><type>SoupMessage</type></link> methods on it
-from any thread other than the one in which it is being sent. (That
-is, you should not call any <type>SoupMessage</type> methods on it
-except from a message or session callback or signal handler.)
+A <link linkend="SoupSession"><type>SoupSession</type></link> can be
+used from multiple threads. However, if you are using the async APIs,
+then each thread you use the session from must have its own
+thread-default <link linkend="GMainContext"><type>GMainContext</type></link>.
</para>
<para>
-All other objects (including <link
-linkend="SoupSessionAsync"><type>SoupSessionAsync</type></link>)
-should only be used from a single thread, with objects that are also
-only be used from that thread. (And in particular, if you set a
-non-default <link
-linkend="GMainContext"><type>GMainContext</type></link> on a session,
-socket, etc, then you can only use that object from the thread in
-which that <type>GMainContext</type> is running.)
+<link linkend="SoupMessage"><type>SoupMessage</type></link> is
+<emphasis>not</emphasis> thread-safe, so once you send a message on
+the session, you must not interact with it from any thread other than
+the one where it was sent.
</para>
</refsect2>
@@ -508,7 +528,8 @@ which that <type>GMainContext</type> is running.)
<para>
A few sample programs are available in the
-<application>libsoup</application> sources:
+<application>libsoup</application> sources, in the
+<literal>examples</literal> directory:
</para>
<itemizedlist>
@@ -518,21 +539,6 @@ A few sample programs are available in the
</para></listitem>
<listitem><para>
- <emphasis role="bold"><literal>getbug</literal></emphasis> is a trivial
- demonstration of the <link
- linkend="libsoup-2.4-XMLRPC-Support">XMLRPC</link> interface.
- (<emphasis
- role="bold"><literal>xmlrpc-test</literal></emphasis> provides
- a slightly more complicated example.)
- </para></listitem>
-
- <listitem><para>
- <emphasis role="bold"><literal>auth-test</literal></emphasis> shows how to use
- authentication handlers and status-code handlers, although in
- a fairly unusual way.
- </para></listitem>
-
- <listitem><para>
<emphasis role="bold"><literal>simple-proxy</literal></emphasis> uses both the
client and server APIs to create a simple (and not very
RFC-compliant) proxy server. It shows how to use the <link
@@ -544,11 +550,7 @@ A few sample programs are available in the
</itemizedlist>
<para>
-More complicated examples are available in GNOME CVS. The <ulink
-url="http://live.gnome.org/LibSoup"><application>libsoup</application>
-pages</ulink> on the GNOME wiki include a <ulink
-url="http://live.gnome.org/LibSoup/Users">list of applications using
-<application>libsoup</application></ulink>.
+More complicated examples are available in GNOME git.
</para>
</refsect2>
diff --git a/docs/reference/libsoup-2.4-docs.sgml b/docs/reference/libsoup-2.4-docs.sgml
index ca92b864..c0c8a05c 100644
--- a/docs/reference/libsoup-2.4-docs.sgml
+++ b/docs/reference/libsoup-2.4-docs.sgml
@@ -10,6 +10,7 @@
<title>Tutorial</title>
<xi:include href="build-howto.xml"/>
<xi:include href="client-howto.xml"/>
+ <xi:include href="request-howto.xml"/>
<xi:include href="server-howto.xml"/>
<xi:include href="session-porting.xml"/>
</chapter>
diff --git a/docs/reference/libsoup-2.4-sections.txt b/docs/reference/libsoup-2.4-sections.txt
index 6b193101..ca423328 100644
--- a/docs/reference/libsoup-2.4-sections.txt
+++ b/docs/reference/libsoup-2.4-sections.txt
@@ -436,6 +436,7 @@ soup_session_get_feature_for_message
soup_session_has_feature
<SUBSECTION>
SOUP_SESSION_PROXY_URI
+SOUP_SESSION_PROXY_RESOLVER
SOUP_SESSION_MAX_CONNS
SOUP_SESSION_MAX_CONNS_PER_HOST
SOUP_SESSION_USE_NTLM
diff --git a/docs/reference/request-howto.xml b/docs/reference/request-howto.xml
new file mode 100644
index 00000000..55a46431
--- /dev/null
+++ b/docs/reference/request-howto.xml
@@ -0,0 +1,184 @@
+<?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-request-howto">
+<refmeta>
+<refentrytitle>libsoup Client SoupRequest API</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>LIBSOUP Library</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>libsoup Client SoupRequest API</refname><refpurpose>Using
+libsoup with a mix of <literal>http</literal> and non-<literal>http</literal> URIs.</refpurpose>
+</refnamediv>
+
+<refsect2>
+<title><type>SoupRequest</type></title>
+
+<para>
+<link linkend="SoupRequest"><type>SoupRequest</type></link> is an
+abstract type representing a request for a particular URI. The
+<type>SoupRequest</type> API is an alternative to the <link
+linkend="SoupMessage"><type>SoupMessage</type></link>-based <link
+linkend="SoupSession"><type>SoupSession</type></link> APIs which may be
+useful to programs that want to deal with multiple kinds of URIs.
+</para>
+
+<para>
+<type>SoupRequest</type> officially became part of the
+<application>libsoup</application> API in 2.42 with the addition of
+<link
+linkend="soup-session-request"><function>soup_session_request</function></link>
+and the related functions. However, parts of it are also available as
+far back as <application>libsoup</application> 2.34 via the
+(now-deprecated) <type>SoupRequester</type> session feature, if you
+define <literal>LIBSOUP_USE_UNSTABLE_REQUEST_API</literal> before
+including the <application>libsoup</application> headers.
+</para>
+
+<para>
+Additionally, before <application>libsoup</application> 2.42, the
+<type>SoupRequest</type> API was the only way to stream an HTTP
+response body via <link
+linkend="GInputStream"><type>GInputStream</type></link>. As of 2.42,
+there are streaming APIs based on <type>SoupMessage</type> (<link
+linkend="soup-session-send"><function>soup_session_send</function></link>
+and <link
+linkend="soup-session-send-async"><function>soup_session_send_async</function></link>),
+so applications that are using <type>SoupRequest</type> with only
+<literal>http</literal> and <literal>https</literal> URIs can be
+ported to those APIs now.
+</para>
+
+</refsect2>
+
+<refsect2>
+<title>Creating a SoupRequest</title>
+
+<para>
+There are four <type>SoupSession</type> methods for creating
+<type>SoupRequest</type>s:
+</para>
+
+<itemizedlist>
+ <listitem>
+ <para>
+ <link linkend="soup-session-request"><function>soup_session_request</function></link>
+ takes an arbitrary URI as a string, and returns a <link
+ linkend="SoupRequest"><type>SoupRequest</type></link>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="soup-session-request-uri"><function>soup_session_request_uri</function></link>
+ takes an arbitrary URI as a <link linkend="SoupURI"><type>SoupURI</type></link>,
+ and returns a <link linkend="SoupRequest"><type>SoupRequest</type></link>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="soup-session-request-http"><function>soup_session_request_http</function></link>
+ takes an HTTP method and an <literal>http</literal> or <literal>https</literal> URI as a string, and returns a <link
+ linkend="SoupRequestHTTP"><type>SoupRequestHTTP</type></link>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="soup-session-request-http-uri"><function>soup_session_request_http_uri</function></link>
+ takes an HTTP method and an <literal>http</literal> or <literal>https</literal> URI as a <link linkend="SoupURI"><type>SoupURI</type></link>,
+ and returns a <link linkend="SoupRequestHTTP"><type>SoupRequestHTTP</type></link>.
+ </para>
+ </listitem>
+</itemizedlist>
+
+</refsect2>
+
+<refsect2>
+<title>Sending a SoupRequest</title>
+
+<para>
+Once you have created a <type>SoupRequest</type>, you can send it with
+either <link
+linkend="soup-request-send"><function>soup_request_send</function></link>
+or <link
+linkend="soup-request-send-async"><function>soup_request_send_async</function></link>.
+This will provide you with a <link
+linkend="GInputStream"><type>GInputStream</type></link> which you can
+read to get the response body.
+</para>
+
+<para>
+After sending, you can use <link
+linkend="soup-request-get-content-length"><function>soup_request_get_content_length</function></link>
+and <link
+linkend="soup-request-get-content-type"><function>soup_request_get_content_type</function></link>
+to get information about the response body.
+</para>
+
+<para>
+As with the streaming <type>SoupMessage</type>-based APIs,
+<function>soup_request_send</function> and
+<function>soup_request_send_async</function> only return errors if a
+transport-level problem occurs (eg, it could not connect to the host,
+or the request was cancelled). In the case of an HTTP request, use the
+message's <structfield>status_code</structfield> field to determine
+whether the request was successful or not at the HTTP level (ie, "<literal>200
+OK</literal>" vs "<literal>401 Bad Request</literal>"). (You can call <link
+linkend="soup-request-http-get-message"><function>soup_request_http_get_message</function></link>
+to get the request's corresponding <link
+linkend="SoupMessage"><type>SoupMessage</type></link>, to look at the
+status code or other HTTP metadata.)
+</para>
+
+</refsect2>
+
+<refsect2>
+<title>Supported URI types, and adding your own</title>
+
+<para>
+Different URI types are implemented by different subclasses of
+<type>SoupRequest</type>. <application>libsoup</application> currently
+implements three <type>SoupRequest</type> classes:
+</para>
+
+<variablelist>
+ <varlistentry>
+ <term><link linkend="SoupRequestHTTP"><type>SoupRequestHTTP</type></link></term>
+ <listitem><para>
+ Handles <literal>http</literal> and
+ <literal>https</literal> URI.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><link linkend="SoupRequestData"><type>SoupRequestData</type></link></term>
+ <listitem><para>
+ Handles <literal>data</literal> URIs containing inline data.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><link linkend="SoupRequestFile"><type>SoupRequestFile</type></link></term>
+ <listitem><para>
+ Handles <literal>file</literal> and
+ <link linkend="GResource"><literal>resource</literal></link> URIs.
+ If you request a URI corresponding to a directory, this
+ will generate an HTML listing of the directory.
+ </para></listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+You can add additional URI types by implementing your own
+<type>SoupRequest</type> subclass; set the
+<type>SoupRequestClass</type>'s <structfield>schemes</structfield>
+field to point to a <literal>NULL</literal>-terminated array of scheme
+names, implement the various <type>SoupRequest</type> methods, and
+then register the type with your <type>SoupSession</type> by calling
+<link linkend="soup-session-add-feature-by-type"><function>soup_session_add_feature_by_type</function></link>
+and passing the <link linkend="GType"><type>GType</type></link> of
+your request class.
+</para>
+
+</refsect2>
+
+</refentry>