/* ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */

#include <stdlib.h>

#define APR_WANT_MEMFUNC
#include <apr_want.h>
#include <apr.h>
#include <apr_uri.h>
#include <apr_strings.h>
#include <apr_atomic.h>
#include <apr_base64.h>
#include <apr_getopt.h>
#include <apr_xml.h>
#include <apr_thread_proc.h>
#include <apr_thread_mutex.h>
#include <apr_thread_cond.h>
#include <apr_version.h>

#include "serf.h"
#include "serf_bucket_util.h"

/*#define SERF_VERBOSE*/

#if !APR_HAS_THREADS
#error serf spider needs threads.
#endif

/* This is a rough-sketch example of how a multi-threaded spider could be
 * constructed using serf.
 *
 * A network thread will read in a URL and feed it into an expat parser.
 * After the entire response is read, the XML structure and the path is
 * passed to a set of parser threads.  These threads will scan the document
 * for HTML href's and queue up any links that it finds.
 *
 * It does try to stay on the same server as it only uses one connection.
 *
 * Because we feed the responses into an XML parser, the documents must be
 * well-formed XHTML.
 *
 * There is no duplicate link detection.  You've been warned.
 */

/* The structure passed to the parser thread after we've read the entire
 * response.
 */
typedef struct doc_path_t {
    apr_xml_doc *doc;
    char *path;
    apr_pool_t *pool;
} doc_path_t;

typedef struct app_baton_t {
    const char *authn;
    int using_ssl;
    serf_ssl_context_t *ssl_ctx;
    serf_bucket_alloc_t *bkt_alloc;
} app_baton_t;

static void closed_connection(serf_connection_t *conn,
                              void *closed_baton,
                              apr_status_t why,
                              apr_pool_t *pool)
{
    if (why) {
        abort();
    }
}

static apr_status_t conn_setup(apr_socket_t *skt,
                                serf_bucket_t **input_bkt,
                                serf_bucket_t **output_bkt,
                                void *setup_baton,
                                apr_pool_t *pool)
{
    serf_bucket_t *c;
    app_baton_t *ctx = setup_baton;

    c = serf_bucket_socket_create(skt, ctx->bkt_alloc);
    if (ctx->using_ssl) {
        c = serf_bucket_ssl_decrypt_create(c, ctx->ssl_ctx, ctx->bkt_alloc);
    }

    *input_bkt = c;

    return APR_SUCCESS;
}

static serf_bucket_t* accept_response(serf_request_t *request,
                                      serf_bucket_t *stream,
                                      void *acceptor_baton,
                                      apr_pool_t *pool)
{
    serf_bucket_t *c;
    serf_bucket_alloc_t *bkt_alloc;

    /* get the per-request bucket allocator */
    bkt_alloc = serf_request_get_alloc(request);

    /* Create a barrier so the response doesn't eat us! */
    c = serf_bucket_barrier_create(stream, bkt_alloc);

    return serf_bucket_response_create(c, bkt_alloc);
}

typedef struct handler_baton_t {
    serf_bucket_alloc_t *allocator;
#if APR_MAJOR_VERSION > 0
    apr_uint32_t *requests_outstanding;
#else
    apr_atomic_t *requests_outstanding;
#endif
    serf_bucket_alloc_t *doc_queue_alloc;
    apr_array_header_t *doc_queue;
    apr_thread_cond_t *doc_queue_condvar;

    const char *hostinfo;

    /* includes: path, query, fragment. */
    char *full_path;
    apr_size_t full_path_len;

    char *path;
    apr_size_t path_len;

    char *query;
    apr_size_t query_len;

    char *fragment;
    apr_size_t fragment_len;

    apr_xml_parser *parser;
    apr_pool_t *parser_pool;

    int hdr_read;
    int is_html;

    serf_response_acceptor_t acceptor;
    void *acceptor_baton;
    serf_response_handler_t handler;

    app_baton_t *app_ctx;
} handler_baton_t;

/* Kludges for APR 0.9 support. */
#if APR_MAJOR_VERSION == 0
#define apr_atomic_inc32 apr_atomic_inc
#define apr_atomic_dec32 apr_atomic_dec
#define apr_atomic_read32 apr_atomic_read
#define apr_atomic_set32 apr_atomic_set
#endif

