#### Migrating from libsoup 2

## Removed APIs

This is a list of APIs that have been removed:

- XML-RPC support.
- Handling of `file://` and `data://` URIs You should use `GFile` for the former and `soup_uri_decode_data_uri()` for the latter.
- Define aliases for property names You must use the string name of properties directly which works in libsoup 2 already.
- `SoupSession:add-feature` and `SoupSession:add-feature-by-type` You must call `soup_session_add_feature()` and `soup_session_add_feature_by_type()` directly.
- `SoupRequest`: You should use `soup_session_send()` or `soup_session_send_async()` methods.
- `SoupAddress` has been replaced with `GInetAddress` and `GNetworkAddress`.
- `SoupSocket` has been removed.
- `SoupProxyResolverDefault` is replaced by `g_proxy_resolver_get_default()`.
- `SoupBuffer` has been replaced by `GBytes` and `GByteArray`.
- `SoupDate` has been replaced by `GDateTime`.
- `SoupSession:ssl-strict` has been removed in favor of using the `SoupMessage::accept-certificate` signal.
- `soup_session_cancel_message()` has been removed instead you pass a `GCancellable` to APIs and call `g_cancellable_cancel()`.

## Moved authenticate signal

The `SoupSession::authenticate` signal has been replaced by `SoupMessage::authenticate`. It now allows returning `TRUE` to signify 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_uri_copy()` 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:is-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 `SoupServerMessage::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 `GInputStream` 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.

libsoup 3 was initially designed to behave in line with other GObject libraries. Once you create a `SoupSession` all usage of that session must happen on the same thread. However, in version 3.2 thread safety support was introduced again, with the same approach as libsoup2.