#include <stdlib.h>

#include <libsoup/soup.h>
#include <glib.h>

GMainLoop *loop;
SoupServer *server;
gint64 size = 8067343738LL;
gint64 current = 0;
gint64 bufsize = 65536;
char buffer[65536] = { 0 };

SoupMessage *message;

gboolean
push_data (gpointer data)
{
    soup_message_body_append (message->response_body, SOUP_MEMORY_COPY, buffer, bufsize);
    soup_server_unpause_message (server, message);

    return FALSE;
}

gpointer thread(gpointer data)
{
    while (current < size) {
        g_idle_add (push_data, NULL);
        usleep (1000);
        current += bufsize;
    }
}

static void
serve (SoupServer        *srv,
       SoupMessage       *msg,
       const char        *path,
       GHashTable        *query,
       SoupClientContext *context,
       gpointer           user_data)
{
    g_debug ("trying to serve %s", path);
    soup_server_pause_message (server, msg);
    soup_message_body_set_accumulate (msg->response_body, FALSE);
    soup_message_headers_set_encoding (msg->response_headers, SOUP_ENCODING_EOF);
    soup_message_headers_set_content_length (msg->response_headers, size);
    soup_message_set_status (msg, SOUP_STATUS_OK);

    message = msg;

    g_thread_create (thread, NULL, FALSE, NULL);
}

int
main (int argc, char *argv[])
{
    g_type_init ();
    server = soup_server_new (SOUP_SERVER_PORT, 12345, NULL);
    g_debug ("Listening on port %d", soup_server_get_port (server));

    soup_server_add_handler (server, "/foo", serve, NULL, NULL);
    soup_server_run_async (server);

    loop = g_main_loop_new (NULL, FALSE);
    g_main_loop_run (loop);

    g_object_unref (loop);
    g_object_unref (server);

    return EXIT_SUCCESS;
}
