From c2d0f8d19eb25f21838a1ddfd4baab1c0218ac9c Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Wed, 11 Dec 2013 11:44:31 +0100 Subject: docs: Update client-side tutorial for 2.42, document request APIs --- docs/reference/Makefile.am | 1 + docs/reference/client-howto.xml | 406 ++++++++++++++++---------------- docs/reference/libsoup-2.4-docs.sgml | 1 + docs/reference/libsoup-2.4-sections.txt | 1 + docs/reference/request-howto.xml | 184 +++++++++++++++ 5 files changed, 391 insertions(+), 202 deletions(-) create mode 100644 docs/reference/request-howto.xml 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,15 +3,25 @@ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> -Soup Client Basics +libsoup Client Basics 3 LIBSOUP Library -Soup Client BasicsClient-side tutorial +libsoup Client BasicsClient-side tutorial + + +This section explains how to use libsoup as +an HTTP client using several new APIs introduced in version 2.42. If +you want to be compatible with older versions of +libsoup, consult the documentation for that +version. + + + Creating a <type>SoupSession</type> @@ -24,35 +34,8 @@ authentication information, etc. -There are two subclasses of SoupSession that you can use, with -slightly different behavior: - - - - - SoupSessionAsync, - which uses callbacks and the glib main loop to provide - asynchronous I/O. - - - - SoupSessionSync, - which uses blocking I/O rather than callbacks, making it more - suitable for threaded applications. - - - - -If you want to do a mix of mainloop-based and blocking I/O, you will -need to create two different session objects. - - - -When you create the session (with soup_session_async_new_with_options -or soup_session_sync_new_with_options), +When you create the session with soup_session_new_with_options, you can specify various additional options: @@ -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. @@ -72,43 +55,60 @@ you can specify various additional options: Allows you to set the maximum total number of connections the session will have open to a single - host at one time. + host at one time. The default value is 2. - SOUP_SESSION_USE_NTLM + SOUP_SESSION_USER_AGENT - If TRUE, then Microsoft NTLM - authentication will be used if available (and will be - preferred to HTTP Basic or Digest authentication). - If FALSE, 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. - SOUP_SESSION_SSL_CA_FILE + SOUP_SESSION_ACCEPT_LANGUAGE + and SOUP_SESSION_ACCEPT_LANGUAGE_AUTO - 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. SOUP_SESSION_ACCEPT_LANGUAGE + takes a list of language tags to use, while + SOUP_SESSION_ACCEPT_LANGUAGE_AUTO + automatically generates the list from the user's locale + settings. - SOUP_SESSION_ASYNC_CONTEXT + SOUP_SESSION_HTTP_ALIASES + and SOUP_SESSION_HTTPS_ALIASES - A GMainContext - which the session will use for asynchronous operations. - This can be set if you want to use a - SoupSessionAsync in a thread other than the - main thread. + Allow you to tell the session to recognize additional URI + schemes as aliases for "http" or + https. You can set this if you are + using URIs with schemes like "dav" or + "webcal" (and in particular, you need + to set this if the server you are talking to might return + redirects with such a scheme). + + SOUP_SESSION_PROXY_RESOLVER and SOUP_SESSION_PROXY_URI + + + SOUP_SESSION_PROXY_RESOLVER + specifies a GProxyResolver + to use to determine the HTTP proxies to use. By default, + this is set to the resolver returned by g_proxy_resolver_get_default, + so you do not need to set it yourself. + + + Alternatively, if you want all requests to go through a + single proxy, you can set SOUP_SESSION_PROXY_URI. + + + SOUP_SESSION_ADD_FEATURE and SOUP_SESSION_ADD_FEATURE_BY_TYPE @@ -120,11 +120,16 @@ you can specify various additional options: + +Other properties are also available; see the SoupSession documentation for +more details. + + If you don't need to specify any options, you can just use soup_session_async_new or -soup_session_sync_new, -which take no arguments. +linkend="soup-session-new">soup_session_new, +which takes no arguments. @@ -143,8 +148,19 @@ options at session-construction-time, or afterward via the soup_session_add_feature and soup_session_add_feature_by_type -functions. Some of the features available in -libsoup are: +functions. + + + +A SoupContentDecoder is +added for you automatically. This advertises to servers that the +client supports compression, and automatically decompresses compressed +responses. + + + +Some other available features that you can add include: @@ -156,26 +172,27 @@ functions. Some of the features available in - SoupCookieJar and SoupCookieJarText + + SoupCookieJar, + SoupCookieJarText, + and SoupCookieJarDB + Support for HTTP cookies. SoupCookieJar provides non-persistent cookie storage, while SoupCookieJarText uses a text file to keep - track of cookies between sessions. - - - - SoupProxyResolverDefault - - A feature that automatically determines the correct HTTP - proxy to use for requests. + track of cookies between sessions, and + SoupCookieJarDB uses a + SQLite database. - SoupCookieJarDB + SoupContentSniffer - Support for HTTP cookies stored in an - SQLite 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. @@ -183,7 +200,7 @@ functions. Some of the features available in Use the "add_feature_by_type" property/function to add features that don't require any configuration (such as SoupProxyResolverDefault), +linkend="SoupContentSniffer">SoupContentSniffer), and the "add_feature" property/function to add features that must be constructed first (such as SoupLogger). For example, an @@ -191,11 +208,10 @@ application might do something like the following: - 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: Creating and Sending SoupMessages -Once you have a session, you do HTTP traffic using SoupMessage. In the simplest case, you only need to create the message and it's ready to send: @@ -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); @@ -262,28 +278,56 @@ flag. To send a message and wait for the response, use soup_session_send_message: +linkend="soup-session-send">soup_session_send: - guint status; + GInputStream *stream; + GError *error = NULL; - status = soup_session_send_message (session, msg); + stream = soup_session_send (session, msg, cancellable, &error); -(If you use soup_session_send_message with a -SoupSessionAsync, -it will run the main loop itself until the message is complete.) +At the point when soup_session_send returns, the +request will have been sent, and the response headers read back in; +you can examine the message's status_code, +reason_phrase, and +response_headers fields to see the response +metadata. To get the response body, read from the returned GInputStream, and close it +when you are done. -The return value from soup_session_send_message -is a libsoup status code, -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 -msg->status_code.) +Note that soup_session_send 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 +status_code field to determine whether the +request was successful or not at the HTTP level (ie, "200 +OK" vs "401 Bad Request"). + + + +If you would prefer to have libsoup gather +the response body for you and then return it all at once, you can use +the older +soup_session_send_message +API: + + + + guint status; + + status = soup_session_send_message (session, msg); + + + +In this case, the response body will be available in the message's +response_body field, and transport-level +errors will be indicated in the status_code +field via special pseudo-HTTP-status codes like SOUP_STATUS_CANT_CONNECT. @@ -293,51 +337,63 @@ response to the message. (The status is also available as To send a message asynchronously, use soup_session_queue_message: +linkend="soup-session-send-async">soup_session_send_async: +{ ... - 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, &error); + ... } 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, -callback will be invoked, along with the data you -passed to soup_session_queue_message. +response be will be read. When the message has been sent, and its +headers received, the callback will be invoked, in the standard +GAsyncReadyCallback +style. -soup_session_queue_message -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 soup_session_send_message, -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, soup_session_queue_message, +in which your callback is not invoked until the response has been +completely read: + +{ + ... + 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 */ +} + + -(If you use soup_session_queue_message -with a SoupSessionSync, the -message will be sent in another thread, with the callback eventually -being invoked in the session's SOUP_SESSION_ASYNC_CONTEXT.) +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. @@ -348,19 +404,17 @@ being invoked in the session's < Processing the Response -Once you have received the response from the server, synchronously or -asynchronously, you can look at the response fields in the -SoupMessage to decide what to do next. The -status_code 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 SoupMessage to decide what +to do next. The status_code and reason_phrase fields contain the numeric status and textual status response from the server. response_headers contains the response headers, which you can investigate using soup_message_headers_get and -soup_message_headers_foreach. -The response body (if any) is in the -response_body field. +linkend="soup-message-headers-get">soup_message_headers_get +and soup_message_headers_foreach. @@ -382,41 +436,6 @@ headers much better than functions like - -Intermediate/Automatic Processing - - -You can also connect to various SoupMessage signals to do -processing at intermediate stages of HTTP I/O. Eg, the got-chunk -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). SoupMessage also provides two convenience -methods, soup_message_add_header_handler, -and soup_message_add_status_code_handler, -which allow you to set up a signal handler that will only be invoked -for messages with certain response headers or status codes. -SoupSession uses this internally to handle authentication -and redirection. - - - -When using the synchronous API, the callbacks and signal handlers will -be invoked during the call to soup_session_send_message. - - - -To automatically set up handlers on all messages sent via a session, -you can connect to the session's request_started -signal, and add handlers to each message from there. - - - - Handling Authentication @@ -467,38 +486,39 @@ linkend="soup-session-unpause-message">soup_session_unpause_message + +By default, NTLM authentication is not enabled. To add NTLM support to +a session, call: + + + + soup_session_add_feature_by_type (session, SOUP_TYPE_AUTH_NTLM); + + + +(You can also disable Basic or Digest authentication by calling soup_session_remove_feature_by_type +on SOUP_TYPE_AUTH_BASIC +or SOUP_TYPE_AUTH_DIGEST.) + + Multi-threaded usage -The only explicitly thread-safe operations in -libsoup are SoupSessionSync's -implementations of the SoupSession methods. So -after creating a SoupSessionSync, you can call soup_session_send_message -and soup_session_cancel_message -on it from any thread. But, eg, while the session is processing a -message, you should not call any SoupMessage methods on it -from any thread other than the one in which it is being sent. (That -is, you should not call any SoupMessage methods on it -except from a message or session callback or signal handler.) +A SoupSession 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 GMainContext. -All other objects (including SoupSessionAsync) -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 GMainContext on a session, -socket, etc, then you can only use that object from the thread in -which that GMainContext is running.) +SoupMessage is +not 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. @@ -508,7 +528,8 @@ which that GMainContext is running.) A few sample programs are available in the -libsoup sources: +libsoup sources, in the +examples directory: @@ -517,21 +538,6 @@ A few sample programs are available in the HTTP GET utility using the asynchronous API. - - getbug is a trivial - demonstration of the XMLRPC interface. - (xmlrpc-test provides - a slightly more complicated example.) - - - - auth-test shows how to use - authentication handlers and status-code handlers, although in - a fairly unusual way. - - simple-proxy uses both the client and server APIs to create a simple (and not very @@ -544,11 +550,7 @@ A few sample programs are available in the -More complicated examples are available in GNOME CVS. The libsoup -pages on the GNOME wiki include a list of applications using -libsoup. +More complicated examples are available in GNOME git. 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 @@ Tutorial + 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 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 @@ + + + + +libsoup Client SoupRequest API +3 +LIBSOUP Library + + + +libsoup Client SoupRequest APIUsing +libsoup with a mix of http and non-http URIs. + + + +<type>SoupRequest</type> + + +SoupRequest is an +abstract type representing a request for a particular URI. The +SoupRequest API is an alternative to the SoupMessage-based SoupSession APIs which may be +useful to programs that want to deal with multiple kinds of URIs. + + + +SoupRequest officially became part of the +libsoup API in 2.42 with the addition of +soup_session_request +and the related functions. However, parts of it are also available as +far back as libsoup 2.34 via the +(now-deprecated) SoupRequester session feature, if you +define LIBSOUP_USE_UNSTABLE_REQUEST_API before +including the libsoup headers. + + + +Additionally, before libsoup 2.42, the +SoupRequest API was the only way to stream an HTTP +response body via GInputStream. As of 2.42, +there are streaming APIs based on SoupMessage (soup_session_send +and soup_session_send_async), +so applications that are using SoupRequest with only +http and https URIs can be +ported to those APIs now. + + + + + +Creating a SoupRequest + + +There are four SoupSession methods for creating +SoupRequests: + + + + + + soup_session_request + takes an arbitrary URI as a string, and returns a SoupRequest. + + + + + soup_session_request_uri + takes an arbitrary URI as a SoupURI, + and returns a SoupRequest. + + + + + soup_session_request_http + takes an HTTP method and an http or https URI as a string, and returns a SoupRequestHTTP. + + + + + soup_session_request_http_uri + takes an HTTP method and an http or https URI as a SoupURI, + and returns a SoupRequestHTTP. + + + + + + + +Sending a SoupRequest + + +Once you have created a SoupRequest, you can send it with +either soup_request_send +or soup_request_send_async. +This will provide you with a GInputStream which you can +read to get the response body. + + + +After sending, you can use soup_request_get_content_length +and soup_request_get_content_type +to get information about the response body. + + + +As with the streaming SoupMessage-based APIs, +soup_request_send and +soup_request_send_async 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 status_code field to determine +whether the request was successful or not at the HTTP level (ie, "200 +OK" vs "401 Bad Request"). (You can call soup_request_http_get_message +to get the request's corresponding SoupMessage, to look at the +status code or other HTTP metadata.) + + + + + +Supported URI types, and adding your own + + +Different URI types are implemented by different subclasses of +SoupRequest. libsoup currently +implements three SoupRequest classes: + + + + + SoupRequestHTTP + + Handles http and + https URI. + + + + SoupRequestData + + Handles data URIs containing inline data. + + + + SoupRequestFile + + Handles file and + resource URIs. + If you request a URI corresponding to a directory, this + will generate an HTML listing of the directory. + + + + + +You can add additional URI types by implementing your own +SoupRequest subclass; set the +SoupRequestClass's schemes +field to point to a NULL-terminated array of scheme +names, implement the various SoupRequest methods, and +then register the type with your SoupSession by calling +soup_session_add_feature_by_type +and passing the GType of +your request class. + + + + + -- cgit v1.2.1