/* ====================================================================
 *    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.
 * ====================================================================
 *
 * Copyright 2014 Lieven Govaerts
 *
 * Licensed 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.
 */

#define APR_WANT_MEMFUNC
#include <apr_want.h>
#include <apr_strings.h>
#include <apr_uri.h>
#include <apr_lib.h>

#include <stdlib.h>

#ifndef OPENSSL_NO_OCSP /* requeires openssl 0.9.7 or later */
#include <openssl/ocsp.h>
#endif

#include "MockHTTP_private.h"

/* Copied from serf.  */
#if defined(APR_VERSION_AT_LEAST) && defined(WIN32)
#if APR_VERSION_AT_LEAST(1,4,0)
#define BROKEN_WSAPOLL
#endif
#endif

/* Forward declarations */
static apr_status_t initSSLCtx(_mhClientCtx_t *cctx);
static apr_status_t sslHandshake(_mhClientCtx_t *cctx);
static apr_status_t sslSocketWrite(_mhClientCtx_t *cctx, const char *data,
                                   apr_size_t *len);
static apr_status_t sslSocketRead(apr_socket_t *skt, void *baton, char *data,
                                  apr_size_t *len);
static apr_status_t sslSocketShutdown(_mhClientCtx_t *cctx, apr_shutdown_how_e how);

static apr_status_t renegotiateSSLSession(_mhClientCtx_t *cctx);

typedef apr_status_t (*handshake_func_t)(_mhClientCtx_t *cctx);
typedef apr_status_t (*reset_conn_func_t)(_mhClientCtx_t *cctx);
typedef apr_status_t (*send_func_t)(_mhClientCtx_t *cctx, const char *data,
                                    apr_size_t *len);
typedef apr_status_t (*receive_func_t)(apr_socket_t *skt, void *baton,
                                       char *data, apr_size_t *len);

typedef apr_status_t (*shutdown_func_t)(_mhClientCtx_t *cctx,
                                        apr_shutdown_how_e how);


typedef struct sslCtx_t sslCtx_t;
typedef struct bucket_t bucket_t;
static const apr_port_t DefaultSrvPort =   30080;
static const apr_port_t DefaultProxyPort = 38080;
static const apr_port_t DefaultOCSPResponderPort = 39080;

/* Buffer size for incoming and outgoing data */
#define BUFSIZE 32768

struct _mhClientCtx_t {
    apr_pool_t *pool;
    mhServCtx_t *serv_ctx;
    apr_socket_t *skt;         /* Socket for conn client <-> proxy/server */
    apr_int16_t reqevents;
    apr_socket_t *proxyskt;    /* Socket for conn proxy <-> server */
    apr_int16_t proxyreqevents;
    const char *proxyhost;     /* Proxy host:port */

    const char *respBody;
    apr_size_t respRem;
    apr_array_header_t *respQueue;  /* test will queue a response */
    mhResponse_t *currResp;         /* response in progress */
    unsigned int reqsReceived;      /* # of reqs received on this connection */
    mhRequest_t *req;
    bool closeConn;
    sslCtx_t *ssl_ctx;
    int protocols;                  /* SSL protocol versions */
    servMode_t mode;      /* default = server, but can switch to proxy/tunnel */

    send_func_t send;
    receive_func_t read;
    shutdown_func_t shutdown;

    bucket_t *stream; /* Bucket for incoming data */

    /* Proxy buffers */
    char osbuf[BUFSIZE]; /* buffer for data to be sent from proxy to the server */
    apr_size_t osbuflen;
    apr_size_t osbufrem;

    char ocbuf[BUFSIZE]; /* buffer for data to be sent from proxy/server to client */
    apr_size_t ocbuflen;
    apr_size_t ocbufrem;


    /* SSL-only callback functions, should be NULL when not implemented */
    handshake_func_t handshake;
    reset_conn_func_t reset;
    const char *keyFile;
    const char *passphrase;
    apr_array_header_t *certFiles;
    mhClientCertVerification_t clientCert;
    bool ocspEnabled;
};

/**
 * Start up a server in a separate thread.
 */
static void * APR_THREAD_FUNC run_thread(apr_thread_t *tid, void *baton)
{
    mhServCtx_t *ctx = baton;

    while (!ctx->cancelThread) {
        _mhRunServerLoop(ctx);
    }

    apr_thread_exit(tid, APR_SUCCESS);
    return NULL;
}

/**
 * Callback called when the mhServCtx_t pool is destroyed.
 */
static apr_status_t cleanupServer(void *baton)
{
    mhServCtx_t *ctx = baton;
    apr_status_t status = APR_SUCCESS;

    /* If mhCleanup() wasn't called before pool cleanup, the server is still
       running. Stop it here to avoid a crash, but this will result in a
       (currently unidentified) pool cleanup crash.
       Conclusion: Always run mhCleanup() at the end of a test!
     */
    mhStopServer(ctx);

    if (ctx->pollset) {
        apr_pollset_destroy(ctx->pollset);
        ctx->pollset = NULL;
    }
    /* We used to explicitly close the socket here, but APR already sets
       up a cleanup handler for that. As our cleanup is registered before
       that of the apr socket, ours will last, which the triggers a close(-1)
       from here on the unix implementations, as the initial close sets
       the socket to -1.

       On Windows APR checks before closing again */
    ctx->skt = NULL;

    return status;
}

/**
 * Callback, writes DATA of length LEN to the socket stored in CCTX.
 */
static apr_status_t socketWrite(_mhClientCtx_t *cctx, const char *data,
                                apr_size_t *len)
{
    return apr_socket_send(cctx->skt, data, len);
}

/**
 * Callback, reads data from the socket stored in CCTX and stores it in DATA,
 * the available bytes will be stored in *LEN.
 */
static apr_status_t socketRead(apr_socket_t *skt, void *baton, char *data,
                               apr_size_t *len)
{
    return apr_socket_recv(skt, data, len);
}

static apr_status_t socketShutdown(_mhClientCtx_t *cctx,
                                   apr_shutdown_how_e how)
{
    return apr_socket_shutdown(cctx->skt, how);
}

/**
 * Sets up a listener on the socket stored in CTX.
 */
static apr_status_t setupTCPServer(mhServCtx_t *ctx)
{
    apr_sockaddr_t *serv_addr;
    apr_pool_t *pool = ctx->pool;
    apr_status_t status;

    ctx->port = ctx->default_port;

    while (1) {
        STATUSERR(apr_sockaddr_info_get(&serv_addr, ctx->hostname,
                                        APR_UNSPEC, ctx->port, 0,
                                        pool));

        /* Create server socket */
        /* Note: this call requires APR v1.0.0 or higher */
        STATUSERR(apr_socket_create(&ctx->skt, serv_addr->family,
                                    SOCK_STREAM, 0, pool));

        STATUSERR(apr_socket_opt_set(ctx->skt, APR_SO_NONBLOCK, 1));
        STATUSERR(apr_socket_timeout_set(ctx->skt, 0));
        /* We used to call apr_socket_opt_set(ctx->skt, APR_SO_REUSEADDR, 1),
           but that is severly broken when we run multiple tests in parallel,
           as that may just listen on a port where another process is
           listening too.

           See http://stackoverflow.com/a/14388707/2094

           Instead of trying to work around the limitations per platform
           by using specific flags, the best fix is to just *not* use
           this option and use a different port if necessary.
         */

        /* Try the next port until bind succeeds */
        status = apr_socket_bind(ctx->skt, serv_addr);
        if (status != APR_SUCCESS) {
            apr_socket_close(ctx->skt);
            ctx->skt = NULL;
            ctx->port++;
            continue;
        }
        /* Listen for clients */
        STATUSERR(apr_socket_listen(ctx->skt, SOMAXCONN));
        break;
    };

    /* Create a new pollset, avoid broken WSAPoll implemenation on Windows. */
#ifdef BROKEN_WSAPOLL
    STATUSERR(apr_pollset_create_ex(&ctx->pollset, 32, pool, 0,
                                    APR_POLLSET_SELECT));
#else
    STATUSERR(apr_pollset_create(&ctx->pollset, 32, pool, 0));
#endif

    /* Listen for POLLIN events on this socket */
    {
        apr_pollfd_t pfd = { 0 };

        pfd.desc_type = APR_POLL_SOCKET;
        pfd.desc.s = ctx->skt;
        pfd.reqevents = APR_POLLIN | APR_POLLHUP | APR_POLLERR;

        STATUSERR(apr_pollset_add(ctx->pollset, &pfd));
    }

    return APR_SUCCESS;
}

/**
 * Opens a non-blocking connection to a remote server at URL (in form
 * localhost:30080).
 */
static apr_status_t connectToServer(mhServCtx_t *ctx, _mhClientCtx_t *cctx)
{
    apr_sockaddr_t *address;
    char *host, *scopeid;
    apr_port_t port;
    apr_status_t status;

    STATUSERR(apr_parse_addr_port(&host, &scopeid, &port, cctx->proxyhost,
                                  cctx->pool));
    STATUSERR(apr_sockaddr_info_get(&address, host, APR_UNSPEC,
                                    port, 0, cctx->pool));

    /* Create server socket */
    /* Note: this call requires APR v1.0.0 or higher */
    STATUSERR(apr_socket_create(&cctx->proxyskt, address->family,
                                SOCK_STREAM, 0, cctx->pool));
    STATUSERR(apr_socket_opt_set(cctx->proxyskt, APR_SO_NONBLOCK, 1));
    STATUSERR(apr_socket_timeout_set(cctx->proxyskt, 0));

    status = apr_socket_connect(cctx->proxyskt, address);
    if (status == APR_SUCCESS || APR_STATUS_IS_EINPROGRESS(status)) {
        apr_pollfd_t pfd = { 0 };

        pfd.desc_type = APR_POLL_SOCKET;
        pfd.desc.s = cctx->proxyskt;
        pfd.reqevents = APR_POLLIN | APR_POLLOUT;
        pfd.client_data = cctx;
        STATUSERR(apr_pollset_add(ctx->pollset, &pfd));
        cctx->proxyreqevents = pfd.reqevents;

        /* ### If EINPROGRESS some operations may fail until the
               socket is really connected. Shouldn't we wait? */
    }

    return status;
}

/**
 * Initialize the server context.
 */
static mhServCtx_t *
initServCtx(const MockHTTP *mh, const char *hostname, apr_port_t port)
{
    apr_pool_t *pool = mh->pool;

    mhServCtx_t *ctx = apr_pcalloc(pool, sizeof(mhServCtx_t));
    ctx->pool = pool;
    ctx->mh = mh;
    ctx->hostname = apr_pstrdup(pool, hostname);
    ctx->default_port = port;
    ctx->port = 0;
    ctx->clients = apr_array_make(pool, 5, sizeof(_mhClientCtx_t *));
    ctx->reqsReceived = apr_array_make(pool, 5, sizeof(mhRequest_t *));
    /* Default settings */
    ctx->clientCert = mhCCVerifyNone;
    ctx->protocols = mhProtoUnspecified;
    ctx->threading = mhThreadMain;
    ctx->reqMatchers = apr_array_make(pool, 5, sizeof(ReqMatcherRespPair_t *));
    ctx->incompleteReqMatchers = apr_array_make(pool, 5,
                                                sizeof(ReqMatcherRespPair_t *));

    apr_pool_cleanup_register(pool, ctx,
                              cleanupServer,
                              apr_pool_cleanup_null);

    return ctx;
}

/******************************************************************************/
/* Parse a request structure from incoming data                               */
/******************************************************************************/

/**
 * Initialize a mhRequest_t object
 */
mhRequest_t *_mhInitRequest(apr_pool_t *pool, requestType_t type)
{
    mhRequest_t *req = apr_pcalloc(pool, sizeof(mhRequest_t));
    req->pool = pool;
    req->type = type;
    req->hdrs = apr_table_make(pool, 5);
    req->hdrHashes = apr_array_make(pool, 5, sizeof(unsigned long));
    req->body = apr_array_make(pool, 5, sizeof(struct iovec));
    req->chunks = apr_array_make(pool, 5, sizeof(struct iovec));

    return req;
}

/******************* BUCKETS **************************************************/
typedef struct _mhBucketType_t {

    const char *name;

    apr_status_t (*read)(bucket_t *bucket, apr_size_t requested,
                         const char **data, apr_size_t *len);

    apr_status_t (*readLine)(bucket_t *bucket,
                             /* int acceptable, int *found, CR, LF? */
                             const char **data, apr_size_t *len);

    apr_status_t (*peek)(bucket_t *bucket, apr_size_t *len);

} _mhBucketType_t;

struct bucket_t {

    /** the type of this bucket */
    const _mhBucketType_t *type;

    /** bucket-private data */
    void *data;
};