static apr_status_t handle_response(serf_request_t *request,
                                    serf_bucket_t *response,
                                    void *handler_baton,
                                    apr_pool_t *pool)
{
    const char *data;
    apr_size_t len;
    serf_status_line sl;
    apr_status_t status;
    handler_baton_t *ctx = handler_baton;

    if (!response) {
        /* Oh no!  We've been cancelled! */
        abort();
    }

    status = serf_bucket_response_status(response, &sl);
    if (status) {
        if (APR_STATUS_IS_EAGAIN(status)) {
            return APR_SUCCESS;
        }
        abort();
    }

    while (1) {
        status = serf_bucket_read(response, 2048, &data, &len);

        if (SERF_BUCKET_READ_ERROR(status))
            return status;

        /*fwrite(data, 1, len, stdout);*/

        if (!ctx->hdr_read) {
            serf_bucket_t *hdrs;
            const char *val;

            printf("Processing %s\n", ctx->path);

            hdrs = serf_bucket_response_get_headers(response);
            val = serf_bucket_headers_get(hdrs, "Content-Type");
            /* FIXME: This check isn't quite right because Content-Type could
             * be decorated; ideally strcasestr would be correct.
             */
            if (val && strcasecmp(val, "text/html") == 0) {
                ctx->is_html = 1;
                apr_pool_create(&ctx->parser_pool, NULL);
                ctx->parser = apr_xml_parser_create(ctx->parser_pool);
            }
            else {
                ctx->is_html = 0;
            }
            ctx->hdr_read = 1;
        }
        if (ctx->is_html) {
            apr_status_t xs;

            xs = apr_xml_parser_feed(ctx->parser, data, len);
            /* Uh-oh. */
            if (xs) {
#ifdef SERF_VERBOSE
                printf("XML parser error (feed): %d\n", xs);
#endif
                ctx->is_html = 0;
            }
        }

        /* are we done yet? */
        if (APR_STATUS_IS_EOF(status)) {

            if (ctx->is_html) {
                apr_xml_doc *xmld;
                apr_status_t xs;
                doc_path_t *dup;

                xs = apr_xml_parser_done(ctx->parser, &xmld);
                if (xs) {
#ifdef SERF_VERBOSE
                    printf("XML parser error (done): %d\n", xs);
#endif
                    return xs;
                }
                dup = (doc_path_t*)
                    serf_bucket_mem_alloc(ctx->doc_queue_alloc,
                                          sizeof(doc_path_t));
                dup->doc = xmld;
                dup->path = (char*)serf_bucket_mem_alloc(ctx->doc_queue_alloc,
                                                         ctx->path_len);
                memcpy(dup->path, ctx->path, ctx->path_len);
                dup->pool = ctx->parser_pool;

                *(doc_path_t **)apr_array_push(ctx->doc_queue) = dup;

                apr_thread_cond_signal(ctx->doc_queue_condvar);
            }

            apr_atomic_dec32(ctx->requests_outstanding);
            serf_bucket_mem_free(ctx->allocator, ctx->path);
            if (ctx->query) {
                serf_bucket_mem_free(ctx->allocator, ctx->query);
                serf_bucket_mem_free(ctx->allocator, ctx->full_path);
            }
            if (ctx->fragment) {
                serf_bucket_mem_free(ctx->allocator, ctx->fragment);
            }
            serf_bucket_mem_free(ctx->allocator, ctx);
            return APR_EOF;
        }

        /* have we drained the response so far? */
        if (APR_STATUS_IS_EAGAIN(status))
            return APR_SUCCESS;

        /* loop to read some more. */
    }
    /* NOTREACHED */
}

typedef struct parser_baton_t {
    apr_uint32_t *requests_outstanding;
    serf_connection_t *connection;
    apr_array_header_t *doc_queue;
    serf_bucket_alloc_t *doc_queue_alloc;

    apr_thread_cond_t *condvar;
    apr_thread_mutex_t *mutex;

    /* Master host: for now, we'll stick to one host. */
    const char *hostinfo;

    app_baton_t *app_ctx;
} parser_baton_t;

