|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
|
|
Packit Service |
ca3877 |
<refentry id="libsoup-client-howto">
|
|
Packit Service |
ca3877 |
<refmeta>
|
|
Packit Service |
ca3877 |
<refentrytitle>libsoup Client Basics</refentrytitle>
|
|
Packit Service |
ca3877 |
<manvolnum>3</manvolnum>
|
|
Packit Service |
ca3877 |
<refmiscinfo>LIBSOUP Library</refmiscinfo>
|
|
Packit Service |
ca3877 |
</refmeta>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<refnamediv>
|
|
Packit Service |
ca3877 |
<refname>libsoup Client Basics</refname><refpurpose>Client-side tutorial</refpurpose>
|
|
Packit Service |
ca3877 |
</refnamediv>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<refsect2>
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
This section explains how to use <application>libsoup</application> as
|
|
Packit Service |
ca3877 |
an HTTP client using several new APIs introduced in version 2.42. If
|
|
Packit Service |
ca3877 |
you want to be compatible with older versions of
|
|
Packit Service |
ca3877 |
<application>libsoup</application>, consult the documentation for that
|
|
Packit Service |
ca3877 |
version.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
</refsect2>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<refsect2>
|
|
Packit Service |
ca3877 |
<title>Creating a <type>SoupSession</type></title>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
The first step in using the client API is to create a
|
|
Packit Service |
ca3877 |
linkend="SoupSession"><type>SoupSession</type></link>. The session object
|
|
Packit Service |
ca3877 |
encapsulates all of the state that <application>libsoup</application>
|
|
Packit Service |
ca3877 |
is keeping on behalf of your program; cached HTTP connections,
|
|
Packit Service |
ca3877 |
authentication information, etc.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
When you create the session with
|
|
Packit Service |
ca3877 |
linkend="soup-session-new-with-options"><function>soup_session_new_with_options</function></link>,
|
|
Packit Service |
ca3877 |
you can specify various additional options:
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<variablelist>
|
|
Packit Service |
ca3877 |
<varlistentry>
|
|
Packit Service |
ca3877 |
<term><link linkend="SOUP-SESSION-MAX-CONNS:CAPS"><literal>SOUP_SESSION_MAX_CONNS</literal></link></term>
|
|
Packit Service |
ca3877 |
<listitem><para>
|
|
Packit Service |
ca3877 |
Allows you to set the maximum total number of connections
|
|
Packit Service |
ca3877 |
the session will have open at one time. (Once it reaches
|
|
Packit Service |
ca3877 |
this limit, it will either close idle connections, or
|
|
Packit Service |
ca3877 |
wait for existing connections to free up before starting
|
|
Packit Service |
ca3877 |
new requests.) The default value is 10.
|
|
Packit Service |
ca3877 |
</para></listitem>
|
|
Packit Service |
ca3877 |
</varlistentry>
|
|
Packit Service |
ca3877 |
<varlistentry>
|
|
Packit Service |
ca3877 |
<term><link linkend="SOUP-SESSION-MAX-CONNS-PER-HOST:CAPS"><literal>SOUP_SESSION_MAX_CONNS_PER_HOST</literal></link></term>
|
|
Packit Service |
ca3877 |
<listitem><para>
|
|
Packit Service |
ca3877 |
Allows you to set the maximum total number of connections
|
|
Packit Service |
ca3877 |
the session will have open <emphasis>to a single
|
|
Packit Service |
ca3877 |
host</emphasis> at one time. The default value is 2.
|
|
Packit Service |
ca3877 |
</para></listitem>
|
|
Packit Service |
ca3877 |
</varlistentry>
|
|
Packit Service |
ca3877 |
<varlistentry>
|
|
Packit Service |
ca3877 |
<term><link linkend="SOUP-SESSION-USER-AGENT:CAPS"><literal>SOUP_SESSION_USER_AGENT</literal></link></term>
|
|
Packit Service |
ca3877 |
<listitem><para>
|
|
Packit Service |
ca3877 |
Allows you to set a User-Agent string that will be sent
|
|
Packit Service |
ca3877 |
on all outgoing requests.
|
|
Packit Service |
ca3877 |
</para></listitem>
|
|
Packit Service |
ca3877 |
</varlistentry>
|
|
Packit Service |
ca3877 |
<varlistentry>
|
|
Packit Service |
ca3877 |
<term><link linkend="SOUP-SESSION-ACCEPT-LANGUAGE:CAPS"><literal>SOUP_SESSION_ACCEPT_LANGUAGE</literal></link>
|
|
Packit Service |
ca3877 |
and <link linkend="SOUP-SESSION-ACCEPT-LANGUAGE-AUTO:CAPS"><literal>SOUP_SESSION_ACCEPT_LANGUAGE_AUTO</literal></link></term>
|
|
Packit Service |
ca3877 |
<listitem><para>
|
|
Packit Service |
ca3877 |
Allow you to set an Accept-Language header on all outgoing
|
|
Packit Service |
ca3877 |
requests. <literal>SOUP_SESSION_ACCEPT_LANGUAGE</literal>
|
|
Packit Service |
ca3877 |
takes a list of language tags to use, while
|
|
Packit Service |
ca3877 |
<literal>SOUP_SESSION_ACCEPT_LANGUAGE_AUTO</literal>
|
|
Packit Service |
ca3877 |
automatically generates the list from the user's locale
|
|
Packit Service |
ca3877 |
settings.
|
|
Packit Service |
ca3877 |
</para></listitem>
|
|
Packit Service |
ca3877 |
</varlistentry>
|
|
Packit Service |
ca3877 |
<varlistentry>
|
|
Packit Service |
ca3877 |
<term><link linkend="SOUP-SESSION-HTTP-ALIASES:CAPS"><literal>SOUP_SESSION_HTTP_ALIASES</literal></link>
|
|
Packit Service |
ca3877 |
and <link linkend="SOUP-SESSION-HTTPS-ALIASES:CAPS"><literal>SOUP_SESSION_HTTPS_ALIASES</literal></link></term>
|
|
Packit Service |
ca3877 |
<listitem><para>
|
|
Packit Service |
ca3877 |
Allow you to tell the session to recognize additional URI
|
|
Packit Service |
ca3877 |
schemes as aliases for "<literal>http</literal>" or
|
|
Packit Service |
ca3877 |
<literal>https</literal>. You can set this if you are
|
|
Packit Service |
ca3877 |
using URIs with schemes like "<literal>dav</literal>" or
|
|
Packit Service |
ca3877 |
"<literal>webcal</literal>" (and in particular, you need
|
|
Packit Service |
ca3877 |
to set this if the server you are talking to might return
|
|
Packit Service |
ca3877 |
redirects with such a scheme).
|
|
Packit Service |
ca3877 |
</para></listitem>
|
|
Packit Service |
ca3877 |
</varlistentry>
|
|
Packit Service |
ca3877 |
<varlistentry>
|
|
Packit Service |
ca3877 |
<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>
|
|
Packit Service |
ca3877 |
<listitem>
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
<link linkend="SOUP-SESSION-PROXY-RESOLVER:CAPS"><literal>SOUP_SESSION_PROXY_RESOLVER</literal></link>
|
|
Packit Service |
ca3877 |
specifies a
|
|
Packit Service |
ca3877 |
linkend="GProxyResolver"><type>GProxyResolver</type></link>
|
|
Packit Service |
ca3877 |
to use to determine the HTTP proxies to use. By default,
|
|
Packit Service |
ca3877 |
this is set to the resolver returned by
|
|
Packit Service |
ca3877 |
linkend="g-proxy-resolver-get-default"><function>g_proxy_resolver_get_default</function></link>,
|
|
Packit Service |
ca3877 |
so you do not need to set it yourself.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
Alternatively, if you want all requests to go through a
|
|
Packit Service |
ca3877 |
single proxy, you can set
|
|
Packit Service |
ca3877 |
linkend="SOUP-SESSION-PROXY-URI:CAPS"><literal>SOUP_SESSION_PROXY_URI</literal></link>.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
</listitem>
|
|
Packit Service |
ca3877 |
</varlistentry>
|
|
Packit Service |
ca3877 |
<varlistentry>
|
|
Packit Service |
ca3877 |
<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>
|
|
Packit Service |
ca3877 |
<listitem><para>
|
|
Packit Service |
ca3877 |
These allow you to specify
|
|
Packit Service |
ca3877 |
linkend="SoupSessionFeature"><type>SoupSessionFeature</type></link>s
|
|
Packit Service |
ca3877 |
(discussed <link linkend="session-features">below</link>)
|
|
Packit Service |
ca3877 |
to add at construct-time.
|
|
Packit Service |
ca3877 |
</para></listitem>
|
|
Packit Service |
ca3877 |
</varlistentry>
|
|
Packit Service |
ca3877 |
</variablelist>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
Other properties are also available; see the
|
|
Packit Service |
ca3877 |
linkend="SoupSession"><type>SoupSession</type></link> documentation for
|
|
Packit Service |
ca3877 |
more details.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
If you don't need to specify any options, you can just use
|
|
Packit Service |
ca3877 |
linkend="soup-session-new"><function>soup_session_new</function></link>,
|
|
Packit Service |
ca3877 |
which takes no arguments.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
</refsect2>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<refsect2 id="session-features">
|
|
Packit Service |
ca3877 |
<title>Session features</title>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
Additional session functionality is provided as
|
|
Packit Service |
ca3877 |
linkend="SoupSessionFeature"><type>SoupSessionFeature</type></link>s,
|
|
Packit Service |
ca3877 |
which can be added to a session, via the
|
|
Packit Service |
ca3877 |
linkend="SOUP-SESSION-ADD-FEATURE:CAPS"><literal>SOUP_SESSION_ADD_FEATURE</literal></link>
|
|
Packit Service |
ca3877 |
and
|
|
Packit Service |
ca3877 |
linkend="SOUP-SESSION-ADD-FEATURE-BY-TYPE:CAPS"><literal>SOUP_SESSION_ADD_FEATURE_BY_TYPE</literal></link>
|
|
Packit Service |
ca3877 |
options at session-construction-time, or afterward via the
|
|
Packit Service |
ca3877 |
linkend="soup-session-add-feature"><function>soup_session_add_feature</function></link>
|
|
Packit Service |
ca3877 |
and
|
|
Packit Service |
ca3877 |
linkend="soup-session-add-feature-by-type"><function>soup_session_add_feature_by_type</function></link>
|
|
Packit Service |
ca3877 |
functions.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
A
|
|
Packit Service |
ca3877 |
linkend="SoupContentDecoder"><type>SoupContentDecoder</type></link> is
|
|
Packit Service |
ca3877 |
added for you automatically. This advertises to servers that the
|
|
Packit Service |
ca3877 |
client supports compression, and automatically decompresses compressed
|
|
Packit Service |
ca3877 |
responses.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
Some other available features that you can add include:
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<variablelist>
|
|
Packit Service |
ca3877 |
<varlistentry>
|
|
Packit Service |
ca3877 |
<term><link linkend="SoupLogger"><type>SoupLogger</type></link></term>
|
|
Packit Service |
ca3877 |
<listitem><para>
|
|
Packit Service |
ca3877 |
A debugging aid, which logs all of libsoup's HTTP traffic
|
|
Packit Service |
ca3877 |
to <literal>stdout</literal> (or another place you specify).
|
|
Packit Service |
ca3877 |
</para></listitem>
|
|
Packit Service |
ca3877 |
</varlistentry>
|
|
Packit Service |
ca3877 |
<varlistentry>
|
|
Packit Service |
ca3877 |
<term>
|
|
Packit Service |
ca3877 |
<link linkend="SoupCookieJar"><type>SoupCookieJar</type></link>,
|
|
Packit Service |
ca3877 |
<link linkend="SoupCookieJarText"><type>SoupCookieJarText</type></link>,
|
|
Packit Service |
ca3877 |
and <link linkend="SoupCookieJarDB"><type>SoupCookieJarDB</type></link>
|
|
Packit Service |
ca3877 |
</term>
|
|
Packit Service |
ca3877 |
<listitem><para>
|
|
Packit Service |
ca3877 |
Support for HTTP cookies. <type>SoupCookieJar</type>
|
|
Packit Service |
ca3877 |
provides non-persistent cookie storage, while
|
|
Packit Service |
ca3877 |
<type>SoupCookieJarText</type> uses a text file to keep
|
|
Packit Service |
ca3877 |
track of cookies between sessions, and
|
|
Packit Service |
ca3877 |
<type>SoupCookieJarDB</type> uses a
|
|
Packit Service |
ca3877 |
<application>SQLite</application> database.
|
|
Packit Service |
ca3877 |
</para></listitem>
|
|
Packit Service |
ca3877 |
</varlistentry>
|
|
Packit Service |
ca3877 |
<varlistentry>
|
|
Packit Service |
ca3877 |
<term><link linkend="SoupContentSniffer"><type>SoupContentSniffer</type></link></term>
|
|
Packit Service |
ca3877 |
<listitem><para>
|
|
Packit Service |
ca3877 |
Uses the HTML5 sniffing rules to attempt to
|
|
Packit Service |
ca3877 |
determine the Content-Type of a response when the
|
|
Packit Service |
ca3877 |
server does not identify the Content-Type, or appears to
|
|
Packit Service |
ca3877 |
have provided an incorrect one.
|
|
Packit Service |
ca3877 |
</para></listitem>
|
|
Packit Service |
ca3877 |
</varlistentry>
|
|
Packit Service |
ca3877 |
</variablelist>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
Use the "add_feature_by_type" property/function to add features that
|
|
Packit Service |
ca3877 |
don't require any configuration (such as
|
|
Packit Service |
ca3877 |
linkend="SoupContentSniffer"><type>SoupContentSniffer</type></link>),
|
|
Packit Service |
ca3877 |
and the "add_feature" property/function to add features that must be
|
|
Packit Service |
ca3877 |
constructed first (such as
|
|
Packit Service |
ca3877 |
linkend="SoupLogger"><type>SoupLogger</type></link>). For example, an
|
|
Packit Service |
ca3877 |
application might do something like the following:
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<informalexample><programlisting>
|
|
Packit Service |
ca3877 |
session = soup_session_new_with_options (
|
|
Packit Service |
ca3877 |
SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_CONTENT_SNIFFER,
|
|
Packit Service |
ca3877 |
NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (debug_level) {
|
|
Packit Service |
ca3877 |
SoupLogger *logger;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
logger = soup_logger_new (debug_level, -1);
|
|
Packit Service |
ca3877 |
soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger));
|
|
Packit Service |
ca3877 |
g_object_unref (logger);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
</programlisting></informalexample>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
</refsect2>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<refsect2>
|
|
Packit Service |
ca3877 |
<title>Creating and Sending SoupMessages</title>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
Once you have a session, you send HTTP requests using
|
|
Packit Service |
ca3877 |
linkend="SoupMessage"><type>SoupMessage</type></link>. In the simplest
|
|
Packit Service |
ca3877 |
case, you only need to create the message and it's ready to send:
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<informalexample><programlisting>
|
|
Packit Service |
ca3877 |
SoupMessage *msg;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
msg = soup_message_new ("GET", "http://example.com/");
|
|
Packit Service |
ca3877 |
</programlisting></informalexample>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
In more complicated cases, you can use various
|
|
Packit Service |
ca3877 |
linkend="SoupMessage">SoupMessage</link>,
|
|
Packit Service |
ca3877 |
linkend="SoupMessageHeaders">SoupMessageHeaders</link>, and
|
|
Packit Service |
ca3877 |
linkend="SoupMessageBody">SoupMessageBody</link> methods to set the
|
|
Packit Service |
ca3877 |
request headers and body of the message:
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<informalexample><programlisting>
|
|
Packit Service |
ca3877 |
SoupMessage *msg;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
msg = soup_message_new ("POST", "http://example.com/form.cgi");
|
|
Packit Service |
ca3877 |
soup_message_set_request (msg, "application/x-www-form-urlencoded",
|
|
Packit Service |
ca3877 |
SOUP_MEMORY_COPY, formdata, strlen (formdata));
|
|
Packit Service |
ca3877 |
soup_message_headers_append (msg->request_headers, "Referer", referring_url);
|
|
Packit Service |
ca3877 |
</programlisting></informalexample>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
(Although this is a bad example, because
|
|
Packit Service |
ca3877 |
<application>libsoup</application> actually has convenience methods
|
|
Packit Service |
ca3877 |
for dealing with <link linkend="libsoup-2.4-HTML-Form-Support">HTML
|
|
Packit Service |
ca3877 |
forms</link>, as well as
|
|
Packit Service |
ca3877 |
linkend="libsoup-2.4-XMLRPC-Support">XML-RPC</link>.)
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
You can also use
|
|
Packit Service |
ca3877 |
linkend="soup-message-set-flags"><function>soup_message_set_flags</function></link>
|
|
Packit Service |
ca3877 |
to change some default behaviors. For example, by default,
|
|
Packit Service |
ca3877 |
<type>SoupSession</type> automatically handles responses from the
|
|
Packit Service |
ca3877 |
server that redirect to another URL. If you would like to handle these
|
|
Packit Service |
ca3877 |
yourself, you can set the <link linkend="SOUP-MESSAGE-NO-REDIRECT:CAPS"><literal>SOUP_MESSAGE_NO_REDIRECT</literal></link>
|
|
Packit Service |
ca3877 |
flag.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<refsect3>
|
|
Packit Service |
ca3877 |
<title>Sending a Message Synchronously</title>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
To send a message and wait for the response, use
|
|
Packit Service |
ca3877 |
linkend="soup-session-send"><function>soup_session_send</function></link>:
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<informalexample><programlisting>
|
|
Packit Service |
ca3877 |
GInputStream *stream;
|
|
Packit Service |
ca3877 |
GError *error = NULL;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
stream = soup_session_send (session, msg, cancellable, &error);
|
|
Packit Service |
ca3877 |
</programlisting></informalexample>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
At the point when <function>soup_session_send</function> returns, the
|
|
Packit Service |
ca3877 |
request will have been sent, and the response headers read back in;
|
|
Packit Service |
ca3877 |
you can examine the message's <structfield>status_code</structfield>,
|
|
Packit Service |
ca3877 |
<structfield>reason_phrase</structfield>, and
|
|
Packit Service |
ca3877 |
<structfield>response_headers</structfield> fields to see the response
|
|
Packit Service |
ca3877 |
metadata. To get the response body, read from the returned
|
|
Packit Service |
ca3877 |
linkend="GInputStream"><type>GInputStream</type></link>, and close it
|
|
Packit Service |
ca3877 |
when you are done.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
Note that <function>soup_session_send</function> only returns an error
|
|
Packit Service |
ca3877 |
if a transport-level problem occurs (eg, it could not connect to the
|
|
Packit Service |
ca3877 |
host, or the request was cancelled). Use the message's
|
|
Packit Service |
ca3877 |
<structfield>status_code</structfield> field to determine whether the
|
|
Packit Service |
ca3877 |
request was successful or not at the HTTP level (ie, "<literal>200
|
|
Packit Service |
ca3877 |
OK</literal>" vs "<literal>401 Bad Request</literal>").
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
If you would prefer to have <application>libsoup</application> gather
|
|
Packit Service |
ca3877 |
the response body for you and then return it all at once, you can use
|
|
Packit Service |
ca3877 |
the older
|
|
Packit Service |
ca3877 |
<link linkend="soup-session-send-message"><function>soup_session_send_message</function></link>
|
|
Packit Service |
ca3877 |
API:
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<informalexample><programlisting>
|
|
Packit Service |
ca3877 |
guint status;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
status = soup_session_send_message (session, msg);
|
|
Packit Service |
ca3877 |
</programlisting></informalexample>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
In this case, the response body will be available in the message's
|
|
Packit Service |
ca3877 |
<structfield>response_body</structfield> field, and transport-level
|
|
Packit Service |
ca3877 |
errors will be indicated in the <structfield>status_code</structfield>
|
|
Packit Service |
ca3877 |
field via special pseudo-HTTP-status codes like
|
|
Packit Service |
ca3877 |
linkend="SOUP-STATUS-CANT-CONNECT:CAPS"><literal>SOUP_STATUS_CANT_CONNECT</literal></link>.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
</refsect3>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<refsect3>
|
|
Packit Service |
ca3877 |
<title>Sending a Message Asynchronously</title>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
To send a message asynchronously, use
|
|
Packit Service |
ca3877 |
linkend="soup-session-send-async"><function>soup_session_send_async</function></link>:
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<informalexample><programlisting>
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
...
|
|
Packit Service |
ca3877 |
soup_session_send_async (session, msg, cancellable, my_callback, my_callback_data);
|
|
Packit Service |
ca3877 |
...
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
my_callback (GObject *object, GAsyncResult *result, gpointer user_data)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GInputStream *stream;
|
|
Packit Service |
ca3877 |
GError *error = NULL;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
stream = soup_session_send_finish (SOUP_SESSION (object), result, &error);
|
|
Packit Service |
ca3877 |
...
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
</programlisting></informalexample>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
The message will be added to the session's queue, and eventually (when
|
|
Packit Service |
ca3877 |
control is returned back to the main loop), it will be sent and the
|
|
Packit Service |
ca3877 |
response be will be read. When the message has been sent, and its
|
|
Packit Service |
ca3877 |
headers received, the callback will be invoked, in the standard
|
|
Packit Service |
ca3877 |
<link linkend="GAsyncReadyCallback"><type>GAsyncReadyCallback</type></link>
|
|
Packit Service |
ca3877 |
style.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
As with synchronous sending, there is also an alternate API,
|
|
Packit Service |
ca3877 |
linkend="soup-session-queue-message"><function>soup_session_queue_message</function></link>,
|
|
Packit Service |
ca3877 |
in which your callback is not invoked until the response has been
|
|
Packit Service |
ca3877 |
completely read:
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<informalexample><programlisting>
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
...
|
|
Packit Service |
ca3877 |
soup_session_queue_message (session, msg, my_callback, my_callback_data);
|
|
Packit Service |
ca3877 |
...
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
my_callback (SoupSession *session, SoupMessage *msg, gpointer user_data)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
/* msg->response_body contains the response */
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
</programlisting></informalexample>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
linkend="soup-session-queue-message"><function>soup_session_queue_message</function></link>
|
|
Packit Service |
ca3877 |
is slightly unusual in that it steals a reference to the message
|
|
Packit Service |
ca3877 |
object, and unrefs it after the last callback is invoked on it. So
|
|
Packit Service |
ca3877 |
when using this API, you should not unref the message yourself.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
</refsect3>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
</refsect2>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<refsect2>
|
|
Packit Service |
ca3877 |
<title>Processing the Response</title>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
Once you have received the initial response from the server,
|
|
Packit Service |
ca3877 |
synchronously or asynchronously, streaming or not, you can look at the
|
|
Packit Service |
ca3877 |
response fields in the <literal>SoupMessage</literal> to decide what
|
|
Packit Service |
ca3877 |
to do next. The <structfield>status_code</structfield> and
|
|
Packit Service |
ca3877 |
<structfield>reason_phrase</structfield> fields contain the numeric
|
|
Packit Service |
ca3877 |
status and textual status response from the server.
|
|
Packit Service |
ca3877 |
<structfield>response_headers</structfield> contains the response
|
|
Packit Service |
ca3877 |
headers, which you can investigate using
|
|
Packit Service |
ca3877 |
linkend="soup-message-headers-get"><function>soup_message_headers_get</function></link>
|
|
Packit Service |
ca3877 |
and
|
|
Packit Service |
ca3877 |
linkend="soup-message-headers-foreach"><function>soup_message_headers_foreach</function></link>.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
linkend="SoupMessageHeaders"><type>SoupMessageHeaders</type></link>
|
|
Packit Service |
ca3877 |
automatically parses several important headers in
|
|
Packit Service |
ca3877 |
<structfield>response_headers</structfield> for you and provides
|
|
Packit Service |
ca3877 |
specialized accessors for them. Eg,
|
|
Packit Service |
ca3877 |
linkend="soup-message-headers-get-content-type"><function>soup_message_headers_get_content_type</function></link>.
|
|
Packit Service |
ca3877 |
There are several generic methods such as
|
|
Packit Service |
ca3877 |
linkend="soup-header-parse-param-list"><function>soup_header_parse_param_list</function></link>
|
|
Packit Service |
ca3877 |
(for parsing an attribute-list-type header) and
|
|
Packit Service |
ca3877 |
linkend="soup-header-contains"><function>soup_header_contains</function></link>
|
|
Packit Service |
ca3877 |
(for quickly testing if a list-type header contains a particular
|
|
Packit Service |
ca3877 |
token). These handle the various syntactical oddities of parsing HTTP
|
|
Packit Service |
ca3877 |
headers much better than functions like
|
|
Packit Service |
ca3877 |
<function>g_strsplit</function> or <function>strstr</function>.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
</refsect2>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<refsect2>
|
|
Packit Service |
ca3877 |
<title>Handling Authentication</title>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
<type>SoupSession</type> handles most of the details of HTTP
|
|
Packit Service |
ca3877 |
authentication for you. If it receives a 401 ("Unauthorized") or 407
|
|
Packit Service |
ca3877 |
("Proxy Authentication Required") response, the session will emit the
|
|
Packit Service |
ca3877 |
<link linkend="SoupSession-authenticate">authenticate</link> signal,
|
|
Packit Service |
ca3877 |
providing you with a
|
|
Packit Service |
ca3877 |
linkend="SoupAuth"><type>SoupAuth</type></link> object indicating the
|
|
Packit Service |
ca3877 |
authentication type ("Basic", "Digest", or "NTLM") and the realm name
|
|
Packit Service |
ca3877 |
provided by the server. If you have a username and password available
|
|
Packit Service |
ca3877 |
(or can generate one), call
|
|
Packit Service |
ca3877 |
linkend="soup-auth-authenticate"><function>soup_auth_authenticate</function></link>
|
|
Packit Service |
ca3877 |
to give the information to libsoup. The session will automatically
|
|
Packit Service |
ca3877 |
requeue the message and try it again with that authentication
|
|
Packit Service |
ca3877 |
information. (If you don't call
|
|
Packit Service |
ca3877 |
<function>soup_auth_authenticate</function>, the session will just
|
|
Packit Service |
ca3877 |
return the message to the application with its 401 or 407 status.)
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
If the server doesn't accept the username and password provided, the
|
|
Packit Service |
ca3877 |
session will emit
|
|
Packit Service |
ca3877 |
linkend="SoupSession-authenticate">authenticate</link> again, with the
|
|
Packit Service |
ca3877 |
<literal>retrying</literal> parameter set to <literal>TRUE</literal>. This lets the
|
|
Packit Service |
ca3877 |
application know that the information it provided earlier was
|
|
Packit Service |
ca3877 |
incorrect, and gives it a chance to try again. If this
|
|
Packit Service |
ca3877 |
username/password pair also doesn't work, the session will contine to
|
|
Packit Service |
ca3877 |
emit <literal>authenticate</literal> again and again until the
|
|
Packit Service |
ca3877 |
provided username/password successfully authenticates, or until the
|
|
Packit Service |
ca3877 |
signal handler fails to call
|
|
Packit Service |
ca3877 |
linkend="soup-auth-authenticate"><function>soup_auth_authenticate</function></link>,
|
|
Packit Service |
ca3877 |
at which point <application>libsoup</application> will allow the
|
|
Packit Service |
ca3877 |
message to fail (with status 401 or 407).
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
If you need to handle authentication asynchronously (eg, to pop up a
|
|
Packit Service |
ca3877 |
password dialog without recursively entering the main loop), you can
|
|
Packit Service |
ca3877 |
do that as well. Just call
|
|
Packit Service |
ca3877 |
linkend="soup-session-pause-message"><function>soup_session_pause_message</function></link>
|
|
Packit Service |
ca3877 |
on the message before returning from the signal handler, and
|
|
Packit Service |
ca3877 |
<function>g_object_ref</function> the <type>SoupAuth</type>. Then,
|
|
Packit Service |
ca3877 |
later on, after calling <function>soup_auth_authenticate</function>
|
|
Packit Service |
ca3877 |
(or deciding not to), call
|
|
Packit Service |
ca3877 |
linkend="soup-session-unpause-message"><function>soup_session_unpause_message</function></link>
|
|
Packit Service |
ca3877 |
to resume the paused message.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
By default, NTLM authentication is not enabled. To add NTLM support to
|
|
Packit Service |
ca3877 |
a session, call:
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<informalexample><programlisting>
|
|
Packit Service |
ca3877 |
soup_session_add_feature_by_type (session, SOUP_TYPE_AUTH_NTLM);
|
|
Packit Service |
ca3877 |
</programlisting></informalexample>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
(You can also disable Basic or Digest authentication by calling
|
|
Packit Service |
ca3877 |
linkend="soup-session-remove-feature-by-type"><function>soup_session_remove_feature_by_type</function></link>
|
|
Packit Service |
ca3877 |
on <link linkend="SOUP-TYPE-AUTH-BASIC:CAPS"><literal>SOUP_TYPE_AUTH_BASIC</literal></link>
|
|
Packit Service |
ca3877 |
or <link linkend="SOUP-TYPE-AUTH-DIGEST:CAPS"><literal>SOUP_TYPE_AUTH_DIGEST</literal></link>.)
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
</refsect2>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<refsect2>
|
|
Packit Service |
ca3877 |
<title>Multi-threaded usage</title>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
A <link linkend="SoupSession"><type>SoupSession</type></link> can be
|
|
Packit Service |
ca3877 |
used from multiple threads. However, if you are using the async APIs,
|
|
Packit Service |
ca3877 |
then each thread you use the session from must have its own
|
|
Packit Service |
ca3877 |
thread-default <link linkend="GMainContext"><type>GMainContext</type></link>.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
<link linkend="SoupMessage"><type>SoupMessage</type></link> is
|
|
Packit Service |
ca3877 |
<emphasis>not</emphasis> thread-safe, so once you send a message on
|
|
Packit Service |
ca3877 |
the session, you must not interact with it from any thread other than
|
|
Packit Service |
ca3877 |
the one where it was sent.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
</refsect2>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<refsect2>
|
|
Packit Service |
ca3877 |
<title>Sample Programs</title>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
A few sample programs are available in the
|
|
Packit Service |
ca3877 |
<application>libsoup</application> sources, in the
|
|
Packit Service |
ca3877 |
<literal>examples</literal> directory:
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<itemizedlist>
|
|
Packit Service |
ca3877 |
<listitem><para>
|
|
Packit Service |
ca3877 |
<emphasis role="bold"><literal>get</literal></emphasis> is a simple command-line
|
|
Packit Service |
ca3877 |
HTTP GET utility using the asynchronous API.
|
|
Packit Service |
ca3877 |
</para></listitem>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<listitem><para>
|
|
Packit Service |
ca3877 |
<emphasis role="bold"><literal>simple-proxy</literal></emphasis> uses both the
|
|
Packit Service |
ca3877 |
client and server APIs to create a simple (and not very
|
|
Packit Service |
ca3877 |
RFC-compliant) proxy server. It shows how to use the
|
|
Packit Service |
ca3877 |
linkend="SoupMessageFlags"><literal>SOUP_MESSAGE_OVERWRITE_CHUNKS</literal></link>
|
|
Packit Service |
ca3877 |
flag when reading a message to save memory by processing each
|
|
Packit Service |
ca3877 |
chunk of the message as it is read, rather than accumulating
|
|
Packit Service |
ca3877 |
them all into a single buffer to process all at the end.
|
|
Packit Service |
ca3877 |
</para></listitem>
|
|
Packit Service |
ca3877 |
</itemizedlist>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
<para>
|
|
Packit Service |
ca3877 |
More complicated examples are available in GNOME git.
|
|
Packit Service |
ca3877 |
</para>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
</refsect2>
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
</refentry>
|