Porting to the new SoupSession

Porting to the new SoupSession — Notes on porting from SoupSessionAsync and SoupSessionSync to SoupSession

Introduction

As of libsoup 2.42, SoupSession is no longer an abstract class, and the base SoupSession class is now preferred over its traditional subclasses, SoupSessionAsync and SoupSessionSync.

There are several changes in behavior between the old and new sessions to be aware of.


Different defaults

The new SoupSession has different (and hopefully better) defaults than SoupSessionAsync and SoupSessionSync:

  • The system TLS/SSL certificate database is used by default to validate https certificates, and sites with invalid certificates will refuse to load with a SOUP_STATUS_SSL_FAILED error.

    You can still override the CA database as before, by setting the "ssl-ca-file" property, although the "tls-database" property is preferred, since it allows you to do proper error handling.

    If you want to accept all certificates, set "ssl-strict" to FALSE. Note that libsoup will still check certificates, it will just continue with the HTTP request even if the certificate fails to validate. You can use soup_message_get_https_status() to look at the certificate after the fact.

  • The "timeout" and "idle-timeout" properties both default to 60 seconds.

  • The "http-aliases" property defaults to NULL, meaning that URI schemes like "webcal" and "dav" (and "ftp") are not considered to be aliases for "http", and so libsoup will not accept requests for such URIs, and will not follow redirects to such URIs.

  • The new "proxy-resolver" property is now initialized to the default GProxyResolver, meaning that it will automatically use the user's system proxy configuration. This replaces the use of the SoupProxyResolverDefault, session feature in earlier releases. You can set this property to NULL if you don't want to use proxies, and the "proxy-uri" property still works if you want to use a single proxy for all requests.

  • Every session gets a SoupContentDecoder attached to it by default, meaning that it will automatically handle (and request) "gzip"- and "deflate"-encoded response bodies.


Differences in feature behavior

If you are using NTLM authentication, the new SoupSession behaves slightly differently from the old session types.

First, the deprecated SOUP_SESSION_USE_NTLM property is no longer supported. If you want to add support for NTLM to a session, call soup_session_add_feature_by_type(), passing SOUP_TYPE_AUTH_NTLM.

Second, with the old session types, enabling NTLM would cause all (otherwise-unauthenticated) requests to be sent with an NTLM request in the Authorization header. That is, libsoup would assume that all servers supported NTLM, and would attempt to begin negotiating NTLM authentication before the server ever returned a 401 response. With the plain SoupSession, this no longer happens. If you want the old behavior, you need to call soup_auth_manager_use_auth() for each host to "preload" the NTLM authentication:

1
2
3
4
5
6
7
8
9
10
SoupAuthManager *auth_manager;
SoupAuth *auth;
SoupURI *uri;

auth_manager = SOUP_AUTH_MANAGER (soup_session_get_feature (session, SOUP_TYPE_AUTH_MANAGER));
auth = g_object_new (SOUP_TYPE_AUTH_NTLM, NULL);
uri = soup_uri_new ("http://ntlm-using-host.example.com/");
soup_auth_manager_use_auth (auth_manager, uri, auth);
g_object_unref (auth);
soup_uri_free (auth);

Differences in SoupMessage-sending APIs

SoupSessionAsync always uses asynchronous I/O, and SoupSessionSync always uses blocking I/O, regardless of the operation. In the new SoupSession, soup_session_queue_message() uses asynchronous I/O (like SoupSessionAsync), and soup_session_send_message() uses blocking I/O (like SoupSessionSync). There is no API on the plain SoupSession that simulates the effect of calling soup_session_send_message() on a SoupSessionAsync (ie, running the main loop internally), or of calling soup_session_queue_message() on a SoupSessionSync (ie, automatically sending the request in another thread).


Differences in Asynchronous I/O

As compared to SoupSessionAsync, SoupSession behaves more like gio with respect to asynchronous I/O.

In particular, the "async-context" and "use-thread-context" properties are now effectively unused, and the session always queues asynchronous requests in the GMainContext that was is the thread default when the asynchronous operation is started. Session bookkeeping tasks (like closing idle connections) happen in the context that was thread default when the session was created.

Additionally, soup_session_cancel_message() now acts asynchronously when you cancel an asynchronous request; rather than having the request's callback be called from inside soup_session_cancel_message(), it just gets called when you need return to the main loop.