static apr_status_t setup_request(serf_request_t *request,
                                  void *setup_baton,
                                  serf_bucket_t **req_bkt,
                                  serf_response_acceptor_t *acceptor,
                                  void **acceptor_baton,
                                  serf_response_handler_t *handler,
                                  void **handler_baton,
                                  apr_pool_t *pool)
{
    handler_baton_t *ctx = setup_baton;
    serf_bucket_t *hdrs_bkt;

    *req_bkt = serf_bucket_request_create("GET", ctx->full_path, NULL,
                                          serf_request_get_alloc(request));

    hdrs_bkt = serf_bucket_request_get_headers(*req_bkt);

    /* FIXME: Shouldn't we be able to figure out the host ourselves? */
    serf_bucket_headers_setn(hdrs_bkt, "Host", ctx->hostinfo);
    serf_bucket_headers_setn(hdrs_bkt, "User-Agent",
                             "Serf/" SERF_VERSION_STRING);

    /* Shouldn't serf do this for us? */
    serf_bucket_headers_setn(hdrs_bkt, "Accept-Encoding", "gzip");

    if (ctx->app_ctx->authn != NULL) {
        serf_bucket_headers_setn(hdrs_bkt, "Authorization",
                                 ctx->app_ctx->authn);
    }

    if (ctx->app_ctx->using_ssl) {
        if (ctx->app_ctx->ssl_ctx == NULL) {
            *req_bkt = serf_bucket_ssl_encrypt_create(*req_bkt, NULL,
                                                      ctx->app_ctx->bkt_alloc);
            ctx->app_ctx->ssl_ctx =
                serf_bucket_ssl_encrypt_context_get(*req_bkt);
        }
        else {
            *req_bkt =
                serf_bucket_ssl_encrypt_create(*req_bkt, ctx->app_ctx->ssl_ctx,
                                               ctx->app_ctx->bkt_alloc);
        }
    }


#ifdef SERF_VERBOSE
    printf("Url requesting: %s\n", ctx->full_path);
#endif

    *acceptor = ctx->acceptor;
    *acceptor_baton = ctx->acceptor_baton;
    *handler = ctx->handler;
    *handler_baton = ctx;

    return APR_SUCCESS;
}

static apr_status_t create_request(const char *hostinfo,
                                   const char *path,
                                   const char *query,
                                   const char *fragment,
                                   parser_baton_t *ctx,
                                   apr_pool_t *tmppool)
{
    handler_baton_t *new_ctx;

    if (hostinfo) {
        /* Yes, this is a pointer comparison; not a string comparison. */
        if (hostinfo != ctx->hostinfo) {
            /* Not on the same host; ignore */
            return APR_SUCCESS;
        }
    }

    new_ctx = (handler_baton_t*)serf_bucket_mem_alloc(ctx->app_ctx->bkt_alloc,
                                                      sizeof(handler_baton_t));
    new_ctx->allocator = ctx->app_ctx->bkt_alloc;
    new_ctx->requests_outstanding = ctx->requests_outstanding;
    new_ctx->app_ctx = ctx->app_ctx;

    /* See above: this example restricts ourselves to the same vhost. */
    new_ctx->hostinfo = ctx->hostinfo;

    /* we need to copy it so it falls under the request's scope. */
    new_ctx->path_len = strlen(path);
    new_ctx->path = (char*)serf_bucket_mem_alloc(ctx->app_ctx->bkt_alloc,
                                                 new_ctx->path_len + 1);
    memcpy(new_ctx->path, path, new_ctx->path_len + 1);

    /* we need to copy it so it falls under the request's scope. */
    if (query) {
        new_ctx->query_len = strlen(query);
        new_ctx->query = (char*)serf_bucket_mem_alloc(ctx->app_ctx->bkt_alloc,
                                                      new_ctx->query_len + 1);
        memcpy(new_ctx->query, query, new_ctx->query_len + 1);
    }
    else {
        new_ctx->query = NULL;
        new_ctx->query_len = 0;
    }

    /* we need to copy it so it falls under the request's scope. */
    if (fragment) {
        new_ctx->fragment_len = strlen(fragment);
        new_ctx->fragment =
            (char*)serf_bucket_mem_alloc(ctx->app_ctx->bkt_alloc,
                                         new_ctx->fragment_len + 1);
        memcpy(new_ctx->fragment, fragment, new_ctx->fragment_len + 1);
    }
    else {
        new_ctx->fragment = NULL;
        new_ctx->fragment_len = 0;
    }

    if (!new_ctx->query) {
        new_ctx->full_path = new_ctx->path;
        new_ctx->full_path_len = new_ctx->path_len;
    }
    else {
        new_ctx->full_path_len = new_ctx->path_len + new_ctx->query_len;
        new_ctx->full_path =
            (char*)serf_bucket_mem_alloc(ctx->app_ctx->bkt_alloc,
                                         new_ctx->full_path_len + 1);
        memcpy(new_ctx->full_path, new_ctx->path, new_ctx->path_len);
        memcpy(new_ctx->full_path + new_ctx->path_len, new_ctx->query,
               new_ctx->query_len + 1);
    }

    new_ctx->hdr_read = 0;

    new_ctx->doc_queue_condvar = ctx->condvar;
    new_ctx->doc_queue = ctx->doc_queue;
    new_ctx->doc_queue_alloc = ctx->doc_queue_alloc;

    new_ctx->acceptor = accept_response;
    new_ctx->acceptor_baton = &ctx->app_ctx;
    new_ctx->handler = handle_response;

    apr_atomic_inc32(ctx->requests_outstanding);

    serf_connection_request_create(ctx->connection, setup_request, new_ctx);

    return APR_SUCCESS;
}