/* Buffered Socket buffer */
typedef struct _bufferedSocketCtx_t {
    apr_socket_t *skt;
    receive_func_t read;
    void *read_baton;
    char buf[BUFSIZE];  /* buffer for data received from the client @ server */
    apr_size_t remaining;  /* remaining bytes in the buffer */
    apr_size_t offset;  /* offset of the first available byte */
} _bufferedSocketCtx_t;

/**
 * Reads data from the socket and stores it in CCTX->buf.
 */
static apr_status_t readFromSocket(bucket_t *bkt)
{
    _bufferedSocketCtx_t *ctx = bkt->data;
    apr_status_t status;

    // assert(ctx->offset = 0);
    apr_size_t len = BUFSIZE - ctx->remaining;
    /* If our buffer is full, process more data first */
    if (len == 0)
        return APR_EAGAIN;

    STATUSREADERR(ctx->read(ctx->skt, ctx->read_baton,
                            ctx->buf + ctx->remaining, &len));
    if (len) {
        _mhLog(MH_VERBOSE, ctx->skt,
               "recvd with status %d:\n%.*s\n---- %d ----\n",
               status, (unsigned int)len, ctx->buf + ctx->remaining,
               (unsigned int)len);
        ctx->remaining += len;
    }
    return status;
}

/**
 * Read a complete line from the buffer in CCTX.
 * *LEN will be non-0 if a line ending with CRLF was found. BUF will be copied
 * in mem allocatod from cctx->pool, cctx->buf ptrs will be moved.
 */
static apr_status_t
buffSktReadLine(bucket_t *bkt, const char **data, apr_size_t *len)
{
    _bufferedSocketCtx_t *ctx = bkt->data;
    const char *ptr = ctx->buf;
    apr_status_t status;

    /* eat data read in a previous read call */
    if (ctx->offset > 0) {
        memmove(ctx->buf, ctx->buf + ctx->offset, BUFSIZE - ctx->offset);
        ctx->offset = 0;
    }

    status = readFromSocket(bkt);

    /* return one line of data */
    *len = 0;
    while (*ptr && ptr - ctx->buf < ctx->remaining) {
        if (*ptr == '\r' && *(ptr+1) == '\n') {
            *len = ptr - ctx->buf + 2;
            *data = ctx->buf;

            ctx->offset += *len;
            ctx->remaining -= *len;

            break;
        }
        ptr++;
    }

    if (ctx->remaining > 0)
        return APR_SUCCESS;

    return status;
}

static apr_status_t buffSktRead(bucket_t *bkt, apr_size_t requested,
                                const char **data, apr_size_t *len)
{
    _bufferedSocketCtx_t *ctx = bkt->data;
    apr_status_t status;

    /* eat data read in a previous read call */
    if (ctx->offset > 0) {
        memmove(ctx->buf, ctx->buf + ctx->offset, BUFSIZE - ctx->offset);
        ctx->offset = 0;
    }

    status = readFromSocket(bkt);

    /* return requested data */
    *len = ctx->remaining <= requested ? ctx->remaining : requested; /* this packet */
    *data = ctx->buf;

    ctx->offset += *len;
    ctx->remaining -= *len;

    if (ctx->remaining > 0)
        return APR_SUCCESS;

    return status;
}


static apr_status_t buffSktPeek(bucket_t *bkt, apr_size_t *len)
{
    _bufferedSocketCtx_t *ctx = bkt->data;
    apr_status_t status;

    /* eat data read in a previous read call */
    if (ctx->offset > 0) {
        memmove(ctx->buf, ctx->buf + ctx->offset, BUFSIZE - ctx->offset);
        ctx->offset = 0;
    }

    status = readFromSocket(bkt);

    if (status && !APR_STATUS_IS_EOF(status) && !APR_STATUS_IS_EAGAIN(status)
        && ctx->remaining > 0) {

        /* If there was a socket read error, assume that it will be returned
           on the next call to readFromSocket */
        status = APR_SUCCESS;
    }

    *len = ctx->remaining;

    return status;
}

const _mhBucketType_t BufferedSocketBucketType = {
    "BUFFSOCKET",
    buffSktRead,
    buffSktReadLine,
    buffSktPeek,
};

static bucket_t *
createBufferedSocketBucket(apr_socket_t *skt, receive_func_t read,
                           void *baton, apr_pool_t *pool)
{
    _bufferedSocketCtx_t *ctx = apr_pcalloc(pool, sizeof(_bufferedSocketCtx_t));
    bucket_t *bkt = apr_palloc(pool, sizeof(bucket_t));

    ctx->skt = skt;
    ctx->read = read;
    ctx->read_baton = baton;
    bkt->type = &BufferedSocketBucketType;
    bkt->data = ctx;
    return bkt;
}

#define FAIL_ON_EOL(ptr)\
    if (*ptr == '\0') return APR_EGENERAL; /* TODO: error code */

/**
 * Reads the request line from the buffer in CCTX, REQ will be updated
 * with the info read from the request line.
 *
 * Returns APR_EAGAIN if the request line isn't completely available,
 *         APR_SUCCESS + *DONE = YES if request line parsed.
 *         error in case the request line couldn't be parsed successfully
 */
static apr_status_t
readReqLine(bucket_t *bkt, mhRequest_t *req, bool *done)
{
    const char *start, *ptr, *version;
    const char *buf;
    apr_size_t len;
    apr_status_t status;

    *done = FALSE;

    status = bkt->type->readLine(bkt, &buf, &len);
    if (!len) return status;

    /* TODO: add checks for incomplete request line */
    start = ptr = buf;
    while (*ptr && *ptr != ' ' && *ptr != '\r') ptr++;
    FAIL_ON_EOL(ptr);
    req->method = apr_pstrndup(req->pool, start, ptr-start);
    req->methodCode = methodToCode(req->method);

    ptr++; start = ptr;
    while (*ptr && *ptr != ' ' && *ptr != '\r') ptr++;
    FAIL_ON_EOL(ptr);
    req->url = apr_pstrndup(req->pool, start, ptr-start);

    ptr++; start = ptr;
    while (*ptr && *ptr != ' ' && *ptr != '\r') ptr++;
    if (ptr - start != strlen("HTTP/x.y")) {
        return APR_EGENERAL;
    }
    version = apr_pstrndup(req->pool, start, ptr-start);
    req->version = (version[5] - '0') * 10 +
    version[7] - '0';

    *done = TRUE;

    return APR_SUCCESS;
}

/* simple hash implementation (djb2). */
unsigned long calculateHeaderHash(const char *hdr, const char *val)
{
    unsigned long hash = 5381;
    int c;

    if (!val)
        return 0;

    while ((c = apr_tolower(*hdr++)))
        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
    hash = ((hash << 5) + hash) + ':';
    while ((c = *val++))
        hash = ((hash << 5) + hash) + c;

    return hash;
}

static void setRequestHeader(mhRequest_t *req, const char *hdr, const char *val)
{
    apr_table_t *hdrs = req->hdrs;
    unsigned long hash;

    apr_table_add(hdrs, hdr, val);
    hash = calculateHeaderHash(hdr, val);
    APR_ARRAY_PUSH(req->hdrHashes, unsigned long) = hash;
}

/**
 * Reads a HTTP header from the buffer in CCTX, header will be added to REQ.
 *
 * Returns APR_EAGAIN if a header line isn't completely available.
 *         APR_SUCCESS if a header line was successfully parsed, maybe more
 *                     are available.
 *           + *DONE = YES when the last header was successfully parsed.
 *         error in case the header line couldn't be parsed successfully
 */
static apr_status_t
readHeader(bucket_t *bkt, mhRequest_t *req, bool *done)
{
    const char *buf;
    apr_size_t len;
    apr_status_t status;

    *done = NO;

    STATUSREADERR(bkt->type->readLine(bkt, &buf, &len));
    if (!len) return APR_EAGAIN;

    /* Last header? */
    if (len == 2 && *buf == '\r' && *(buf+1) == '\n') {
        *done = YES;
        return APR_SUCCESS;
    } if (len < 5) {
        /* TODO: error handling. header line is too short */
        return APR_EGENERAL;
    } else {
        const char *start = buf, *ptr = buf, *end = buf + len;
        const char *hdr, *val;

        /* Read header from a line in the form of 'Header: value' */
        while (*ptr && ptr < end && *ptr != ':' && *ptr != '\r') ptr++;
        hdr = apr_pstrndup(req->pool, start, ptr-start);

        /* skip : and blanks */
        ptr++; while (*ptr && ptr < end && *ptr == ' ') ptr++; start = ptr;

        /* Read value */
        while (*ptr && ptr < end && *ptr != '\r') ptr++;
        val = apr_pstrndup(req->pool, start, ptr-start);

        setRequestHeader(req, hdr, val);
    }
    return APR_SUCCESS;
}

/**
 * Append a block of data in BUF of length LEN (not-'\0' terminated) to the
 * list in REQ. Data will be copied in the REQ->pool.
 */
static void
storeRawDataBlock(mhRequest_t *req, const char *buf, apr_size_t len)
{
    struct iovec vec;
    vec.iov_base = apr_pstrndup(req->pool, buf, len);
    vec.iov_len = len;
    *((struct iovec *)apr_array_push(req->body)) = vec;
    req->bodyLen += len;
}

/**
 * Reads the unencoded (not chunked) body from the buffer in CCTX. The length
 * of the body is determined by reading the "Content-Length" header in REQ.
 * The body will be copied in REQ->pool and stored in REQ.
 *
 * Returns APR_EAGAIN if the body isn't completely available.
 *         APR_SUCCESS + *DONE = YES when the whole body was read completely.
 *         error in case the "Content-Length" header isn't set.
 */
static apr_status_t readBody(bucket_t *bkt, mhRequest_t *req, bool *done)
{
    const char *clstr, *data;
    char *body;
    apr_size_t cl;
    apr_size_t len;
    apr_status_t status;

    req->chunked = NO;

    clstr = getHeader(req->hdrs, "Content-Length");
    /* TODO: error if no Content-Length header */
    cl = atol(clstr);

    len = cl - req->bodyLen; /* remaining # of bytes */

    STATUSREADERR(bkt->type->read(bkt, len, &data, &len));

    /* copy data to the request */
    if (req->body == NULL) {
        req->body = apr_palloc(req->pool, sizeof(struct iovec) * 256);
    }
    body = apr_palloc(req->pool, len + 1);
    memcpy(body, data, len);
    *(body + len) = '\0';
    storeRawDataBlock(req, body, len);

    if (req->bodyLen < cl)
        return APR_EAGAIN;

    *done = YES;
    return APR_SUCCESS;
}

/**
 * Reads a chunk of the body from the buffer in CCTX. The length
 * of the body is determined by reading the chunk header, length of current
 * chunk and partial read data will be stored in REQ->chunks.
 * The chunk will be copied in REQ->pool and stored in REQ.
 *
 * Returns APR_EAGAIN if the chunk isn't completely available.
 *         APR_SUCCESS if a chunk was read completely, maybe more are available.
 *           + *DONE = YES when the last chunk and the trailer were read.
 *         error in case of problems parsing the chunk header, length or trailer.
 */
static apr_status_t readChunk(bucket_t *bkt, mhRequest_t *req, bool *done)
{
    apr_status_t status;

    *done = NO;

    switch (req->readState) {
        case ReadStateBody:
        case ReadStateChunked:
            req->readState = ReadStateChunkedHeader;
            /* fall through */
        case ReadStateChunkedHeader:
        {
            struct iovec vec;
            const char *data;
            apr_size_t len, chlen;

            STATUSREADERR(bkt->type->readLine(bkt, &data, &len));
            if (!len)
                return APR_EAGAIN;
            storeRawDataBlock(req, data, len);

            /* read hex chunked length */
            chlen = (apr_size_t)apr_strtoi64(data, NULL, 16);
            vec.iov_len = chlen;
            APR_ARRAY_PUSH(req->chunks, struct iovec) = vec;
            if (chlen == 0) {
                req->readState = ReadStateChunkedTrailer;
                return APR_SUCCESS;
            }

            req->readState = ReadStateChunkedChunk;
            /* fall through */
        }
        case ReadStateChunkedChunk:
        {
            const char *data;
            struct iovec *vec;
            apr_size_t chlen, curchunklen, len;

            vec = &APR_ARRAY_IDX(req->chunks, req->chunks->nelts - 1,
                                 struct iovec);
            chlen = vec->iov_len;

            /* already read some data of this chunk? */
            if (req->incomplete_chunk) {
                const char *tmp;
                curchunklen = strlen(vec->iov_base);
                /* read as much as possible from remaining part */
                STATUSREADERR(bkt->type->read(bkt, chlen - curchunklen,
                                              &data, &len));
                tmp = apr_pstrndup(req->pool, data, len);
                storeRawDataBlock(req, data, len);
                vec->iov_base = apr_pstrcat(req->pool, vec->iov_base, tmp, NULL);
                curchunklen += len;
            } else {
                /* read as much as possible */
                STATUSREADERR(bkt->type->read(bkt, chlen, &data, &len));
                vec->iov_base = apr_pstrndup(req->pool, data, len);
                storeRawDataBlock(req, data, len);
                curchunklen = len;
            }

            if (curchunklen < chlen) {
                /* More data is needed to read one chunk */
                req->incomplete_chunk = YES;
                return APR_EAGAIN;
            }
            req->incomplete_chunk = NO;
            req->readState = ReadStateChunkedTrailer;

            /* fall through */
        }
        case ReadStateChunkedTrailer:
        {
            const char *data;
            apr_size_t len, chlen;
            struct iovec vec;

            vec = APR_ARRAY_IDX(req->chunks, req->chunks->nelts - 1, struct iovec);
            chlen = vec.iov_len;

            STATUSREADERR(bkt->type->readLine(bkt, &data, &len));
            if (len < 2)
                return APR_EAGAIN;
            storeRawDataBlock(req, data, len);
            if (len == 2 && *data == '\r' && *(data+1) == '\n') {
                if (chlen == 0) {
                    /* body ends with chunk of length 0 */
                    *done = YES;
                    req->readState = ReadStateDone;
                    /* remove the 0-chunk from the request*/
                    apr_array_pop(req->chunks);
                } else {
                    req->readState = ReadStateChunked;
                }
            } else {
                return APR_EGENERAL; /* TODO: error code */
            }
            break;
        }
        default:
            break;
    }

    return APR_SUCCESS;
}

