Migrating from libsoup 2

Removed APIs

This is a list of APIs that have been removed:

Moved authenticate signal

The SoupSession::authenticate signal has been replaced by SoupMessage::authenticate. It now allows returning TRUE to signifiy if you will handle authentication which allows for asynchronous handling.

Structs are private

You can no longer directly access various structs such as SoupMessage. These are now accessed by getters and setters. See below for direct conversions:

Struct field Getter/Setter function
SoupMessage.method soup_message_get_method()
SoupMessage.status_code soup_message_get_status()
SoupMessage.reason_phrase soup_message_get_reason_phrase()
SoupMessage.uri soup_message_get_uri(), soup_message_set_uri()
SoupMessage.request_headers soup_message_get_request_headers()
SoupMessage.response_headers soup_message_get_response_headers()
SoupMessage.request_body soup_message_set_request_body(), soup_message_set_request_body_from_bytes()
SoupMessage.response_body See section on IO

Similar struct changes exist for SoupCookie but have very straightforward replacements.

URI type changed

The SoupURI type has been replaced with the GUri type which has some implications.

Creating a GUri is generally as simple as g_uri_parse (uri, SOUP_HTTP_URI_FLAGS, NULL). You may want to add G_URI_FLAGS_PARSE_RELAXED to accept input that used to be considered valid.

Note that unlike SoupURI GUri is an immutable type so you cannot change the contents of one after it has been constructed. We provide soup_copy_uri() to aid in modifying them.

The equivalent behavior to soup_uri_to_string (uri, FALSE) is g_uri_to_string_partial (uri, G_URI_HIDE_PASSWORD).

Since GUri does not provide any function to check for equality soup_uri_equal() still exists.

Sending a OPTIONS message with a path of * is no longer a valid URI and has been replaced with SoupMessage:options-ping.

Status codes no longer used for internal errors

Previously SoupStatus was used to hold libsoup errors (SOUP_STATUS_IS_TRANSPORT_ERROR()). Now all of these errors are propagated up through the normal GError method on the various APIs to send messages. Here is a mapping chart between the status codes and new errors:

Old Status Codes New GError
SOUP_STATUS_CANCELLED G_IO_ERROR_CANCELLED
SOUP_STATUS_MALFORMED SOUP_SESSION_ERROR_PARSING, SOUP_SESSION_ERROR_ENCODING
SOUP_STATUS_TOO_MANY_REDIRECTS SOUP_SESSION_ERROR_TOO_MANY_REDIRECTS

All IO is now GIOStream-based

Previously there were ways to allow libsoup to read data into buffers and for you to read from those buffers such as SoupMessage:response-body, SoupMessage:response-body-data, and SoupMessage::got-chunk.

libsoup no longer stores a buffer of data for you to read from and instead it returns a GInputStream which you read from using normal GIO APIs.

If you want to simply request a buffer and nothing more you can use the soup_session_send_and_read() or soup_session_send_and_read_async() APIs.

This also applies to writing data where you can set a GOutputStream using soup_message_set_request_body() or use the convenience API soup_message_set_request_body_from_bytes() to use a GBytes buffer.

Clarification on thread-safety

In libsoup 2 there was an attempt at making various APIs of the library thread-safe. However this was never well tested, maintained, or documented.

In libsoup 3 it now behaves in line with other GObject libraries. Once you create a SoupSession all usage of that session must happen on the same thread. You may create seperate sessions per thread but in most use-cases you should be using the async APIs which handle non-blocking IO for you.