/* ====================================================================
 *    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>

#include <apr.h>
#include <apr_pools.h>
#include <apr_strings.h>
#include <apr_version.h>

#include "serf.h"

#include "test_serf.h"

/* Validate that requests are sent and completed in the order of creation. */
static void test_serf_connection_request_create(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    handler_baton_t handler_ctx[2];
    const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);
    apr_status_t status;
    int i;

    /* Set up a test context with a server */
    setup_test_mock_server(tb);
    status = setup_test_client_context(tb, NULL, tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    Given(tb->mh)
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("1"),
                 HeaderEqualTo("Host", tb->serv_host))
        Respond(WithCode(200), WithChunkedBody(""))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("2"),
                 HeaderEqualTo("Host", tb->serv_host))
        Respond(WithCode(200), WithChunkedBody(""))
    EndGiven

    create_new_request(tb, &handler_ctx[0], "GET", "/", 1);
    create_new_request(tb, &handler_ctx[1], "GET", "/", 2);

    status = run_client_and_mock_servers_loops(tb, num_requests,
                                               handler_ctx, tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    /* Check that the requests were sent and reveived by the server in the order
       we created them */
    Verify(tb->mh)
      CuAssertTrue(tc, VerifyAllRequestsReceivedInOrder);
    EndVerify

    /* Check that the responses were received in the order we created them */
    for (i = 0; i < tb->handled_requests->nelts; i++) {
        int req_nr = APR_ARRAY_IDX(tb->handled_requests, i, int);
        CuAssertIntEquals(tc, i + 1, req_nr);
    }
}

/* Validate that priority requests are sent and completed before normal
   requests. */
static void test_serf_connection_priority_request_create(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    handler_baton_t handler_ctx[3];
    const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);
    apr_status_t status;
    int i;

    /* Set up a test context with a server */
    setup_test_mock_server(tb);
    status = setup_test_client_context(tb, NULL, tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    Given(tb->mh)
      DefaultResponse(WithCode(200), WithRequestBody)

      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("1"),
                 HeaderEqualTo("Host", tb->serv_host))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("2"),
                 HeaderEqualTo("Host", tb->serv_host))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("3"),
                 HeaderEqualTo("Host", tb->serv_host))
    EndGiven

    create_new_request(tb, &handler_ctx[0], "GET", "/", 2);
    create_new_request(tb, &handler_ctx[1], "GET", "/", 3);
    create_new_prio_request(tb, &handler_ctx[2], "GET", "/", 1);

    run_client_and_mock_servers_loops_expect_ok(tc, tb, num_requests,
                                                handler_ctx, tb->pool);

    /* Check that the responses were received in the order we created them */
    for (i = 0; i < tb->handled_requests->nelts; i++) {
        int req_nr = APR_ARRAY_IDX(tb->handled_requests, i, int);
        CuAssertIntEquals(tc, i + 1, req_nr);
    }
}

/* Test that serf correctly handles the 'Connection:close' header when the
   server is planning to close the connection. */