/**
 * Keeps reading chunks until no more data is available.
 *
 * Returns APR_EAGAIN if a chunk isn't completely available.
 *         APR_SUCCESS + *DONE = YES when the last chunk and the trailer were
 *              read.
 *         error in case of problems parsing the chunk header, length or trailer.
 */
static apr_status_t
readChunked(bucket_t *bkt, mhRequest_t *req, bool *done)
{
    apr_status_t status = APR_SUCCESS;

    *done = NO;
    req->chunked = YES;

    while (*done == NO)
        STATUSERR(readChunk(bkt, req, done));

    return status;
}

/**
 * New request data is available, read status line/hdrs/body (chunks).
 *
 * Returns APR_EAGAIN: wait for more data
 *         APR_EOF: request received, or no more data available.
 *         MH_STATUS_INCOMPLETE_REQUEST: APR_EOF but the request wasn't received
 *             completely.
 */
static apr_status_t readRequest(_mhClientCtx_t *cctx, mhRequest_t **preq)
{
    mhRequest_t *req = *preq;
    bucket_t *bkt;
    apr_status_t status = APR_SUCCESS;

    bkt = cctx->stream;
    if (req == NULL) {
        apr_size_t len;
        STATUSREADERR(bkt->type->peek(bkt, &len));
        if (!len)
            return status;
        req = *preq = _mhInitRequest(cctx->pool, RequestTypeHTTP);
    }

    while (!status) { /* read all available data */
        bool done = NO;

        switch(cctx->req->readState) {
            case ReadStateStatusLine: /* status line */
                STATUSREADERR(readReqLine(bkt, req, &done));
                if (done) req->readState = ReadStateHeaders;
                break;
            case ReadStateHeaders: /* headers */
                STATUSREADERR(readHeader(bkt, req, &done));
                if (done) req->readState = ReadStateBody;
                break;
            case ReadStateBody: /* body */
            case ReadStateChunked:
            case ReadStateChunkedHeader:
            case ReadStateChunkedChunk:
            case ReadStateChunkedTrailer:
            {
                const char *clstr, *chstr;
                chstr = getHeader(req->hdrs, "Transfer-Encoding");
                /* TODO: chunked can be one of more encodings */
                /* Read Transfer-Encoding first, ignore C-L when T-E is set */
                if (chstr && apr_strnatcasecmp(chstr, "chunked") == 0) {
                    STATUSREADERR(readChunked(bkt, req, &done));
                } else {
                    clstr = getHeader(req->hdrs, "Content-Length");
                    if (clstr) {
                        STATUSREADERR(readBody(bkt, req, &done));
                    } else {
                        done = YES; /* no body to read */
                    }
                }
                if (done) {
                    _mhLog(MH_VERBOSE, cctx->skt, "Server received request: %s %s\n",
                           req->method, req->url);
                    return APR_EOF;
                }
            }
            case ReadStateDone:
                break;
        }
    }
#if 0
    /* TODO: fix or cleanup */
    if (!cctx->buflen) {
        if (APR_STATUS_IS_EOF(status))
            return MH_STATUS_INCOMPLETE_REQUEST;

        return status;
    }
#endif

    return status;
}

/******************************************************************************/
/* Send a response                                                            */
/******************************************************************************/

/**
 * Translate a HTTP status code to a string representation.
 */
static const char *codeToString(unsigned int code)
{
    switch(code) {
        case 100: return "Continue"; break;
        case 101: return "Switching Protocols"; break;
        case 200: return "OK"; break;
        case 201: return "Created"; break;
        case 202: return "Accepted"; break;
        case 203: return "Non-Authoritative Information"; break;
        case 204: return "No Content"; break;
        case 205: return "Reset Content"; break;
        case 206: return "Partial Content"; break;
        case 300: return "Multiple Choices"; break;
        case 301: return "Moved Permanently"; break;
        case 302: return "Found"; break;
        case 303: return "See Other"; break;
        case 304: return "Not Modified"; break;
        case 305: return "Use Proxy"; break;
        case 307: return "Temporary Redirect"; break;
        case 400: return "Bad Request"; break;
        case 401: return "Unauthorized"; break;
        case 402: return "Payment Required"; break;
        case 403: return "Forbidden"; break;
        case 404: return "Not Found"; break;
        case 405: return "Method Not Allowed"; break;
        case 406: return "Not Acceptable"; break;
        case 407: return "Proxy Authentication Required"; break;
        case 408: return "Request Timeout"; break;
        case 409: return "Conflict"; break;
        case 410: return "Gone"; break;
        case 411: return "Length Required"; break;
        case 412: return "Precondition Failed"; break;
        case 413: return "Request Entity Too Large"; break;
        case 414: return "Request-URI Too Long"; break;
        case 415: return "Unsupported Media Type"; break;
        case 416: return "Requested Range Not Satisfiable"; break;
        case 417: return "Expectation Failed"; break;
        case 500: return "Internal Server Error"; break;
        case 501: return "Not Implemented"; break;
        case 502: return "Bad Gateway"; break;
        case 503: return "Service Unavailable"; break;
        case 504: return "Gateway Timeout"; break;
        case 505: return "HTTP Version Not Supported"; break;
        default: return "<not defined>";
    }
}

/**
 * Serializes the response RESP to a '\0'-terminated string, allocated in POOL.
 */
static char *respToString(apr_pool_t *pool, mhResponse_t *resp)
{
    char *str;
    const apr_table_entry_t *elts;
    const apr_array_header_t *arr;
    int i;

    /* status line */
    str = apr_psprintf(pool, "HTTP/1.1 %d %s\r\n", resp->code,
                       codeToString(resp->code));

    /* headers */
    arr = apr_table_elts(resp->hdrs);
    elts = (const apr_table_entry_t *)arr->elts;

    for (i = 0; i < arr->nelts; ++i) {
        str = apr_psprintf(pool, "%s%s: %s\r\n", str, elts[i].key, elts[i].val);
    }
    str = apr_psprintf(pool, "%s\r\n", str);

    /* body */
    if (resp->chunked == NO) {
        for (i = 0 ; i < resp->body->nelts; i++) {
            struct iovec vec;

            vec = APR_ARRAY_IDX(resp->body, i, struct iovec);
            str = apr_psprintf(pool, "%s%.*s", str, (unsigned int)vec.iov_len,
                               (const char *)vec.iov_base);
        }
    } else {
        bool emptyChunk = NO; /* empty response should atleast have 0-chunk */
        for (i = 0 ; i < resp->chunks->nelts; i++) {
            struct iovec vec;

            vec = APR_ARRAY_IDX(resp->chunks, i, struct iovec);
            str = apr_psprintf(pool, "%s%" APR_UINT64_T_HEX_FMT "\r\n%.*s\r\n",
                               str, (apr_uint64_t)vec.iov_len,
                               (unsigned int)vec.iov_len, (char *)vec.iov_base);
            emptyChunk = vec.iov_len == 0 ? YES : NO;
        }
        if (!emptyChunk) /* Add 0 chunk only if last chunk wasn't empty already */
            str = apr_psprintf(pool, "%s0\r\n\r\n", str);
    }
    return str;
}

/**
 * Serializes the response RESP and writes it to the socket. Unwritten data will
 * be stored in CCTX->respBody.
 */
static apr_status_t writeResponse(_mhClientCtx_t *cctx, mhResponse_t *resp)
{
    apr_pool_t *pool = cctx->pool;
    apr_size_t len;
    apr_status_t status;

    if (!cctx->respRem) {
        _mhBuildResponse(resp);
        if (resp->raw_data) {
            cctx->respBody = resp->raw_data;
            cctx->respRem = resp->raw_data_length;
        } else {
            cctx->respBody = respToString(pool, resp);
            cctx->respRem = strlen(cctx->respBody);
        }
    }

    len = cctx->respRem;
    STATUSREADERR(cctx->send(cctx, cctx->respBody, &len));
    _mhLog(MH_VERBOSE, cctx->skt, "sent with status %d:\n%.*s\n---- %d ----\n",
           status, (unsigned int)len, cctx->respBody, (unsigned int)len);

    if (len < cctx->respRem) {
        cctx->respBody += len;
        cctx->respRem -= len;
        cctx->currResp = resp;
    } else {
        cctx->respBody = NULL;
        cctx->respRem = 0;
        cctx->currResp = 0;
        return APR_EOF;
    }
    return status;
}

/******************************************************************************/
/* Match a request                                                            */
/******************************************************************************/

/**
 * Stores a request matcher RM on the list of matchers for server CTX.
 */
void mhPushRequest(MockHTTP *mh, mhServCtx_t *ctx, mhRequestMatcher_t *rm)
{
    apr_array_header_t *matchers;
    ReqMatcherRespPair_t *pair;
    int i;

    if (ctx) {
        pair = apr_palloc(ctx->pool, sizeof(ReqMatcherRespPair_t));
    } else {
        pair = apr_palloc(mh->pool, sizeof(ReqMatcherRespPair_t));
    }
    pair->rm = rm;
    pair->resp = NULL;
    pair->action = mhActionInitiateNone;

    /* Check if any of this request's matchers work on an incomplete request. */
    for (i = 0 ; i < rm->matchers->nelts; i++) {
        const mhReqMatcherBldr_t *mp;

        mp = APR_ARRAY_IDX(rm->matchers, i, mhReqMatcherBldr_t *);
        if (mp->match_incomplete == YES) {
            rm->incomplete = YES;
            break;
        }
    }

    switch (rm->type) {
        case RequestTypeHTTP:
            if (ctx) {
                matchers = rm->incomplete ? ctx->incompleteReqMatchers :
                                            ctx->reqMatchers;
            } else {
                matchers = rm->incomplete ? mh->incompleteReqMatchers :
                                            mh->reqMatchers;
            }
            break;
        case RequestTypeOCSP:
            matchers = mh->ocspReqMatchers;
            break;
        default:
            /* Unsupported request type */
            return;
    }
    *((ReqMatcherRespPair_t **)apr_array_push(matchers)) = pair;
}

/**
 * Tries to match the request REQ with any of the request matchers MATCHERS.
 * Returns NO if the request wasn't matched.
 *         YES + *RESP + *ACTION if the request was matched successfully.
 */

/* TOOD:
   This function is the main bottleneck for performance. Possible fixes:
   - if a test is setup to continuously add new request matchers while sending
     requests, evaluation the matchers from last to first drastically
     improves matching performance. Problem: user expects matches are run in
     order of definition.
   - when using a header with an unique value per request, we could create
     an index on that header:value (hashtable or b-tree) to bypass this whole
     loop. Probably requires a new API so the user can specify the index.
   - create a universal string that contains the union of all criteria
     of all matchers, e.g. "GET/header1:value1/header2:value2" and create an
     index on that string. Problem is updating that index with new matchers when
     they use new criteria (OTOH: as long as the criteria are sorted this
     shouldn't be a problem, a criteria not defined = 0 bytes in the string).
 */
static bool
matchRequest(mhRequest_t *req, mhResponse_t **resp,
             mhAction_t *action, const apr_array_header_t *matchers)
{
    int i;

    for (i = 0 ; i < matchers->nelts; i++) {
        const ReqMatcherRespPair_t *pair;

        pair = APR_ARRAY_IDX(matchers, i, ReqMatcherRespPair_t *);

        if (_mhRequestMatcherMatch(pair->rm, req) == YES) {
            *resp = pair->resp;
            *action = pair->action;
            return YES;
        }
    }

    *resp = NULL;
    return NO;
}

