Porting to the new SoupSession

## 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.