static apr_status_t put_req(const char *c, const char *orig_path,
                            parser_baton_t *ctx, apr_pool_t *pool)
{
    apr_status_t status;
    apr_uri_t url;

    /* Build url */
#ifdef SERF_VERBOSE
    printf("Url discovered: %s\n", c);
#endif

    status = apr_uri_parse(pool, c, &url);

    /* We got something that was minimally useful. */
    if (status == 0 && url.path) {
        const char *path, *query, *fragment;

        /* This is likely a relative URL. So, merge and hope for the
         * best.
         */
        if (!url.hostinfo && url.path[0] != '/') {
            struct iovec vec[2];
            char *c;
            apr_size_t nbytes;

            c = strrchr(orig_path, '/');

            /* assert c */
            if (!c) {
                return APR_EGENERAL;
            }

            vec[0].iov_base = (char*)orig_path;
            vec[0].iov_len = c - orig_path + 1;

            /* If the HTML is cute and gives us ./foo - skip the ./ */
            if (url.path[0] == '.' && url.path[1] == '/') {
                vec[1].iov_base = url.path + 2;
                vec[1].iov_len = strlen(url.path + 2);
            }
            else if (url.path[0] == '.' && url.path[1] == '.') {
                /* FIXME We could be cute and consolidate the path; we're a
                 * toy example.  So no.
                 */
                vec[1].iov_base = url.path;
                vec[1].iov_len = strlen(url.path);
            }
            else {
                vec[1].iov_base = url.path;
                vec[1].iov_len = strlen(url.path);
            }

            path = apr_pstrcatv(pool, vec, 2, &nbytes);
        }
        else {
            path = url.path;
        }

        query = url.query;
        fragment = url.fragment;

        return create_request(url.hostinfo, path, query, fragment, ctx, pool);
    }

    return APR_SUCCESS;
}

static apr_status_t find_href(apr_xml_elem *e, const char *orig_path,
                              parser_baton_t *ctx, apr_pool_t *pool)
{
    apr_status_t status;

    do {
        /* print */
        if (e->name[0] == 'a' && e->name[1] == '\0') {
            apr_xml_attr *a;

            a = e->attr;
            while (a) {
                if (strcasecmp(a->name, "href") == 0) {
                    break;
                }
                a = a->next;
            }
            if (a) {
                status = put_req(a->value, orig_path, ctx, pool);
                if (status) {
                    return status;
                }
            }
        }

        if (e->first_child) {
            status = find_href(e->first_child, orig_path, ctx, pool);
            if (status) {
                return status;
            }
        }

        e = e->next;
    }
    while (e);

    return APR_SUCCESS;
}

static apr_status_t find_href_doc(apr_xml_doc *doc, const char *path,
                                  parser_baton_t *ctx,
                                  apr_pool_t *pool)
{
    return find_href(doc->root, path, ctx, pool);
}