/**
 * Tries to match a complete request REQ with the list of complete request
 * matchers.
 * Returns NO if the request wasn't matched.
 *         YES + *RESP + *ACTION if the request was matched successfully.
 */
static bool
_mhMatchRequest(const mhServCtx_t *ctx, const _mhClientCtx_t *cctx,
                mhRequest_t *req, mhResponse_t **resp, mhAction_t *action)
{
    bool found;
    const MockHTTP *mh = ctx->mh;

    /* Try to see if a request matcher for this server exists */
    found = matchRequest(req, resp, action, ctx->reqMatchers);
    if (found) return found;

    /* Nope, then see of there's a request matcher for all servers */
    found = matchRequest(req, resp, action, mh->reqMatchers);
    if (found) return found;

    _mhLog(MH_VERBOSE, cctx->skt, "Couldn't match request!\n");
    return NO;
}

/**
 * Tries to match an incomplete (partial) request REQ with the list of
 * incomplete request matchers.
 * Returns NO if the request wasn't matched.
 *         YES + *RESP + *ACTION if the request was matched successfully.
 */
static bool
_mhMatchIncompleteRequest(const mhServCtx_t *ctx, const _mhClientCtx_t *cctx,
                          mhRequest_t *req, mhResponse_t **resp,
                          mhAction_t *action)
{
    bool found;
    const MockHTTP *mh = ctx->mh;

    /* Try to see if a request matcher for this server exists */
    found = matchRequest(req, resp, action, ctx->incompleteReqMatchers);
    if (found) return found;

    /* Nope, then see of there's a request matcher for all servers */
    found = matchRequest(req, resp, action, mh->incompleteReqMatchers);
    if (found) return found;

    _mhLog(MH_VERBOSE, cctx->skt, "Couldn't match incomplete request!\n");
    return NO;
}

/**
 * Deep copy of a response RESP to a new response allocated in POOL.
 */
static mhResponse_t *cloneResponse(apr_pool_t *pool, mhResponse_t *resp)
{
    mhResponse_t *clone;
    clone = apr_pmemdup(pool, resp, sizeof(mhResponse_t));
    clone->hdrs = apr_table_clone(pool, resp->hdrs);
    if (resp->chunks)
        clone->chunks = apr_array_copy(pool, resp->chunks);
    if (resp->body)
        clone->body = apr_array_copy(pool, resp->body);
    return clone;
}


/******************************************************************************/
/* Process socket events                                                      */
/******************************************************************************/

/**
 * Process events on connection proxy <-> server, reads all incoming data,
 * writes all outgoing data.
 * This only supports SSL TUNNEL mode at this time.
 */
static apr_status_t processProxy(_mhClientCtx_t *cctx, const apr_pollfd_t *desc)
{
    apr_status_t status = APR_SUCCESS;

    if ((desc->rtnevents & APR_POLLOUT) && (cctx->osbuflen > 0)) {
        apr_size_t len = cctx->osbuflen;
        STATUSREADERR(apr_socket_send(cctx->proxyskt, cctx->osbuf, &len));
        _mhLog(MH_VERBOSE, cctx->proxyskt,
               "Proxy sent to server, status %d:\n%.*s\n---- %d ----\n",
               status, (unsigned int)len, cctx->osbuf, (unsigned int)len);
        cctx->osbufrem += len;
        cctx->osbuflen -= len;
    }

    if (desc->rtnevents & APR_POLLIN) {
        char *buf = cctx->ocbuf + cctx->ocbuflen;
        apr_size_t len = cctx->ocbufrem;
        STATUSREADERR(apr_socket_recv(cctx->proxyskt, buf, &len));
        _mhLog(MH_VERBOSE, cctx->proxyskt,
               "Proxy received from server, status %d:\n%.*s\n---- %d ----\n",
               status, (unsigned int)len, buf, (unsigned int)len);
        cctx->ocbuflen += len;
        cctx->ocbufrem -= len;
    }

    return status;

}

/**
 * Process events on connection client <-> proxy or client <-> server
 * Reads all incoming data, tries to match complete and/or incomplete requests,
 * and then writes responses back to the socket CCTX.
 *
 * Returns APR_EOF when the connection should be closed.
 **/
static apr_status_t processServer(mhServCtx_t *ctx, _mhClientCtx_t *cctx,
                                  const apr_pollfd_t *desc)
{
    apr_status_t status = APR_EAGAIN;
    bucket_t *stream = cctx->stream;
    apr_size_t len;

    /* First sent any pending responses before reading the next request. */
    if (desc->rtnevents & APR_POLLOUT &&
        (cctx->currResp || cctx->respQueue->nelts || cctx->ocbuflen)) {
        mhResponse_t *resp;

        if (cctx->ocbuflen) {
            len = cctx->ocbuflen;
            STATUSREADERR(apr_socket_send(cctx->skt, cctx->ocbuf, &len));
            _mhLog(MH_VERBOSE, cctx->skt,
                   "Proxy/Server sent to client, status %d:\n%.*s\n---- %d ----\n",
                   status, (unsigned int)len, cctx->ocbuf, (unsigned int)len);
            cctx->ocbufrem += len;
            cctx->ocbuflen -= len;
            /* TODO: len < ocbuflen? */
            return status; /* can't send more data */
        }

        while (cctx->currResp || cctx->respQueue->nelts > 0) {
            resp = cctx->currResp ? cctx->currResp :
                            *(mhResponse_t **)apr_array_pop(cctx->respQueue);
            if (resp) {
                _mhLog(MH_VERBOSE, cctx->skt, "Sending response to client.\n");

                status = writeResponse(cctx, resp);
                if (status == APR_EOF) {
                    cctx->currResp = NULL;
                    ctx->mh->verifyStats->requestsResponded++;
                    if (resp->closeConn) {
                        _mhLog(MH_VERBOSE, cctx->skt,
                               "Actively closing connection.\n");
                        cctx->shutdown(cctx, APR_SHUTDOWN_READWRITE);
                        return APR_EOF;
                    }
                    status = APR_SUCCESS;
                } else {
                    cctx->currResp = resp;
                    status = APR_EAGAIN;
                    break;
                }
            } else {
                return APR_EGENERAL;
            }
        }
    }

    status = stream->type->peek(stream, &len);
    if (desc->rtnevents & APR_POLLIN || len > 0) {
        mhAction_t action;

        switch (cctx->mode) {
          case ModeServer:
          case ModeProxy:
            /* Read partial or full requests */
            STATUSREADERR(readRequest(cctx, &cctx->req));

            if (!cctx->req)
                return status;

            if (status == APR_EOF) {
                mhResponse_t *resp;

                /* complete request received */
                ctx->mh->verifyStats->requestsReceived++;
                cctx->reqsReceived++;
                ctx->reqState = FullReqReceived;
                *((mhRequest_t **)apr_array_push(ctx->reqsReceived)) = cctx->req;
                if (_mhMatchRequest(ctx, cctx, cctx->req,
                                    &resp, &action) == YES) {
                    ctx->mh->verifyStats->requestsMatched++;
                    if (resp) {
                        _mhLog(MH_VERBOSE, cctx->skt,
                               "Request matched, queueing response.\n");
                        resp = cloneResponse(cctx->pool, resp);
                    } else {
                        _mhLog(MH_VERBOSE, cctx->skt,
                               "Request matched, queueing default response.\n");
                        resp = cloneResponse(cctx->pool, ctx->mh->defResponse);
                    }

                    switch (action) {
                      case mhActionInitiateSSLTunnel:
                        _mhLog(MH_VERBOSE, cctx->skt, "Initiating SSL tunnel.\n");
                        cctx->mode = ModeTunnel;
                        cctx->proxyhost = apr_pstrdup(cctx->pool,
                                                      cctx->req->url);
                        connectToServer(ctx, cctx);
                        break;
                      case mhActionSSLRenegotiate:
                        _mhLog(MH_VERBOSE, cctx->skt, "Renegotiating SSL "
                               "session.\n");
                        STATUSREADERR(renegotiateSSLSession(cctx));
                        break;
                      case mhActionCloseConnection:
                        /* close conn after response */
                        resp->closeConn = YES;
                        cctx->shutdown(cctx, APR_SHUTDOWN_READ);
                        break;
                      default:
                        break;
                    }
                } else {
                    ctx->mh->verifyStats->requestsNotMatched++;
                    _mhLog(MH_VERBOSE, cctx->skt,
                           "Request found no match, queueing error response.\n");
                    resp = cloneResponse(cctx->pool, ctx->mh->defErrorResponse);
                }
                if (ctx->maxRequests && cctx->reqsReceived >= ctx->maxRequests) {
                    setHeader(resp->hdrs, "Connection", "close");
                    resp->closeConn = YES;
                    cctx->shutdown(cctx, APR_SHUTDOWN_READ);
                }

                /* Link the request to the response, and push the response on the
                   queue back to the client */
                resp->req = cctx->req;
                *((mhResponse_t **)apr_array_push(cctx->respQueue)) = resp;
                cctx->req = NULL;

                return APR_SUCCESS;
            } else if (status == APR_SUCCESS || APR_STATUS_IS_EAGAIN(status)) {
                ctx->reqState = PartialReqReceived;
            }

            if (ctx->incompleteReqMatchers->nelts > 0 ||
                ctx->mh->incompleteReqMatchers->nelts > 0) {
                mhResponse_t *resp = NULL;
                /* (currently) incomplete request received? */
                if (_mhMatchIncompleteRequest(ctx, cctx, cctx->req,
                                              &resp, &action) == YES) {
                    _mhLog(MH_VERBOSE, cctx->skt,
                           "Incomplete request matched, queueing response.\n");
                    ctx->mh->verifyStats->requestsMatched++;
                    if (!resp)
                        resp = cloneResponse(cctx->pool, ctx->mh->defResponse);
                    resp->req = cctx->req;
                    *((mhResponse_t **)apr_array_push(cctx->respQueue)) = resp;
                    cctx->req = NULL;
                    return APR_SUCCESS;
                }
            }
            break;
          case ModeTunnel:
            {
                const char *data;
                /* Forward raw data */
                len = cctx->osbufrem;
                STATUSREADERR(stream->type->read(stream, len, &data, &len));

                if (len) {
                    memmove(cctx->osbuf, data, len);
                    _mhLog(MH_VERBOSE, cctx->skt,
                           "recvd with status %d:\n%.*s\n---- %d ----\n",
                           status, (unsigned int)len, cctx->osbuf + cctx->osbuflen,
                           (unsigned int)len);
                    cctx->osbuflen += len;
                    cctx->osbufrem -= len;
                }
            }
            break;
          default:
            break;
        }
    }

    if ((desc->rtnevents & (APR_POLLHUP | APR_POLLERR))
        || APR_STATUS_IS_ECONNRESET(status)
        || APR_STATUS_IS_ECONNABORTED(status)) {

        /* overwrites the result of stream->type->peek() */
        status = APR_EOF;
    }

    return status;
}

/**
 * Initialize the client context. This stores all info related to one client
 * socket in the server.
 */
static apr_status_t initClientCtx(_mhClientCtx_t **ppctx,
                                  apr_pool_t *pool, mhServCtx_t *serv_ctx,
                                  apr_socket_t *cskt, mhServerType_t type)
{
    _mhClientCtx_t *cctx;
    apr_pool_t *ccpool;
    apr_pool_create(&ccpool, pool);

    cctx = apr_pcalloc(ccpool, sizeof(_mhClientCtx_t));
    cctx->pool = ccpool;
    cctx->serv_ctx = serv_ctx;
    cctx->skt = cskt;
    cctx->ocbuflen = 0;
    cctx->ocbufrem = BUFSIZE;
    cctx->osbuflen = 0;
    cctx->osbufrem = BUFSIZE;
    cctx->closeConn = NO;
    cctx->respQueue = apr_array_make(pool, 5, sizeof(mhResponse_t *));
    cctx->currResp = NULL;
    cctx->mode = ModeServer;
    if (type == mhHTTPv1Server || type == mhHTTPv11Server ||
        type == mhHTTPv1Proxy || type == mhHTTPv11Proxy) {
        cctx->read = socketRead;
        cctx->send = socketWrite;
        cctx->shutdown = socketShutdown;
    }
#ifdef MOCKHTTP_OPENSSL
    if (type == mhHTTPSv1Server || type == mhHTTPSv11Server) {
        apr_status_t status;

        cctx->handshake = sslHandshake;
        cctx->read = sslSocketRead;
        cctx->send = sslSocketWrite;
        cctx->shutdown = sslSocketShutdown;
        cctx->keyFile = serv_ctx->keyFile;
        cctx->passphrase = serv_ctx->passphrase;
        cctx->certFiles = serv_ctx->certFiles;
        cctx->clientCert = serv_ctx->clientCert;
        cctx->protocols = serv_ctx->protocols;
        cctx->ocspEnabled = serv_ctx->ocspEnabled;

        status = initSSLCtx(cctx);

        if (status)
            return status;
    }
#endif
    cctx->stream = createBufferedSocketBucket(cskt, cctx->read,
                                              cctx->ssl_ctx, ccpool);

    *ppctx = cctx;

    return APR_SUCCESS;
}