static void test_closed_connection(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    apr_status_t status;
    handler_baton_t handler_ctx[10];
    const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);
    int i;

    /* Set up a test context with a server */
    setup_test_mock_server(tb);
    status = setup_test_client_context(tb, NULL, tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    /* We will send 10 requests to the mock server, close connection after the
       4th and the 8th response */
    Given(tb->mh)
      DefaultResponse(WithCode(200), WithRequestBody)

      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("1"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("2"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("3"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("4"))
        Respond(WithCode(200), WithRequestBody,
                WithConnectionCloseHeader)
      /* All messages from hereon can potentially be sent (but not responded to)
         twice */
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("5"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("6"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("7"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("8"))
        Respond(WithCode(200), WithRequestBody,
                WithConnectionCloseHeader)
      /* All messages from hereon can potentially be sent (but not responded to)
         three times */
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("9"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("10"))
    EndGiven

    /* Send some requests on the connections */
    for (i = 0 ; i < num_requests ; i++) {
        create_new_request(tb, &handler_ctx[i], "GET", "/", i+1);
    }

    status = run_client_and_mock_servers_loops(tb, num_requests, handler_ctx,
                                               tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    /* Check that the requests were sent and reveived by the server */
    Verify(tb->mh)
      CuAssert(tc, ErrorMessage, VerifyAllRequestsReceived);
    EndVerify
    CuAssertTrue(tc, tb->sent_requests->nelts >= num_requests);
    CuAssertIntEquals(tc, num_requests, tb->accepted_requests->nelts);
    CuAssertIntEquals(tc, num_requests, tb->handled_requests->nelts);
}

/* Default implementation of a serf_connection_setup_t callback. */
static apr_status_t http_conn_setup_mock_socket(apr_socket_t *skt,
                                                serf_bucket_t **input_bkt,
                                                serf_bucket_t **output_bkt,
                                                void *setup_baton,
                                                apr_pool_t *pool)
{
    test_baton_t *tb = setup_baton;

    serf_bucket_t *skt_bkt = serf_context_bucket_socket_create(tb->context,
                                                               skt,
                                                               tb->bkt_alloc);
    *input_bkt = serf_bucket_mock_sock_create(skt_bkt,
                                              tb->user_baton_l,
                                              tb->bkt_alloc);

    return APR_SUCCESS;
}

static void
send_more_requests_than_keepalive_of_server(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    handler_baton_t handler_ctx[10];
    const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);
    int i;
    apr_status_t status;

    /* We will send 10 requests to the mock server, close connection after the
       4th and the 8th response */
    Given(tb->mh)
      DefaultResponse(WithCode(200), WithRequestBody)

      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("1"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("2"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("3"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("4"))
        Respond(WithCode(200), WithRequestBody)
        CloseConnection
      /* All messages from hereon can potentially be sent (but not responded to)
         twice */
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("5"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("6"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("7"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("8"))
        Respond(WithCode(200), WithRequestBody)
        CloseConnection
      /* All messages from hereon can potentially be sent (but not responded to)
         three times */
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("9"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("10"))
    EndGiven

    /* Send some requests on the connections */
    for (i = 0 ; i < num_requests ; i++) {
        create_new_request(tb, &handler_ctx[i], "GET", "/", i+1);
    }

    status = run_client_and_mock_servers_loops(tb, num_requests, handler_ctx,
                                               tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    /* Check that the requests were sent and reveived by the server */
    Verify(tb->mh)
      CuAssert(tc, ErrorMessage, VerifyAllRequestsReceived);
    EndVerify
    CuAssertTrue(tc, tb->sent_requests->nelts >= num_requests);
    CuAssertTrue(tc, tb->accepted_requests->nelts >= num_requests);
    CuAssertIntEquals(tc, num_requests, tb->handled_requests->nelts);

}

/* Test that serf correctly handles suddenly closed connections (where the last
   response didn't have a Connection: close header). It should be handled as a
   normal connection closure. */
static void test_eof_connection(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    apr_status_t status;

    /* Set up a test context with a server. */
    setup_test_mock_server(tb);
    status = setup_test_client_context(tb, NULL, tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    send_more_requests_than_keepalive_of_server(tc);
}

/* The same test as test_eof_connection, but with the authn callback set.
   This makes serf follow a slightly different code path in handle_response(). */
static void test_eof_connection_with_authn_cb(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    apr_status_t status;

    /* Set up a test context with a server. */
    setup_test_mock_server(tb);
    status = setup_test_client_context(tb, NULL, tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    serf_config_credentials_callback(tb->context, dummy_authn_callback);
    send_more_requests_than_keepalive_of_server(tc);
}

/* Test that serf correctly handles aborted connections. This can happen
   on Windows when the server (cleanly) closes the connection, and where it
   happens between responses, it should be handled as a normal connection
   closure. */
static void test_aborted_connection(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    apr_status_t status;

    /* Set up a test context with a server. Use the mock socket to return
       APR_ECONNABORTED instead of APR_EOF. */
    setup_test_mock_server(tb);
    tb->user_baton_l = APR_ECONNABORTED;
    status = setup_test_client_context(tb, http_conn_setup_mock_socket,
                                       tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    send_more_requests_than_keepalive_of_server(tc);
}

/* The same test as test_aborted_connection, but with the authn callback set.
   This makes serf follow a slightly different code path in handle_response(). */
static void test_aborted_connection_with_authn_cb(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    apr_status_t status;

    /* Set up a test context with a server. Use the mock socket to return
     APR_ECONNABORTED instead of APR_EOF. */
    setup_test_mock_server(tb);
    tb->user_baton_l = APR_ECONNABORTED;
    status = setup_test_client_context(tb, http_conn_setup_mock_socket,
                                       tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    serf_config_credentials_callback(tb->context, dummy_authn_callback);
    send_more_requests_than_keepalive_of_server(tc);
}

/* The same test as test_aborted_connection, but with APR_ECONNRESET instead
   of APR_ECONNABORTED. */
static void test_reset_connection(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    apr_status_t status;

    /* Set up a test context with a server. Use the mock socket to return
       APR_ECONNRESET instead of APR_EOF. */
    setup_test_mock_server(tb);
    tb->user_baton_l = APR_ECONNRESET;
    status = setup_test_client_context(tb, http_conn_setup_mock_socket,
                                       tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    send_more_requests_than_keepalive_of_server(tc);
}

/* The same test as test_reset_connection, but with the authn callback set.
   This makes serf follow a slightly different code path in handle_response(). */
static void test_reset_connection_with_authn_cb(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    apr_status_t status;

    /* Set up a test context with a server. Use the mock socket to return
       APR_ECONNRESET instead of APR_EOF. */
    setup_test_mock_server(tb);
    tb->user_baton_l = APR_ECONNRESET;
    status = setup_test_client_context(tb, http_conn_setup_mock_socket,
                                       tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    serf_config_credentials_callback(tb->context, dummy_authn_callback);
    send_more_requests_than_keepalive_of_server(tc);
}

/* Test if serf is sending the request to the proxy, not to the server
   directly. */
static void test_setup_proxy(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    handler_baton_t handler_ctx[1];
    const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);
    apr_status_t status;

    /* Set up a test context with a proxy */
    setup_test_mock_server(tb);
    status = setup_test_mock_proxy(tb);
    CuAssertIntEquals(tc, APR_SUCCESS, status);
    status = setup_test_client_context_with_proxy(tb, NULL, tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    Given(tb->mh)
      RequestsReceivedByProxy
        GETRequest(
            URLEqualTo(apr_psprintf(tb->pool, "http://%s", tb->serv_host)),
            HeaderEqualTo("Host", tb->serv_host),
            ChunkedBodyEqualTo("1"))
          Respond(WithCode(200), WithChunkedBody(""))
    EndGiven
    create_new_request(tb, &handler_ctx[0], "GET", "/", 1);

    run_client_and_mock_servers_loops_expect_ok(tc, tb, num_requests,
                                                handler_ctx, tb->pool);
}

/*****************************************************************************
 * Test if we can make serf send requests one by one.
 *****************************************************************************/

/* Resend the first request 2 more times as priority requests. */
static apr_status_t
handle_response_keepalive_limit(serf_request_t *request,
                                serf_bucket_t *response,
                                void *handler_baton,
                                apr_pool_t *pool)
{
    handler_baton_t *ctx = handler_baton;

    if (! response) {
        return APR_SUCCESS;
    }

    while (1) {
        apr_status_t status;
        const char *data;
        apr_size_t len;

        status = serf_bucket_read(response, 2048, &data, &len);
        if (SERF_BUCKET_READ_ERROR(status)) {
            return status;
        }

        if (APR_STATUS_IS_EOF(status)) {
            APR_ARRAY_PUSH(ctx->handled_requests, int) = ctx->req_id;
            ctx->done = TRUE;
            if (ctx->req_id == 1 && ctx->handled_requests->nelts < 3) {
                serf_connection_priority_request_create(ctx->tb->connection,
                                                        setup_request,
                                                        ctx);
                ctx->done = FALSE;
            }
            return APR_EOF;
        }
    }

    return APR_SUCCESS;
}

#define SENT_REQUESTS 5
#define RCVD_REQUESTS 7
static void test_keepalive_limit_one_by_one(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    apr_status_t status;
    handler_baton_t handler_ctx[RCVD_REQUESTS];
    int i;


    /* Set up a test context with a server */
    setup_test_mock_server(tb);
    status = setup_test_client_context(tb, NULL, tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    /* Reduce the bandwidth to one at a time. The first request will be resend
       twice as priority requests, so iff the bandwidth reduction is in effect
       these should be sent before all other requests. */
    serf_connection_set_max_outstanding_requests(tb->connection, 1);

    Given(tb->mh)
      DefaultResponse(WithCode(200), WithRequestBody)

      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("1"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("1"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("1"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("2"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("3"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("4"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("5"))
    EndGiven

    for (i = 0 ; i < SENT_REQUESTS ; i++) {
        create_new_request_with_resp_hdlr(tb, &handler_ctx[i], "GET", "/", i+1,
                                          handle_response_keepalive_limit);
    }

    /* The two retries of request 1 both also have req_id=1, which means that
       we can't expected RECV_REQUESTS # of requests here, because the done flag
       of these 2 request will not be registered correctly. */
    status = run_client_and_mock_servers_loops(tb, SENT_REQUESTS, handler_ctx,
                                               tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    Verify(tb->mh)
      CuAssert(tc, ErrorMessage, VerifyAllRequestsReceivedInOrder);
    EndVerify

    CuAssertIntEquals(tc, RCVD_REQUESTS, tb->sent_requests->nelts);
    CuAssertIntEquals(tc, RCVD_REQUESTS, tb->accepted_requests->nelts);
    CuAssertIntEquals(tc, RCVD_REQUESTS, tb->handled_requests->nelts);
}
#undef SEND_REQUESTS
#undef RCVD_REQUESTS

/*****************************************************************************
 * Test if we can make serf first send requests one by one, and then change
 * back to burst mode.
 *****************************************************************************/
#define SENT_REQUESTS 5
#define RCVD_REQUESTS 7
/* Resend the first request 2 times by reducing the pipeline bandwidth to
   one request at a time, and by adding the first request again at the start of
   the outgoing queue. */
static apr_status_t
handle_response_keepalive_limit_burst(serf_request_t *request,
                                      serf_bucket_t *response,
                                      void *handler_baton,
                                      apr_pool_t *pool)
{
    handler_baton_t *ctx = handler_baton;

    if (! response) {
        return APR_SUCCESS;
    }

    while (1) {
        apr_status_t status;
        const char *data;
        apr_size_t len;

        status = serf_bucket_read(response, 2048, &data, &len);
        if (SERF_BUCKET_READ_ERROR(status)) {
            return status;
        }

        if (APR_STATUS_IS_EOF(status)) {
            APR_ARRAY_PUSH(ctx->handled_requests, int) = ctx->req_id;
            ctx->done = TRUE;
            if (ctx->req_id == 1 && ctx->handled_requests->nelts < 3) {
                serf_connection_priority_request_create(ctx->tb->connection,
                                                        setup_request,
                                                        ctx);
                ctx->done = FALSE;
            }
            else  {
                /* No more one-by-one. */
                serf_connection_set_max_outstanding_requests(ctx->tb->connection,
                                                             0);
            }
            return APR_EOF;
        }

        if (APR_STATUS_IS_EAGAIN(status)) {
            return status;
        }
    }

    return APR_SUCCESS;
}

static void test_keepalive_limit_one_by_one_and_burst(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
        apr_status_t status;
    handler_baton_t handler_ctx[SENT_REQUESTS];
    int i;

    /* Set up a test context with a server */
    setup_test_mock_server(tb);
    status = setup_test_client_context(tb, NULL, tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    serf_connection_set_max_outstanding_requests(tb->connection, 1);

    Given(tb->mh)
      DefaultResponse(WithCode(200), WithRequestBody)

      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("1"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("1"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("1"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("2"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("3"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("4"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("5"))
    EndGiven

    for (i = 0 ; i < SENT_REQUESTS ; i++) {
        create_new_request_with_resp_hdlr(tb, &handler_ctx[i], "GET", "/", i+1,
                                          handle_response_keepalive_limit_burst);
    }

    /* The two retries of request 1 both also have req_id=1, which means that
       we can't expected RECV_REQUESTS # of requests here, because the done flag
       of these 2 request will not be registered correctly. */
    status = run_client_and_mock_servers_loops(tb, SENT_REQUESTS, handler_ctx,
                                               tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    Verify(tb->mh)
      CuAssert(tc, ErrorMessage, VerifyAllRequestsReceivedInOrder);
    EndVerify

    CuAssertIntEquals(tc, RCVD_REQUESTS, tb->sent_requests->nelts);
    CuAssertIntEquals(tc, RCVD_REQUESTS, tb->accepted_requests->nelts);
    CuAssertIntEquals(tc, RCVD_REQUESTS, tb->handled_requests->nelts);
}
#undef SEND_REQUESTS
#undef RCVD_REQUESTS

typedef struct progress_baton_t {
  apr_off_t read;
  apr_off_t written;
} progress_baton_t;

static void
progress_cb(void *progress_baton, apr_off_t read, apr_off_t written)
{
    test_baton_t *tb = progress_baton;
    progress_baton_t *pb = tb->user_baton;

    pb->read = read;
    pb->written = written;
}

static apr_status_t progress_conn_setup(apr_socket_t *skt,
                                          serf_bucket_t **input_bkt,
                                          serf_bucket_t **output_bkt,
                                          void *setup_baton,
                                          apr_pool_t *pool)
{
    test_baton_t *tb = setup_baton;
    *input_bkt = serf_context_bucket_socket_create(tb->context, skt,
                                                   tb->bkt_alloc);
    return APR_SUCCESS;
}

static void test_progress_callback(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    apr_status_t status;
    handler_baton_t handler_ctx[5];
    const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);
    int i;
    progress_baton_t *pb;


    /* Set up a test context with a server */
    setup_test_mock_server(tb);
    status = setup_test_client_context(tb, progress_conn_setup, tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    /* Set up the progress callback. */
    pb = apr_pcalloc(tb->pool, sizeof(*pb));
    tb->user_baton = pb;
    serf_context_set_progress_cb(tb->context, progress_cb, tb);

    Given(tb->mh)
      DefaultResponse(WithCode(200), WithRequestBody)

      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("1"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("2"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("3"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("4"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("5"))
    EndGiven

    /* Send some requests on the connections */
    for (i = 0 ; i < num_requests ; i++) {
        create_new_request(tb, &handler_ctx[i], "GET", "/", i+1);
    }

    run_client_and_mock_servers_loops_expect_ok(tc, tb, num_requests,
                                                handler_ctx, tb->pool);

    /* Check that progress was reported. */
    CuAssertTrue(tc, pb->written > 0);
    CuAssertTrue(tc, pb->read > 0);
}

/* Test that username:password components in url are ignored. */
static void test_connection_userinfo_in_url(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    apr_status_t status;
    handler_baton_t handler_ctx[2];
    const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);
    int i;

    /* Set up a test context with a server */
    setup_test_mock_server(tb);
    status = setup_test_client_context(tb, NULL, tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    Given(tb->mh)
      DefaultResponse(WithCode(200), WithRequestBody)

      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("1"))
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("2"))
    EndGiven

    /* Create a connection using user:password@hostname syntax */
    tb->serv_url = apr_psprintf(tb->pool, "http://user:password@localhost:%d",
                                tb->serv_port);

    use_new_connection(tb, tb->pool);

    /* Send some requests on the connections */
    for (i = 0 ; i < num_requests ; i++) {
        create_new_request(tb, &handler_ctx[i], "GET", "/", i+1);
    }

    run_client_and_mock_servers_loops_expect_ok(tc, tb, num_requests,
                                                handler_ctx, tb->pool);
}

/*****************************************************************************
 * Issue #91: test that serf correctly handle an incoming 4xx reponse while
 * the outgoing request wasn't written completely yet.
 *****************************************************************************/

#define REQUEST_BODY_PART1\
    "<?xml version=""1.0"" encoding=""utf-8""?><propfind xmlns=""DAV:""><prop>"

#define REQUEST_PART1 "PROPFIND / HTTP/1.1" CRLF\
"Host: lgo-ubuntu.local" CRLF\
"User-Agent: SVN/1.8.0-dev (x86_64-apple-darwin11.4.2) serf/2.0.0" CRLF\
"Content-Type: text/xml" CRLF\
"Transfer-Encoding: chunked" CRLF \
CRLF\
"12d" CRLF\
"<?xml version=""1.0"" encoding=""utf-8""?><propfind xmlns=""DAV:""><prop>"


#define REQUEST_PART2 \
"<resourcetype xmlns=""DAV:""/><getcontentlength xmlns=""DAV:""/>"\
"<deadprop-count xmlns=""http://subversion.tigris.org/xmlns/dav/""/>"\
"<version-name xmlns=""DAV:""/><creationdate xmlns=""DAV:""/>"\
"<creator-displayname xmlns=""DAV:""/></prop></propfind>" CRLF\
"0" CRLF \
CRLF

#define RESPONSE_408 "HTTP/1.1 408 Request Time-out" CRLF\
"Date: Wed, 14 Nov 2012 19:50:35 GMT" CRLF\
"Server: Apache/2.2.17 (Ubuntu)" CRLF\
"Vary: Accept-Encoding" CRLF\
"Content-Length: 305" CRLF\
"Connection: close" CRLF\
"Content-Type: text/html; charset=iso-8859-1" CRLF \
CRLF\
"<!DOCTYPE HTML PUBLIC ""-//IETF//DTD HTML 2.0//EN""><html><head>"\
"<title>408 Request Time-out</title></head><body><h1>Request Time-out</h1>"\
"<p>Server timeout waiting for the HTTP request from the client.</p><hr>"\
"<address>Apache/2.2.17 (Ubuntu) Server at lgo-ubuntu.local Port 80</address>"\
"</body></html>"


static apr_status_t queue_part2(void *baton, serf_bucket_t *aggregate_bucket)
{
    serf_bucket_t *body_bkt;
    handler_baton_t *ctx = baton;

    if (ctx->done) {
        body_bkt = serf_bucket_simple_create(REQUEST_PART2, strlen(REQUEST_PART2),
                                             NULL, NULL,
                                             aggregate_bucket->allocator);
        serf_bucket_aggregate_append(aggregate_bucket, body_bkt);
    }

    return APR_EAGAIN;
}

static apr_status_t setup_request_timeout(
                                  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 *body_bkt;

    *req_bkt = serf_bucket_aggregate_create(serf_request_get_alloc(request));

    /* create a simple body text */
    body_bkt = serf_bucket_simple_create(REQUEST_PART1, strlen(REQUEST_PART1),
                                         NULL, NULL,
                                         serf_request_get_alloc(request));
    serf_bucket_aggregate_append(*req_bkt, body_bkt);

    /* When REQUEST_PART1 runs out, we will queue up PART2.  */
    serf_bucket_aggregate_hold_open(*req_bkt, queue_part2, ctx);

    APR_ARRAY_PUSH(ctx->sent_requests, int) = ctx->req_id;

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

    return APR_SUCCESS;
}

static apr_status_t handle_response_timeout(
                                    serf_request_t *request,
                                    serf_bucket_t *response,
                                    void *handler_baton,
                                    apr_pool_t *pool)
{
    handler_baton_t *ctx = handler_baton;
    serf_status_line sl;
    apr_status_t status;

    if (! response) {
        serf_connection_request_create(ctx->tb->connection,
                                       setup_request,
                                       ctx);
        return APR_SUCCESS;
    }

    if (serf_request_is_written(request) != APR_EBUSY) {
        return REPORT_TEST_SUITE_ERROR();
    }


    status = serf_bucket_response_status(response, &sl);
    if (SERF_BUCKET_READ_ERROR(status)) {
        return status;
    }
    if (!sl.version && (APR_STATUS_IS_EOF(status) ||
                        APR_STATUS_IS_EAGAIN(status))) {
        return status;
    }
    if (sl.code == 408) {
        APR_ARRAY_PUSH(ctx->handled_requests, int) = ctx->req_id;
        ctx->done = TRUE;
    }

    /* discard the rest of the body */
    while (1) {
        const char *data;
        apr_size_t len;

        status = serf_bucket_read(response, 2048, &data, &len);
        if (SERF_BUCKET_READ_ERROR(status) ||
            APR_STATUS_IS_EAGAIN(status) ||
            APR_STATUS_IS_EOF(status))
            return status;
    }

    return APR_SUCCESS;
}

static void test_request_timeout(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    apr_status_t status;
    handler_baton_t handler_ctx[1];
    const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);

    /* Set up a test context with a server */
    setup_test_mock_server(tb);
    status = setup_test_client_context(tb, NULL, tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    Given(tb->mh)
      HTTPRequest(MethodEqualTo("PROPFIND"),
                  URLEqualTo("/"),
                  IncompleteBodyEqualTo(REQUEST_BODY_PART1))
        Respond(WithRawData(RESPONSE_408, strlen(RESPONSE_408)))
    EndGiven

    /* Send a incomplete requesta on the connection */
    handler_ctx[0].method = "PROPFIND";
    handler_ctx[0].path = "/";
    handler_ctx[0].done = FALSE;

    handler_ctx[0].acceptor = accept_response;
    handler_ctx[0].acceptor_baton = NULL;
    handler_ctx[0].handler = handle_response_timeout;
    handler_ctx[0].req_id = 1;
    handler_ctx[0].accepted_requests = tb->accepted_requests;
    handler_ctx[0].sent_requests = tb->sent_requests;
    handler_ctx[0].handled_requests = tb->handled_requests;
    handler_ctx[0].tb = tb;

    serf_connection_request_create(tb->connection,
                                   setup_request_timeout,
                                   &handler_ctx[0]);

    run_client_and_mock_servers_loops_expect_ok(tc, tb, num_requests,
                                                handler_ctx, tb->pool);
}

/* Validate reading a large chunked response. */
static void test_connection_large_response(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    handler_baton_t handler_ctx[1];
    const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);
    apr_status_t status;


    /* create large chunked response message */
    const char *response = create_large_response_message(tb->pool);

    /* Set up a test context with a server */
    setup_test_mock_server(tb);
    status = setup_test_client_context(tb, NULL, tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    Given(tb->mh)
      GETRequest(URLEqualTo("/"), ChunkedBodyEqualTo("1"))
        Respond(WithRawData(response, strlen(response)))
    EndGiven

    create_new_request(tb, &handler_ctx[0], "GET", "/", 1);

    run_client_and_mock_servers_loops_expect_ok(tc, tb, num_requests,
                                                handler_ctx, tb->pool);
}

/* Validate sending a large chunked response. */
static void test_connection_large_request(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    handler_baton_t handler_ctx[1];
    const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);
    const char *request, *body;
    apr_status_t status;


    /* Set up a test context with a server */
    setup_test_mock_server(tb);
    status = setup_test_client_context(tb, NULL, tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    /* create large chunked request message */
    body = create_large_request_message_body(tb->pool);
    request = create_large_request_message(tb->pool, body);

    Given(tb->mh)
      GETRequest(URLEqualTo("/"), RawBodyEqualTo(body))
        Respond(WithCode(200), WithChunkedBody(""))
    EndGiven

    create_new_request(tb, &handler_ctx[0], "GET", "/", 1);
    handler_ctx[0].request = request;

    run_client_and_mock_servers_loops_expect_ok(tc, tb, num_requests,
                                                handler_ctx, tb->pool);
}

static void test_max_keepalive_requests(CuTest *tc)
{
    test_baton_t *tb = tc->testBaton;
    apr_status_t status;
    handler_baton_t handler_ctx[200];
    const int num_requests = sizeof(handler_ctx)/sizeof(handler_ctx[0]);
    int i;

    /* Set up a test context with a server */
    setup_test_mock_server(tb);
    status = setup_test_client_context(tb, NULL, tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    InitMockServers(tb->mh)
      ConfigServerWithID("server", WithMaxKeepAliveRequests(4))
    EndInit

    /* We will NUM_REQUESTS requests to the mock server, close connection after
       every 4th response. */
    Given(tb->mh)
      DefaultResponse(WithCode(200), WithRequestBody)

      GETRequest(URLEqualTo("/index.html"))
    EndGiven

    /* Send some requests on the connections */
    for (i = 0 ; i < num_requests ; i++) {
        create_new_request(tb, &handler_ctx[i], "GET", "/index.html", i+1);
    }

    status = run_client_and_mock_servers_loops(tb, num_requests, handler_ctx,
                                               tb->pool);
    CuAssertIntEquals(tc, APR_SUCCESS, status);

    /* Check that the requests were sent and reveived by the server */
    Verify(tb->mh)
      CuAssert(tc, ErrorMessage, VerifyAllRequestsReceived);
      CuAssertIntEquals(tc, num_requests, VerifyStats->requestsResponded);
    EndVerify
    CuAssertTrue(tc, tb->sent_requests->nelts >= num_requests);
    CuAssertIntEquals(tc, num_requests, tb->accepted_requests->nelts);
    CuAssertIntEquals(tc, num_requests, tb->handled_requests->nelts);
}

/*****************************************************************************/
CuSuite *test_context(void)
{
    CuSuite *suite = CuSuiteNew();

    CuSuiteSetSetupTeardownCallbacks(suite, test_setup, test_teardown);

    SUITE_ADD_TEST(suite, test_serf_connection_request_create);
    SUITE_ADD_TEST(suite, test_serf_connection_priority_request_create);
    SUITE_ADD_TEST(suite, test_closed_connection);
    SUITE_ADD_TEST(suite, test_eof_connection);
    SUITE_ADD_TEST(suite, test_eof_connection_with_authn_cb);
    SUITE_ADD_TEST(suite, test_aborted_connection);
    SUITE_ADD_TEST(suite, test_aborted_connection_with_authn_cb);
    SUITE_ADD_TEST(suite, test_reset_connection);
    SUITE_ADD_TEST(suite, test_reset_connection_with_authn_cb);
    SUITE_ADD_TEST(suite, test_setup_proxy);
    SUITE_ADD_TEST(suite, test_keepalive_limit_one_by_one);
    SUITE_ADD_TEST(suite, test_keepalive_limit_one_by_one_and_burst);
    SUITE_ADD_TEST(suite, test_progress_callback);
    SUITE_ADD_TEST(suite, test_connection_userinfo_in_url);
    SUITE_ADD_TEST(suite, test_request_timeout);
    SUITE_ADD_TEST(suite, test_connection_large_response);
    SUITE_ADD_TEST(suite, test_connection_large_request);
    SUITE_ADD_TEST(suite, test_max_keepalive_requests);

    return suite;
}