static void * APR_THREAD_FUNC parser_thread(apr_thread_t *thread, void *data)
{
    apr_status_t status;
    apr_pool_t *pool, *subpool;
    parser_baton_t *ctx;

    ctx = (parser_baton_t*)data;
    pool = apr_thread_pool_get(thread);

    apr_pool_create(&subpool, pool);

    while (1) {
        doc_path_t *dup;

        apr_pool_clear(subpool);

        /* Grab it. */
        apr_thread_mutex_lock(ctx->mutex);
        /* Sleep. */
        apr_thread_cond_wait(ctx->condvar, ctx->mutex);

        /* Fetch the doc off the list. */
        if (ctx->doc_queue->nelts) {
            dup = *(doc_path_t**)(apr_array_pop(ctx->doc_queue));
            /* dup = (ctx->doc_queue->conns->elts)[0]; */
        }
        else {
            dup = NULL;
        }

        /* Don't need the mutex now. */
        apr_thread_mutex_unlock(ctx->mutex);

        /* Parse the doc/url pair. */
        if (dup) {
            status = find_href_doc(dup->doc, dup->path, ctx, subpool);
            if (status) {
                printf("Error finding hrefs: %d %s\n", status, dup->path);
            }
            /* Free the doc pair and its pool. */
            apr_pool_destroy(dup->pool);
            serf_bucket_mem_free(ctx->doc_queue_alloc, dup->path);
            serf_bucket_mem_free(ctx->doc_queue_alloc, dup);
        }

        /* Hey are we done? */
        if (!apr_atomic_read32(ctx->requests_outstanding)) {
            break;
        }
    }
    return NULL;
}

static void print_usage(apr_pool_t *pool)
{
    puts("serf_get [options] URL");
    puts("-h\tDisplay this help");
    puts("-v\tDisplay version");
    puts("-H\tPrint response headers");
    puts("-a <user:password> Present Basic authentication credentials");
}