static void closeAndRemoveClientCtx(mhServCtx_t *ctx, _mhClientCtx_t *cctx)
{
    int i;
    apr_array_header_t *clients = ctx->clients;
    apr_pollfd_t pfd = { 0 };

    /* Close socket and clean up client context */
    pfd.desc_type = APR_POLL_SOCKET;
    pfd.desc.s = cctx->skt;
    pfd.reqevents = cctx->reqevents;
    apr_pollset_remove(ctx->pollset, &pfd);
    apr_socket_close(cctx->skt);
    cctx->skt = NULL;

    if (cctx->proxyskt) {
        pfd.desc_type = APR_POLL_SOCKET;
        pfd.desc.s = cctx->proxyskt;
        pfd.reqevents = cctx->proxyreqevents;
        apr_pollset_remove(ctx->pollset, &pfd);
        apr_socket_close(cctx->proxyskt);
        cctx->proxyskt = NULL;
    }

    /* TODO: a linked list would be more efficient. */
    /* Swap the last element to the location of the element to be
     deleted, then decrease the size of the array by 1 */
    for (i = 0; i < clients->nelts; i++) {
        _mhClientCtx_t *tmp = APR_ARRAY_IDX(clients, i, _mhClientCtx_t *);
        if (cctx == tmp) {
            if (i+1 < clients->nelts) {
                _mhClientCtx_t *last;
                last = APR_ARRAY_IDX(clients, clients->nelts - 1,
                                     _mhClientCtx_t *);
                *(_mhClientCtx_t **)&clients->elts[i] = last;
            }
            clients->nelts--;
        }
    }
}

/**
 * Process all events on all sockets related to this server CTX, i.e. the server
 * socket for incoming connections, the client socket(s) and the outgoing
 * socket in case this server acts as a proxy.
 */
apr_status_t _mhRunServerLoop(mhServCtx_t *ctx)
{
    apr_int32_t num;
    const apr_pollfd_t *desc;
    apr_status_t status;

    if (!ctx->pollset) {
        /* Somebody ignored the result of mhStartServer().
           ... Not that hard given that it returns void */
        return APR_EINCOMPLETE;
    }

    if (ctx->reqState == FullReqReceived)
        ctx->reqState = NoReqsReceived;
#if 0
    /* TODO: add a dirty flag to every socket wrapping context, only listen
       for writeable events with the socket is dirty */
    apr_pollfd_t pfd = { 0 };
    cctx = ctx->cctx;
    /* something to write */
    if (cctx && cctx->skt) {
        pfd.desc_type = APR_POLL_SOCKET;
        pfd.desc.s = cctx->skt;
        pfd.reqevents = cctx->reqevents;
        pfd.client_data = cctx;
        apr_pollset_remove(ctx->pollset, &pfd);

        cctx->reqevents = APR_POLLIN;
        if (cctx->currResp || cctx->respQueue->nelts > 0 || cctx->obuflen > 0)
            cctx->reqevents |= APR_POLLOUT;
        pfd.reqevents = ctx->cctx->reqevents;
        STATUSERR(apr_pollset_add(ctx->pollset, &pfd));
    }
#endif
    STATUSERR(apr_pollset_poll(ctx->pollset, APR_USEC_PER_SEC / 100,
                               &num, &desc));

    /* The same socket can be returned multiple times by apr_pollset_poll() */
    while (num--) {
        if (desc->desc.s == ctx->skt) {
            _mhClientCtx_t *cctx;
            apr_socket_t *cskt;
            apr_pollfd_t pfd = { 0 };

            _mhLog(MH_VERBOSE, ctx->skt, "Accepting client connection.\n");

            STATUSERR(apr_socket_accept(&cskt, ctx->skt, ctx->pool));

            STATUSERR(apr_socket_opt_set(cskt, APR_SO_NONBLOCK, 1));
            STATUSERR(apr_socket_timeout_set(cskt, 0));

            /* Push a client context on the ctx->clients stack */
            STATUSERR(initClientCtx(&cctx, ctx->pool, ctx, cskt, ctx->type));
            pfd.desc_type = APR_POLL_SOCKET;
            pfd.desc.s = cskt;
            pfd.reqevents = APR_POLLIN | APR_POLLOUT | APR_POLLHUP | APR_POLLERR;
            pfd.client_data = cctx;
            STATUSERR(apr_pollset_add(ctx->pollset, &pfd));
            cctx->reqevents = pfd.reqevents;
            *((_mhClientCtx_t **)apr_array_push(ctx->clients)) = cctx;

        } else {
            _mhClientCtx_t *cctx = desc->client_data;

            if (!cctx || !cctx->skt) {
                _mhLog(MH_VERBOSE, NULL, "Getting event from unknown socket.\n");
            } else if (desc->desc.s == cctx->proxyskt) {
                /* Connection proxy <-> server */
                STATUSREADERR(processProxy(cctx, desc));
                if (status == APR_EOF) {
                    apr_pollfd_t pfd = { 0 };
                    pfd.desc_type = APR_POLL_SOCKET;
                    pfd.desc.s = cctx->proxyskt;
                    pfd.reqevents = cctx->proxyreqevents;
                    apr_pollset_remove(ctx->pollset, &pfd);
                    apr_socket_close(cctx->proxyskt);
                    cctx->proxyskt = NULL;

                }
            } else {
                /* Connection client <-> proxy/server */
                status = APR_SUCCESS;

                if (cctx->handshake)
                    status = cctx->handshake(cctx);

                /* APR_SUCCESS -> handshake finished or not needed */
                if (status == APR_SUCCESS) {
                    STATUSREADERR(processServer(ctx, cctx, desc));
                    if (status == APR_EOF) {
                        /* Close the socket and an associated proxy skt */
                        closeAndRemoveClientCtx(ctx, cctx);
                        break;
                    }
                }
            }
        }
        desc++;
    }

    return status;
}

/******************************************************************************/
/* Init HTTP server                                                           */
/******************************************************************************/

/**
 * Creates a new server on localhost and on the default server port.
 */
mhServCtx_t *mhNewServer(MockHTTP *mh)
{
    mh->servCtx = initServCtx(mh, "localhost", DefaultSrvPort);
    mh->servCtx->type = mhGenericServer;
    return mh->servCtx;
}

/**
 * Creates a new proxy server on localhost and on the default proxy port.
 */
mhServCtx_t *mhNewProxy(MockHTTP *mh)
{
    mh->proxyCtx = initServCtx(mh, "localhost", DefaultProxyPort);
    mh->proxyCtx->type = mhGenericProxy;
    return mh->proxyCtx;
}

/**
 * Creates a new OCSP responder on localhost and on its default port.
 */
mhServCtx_t *mhNewOCSPResponder(MockHTTP *mh)
{
    mh->ocspRespCtx = initServCtx(mh, "localhost", DefaultOCSPResponderPort);
    mh->ocspRespCtx->type = mhOCSPResponder;
    return mh->ocspRespCtx;
}

/**
 * Returns the server context associated with id SERVERID.
 */
mhServCtx_t *mhFindServerByID(const MockHTTP *mh, const char *serverID)
{
    if (mh->servCtx && mh->servCtx->serverID &&
        strcmp(mh->servCtx->serverID, serverID) == 0) {
        return mh->servCtx;
    }

    if (mh->proxyCtx && mh->proxyCtx->serverID &&
        strcmp(mh->proxyCtx->serverID, serverID) == 0) {
        return mh->proxyCtx;
    }
    return NULL;
}

/**
 * Takes a list of builders of type mhServerSetupBldr_t *'s and executes them
 * one by one (in the order they are passed as arguments) to configure the
 * server SERV_CTX.
 */
void mhConfigServer(mhServCtx_t *serv_ctx, ...)
{
    va_list argp;

    /* Build the server configuration */
    va_start(argp, serv_ctx);
    while (1) {
        mhServerSetupBldr_t *ssb;
        ssb = va_arg(argp, mhServerSetupBldr_t *);
        if (ssb == NULL)
            break;
        if (ssb->builder.type == BuilderTypeNone)
            continue;
        if (ssb->builder.type != BuilderTypeServerSetup) {
            _mhErrorUnexpectedBuilder(serv_ctx->mh, ssb, BuilderTypeServerSetup);
            break;
        }
        ssb->serversetup(ssb, serv_ctx);
    }
    va_end(argp);

    if (serv_ctx->protocols == mhProtoUnspecified) {
        serv_ctx->protocols = mhProtoAllSecure;
    }
    if (!serv_ctx->serverID) {
        if (serv_ctx->type == mhGenericProxy) {
            serv_ctx->serverID = DEFAULT_PROXY_ID;
        } else {
            serv_ctx->serverID = DEFAULT_SERVER_ID;
        }
    }
}

/**
 * Starts the server CTX, makes it start listening for incoming connections.
 */
void mhStartServer(mhServCtx_t *ctx)
{
    apr_thread_t *thread;
    mhError_t err = MOCKHTTP_NO_ERROR;
    apr_status_t status;

    if (ctx->threading == mhThreadSeparate) {
#if APR_HAS_THREADS
        /* Setup a non-blocking TCP server */
        status = setupTCPServer(ctx);
        if (!status) {
            status = apr_thread_create(&thread, NULL, run_thread,
                                       ctx, ctx->pool);
            if (!status)
                ctx->threadid = thread;
        }
#else
        status = APR_EGENERAL;
#endif
    } else {
        /* Setup a non-blocking TCP server */
        status = setupTCPServer(ctx);
    }

    if (status) {
        err = MOCKHTTP_SETUP_FAILED;
    }
    /* TODO: store error message */
}

void mhStopServer(mhServCtx_t *ctx)
{
    apr_status_t status;
#ifdef APR_HAS_THREADS
    if (ctx->threading == mhThreadSeparate && ctx->threadid) {
        ctx->cancelThread = YES;
        apr_thread_join(&status, ctx->threadid);
    }
#endif
}


/**
 * Factory function, creates a builder of type mhServerSetupBldr_t.
 */
static mhServerSetupBldr_t *createServerSetupBldr(apr_pool_t *pool)
{
    mhServerSetupBldr_t *ssb = apr_pcalloc(pool, sizeof(mhServerSetupBldr_t));
    ssb->builder.magic = MagicKey;
    ssb->builder.type = BuilderTypeServerSetup;
    return ssb;
}

/**
 * Builder callback, sets the server id on server CTX.
 */
static bool set_server_id(const mhServerSetupBldr_t *ssb, mhServCtx_t *ctx)
{
    ctx->serverID = ssb->baton;
    return YES;
}


/**
 * Create a builder of type mhServerSetupBldr_t, sets the server id
 */
mhServerSetupBldr_t *mhSetServerID(mhServCtx_t *ctx, const char *serverID)
{
    apr_pool_t *pool = ctx->pool;
    mhServerSetupBldr_t *ssb = createServerSetupBldr(pool);
    ssb->baton = apr_pstrdup(pool, serverID);
    ssb->serversetup = set_server_id;
    return ssb;
}

/**
 * Builder callback, sets the number of maximum requests per connection on
 * server CTX.
 */
static bool
set_server_maxreqs_per_conn(const mhServerSetupBldr_t *ssb, mhServCtx_t *ctx)
{
    ctx->maxRequests = ssb->ibaton;
    return YES;
}

/**
 * Create a builder of type mhServerSetupBldr_t, sets the number of maximum
 * requests per connection.
 */
mhServerSetupBldr_t *
mhSetServerMaxRequestsPerConn(mhServCtx_t *ctx, unsigned int maxRequests)
{
    apr_pool_t *pool = ctx->pool;
    mhServerSetupBldr_t *ssb = createServerSetupBldr(pool);
    ssb->ibaton = maxRequests;
    ssb->serversetup = set_server_maxreqs_per_conn;
    return ssb;
}

apr_port_t mhServerByIDPortNr(const MockHTTP *mh, const char *serverID)
{
    mhServCtx_t *ctx = mhFindServerByID(mh, serverID);

    if (ctx) {
        if (!ctx->port)
            abort();
        return ctx->port;
    }
    return 0;
}

apr_port_t mhServerPortNr(const MockHTTP *mh)
{
    return mhServerByIDPortNr(mh, DEFAULT_SERVER_ID);
}

apr_port_t mhProxyPortNr(const MockHTTP *mh)
{
    return mhServerByIDPortNr(mh, DEFAULT_PROXY_ID);
}

