SRA Lab Open Source Code

14Jan/110

libsoup and Django

If you need to interface C code with a Django app, you should consider to use libsoup. It's a nice HTTP client/server library based on GObject and integrated with the glib main loop.

This is the code I used to authenticate with libsoup against my Django application (and the code is similar for any forms):

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <glib.h>

#include <libsoup/soup.h>
#include <libsoup/soup-auth.h>

static char* django_get_csrftoken_from_body(SoupMessage *msg)
{
    char *csrftoken = NULL;
    char *p_found;

    p_found = g_strrstr_len(msg->response_body->data,
                msg->response_body->length,
                "csrfmiddlewaretoken");
    if (p_found != NULL) {
    csrftoken = g_strndup(p_found + strlen("csrfmiddlewaretoken' value='"),
                  strlen("c711343cd20077a3aa869fcc9b931ff3"));
    }
    return csrftoken;
}

static int django_authenticate(SoupSession *session, const char *base_uri)
{
    char *uri;
    SoupMessage *msg;
    char *csrftoken;

    uri = g_strconcat(base_uri, "login/", NULL);
    msg = soup_message_new(SOUP_METHOD_GET, uri);
    soup_session_send_message(session, msg);
    printf("Login Status Code: %d\n", msg->status_code);
    if (msg->status_code != 200) {
    g_object_unref(msg);
    g_free(uri);
    return -1;
    }

    csrftoken = django_get_csrftoken_from_body(msg);
    g_object_unref(msg);

    printf("CSRF token %s\n", csrftoken);

    msg = soup_form_request_new("POST", uri,
                "username", "MYUSERNAME",
                "password", "MYPASSWORD",
                "csrfmiddlewaretoken", csrftoken,
                NULL);
    soup_session_send_message(session, msg);
    printf("POST Login Status Code: %d\n", msg->status_code);
    printf("Message %s\n", msg->response_body->data);

    g_free(csrftoken);
    g_object_unref(msg);
    g_free(uri);

    return 0;
}

int main(int argc, char** argv)
{
    SoupSession *session;
    SoupCookieJar *jar;

    g_type_init();

    session = soup_session_sync_new();

    /* Accept all cookies */
    soup_session_add_feature_by_type(session, SOUP_TYPE_COOKIE_JAR);
    jar = SOUP_COOKIE_JAR(soup_session_get_feature(session,
                           SOUP_TYPE_COOKIE_JAR));
    soup_cookie_jar_set_accept_policy(jar, SOUP_COOKIE_JAR_ACCEPT_ALWAYS);

    django_authenticate(session, "http://localhost:8000/");

    soup_session_abort(session);
    g_object_unref(session);

    return 0;
}