# Advanced Usage

## Customizing Session Options

When you create the session with `soup_session_new_with_options()`, you can specify various additional options. See the SoupSession documentation for more details but these may be interesting: `SoupSession:max-conns` and `SoupSession:max-conns-per-host`, `SoupSession:user-agent`, `SoupSession:timeout`, `SoupSession:accept-language` and `SoupSession:accept-language-auto`

## Adding Session Features

Additional session functionality is provided as SoupSessionFeatures, which can be added to or removed from a session.

One such feature is SoupContentDecoder which is added by default. This advertises to servers that the client supports compression, and automatically decompresses compressed responses.

Some other available features that you can add include:

SoupLogger

  A debugging aid, which logs all of libsoup's HTTP traffic to `stdout` (or another place you specify).

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, and SoupCookieJarDB uses a SQLite database.

SoupContentSniffer

  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.

Use the `soup_session_add_feature_by_type()` function to add features that don't require any configuration (such as SoupContentSniffer), and the `soup_session_add_feature()`function to add features that must be constructed first (such as SoupLogger). For example, an application might do something like the following:

    session = soup_session_new ();
    soup_session_add_feature_by_type (session, SOUP_TYPE_CONTENT_SNIFFER);

    if (debug_level) {
        SoupLogger *logger = soup_logger_new (debug_level);
        soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger));
        g_object_unref (logger);
    }

You can also remove features by calling `soup_session_remove_feature()` or `soup_session_remove_feature_by_type()`

.

See the Additional Features section for other features.

## Using a proxy

By default libsoup tries to respect the default proxy (as best as `g_proxy_resolver_get_default()` knows), however you can set a custom one or disable it outright using the `SoupSession:proxy-resolver` property. For example:

    {
        GProxyResolver *resolver = g_simple_proxy_resolver_new ("https://my-proxy-example.org", NULL);
        SoupSession *session = soup_session_new_with_options ("proxy-resolver", resolver, NULL);
        g_object_unref (resolver);
    }

## Using the SoupMessage API

The SoupMessage type contains all the state for a request and response pair that you send and recieve to a server. For many more complex tasks you will have to create one of these and send it with the `soup_session_send()` function. For example this sends a request with the `HEAD` method:

    {
        SoupSession *session = soup_session_new ();
        SoupMessage *msg = soup_message_new (SOUP_METHOD_HEAD, "https://example.org");

        // This allows you to also customize the request headers:
        SoupMessageHeaders *request_headers = soup_message_get_request_headers (msg);
        soup_message_headers_replace (request_headers, "Foo", "Bar");

        GInputStream *in_stream = soup_session_send (session, msg, NULL, NULL);
        if (in_stream) {
            g_print ("Message was sent and recived a response of %u (%s)\n",
                     soup_message_get_status (msg), soup_message_get_reason_phrase (msg));
            // You can also inspect the response headers via soup_message_get_response_headers();
            g_object_unref (in_stream);
        }

        g_object_unref (msg);
        g_object_unref (session);
    }

## Handling authentication

    static gboolean
    authenticate_callback (SoupMessage *msg, SoupAuth *auth, gboolean retrying, gpointer user_data)
    {
        if (retrying) {
            // Maybe don't try again if our password failed
            return FALSE;
        }

        soup_auth_authenticate (auth, "username", "password");

        // Returning TRUE means we have or *will* handle it.
        // soup_auth_authenticate() or soup_auth_cancel() can be called later
        // for example after showing a prompt to the user or loading the password
        // from a keyring.
        return TRUE;
    }

    int main (int argc, char **argv)
    {
        SoupSession *session = soup_session_new ();
        SoupMessage *msg = soup_message_new (SOUP_METHOD_GET, "https://example.org");
        g_signal_connect (msg, "authenticate", G_CALLBACK (authenticate_callback), NULL);
        GInputStream *in_stream = soup_session_send (session, msg, NULL, NULL);

        if (in_stream) {
            g_object_unref (in_stream);
        }

        return 0;
    }