/**
 * Builder callback, sets the port number on server CTX.
 */
static bool set_server_port(const mhServerSetupBldr_t *ssb, mhServCtx_t *ctx)
{
    ctx->default_port = (apr_port_t)ssb->ibaton;
    return YES;
}

/**
 * Create a builder of type mhServerSetupBldr_t, sets the server port
 */
mhServerSetupBldr_t *mhSetServerPort(mhServCtx_t *ctx, unsigned int port)
{
    apr_pool_t *pool = ctx->pool;
    mhServerSetupBldr_t *ssb = createServerSetupBldr(pool);
    ssb->ibaton = port;
    ssb->serversetup = set_server_port;
    return ssb;
}

static bool set_server_protocol(const mhServerSetupBldr_t *ssb, mhServCtx_t *ctx)
{
  ctx->alpn = ssb->baton;
  return YES;
}

mhServerSetupBldr_t *mhSetServerProtocol(mhServCtx_t *ctx, const char *protocols)
{
  apr_pool_t *pool = ctx->pool;
  mhServerSetupBldr_t *ssb = createServerSetupBldr(pool);
  ssb->baton = apr_pstrdup(pool, protocols);
  ssb->serversetup = set_server_protocol;
  return ssb;
}

/**
 * Builder callback, sets the server type on server CTX.
 */
static bool set_server_type(const mhServerSetupBldr_t *ssb, mhServCtx_t *ctx)
{
    mhServerType_t type = ssb->ibaton;

    switch (ctx->type) {
        case mhGenericServer:
            if (type == mhHTTPv1)
                ctx->type = mhHTTPv1Server;
            else if (type == mhHTTPv11)
                ctx->type = mhHTTPv11Server;
            else if (type == mhHTTPSv1)
                ctx->type = mhHTTPSv1Server;
            else
                ctx->type = mhHTTPSv11Server;
            break;
        case mhGenericProxy:
            if (type == mhHTTPv1)
                ctx->type = mhHTTPv1Proxy;
            else if (type == mhHTTPv11)
                ctx->type = mhHTTPv11Proxy;
            else if (type == mhHTTPSv1)
                ctx->type = mhHTTPSv1Proxy;
            else
                ctx->type = mhHTTPSv11Proxy;
            break;
        default:
            /* TODO: error in test configuration. */
            break;
    }
    return YES;
}

/**
 * Create a builder of type mhServerSetupBldr_t, sets the server type
 */
mhServerSetupBldr_t *mhSetServerType(mhServCtx_t *ctx, mhServerType_t type)
{
    apr_pool_t *pool = ctx->pool;
    mhServerSetupBldr_t *ssb = createServerSetupBldr(pool);
    ssb->ibaton = type;
    ssb->serversetup = set_server_type;
    return ssb;
}

/**
 * Builder callback, sets the server's threading mode on server CTX.
 */
static bool
set_server_threading(const mhServerSetupBldr_t *ssb, mhServCtx_t *ctx)
{
    ctx->threading = ssb->ibaton;
    return YES;
}


/**
 * Create a builder of type mhServerSetupBldr_t, sets the server threading mode.
 */
mhServerSetupBldr_t *
mhSetServerThreading(mhServCtx_t *ctx, mhThreading_t threading)
{
    apr_pool_t *pool = ctx->pool;
    mhServerSetupBldr_t *ssb = createServerSetupBldr(pool);
    ssb->ibaton = threading;
    ssb->serversetup = set_server_threading;
    return ssb;
}

/**
 * Builder callback, sets the prefix for certificate paths on server CTX.
 */
static bool
set_server_cert_prefix(const mhServerSetupBldr_t *ssb, mhServCtx_t *ctx)
{
    ctx->certFilesPrefix = ssb->baton;
    return YES;
}


/**
 * Create a builder of type mhServerSetupBldr_t, sets the prefix for cert paths.
 */
mhServerSetupBldr_t *
mhSetServerCertPrefix(mhServCtx_t *ctx, const char *prefix)
{
    apr_pool_t *pool = ctx->pool;
    mhServerSetupBldr_t *ssb = createServerSetupBldr(pool);
    ssb->baton = apr_pstrdup(pool, prefix);
    ssb->serversetup = set_server_cert_prefix;
    return ssb;
}

/**
 * Builder callback, sets the path of the server private key file on server CTX.
 */
static bool
set_server_key_file(const mhServerSetupBldr_t *ssb, mhServCtx_t *ctx)
{
    const char *keyFile = ssb->baton;
    if (ctx->certFilesPrefix) {
        ctx->keyFile = apr_pstrcat(ctx->pool, ctx->certFilesPrefix, "/",
                                   keyFile, NULL);
    } else {
        ctx->keyFile = keyFile;
    }
    return YES;
}


/**
 * Create a builder of type mhServerSetupBldr_t, sets the private key file.
 */
mhServerSetupBldr_t *
mhSetServerCertKeyFile(mhServCtx_t *ctx, const char *keyFile)
{
    apr_pool_t *pool = ctx->pool;
    mhServerSetupBldr_t *ssb = createServerSetupBldr(pool);
    ssb->baton = apr_pstrdup(pool, keyFile);
    ssb->serversetup = set_server_key_file;
    return ssb;
}

/**
 * Builder callback, sets the passphrase to be used to decrypt the private key
 * file on server CTX.
 */
static bool
set_server_key_passphrase(const mhServerSetupBldr_t *ssb, mhServCtx_t *ctx)
{
    ctx->passphrase = ssb->baton;
    return YES;
}


/**
 * Create a builder of type mhServerSetupBldr_t, sets the private key passphrase.
 */
mhServerSetupBldr_t *
mhSetServerCertKeyPassPhrase(mhServCtx_t *ctx, const char *passphrase)
{
    apr_pool_t *pool = ctx->pool;
    mhServerSetupBldr_t *ssb = createServerSetupBldr(pool);
    ssb->baton = apr_pstrdup(pool, passphrase);
    ssb->serversetup = set_server_key_passphrase;
    return ssb;
}

/**
 * Builder callback, adds a list of certificate files on server CTX.
 */
static bool
add_server_cert_files(const mhServerSetupBldr_t *ssb, mhServCtx_t *ctx)
{
    int i;
    const apr_array_header_t *certFiles = ssb->baton;

    if (!ctx->certFiles)
        ctx->certFiles = apr_array_make(ctx->pool, 5, sizeof(const char *));

    /* Copy over the cert file paths, add prefix */
    for (i = 0; i < certFiles->nelts; i++) {
        const char *certFile = APR_ARRAY_IDX(certFiles, i, const char *);

        if (ctx->certFilesPrefix)
            certFile = apr_pstrcat(ctx->pool, ctx->certFilesPrefix, "/",
                                   certFile, NULL);
        *((const char **)apr_array_push(ctx->certFiles)) = certFile;
    }
    return YES;
}


/**
 * Create a builder of type mhServerSetupBldr_t, adds certificates.
 */
mhServerSetupBldr_t *
mhAddServerCertFiles(mhServCtx_t *ctx, ...)
{
    apr_pool_t *pool = ctx->pool;
    mhServerSetupBldr_t *ssb = createServerSetupBldr(pool);
    va_list argp;
    apr_array_header_t *certFiles;

    certFiles = apr_array_make(ctx->pool, 5, sizeof(const char *));

    va_start(argp, ctx);
    while (1) {
        const char *certFile = va_arg(argp, const char *);
        if (certFile == NULL)
            break;
        *((const char **)apr_array_push(certFiles)) = apr_pstrdup(pool, certFile);
    }
    va_end(argp);

    ssb->baton = certFiles;
    ssb->serversetup = add_server_cert_files;

    return ssb;
}


/**
 * Create a builder of type mhServerSetupBldr_t, adds an array of certificates.
 */
mhServerSetupBldr_t *
mhAddServerCertFileArray(mhServCtx_t *ctx, const char **certFiles)
{
    apr_pool_t *pool = ctx->pool;
    mhServerSetupBldr_t *ssb = createServerSetupBldr(pool);
    apr_array_header_t *certFileAry;
    const char *certFile;
    int i = 0;

    certFileAry = apr_array_make(ctx->pool, 5, sizeof(const char *));

    do {
        certFile = certFiles[i++];
        *((const char **)apr_array_push(certFileAry)) = apr_pstrdup(pool,
                                                                    certFile);
    } while (certFiles[i] != NULL);
    ssb->baton = certFileAry;
    ssb->serversetup = add_server_cert_files;
    return ssb;
}

/**
 * Builder callback, sets how server CTX should request client certificates.
 */
static bool
set_server_request_client_cert(const mhServerSetupBldr_t *ssb, mhServCtx_t *ctx)
{
    ctx->clientCert = ssb->ibaton;
    return YES;
}


/**
 * Create a builder of type mhServerSetupBldr_t, sets how the server should
 * request client certificates.
 */
mhServerSetupBldr_t *
mhSetServerRequestClientCert(mhServCtx_t *ctx, mhClientCertVerification_t v)
{
    apr_pool_t *pool = ctx->pool;
    mhServerSetupBldr_t *ssb = createServerSetupBldr(pool);
    ssb->ibaton = v;
    ssb->serversetup = set_server_request_client_cert;
    return ssb;
}

/**
 * Builder callback, adds an allowed SSL/TLS version on server CTX.
 */
static bool
add_server_ssl_protocol(const mhServerSetupBldr_t *ssb, mhServCtx_t *ctx)
{
    ctx->protocols |= ssb->ibaton;
    return YES;
}

/**
 * Create a builder of type mhServerSetupBldr_t, adds allowed SSL/TLS version.
 */
mhServerSetupBldr_t *mhAddSSLProtocol(mhServCtx_t *ctx, mhSSLProtocol_t proto)
{
    apr_pool_t *pool = ctx->pool;
    mhServerSetupBldr_t *ssb = createServerSetupBldr(pool);
    ssb->ibaton = proto;
    ssb->serversetup = add_server_ssl_protocol;
    return ssb;
}

/**
 * Builder callback, sets the "OCSP Enabled" flag.
 */
static bool
enable_server_ocsp(const mhServerSetupBldr_t *ssb, mhServCtx_t *ctx)
{
    ctx->ocspEnabled = ssb->ibaton;
    return YES;
}

/**
 * Create a builder of type mhServerSetupBldr_t, enable OCSP stapling support.
 */
mhServerSetupBldr_t *
mhSetServerEnableOCSP(mhServCtx_t *ctx)
{
    apr_pool_t *pool = ctx->pool;
    mhServerSetupBldr_t *ssb = createServerSetupBldr(pool);
    ssb->ibaton = YES;
    ssb->serversetup = enable_server_ocsp;
    return ssb;
}


#ifdef MOCKHTTP_OPENSSL
/******************************************************************************/
/* Init HTTPS server                                                          */
/******************************************************************************/
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

struct sslCtx_t {
    bool handshake_done;
    bool renegotiate;
    bool hit_eof;
    apr_status_t bio_status;

    SSL_CTX* ctx;
    SSL* ssl;
    BIO *bio;
    BIO_METHOD *biom;

    char read_buffer[8192];
};

static int init_done = 0;

#if MH_VERBOSE
/**
 * OpenSSL callback for ERR_print_errors_cb().
 */
static int err_file_print_cb(const char *str, size_t len, void *bp)
{
    return fwrite(str, 1, len, bp);
}
#endif

/**
 * OpenSSL callback, returns the passphrase used to decrypt the private key.
 */
static int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata)
{
    _mhClientCtx_t *cctx = userdata;

    if (!cctx->passphrase)
        return 0;

    strncpy(buf, cctx->passphrase, size);
    buf[size - 1] = '\0';
    return strlen(buf);
}

/**
 * OpenSSL BIO callback. Creates a new BIO structure.
 */
static int bio_apr_socket_create(BIO *bio)
{
#ifndef SERF_NO_SSL_BIO_WRAPPERS
    BIO_set_shutdown(bio, 1);
    BIO_set_init(bio, 1);
    BIO_set_data(bio, NULL);
#else
    bio->shutdown = 1;
    bio->init = 1;
    bio->num = -1;
    bio->ptr = NULL;
#endif

    return 1;
}

static void bio_set_data(BIO *bio, void *data)
{
#ifndef SERF_NO_SSL_BIO_WRAPPERS
    BIO_set_data(bio, data);
#else
    bio->ptr = data;
#endif
}

static void *bio_get_data(BIO *bio)
{
#ifndef SERF_NO_SSL_BIO_WRAPPERS
    return BIO_get_data(bio);
#else
    return bio->ptr;
#endif
}

/**
 * OpenSSL BIO callback. Cleans up the BIO structure.
 */
static int bio_apr_socket_destroy(BIO *bio)
{
    /* Did we already free this? */
    if (bio == NULL) {
        return 0;
    }

    return 1;
}