int main(int argc, const char **argv)
{
    apr_status_t status;
    apr_pool_t *pool;
    apr_sockaddr_t *address;
    serf_context_t *context;
    serf_connection_t *connection;
    app_baton_t app_ctx;
    handler_baton_t *handler_ctx;
    apr_uri_t url;
    const char *raw_url;
    apr_getopt_t *opt;
    char opt_c;
    char *authn = NULL;
    const char *opt_arg;

    /* For the parser threads */
    apr_thread_t *thread[3];
    apr_threadattr_t *tattr;
    apr_status_t parser_status;
    parser_baton_t *parser_ctx;

    apr_initialize();
    atexit(apr_terminate);

    apr_pool_create(&pool, NULL);
    apr_atomic_init(pool);
    /* serf_initialize(); */

    apr_getopt_init(&opt, pool, argc, argv);

    while ((status = apr_getopt(opt, "a:hv", &opt_c, &opt_arg)) ==
           APR_SUCCESS) {
        int srclen, enclen;

        switch (opt_c) {
        case 'a':
            srclen = strlen(opt_arg);
            enclen = apr_base64_encode_len(srclen);
            authn = apr_palloc(pool, enclen + 6);
            strcpy(authn, "Basic ");
            (void) apr_base64_encode(&authn[6], opt_arg, srclen);
            break;
        case 'h':
            print_usage(pool);
            exit(0);
            break;
        case 'v':
            puts("Serf version: " SERF_VERSION_STRING);
            exit(0);
        default:
            break;
        }
    }

    if (opt->ind != opt->argc - 1) {
        print_usage(pool);
        exit(-1);
    }

    raw_url = argv[opt->ind];

    apr_uri_parse(pool, raw_url, &url);
    if (!url.port) {
        url.port = apr_uri_port_of_scheme(url.scheme);
    }
    if (!url.path) {
        url.path = "/";
    }

    if (strcasecmp(url.scheme, "https") == 0) {
        app_ctx.using_ssl = 1;
    }
    else {
        app_ctx.using_ssl = 0;
    }

    status = apr_sockaddr_info_get(&address,
                                   url.hostname, APR_UNSPEC, url.port, 0,
                                   pool);
    if (status) {
        printf("Error creating address: %d\n", status);
        exit(1);
    }

    context = serf_context_create(pool);

    /* ### Connection or Context should have an allocator? */
    app_ctx.bkt_alloc = serf_bucket_allocator_create(pool, NULL, NULL);
    app_ctx.ssl_ctx = NULL;
    app_ctx.authn = authn;

    connection = serf_connection_create(context, address,
                                        conn_setup, &app_ctx,
                                        closed_connection, &app_ctx,
                                        pool);

    handler_ctx = (handler_baton_t*)serf_bucket_mem_alloc(app_ctx.bkt_alloc,
                                                      sizeof(handler_baton_t));
    handler_ctx->allocator = app_ctx.bkt_alloc;
    handler_ctx->doc_queue = apr_array_make(pool, 1, sizeof(doc_path_t*));
    handler_ctx->doc_queue_alloc = app_ctx.bkt_alloc;

    handler_ctx->requests_outstanding =
        (apr_uint32_t*)serf_bucket_mem_alloc(app_ctx.bkt_alloc,
                                             sizeof(apr_uint32_t));
    apr_atomic_set32(handler_ctx->requests_outstanding, 0);
    handler_ctx->hdr_read = 0;

    parser_ctx = (void*)serf_bucket_mem_alloc(app_ctx.bkt_alloc,
                                       sizeof(parser_baton_t));

    parser_ctx->requests_outstanding = handler_ctx->requests_outstanding;
    parser_ctx->connection = connection;
    parser_ctx->app_ctx = &app_ctx;
    parser_ctx->doc_queue = handler_ctx->doc_queue;
    parser_ctx->doc_queue_alloc = handler_ctx->doc_queue_alloc;
    /* Restrict ourselves to this host. */
    parser_ctx->hostinfo = url.hostinfo;

    status = apr_thread_mutex_create(&parser_ctx->mutex,
                                     APR_THREAD_MUTEX_DEFAULT, pool);
    if (status) {
        printf("Couldn't create mutex %d\n", status);
        return status;
    }

    status = apr_thread_cond_create(&parser_ctx->condvar, pool);
    if (status) {
        printf("Couldn't create condvar: %d\n", status);
        return status;
    }

    /* Let the handler now which condvar to use. */
    handler_ctx->doc_queue_condvar = parser_ctx->condvar;

    apr_threadattr_create(&tattr, pool);

    /* Start the parser thread. */
    apr_thread_create(&thread[0], tattr, parser_thread, parser_ctx, pool);

    /* Deliver the first request. */
    create_request(url.hostinfo, url.path, NULL, NULL, parser_ctx, pool);

    /* Go run our normal thread. */
    while (1) {
        int tries = 0;

        status = serf_context_run(context, SERF_DURATION_FOREVER, pool);
        if (APR_STATUS_IS_TIMEUP(status))
            continue;
        if (status) {
            char buf[200];

            printf("Error running context: (%d) %s\n", status,
                   apr_strerror(status, buf, sizeof(buf)));
            exit(1);
        }

        /* We run this check to allow our parser threads to add more
         * requests to our queue.
         */
        for (tries = 0; tries < 3; tries++) {
            if (!apr_atomic_read32(handler_ctx->requests_outstanding)) {
#ifdef SERF_VERBOSE
                printf("Waiting...");
#endif
                apr_sleep(100000);
#ifdef SERF_VERBOSE
                printf("Done\n");
#endif
            }
            else {
                break;
            }
        }
        if (tries >= 3) {
            break;
        }
        /* Debugging purposes only! */
        serf_debug__closed_conn(app_ctx.bkt_alloc);
    }

    printf("Quitting...\n");
    serf_connection_close(connection);

    /* wake up the parser via condvar signal */
    apr_thread_cond_signal(parser_ctx->condvar);

    status = apr_thread_join(&parser_status, thread[0]);
    if (status) {
        printf("Error joining thread: %d\n", status);
        return status;
    }

    serf_bucket_mem_free(app_ctx.bkt_alloc, handler_ctx->requests_outstanding);
    serf_bucket_mem_free(app_ctx.bkt_alloc, parser_ctx);

    apr_pool_destroy(pool);
    return 0;
}