/**
 * OpenSSL BIO callback.
 */
static long bio_apr_socket_ctrl(BIO *bio, int cmd, long num, void *ptr)
{
    _mhClientCtx_t *cctx = bio_get_data(bio);
    sslCtx_t *ssl_ctx = cctx->ssl_ctx;

    switch (cmd) {
        case BIO_CTRL_FLUSH:
            /* At this point we can't force a flush. */
            return 1;
        case BIO_CTRL_PUSH:
        case BIO_CTRL_POP:
            return 0;
        case BIO_CTRL_EOF:
            return ssl_ctx->hit_eof;
        default:
            /* abort(); */
            return 0;
    }
}

/**
 * OpenSSL BIO callback. Reads data from a socket, returns the amount read.
 */
static int bio_apr_socket_read(BIO *bio, char *in, int inlen)
{
    apr_size_t len = inlen;
    _mhClientCtx_t *cctx = bio_get_data(bio);
    sslCtx_t *ssl_ctx = cctx->ssl_ctx;
    apr_status_t status;

    BIO_clear_retry_flags(bio);

    status = apr_socket_recv(cctx->skt, in, &len);
    ssl_ctx->bio_status = status;

    if (len > 0)
        _mhLog(MH_VERBOSE, cctx->skt, "Read %d bytes from ssl socket with "
               "status %d.\n", len, status);

    if (APR_STATUS_IS_EOF(status)) {
        ssl_ctx->hit_eof = YES;
    } else if (APR_STATUS_IS_EAGAIN(status)) {
        BIO_set_retry_read(bio);
    }

    if (READ_ERROR(status))
        return -1;

    return len ? len : -1;
}

/**
 * OpenSSL BIO callback. Write data to a socket, returns the amount written.
 */
static int bio_apr_socket_write(BIO *bio, const char *in, int inlen)
{
    apr_size_t len = inlen;
    _mhClientCtx_t *cctx = bio_get_data(bio);
    sslCtx_t *ssl_ctx = cctx->ssl_ctx;
    apr_status_t status;

    BIO_clear_retry_flags(bio);

    status = apr_socket_send(cctx->skt, in, &len);
    ssl_ctx->bio_status = status;

    if (len > 0)
        _mhLog(MH_VERBOSE, cctx->skt, "Wrote %d of %d bytes to ssl socket with "
               "status %d.\n", len, inlen, status);

    if (APR_STATUS_IS_EAGAIN(status)) {
        BIO_set_retry_write(bio);
    }

    if (READ_ERROR(status))
        return -1;

    return len ? len : -1;
}


#ifdef SERF_NO_SSL_BIO_WRAPPERS
static BIO_METHOD bio_apr_socket_method = {
    BIO_TYPE_SOCKET,
    "APR sockets",
    bio_apr_socket_write,
    bio_apr_socket_read,
    NULL,                        /* Is this called? */
    NULL,                        /* Is this called? */
    bio_apr_socket_ctrl,
    bio_apr_socket_create,
    bio_apr_socket_destroy,
#ifdef OPENSSL_VERSION_NUMBER
    NULL /* sslc does not have the callback_ctrl field */
#endif
};
#endif

static BIO_METHOD *bio_meth_apr_socket_new(void)
{
    BIO_METHOD *biom = NULL;

#ifndef SERF_NO_SSL_BIO_WRAPPERS
    biom = BIO_meth_new(BIO_TYPE_SOCKET, "APR sockets");
    if (biom) {
        BIO_meth_set_write(biom, bio_apr_socket_write);
        BIO_meth_set_read(biom, bio_apr_socket_read);
        BIO_meth_set_ctrl(biom, bio_apr_socket_ctrl);
        BIO_meth_set_create(biom, bio_apr_socket_create);
        BIO_meth_set_destroy(biom, bio_apr_socket_destroy);
    }
#else
    biom = &bio_apr_socket_method;
#endif

    return biom;
}

static void bio_meth_free(BIO_METHOD *biom)
{
#ifndef SERF_NO_SSL_BIO_WRAPPERS
    BIO_meth_free(biom);
#endif
}

#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_OCSP)
static int ocspCreateResponse(OCSP_RESPONSE **resp, mhOCSPRespnseStatus_t status)
{
    int ret = 1;
    int ocspStatus;
/*
    OCSP_BASICRESP *basicResp = NULL;

    basicResp = OCSP_BASICRESP_new();

    *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);

    OCSP_BASICRESP_free(basicResp);
*/

    switch (status) {
        case mhOCSPRespnseStatusSuccessful:
            ocspStatus = OCSP_RESPONSE_STATUS_SUCCESSFUL;
            break;
        case mhOCSPRespnseStatusMalformedRequest:
            ocspStatus = OCSP_RESPONSE_STATUS_MALFORMEDREQUEST;
            break;
        case mhOCSPRespnseStatusInternalError:
            ocspStatus = OCSP_RESPONSE_STATUS_INTERNALERROR;
            break;
        case mhOCSPRespnseStatusTryLater:
            ocspStatus = OCSP_RESPONSE_STATUS_TRYLATER;
            break;
        case mhOCSPRespnseStatusSigRequired:
            ocspStatus = OCSP_RESPONSE_STATUS_SIGREQUIRED;
            break;
        case mhOCSPRespnseStatusUnauthorized:
            ocspStatus = OCSP_RESPONSE_STATUS_UNAUTHORIZED;
            break;
        default:
            /* Unsupported OCSP status */
            return 0;
    }

    *resp = OCSP_response_create(ocspStatus, NULL);

    return ret;
}

/**
 * OpenSSL callback, executed on the server when the client has enabled OCSP
 * support. If an OCSP responder was defined in the test, call it now with an
 * OCSP request to get an OCSP response that can be returned to the client.
 */
static int ocspStatusCallback(SSL *ssl, void *userdata)
{
    _mhClientCtx_t *cctx = userdata;
    const MockHTTP *mh = cctx->serv_ctx->mh;
    OCSP_RESPONSE *ocspResp;
    int result;
    int rspderlen;
    unsigned char *rspder = NULL;
    mhResponse_t *resp;
    mhAction_t dummy;
    mhRequest_t *req;
    req = _mhInitRequest(cctx->pool, RequestTypeOCSP);
    /* Nope, then see if there's a request matcher for all servers */
    if (matchRequest(req, &resp, &dummy, mh->ocspReqMatchers) == YES) {
        _mhBuildResponse(resp);

        if ((result = ocspCreateResponse(&ocspResp,
                                         resp->ocsp_response_status)) <= 0)
            return result;

        rspderlen = i2d_OCSP_RESPONSE(ocspResp, &rspder);
        if (rspderlen <= 0)
            return SSL_TLSEXT_ERR_ALERT_FATAL;

        SSL_set_tlsext_status_ocsp_resp(ssl, rspder, rspderlen);
        return SSL_TLSEXT_ERR_OK;
    }
    /* Couldn't find match */
    return SSL_TLSEXT_ERR_ALERT_FATAL;
}
#endif  /* OPENSSL_NO_TLSEXT && OPENSSL_NO_OCSP */

/* Convert an ssl error into an apr status code for a specific context */
static apr_status_t status_from_ssl(sslCtx_t *ssl_ctx, int ret_code)
{
    int ssl_error = SSL_get_error(ssl_ctx->ssl, ret_code);

    if (ret_code > 0)
        return APR_SUCCESS;

    switch (ssl_error) {
        case 0:
            return APR_EOF;
        case SSL_ERROR_SYSCALL:
            return ssl_ctx->bio_status;
        default:
            return APR_EGENERAL;
    }
}

/**
 * Action: renegotiates a SSL session on client socket CCTX.
 * Returns APR_SUCCESS if the renegotiation handshake was successfull
 *         error if not.
 */
static apr_status_t renegotiateSSLSession(_mhClientCtx_t *cctx)
{
    sslCtx_t *ssl_ctx = cctx->ssl_ctx;
    int ssl_result;
    apr_status_t status;

    /* TODO: check for APR_EAGAIN situation */
    ssl_result = SSL_renegotiate(ssl_ctx->ssl);
    status = status_from_ssl(ssl_ctx, ssl_result);

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

    ssl_result = SSL_do_handshake(ssl_ctx->ssl);
    status = status_from_ssl(ssl_ctx, ssl_result);

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

    ssl_ctx->renegotiate = YES;

    return APR_SUCCESS;
}

/**
 * Pool cleanup callback, cleans up the OpenSSL structures
 */
static apr_status_t cleanupSSL(void *baton)
{
    _mhClientCtx_t *cctx = baton;
    sslCtx_t *ssl_ctx = cctx->ssl_ctx;

    if (ssl_ctx) {
        if (ssl_ctx->ssl) {
            SSL_clear(ssl_ctx->ssl);
            bio_meth_free(ssl_ctx->biom);
        }
        SSL_CTX_free(ssl_ctx->ctx);
    }

    return APR_SUCCESS;
}

/**
 * OpenSSL callback, accepts the client certificate.
 */
static int validateClientCertificate(int preverify_ok, X509_STORE_CTX *ctx)
{
    SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
                                          SSL_get_ex_data_X509_STORE_CTX_idx());
    _mhClientCtx_t *cctx = SSL_get_app_data(ssl);

    _mhLog(MH_VERBOSE, cctx->skt, "validate_client_certificate called, "
                                 "preverify: %d.\n", preverify_ok);
    /* Client cert is valid for now, can be validated later. */
    return 1;
}

/**
 * Inits the OpenSSL SSL structure.
 */
static apr_status_t initSSL(_mhClientCtx_t *cctx)
{
    sslCtx_t *ssl_ctx = cctx->ssl_ctx;

    ssl_ctx->ssl = SSL_new(ssl_ctx->ctx);
    SSL_set_cipher_list(ssl_ctx->ssl, "ALL");
    SSL_set_bio(ssl_ctx->ssl, ssl_ctx->bio, ssl_ctx->bio);
    SSL_set_app_data(ssl_ctx->ssl, cctx);

    return APR_SUCCESS;
}

#ifndef OPENSSL_NO_TLSEXT
static int alpn_select_callback(SSL *ssl,
                                const unsigned char **out,
                                unsigned char *outlen,
                                const unsigned char *in,
                                unsigned int inlen,
                                void *arg)
{
  mhServCtx_t *serv_ctx = arg;
  const char *select = serv_ctx->alpn;
  apr_size_t select_sz = strlen(select);

  const unsigned char *p = in;

  while ((p + *p) < (in + inlen)) {

      if ((*p == select_sz)
          && !memcmp(p+1, select, select_sz)) {

          *out = (const unsigned char *)select;
          *outlen = (unsigned char)select_sz;
          return SSL_TLSEXT_ERR_OK;
      }

      p += *p + 1;
  }

  return SSL_TLSEXT_ERR_ALERT_FATAL;
}
#endif  /* OPENSSL_NO_TLSEXT */

/**
 * Inits the OpenSSL context.
 */
static apr_status_t initSSLCtx(_mhClientCtx_t *cctx)
{
    sslCtx_t *ssl_ctx = apr_pcalloc(cctx->pool, sizeof(*ssl_ctx));
    cctx->ssl_ctx = ssl_ctx;
    ssl_ctx->hit_eof = NO;
    ssl_ctx->bio_status = APR_SUCCESS;

    _mhLog(MH_VERBOSE, cctx->skt, "Initializing SSL context.\n");

    /* Init OpenSSL globally */
    if (!init_done)
    {
        ERR_load_crypto_strings();
        SSL_load_error_strings();
        SSL_library_init();
        OpenSSL_add_all_algorithms();
        init_done = 1;
    }

    if (!ssl_ctx->ctx) {
        X509_STORE *store;
        const char *certfile;
        int i;

        /* Configure supported protocol versions */
        ssl_ctx->ctx = SSL_CTX_new(SSLv23_server_method());
        if (! (cctx->protocols & mhProtoSSLv2))
            SSL_CTX_set_options(ssl_ctx->ctx, SSL_OP_NO_SSLv2);
        if (! (cctx->protocols & mhProtoSSLv3))
            SSL_CTX_set_options(ssl_ctx->ctx, SSL_OP_NO_SSLv3);
        if (! (cctx->protocols & mhProtoTLSv1))
            SSL_CTX_set_options(ssl_ctx->ctx, SSL_OP_NO_TLSv1);
#ifdef SSL_OP_NO_TLSv1_1
        if (! (cctx->protocols & mhProtoTLSv11))
            SSL_CTX_set_options(ssl_ctx->ctx, SSL_OP_NO_TLSv1_1);
#endif
#ifdef SSL_OP_NO_TLSv1_2
        if (! (cctx->protocols & mhProtoTLSv12))
            SSL_CTX_set_options(ssl_ctx->ctx, SSL_OP_NO_TLSv1_2);
#endif
#ifdef SSL_OP_NO_TLSv1_3
        if (! (cctx->protocols & mhProtoTLSv13))
            SSL_CTX_set_options(ssl_ctx->ctx, SSL_OP_NO_TLSv1_3);
#endif

#if OPENSSL_VERSION_NUMBER >= 0x10002000L /* >= 1.0.2 */
#  ifndef OPENSSL_NO_TLSEXT
        if (cctx->serv_ctx->alpn) {
            SSL_CTX_set_alpn_select_cb(ssl_ctx->ctx,
                                       alpn_select_callback,
                                       cctx->serv_ctx);
        }
#  endif
#endif

        if (cctx->protocols == mhProtoSSLv2) {
            /* In recent versions of OpenSSL, SSLv2 has been disabled by removing
               all SSLv2 ciphers from the cipher string.
               If SSLv2 is the only protocol this test wants to be enabled,
               re-add the SSLv2 ciphers. */
            SSL_CTX_set_cipher_list(ssl_ctx->ctx, "SSLv2");
            /* ignore result */
        }

        /* Always set this callback, even if no passphrase is set. Otherwise
           OpenSSL will prompt the user to provide a passphrase if one is
           needed. */
        SSL_CTX_set_default_passwd_cb(ssl_ctx->ctx, pem_passwd_cb);
        SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx->ctx, cctx);
        if (SSL_CTX_use_PrivateKey_file(ssl_ctx->ctx, cctx->keyFile,
                                        SSL_FILETYPE_PEM) != 1) {
            _mhLog(MH_VERBOSE, cctx->skt,
                   "Cannot load private key from file '%s'\n", cctx->keyFile);
            return APR_EGENERAL;
        }

        /* Set server certificate, add ca certificates if provided. */
        certfile = APR_ARRAY_IDX(cctx->certFiles, 0, const char *);
        if (SSL_CTX_use_certificate_file(ssl_ctx->ctx, certfile,
                                         SSL_FILETYPE_PEM) != 1) {
            _mhLog(MH_VERBOSE, cctx->skt,
                   "Cannot load certificatefrom file '%s'\n", certfile);
            return APR_EGENERAL;
        }

        store = SSL_CTX_get_cert_store(ssl_ctx->ctx);
        for (i = 1; i < cctx->certFiles->nelts; i++) {
            BIO *bio;
            certfile = APR_ARRAY_IDX(cctx->certFiles, i, const char *);
            bio = BIO_new_file(certfile, "r");
            if (bio) {
                X509 *ssl_cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
                BIO_free(bio);

                X509_STORE_add_cert(store, ssl_cert);
                SSL_CTX_add_extra_chain_cert(ssl_ctx->ctx, ssl_cert);
            }
        }

        /* Check if the server needs to ask the client to send a certificate
           during handshake. */
        switch (cctx->clientCert) {
            case mhCCVerifyNone:
                break;
            case mhCCVerifyPeer:
                SSL_CTX_set_verify(ssl_ctx->ctx, SSL_VERIFY_PEER,
                                   validateClientCertificate);
                break;
            case mhCCVerifyFailIfNoPeerSet:
                SSL_CTX_set_verify(ssl_ctx->ctx,
                                   SSL_VERIFY_PEER |
                                     SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
                                   validateClientCertificate);
                break;
            default:
                break;
        }

#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_OCSP)
        if (cctx->ocspEnabled) {
            SSL_CTX_set_tlsext_status_cb(ssl_ctx->ctx, ocspStatusCallback);
            SSL_CTX_set_tlsext_status_arg(ssl_ctx->ctx, cctx);
        }
#endif

        SSL_CTX_set_mode(ssl_ctx->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER
                                       | SSL_MODE_ENABLE_PARTIAL_WRITE
                                       | SSL_MODE_AUTO_RETRY);

        ssl_ctx->bio = BIO_new(bio_meth_apr_socket_new());
        bio_set_data(ssl_ctx->bio, cctx);
        initSSL(cctx);

        apr_pool_cleanup_register(cctx->pool, cctx,
                                  cleanupSSL, apr_pool_cleanup_null);
    }
    return APR_SUCCESS;
}

/**
 * Callback, encrypts data of length LEN in buffer DATA and writes to the socket.
 */
static apr_status_t
sslSocketWrite(_mhClientCtx_t *cctx, const char *data, apr_size_t *len)
{
    sslCtx_t *ssl_ctx = cctx->ssl_ctx;
    int result, ssl_err;

    if (*len == 0)
        return APR_SUCCESS;

    ssl_ctx->bio_status = APR_SUCCESS;
    result = SSL_write(ssl_ctx->ssl, data, *len);
    if (result > 0) {
        *len = result;
        return APR_SUCCESS;
    }

    ssl_err = SSL_get_error(ssl_ctx->ssl, result);
    switch (ssl_err) {
      case SSL_ERROR_ZERO_RETURN:
        *len = 0;
        return APR_EOF; /* Clean SSL shutdown */
      case SSL_ERROR_SYSCALL:
        /* error in bio_bucket_read, probably APR_EAGAIN or APR_EOF */
        *len = 0;
        return ssl_ctx->bio_status;
      case SSL_ERROR_WANT_READ:
      case SSL_ERROR_WANT_WRITE:
        *len = 0;
        return APR_EAGAIN;
      case SSL_ERROR_SSL:
        /* When the client kills the connection, we can expect protocol
        errors... Let's just return that we didn't see an error,
        but that the connection was closed. */
        *len = 0;
        return APR_EOF;
      default:
        *len = 0;
        _mhLog(MH_VERBOSE, cctx->skt,
               "sslSocketWrite SSL Error %d: ", ssl_err);
#if MH_VERBOSE
        ERR_print_errors_cb(err_file_print_cb, stderr);
#endif
        return APR_EGENERAL;
    }


    if (result == 0)
        return APR_EAGAIN;



    return ssl_ctx->bio_status ? ssl_ctx->bio_status : APR_EGENERAL;
}

/**
 * Callback, reads data and decrypt it. Decrypted buffer of length LEN is
 * returned in DATA.
 */
static apr_status_t
sslSocketRead(apr_socket_t *skt, void *baton, char *data, apr_size_t *len)
{
    sslCtx_t *ssl_ctx = baton;
    int result;

    if (*len > sizeof(ssl_ctx->read_buffer))
      *len = sizeof(ssl_ctx->read_buffer);

    ssl_ctx->bio_status = APR_SUCCESS;
    result = SSL_read(ssl_ctx->ssl, ssl_ctx->read_buffer, *len);
    if (result > 0) {
        *len = result;
        memcpy(data, ssl_ctx->read_buffer, *len);
        return APR_SUCCESS;
    } else {
        int ssl_err;

        ssl_err = SSL_get_error(ssl_ctx->ssl, result);
        switch (ssl_err) {
            case SSL_ERROR_ZERO_RETURN:
                *len = 0;
                return APR_EOF; /* Clean SSL shutdown */
            case SSL_ERROR_SYSCALL:
                /* error in bio_bucket_read, probably APR_EAGAIN or APR_EOF */
                *len = 0;
                return ssl_ctx->bio_status;
            case SSL_ERROR_WANT_READ:
            case SSL_ERROR_WANT_WRITE:
                *len = 0;
                return APR_EAGAIN;
            case SSL_ERROR_SSL:
                /* When the client kills the connection, we can expect protocol
                   errors... Let's just return that we didn't see an error,
                   but that the connection was closed. */
                *len = 0;
                return APR_EOF;
            default:
                *len = 0;
                _mhLog(MH_VERBOSE, skt,
                          "sslSocketRead SSL Error %d: ", ssl_err);
#if MH_VERBOSE
                ERR_print_errors_cb(err_file_print_cb, stderr);
#endif
                return APR_EGENERAL;
        }
    }

    /* not reachable */
    return APR_EGENERAL;
}

static apr_status_t sslSocketShutdown(_mhClientCtx_t *cctx,
                              apr_shutdown_how_e how)
{
    if (how == APR_SHUTDOWN_READ
        || how == APR_SHUTDOWN_READWRITE) {
        SSL_shutdown(cctx->ssl_ctx->ssl);
        return APR_SUCCESS;
    }
    return APR_ENOTIMPL;
}

static void appendSSLErrMessage(const MockHTTP *mh, long result)
{
    apr_size_t startpos = strlen(mh->errmsg);
    ERR_error_string(result, mh->errmsg + startpos);
#if MH_VERBOSE
    ERR_print_errors_cb(err_file_print_cb, stderr);
#endif
}

/******************************************************************************/
/* Connection-level matchers: define criteria to match different aspects of a */
/* HTTP or HTTPS connection.                                                  */
/******************************************************************************/

/**
 * Builder callback, verifies if the client certificate is valid (its issuer
 * is in the provided list of trusted certificates).
 */
bool _mhClientcert_valid_matcher(const mhConnMatcherBldr_t *mp,
                                 const _mhClientCtx_t *cctx)
{
    sslCtx_t *ssl_ctx = cctx->ssl_ctx;
    X509 *peer;

    /* Check client certificate */
    peer = SSL_get_peer_certificate(ssl_ctx->ssl);
    if (peer) {
        long result = SSL_get_verify_result(ssl_ctx->ssl);
        if (result == X509_V_OK) {
            /* The client sent a certificate which verified OK */
            return YES;
        } else {
//            appendSSLErrMessage(mh, result);
        }
        /* TODO: add to error message */
        _mhLog(MH_VERBOSE, cctx->skt, "No client certificate was received.\n");
    }
    return NO;
}

/**
 * Builder callback, verifies if the client certificate CN equals a certain
 * string.
 */
bool _mhClientcertcn_matcher(const mhConnMatcherBldr_t *mp,
                             const _mhClientCtx_t *cctx)
{
    sslCtx_t *ssl_ctx = cctx->ssl_ctx;
    X509 *peer;
    const char *clientCN = mp->baton;

    /* Check client certificate */
    peer = SSL_get_peer_certificate(ssl_ctx->ssl);
    if (peer) {
        char buf[1024];
        int ret;
        X509_NAME *subject = X509_get_subject_name(peer);

        ret = X509_NAME_get_text_by_NID(subject,
                                        NID_commonName,
                                        buf, 1024);
        if (ret != -1 && strcmp(clientCN, buf) == 0) {
            return YES;
        }

        /* TODO: add to error message */
        _mhLog(MH_VERBOSE, cctx->skt, "Client certificate common name "
               "\"%s\" doesn't match expected \"%s\".\n", buf, clientCN);
        return NO;
    } else {
        /* TODO: add to error message */
        _mhLog(MH_VERBOSE, cctx->skt, "No client certificate was received.\n");
        return NO;
    }
}

/**
 * Performs the SSL handshake on the connection client/proxy <-> server, can be
 * called multiple times until successful.
 * Returns APR_EAGAIN when handshake in progress.
 *         APR_SUCCESS when handshake finished
 *         error in case of error during handshake.
 */
static apr_status_t sslHandshake(_mhClientCtx_t *cctx)
{
    sslCtx_t *ssl_ctx = cctx->ssl_ctx;
    int result;

    if (ssl_ctx->renegotiate) {
        if (!SSL_do_handshake(ssl_ctx->ssl))
            return APR_EGENERAL;
    }

    if (ssl_ctx->handshake_done)
        return APR_SUCCESS;

    /* Initial SSL handshake */
    result = SSL_accept(ssl_ctx->ssl);
    if (result == 1) {
        _mhLog(MH_VERBOSE, cctx->skt, "Handshake successful.\n");
        ssl_ctx->handshake_done = YES;

        return APR_SUCCESS;
    } else {
        int ssl_err;
        unsigned long l = ERR_peek_error();

        ssl_err = SSL_get_error(ssl_ctx->ssl, result);
        switch (ssl_err) {
            case SSL_ERROR_WANT_READ:
            case SSL_ERROR_WANT_WRITE:
                return APR_EAGAIN;
            case SSL_ERROR_SYSCALL:
                return ssl_ctx->bio_status; /* Usually APR_EAGAIN */
            default:
                {
                    int lib = ERR_GET_LIB(l);
                    int reason = ERR_GET_REASON(l);

                    if (lib == ERR_LIB_SSL
                        && (reason == SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE
                            || reason == ERR_R_INTERNAL_ERROR)) {
                        /* The server shouldn't fail for this...

                           We test the client. Go on, and report the problem
                           there */
                        return APR_EAGAIN;
                    }

                    _mhLog(MH_VERBOSE, cctx->skt,
                           "SSL Error %d: Library=%d, Reason=%d",
                           ssl_err, lib, reason);
#if MH_VERBOSE
                    ERR_print_errors_cb(err_file_print_cb, stderr);
#endif
                }
                return APR_EGENERAL;
        }
    }

    /* not reachable */
    return APR_EGENERAL;
}

#else /* TODO: OpenSSL not available => empty implementations */

#endif

