/* Copyright 2001-2004 The Apache Software Foundation
 *
 * 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.
 *
 * Originally developed by Aaron Bannert and Justin Erenkrantz, eBuilt.
 */

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

#if APR_HAVE_STDLIB_H
#include <stdlib.h>     /* rand/strtol */
#endif
#if APR_HAVE_STRING_H
#include <string.h>
#endif
#include <assert.h>

#include "config.h"
#include "flood_net.h"
#include "flood_net_ssl.h"
#include "flood_socket_keepalive.h"

#define ksock_read_socket(ksock, buf, lenaddr) \
    ksock->ssl ? ssl_read_socket(ksock->s, buf, lenaddr) : \
                 read_socket(ksock->s, buf, lenaddr)

#define ksock_write_socket(ksock, req) \
    ksock->ssl ? ssl_write_socket(ksock->s, req) : \
                 write_socket(ksock->s, req)

typedef struct {
    void *s;
    apr_pollfd_t *p;
    int reopen_socket; /* A boolean */
    int wantresponse;  /* A boolean */
    int ssl;           /* A boolean */
    method_e method;   /* The method of the request. */
} keepalive_socket_t;

/**
 * Keep-alive implementation for socket_init.
 */
apr_status_t keepalive_socket_init(socket_t **sock, apr_pool_t *pool)
{
    keepalive_socket_t *new_ksock;

    new_ksock = (keepalive_socket_t *)apr_palloc(pool, sizeof(keepalive_socket_t));
    if (new_ksock == NULL)
        return APR_ENOMEM;
    new_ksock->s = NULL;
    new_ksock->p = NULL;
    new_ksock->reopen_socket = 1;
    new_ksock->wantresponse = 1;
    new_ksock->ssl = 0;

    *sock = new_ksock;
    return APR_SUCCESS;
}

/**
 * Keep-alive implementation for begin_conn.
 */
apr_status_t keepalive_begin_conn(socket_t *sock, request_t *req, apr_pool_t *pool)
{
    keepalive_socket_t *ksock = (keepalive_socket_t *)sock;

    if (!ksock->reopen_socket && ksock->s) {
        apr_status_t e;
        e = check_socket(ksock->s, pool);
        if (e != APR_SUCCESS) {
            ksock->reopen_socket = 1;
        }
    }
    if (ksock->reopen_socket || ksock->s == NULL) {
        apr_status_t rv;
        if (strcasecmp(req->parsed_uri->scheme, "https") == 0) {
        /* If we don't have SSL, error out. */
#if FLOOD_HAS_OPENSSL
            ksock->ssl = 1;
#else
        return APR_ENOTIMPL;
#endif
        }
        else {
            ksock->ssl = 0;
        }

        /* The return types are not identical, so it can't be a ternary
         * operation. */
        if (ksock->ssl)
            ksock->s = ssl_open_socket(pool, req, &rv);
        else
            ksock->s = open_socket(pool, req, &rv);

        if (ksock->s == NULL)
            return rv;

        ksock->reopen_socket = 0; /* we just opened it */
    }
    req->keepalive = 1;
    return APR_SUCCESS;
}

/**
 * Keep-alive implementation for send_req.
 */
apr_status_t keepalive_send_req(socket_t *sock, request_t *req, apr_pool_t *pool)
{
    keepalive_socket_t *ksock = (keepalive_socket_t *)sock;
    ksock->wantresponse = req->wantresponse;
    ksock->method = req->method;
    return ksock->ssl ? ssl_write_socket(ksock->s, req) :
                        write_socket(ksock->s, req);
}

static long keepalive_read_chunk_size(char *begin_chunk)
{
    char chunk[17], *end_chunk;
    long chunk_length;

    /* FIXME: Handle chunk-extension */
    end_chunk = strstr(begin_chunk, CRLF);

    if (end_chunk && end_chunk - begin_chunk < 16)
    {
        strncpy(chunk, begin_chunk, end_chunk - begin_chunk);
        chunk[end_chunk-begin_chunk] = '\0';
        /* Chunks are base-16 */
        chunk_length = strtol(chunk, &end_chunk, 16);
        if (*end_chunk == '\0')
            return chunk_length;
    }

    return 0;
}

static apr_status_t keepalive_read_chunk(response_t *resp,
                                         keepalive_socket_t *sock,
                                         int chunk_length,
                                         char **bp, int bplen)
{
    apr_status_t status = APR_SUCCESS;
    int old_length = 0;

    if (!chunk_length) {
        return status;
    }

    if (!resp->chunk || !*resp->chunk) {
        chunk_length = 0;
    }

    if (chunk_length < 0) {
        old_length = chunk_length;
        chunk_length = 0;
    }

    do {
        /* Sentinel value */
        int blen = 0;
        char *start_chunk, *end_chunk, *b;

        /* Always reset the b. */
        b = *bp;

        /* Time to read the next chunk size.  At this point,
         * we should be ready to read a CRLF followed by
         * a line that contains the next chunk size.
         */
        while (!chunk_length)
        {
            /* We are reading the next chunk and see a CRLF. */
            if (blen >= 1 && b[0] == '\r') {
                b++;
                blen--;
                if (blen >= 1 && b[0] == '\n') {
                    b++;
                    blen--;
                }
                else {
                    old_length = -1;
                }
            }

            /* If blen is 0, we're empty so read more data. */
            while (!blen)
            {
                /* Reset and read as much as we can. */
                blen = bplen;
                b = *bp;
                status = ksock_read_socket(sock, b, &blen);
                if (status != APR_SUCCESS) {
                    return status;
                }

                /* We got caught in the middle of a chunk last time. */ 
                if (old_length < 0) {
                    b -= old_length;
                    blen += old_length;
                    old_length = 0;
                }
                /* We are reading the next chunk and see a CRLF. */
                if (blen >= 2 && b[0] == '\r' && b[1] == '\n') {
                    b += 2;
                    blen -= 2;
                }
            }

            start_chunk = b;
            chunk_length = keepalive_read_chunk_size(start_chunk);

            /* last-chunk */
            if (!chunk_length)
            {
                /* See if we already read the trailer and final CRLF */
                end_chunk = strstr(b, CRLF CRLF);
                if (!end_chunk)
                {
                    /* Read as much as we can. */
                    blen = bplen;
                    b = *bp;
                    status = ksock_read_socket(sock, b, &blen);
                    if (status != APR_SUCCESS)
                        return status;
                }

                /* FIXME: If we add pipelining, we need to put
                 * the remainder back so that it can be read. */
                blen -= end_chunk - b + 4;

                return APR_SUCCESS;
            }

            /* If this fails, we're very unlikely to have read a chunk! */
            end_chunk = strstr(start_chunk, CRLF) + 2;
            blen -= end_chunk - b;

            /* Oh no, we read more than one chunk this go-around! */
            if (chunk_length <= blen) {
                b += chunk_length + (end_chunk - b);
                blen -= chunk_length;
                chunk_length = 0;
            }
            else
                chunk_length -= blen;
        }

        if (chunk_length > bplen)
            blen = bplen;
        else
            blen = chunk_length;

        status = ksock_read_socket(sock, b, &blen);

        chunk_length -= blen;
    }
    while (status == APR_SUCCESS);

    return APR_SUCCESS;
}

static apr_status_t keepalive_load_resp(response_t *resp, 
                                        keepalive_socket_t *sock,
                                        apr_size_t remaining, apr_pool_t *pool)
{
    /* Ugh, we want everything. */
    int currentalloc, remain, i;
    char *cp, *op, b[MAX_DOC_LENGTH];
    apr_status_t status;

    if (remaining > 0)
    {
        remain = 1;
        currentalloc = remaining + resp->rbufsize;
    }
    else
    {
        remain = 0;
        currentalloc = MAX_DOC_LENGTH + resp->rbufsize;
    }

    cp = apr_palloc(pool, currentalloc);
    memcpy(cp, resp->rbuf, resp->rbufsize);
    resp->rbuf = cp;
    cp = resp->rbuf + resp->rbufsize;

    do
    {
        if (!remain)
            i = MAX_DOC_LENGTH - 1;
        else
        {
            if (remaining > MAX_DOC_LENGTH - 1)
                i = MAX_DOC_LENGTH - 1;
            else
                i = remaining;
        }

        status = ksock_read_socket(sock, b, &i);
        if (resp->rbufsize + i > currentalloc)
        {
            /* You can think why this always work. */
            currentalloc *= 2;
            op = resp->rbuf;
            resp->rbuf = apr_palloc(pool, currentalloc);
            memcpy(resp->rbuf, op, cp - op);
            cp = resp->rbuf + (cp - op);
        }

        memcpy(cp, b, i);
        resp->rbufsize += i;
        cp += i;
        remaining -= i;
    }
    while (status != APR_EGENERAL && status != APR_EOF && 
           status != APR_TIMEUP && (!remain || remaining));

    return status;
}

/**
 * Keep-alive implementation for recv_resp.
 */
apr_status_t keepalive_recv_resp(response_t **resp, socket_t *sock, apr_pool_t *pool)
{
    keepalive_socket_t *ksock = (keepalive_socket_t *)sock;
    char *cl, *ecl, cls[17];
    char *current_line;
    int i;
    response_t *new_resp;
    apr_status_t status;
    long content_length = 0, chunk_length;
    const char *header;

    new_resp = apr_pcalloc(pool, sizeof(response_t));
    new_resp->rbuftype = POOL;
    new_resp->rbufsize = MAX_DOC_LENGTH - 1;
    new_resp->rbuf = apr_palloc(pool, new_resp->rbufsize);

    status = ksock_read_socket(ksock, new_resp->rbuf, &new_resp->rbufsize);

    if (status != APR_SUCCESS && status != APR_EOF) {
        return status;
    }

    /* FIXME: Assume we got the full header for now. */
    new_resp->headers = apr_table_make(pool, 25);
    current_line = new_resp->rbuf;
    do {
        char *end_of_line, *header_end, *header_key, *header_val;
        int line_length, key_length;

        end_of_line = strstr(current_line, CRLF);
        if (!end_of_line || end_of_line == current_line) {
            break;
        }
        line_length = end_of_line - current_line;

        header_end = memchr(current_line, ':', line_length);
        if (header_end) {
            key_length = header_end - current_line;
 
            header_key = apr_pstrmemdup(pool, current_line, key_length);
            header_val = apr_pstrmemdup(pool, current_line + key_length + 2,
                                        line_length - key_length - 2);
            apr_table_set(new_resp->headers, header_key, header_val);
        }
        current_line += line_length + sizeof(CRLF) - 1;
    }
    while((current_line - new_resp->rbuf) < new_resp->rbufsize);

    /* If this exists, we aren't keepalive anymore. */
    header = apr_table_get(new_resp->headers, "Connection");
    if (header && !strcasecmp(header, "Close")) {
        new_resp->keepalive = 0; 
    }
    else {
        new_resp->keepalive = 1; 
    }

    /* If we have a HEAD request, we shouldn't be receiving a body. */
    if (ksock->method == HEAD) {
        *resp = new_resp;

        return APR_SUCCESS;
    }

    header = apr_table_get(new_resp->headers, "Transfer-Encoding");
    if (header && !strcasecmp(header, "Chunked"))
    {
        new_resp->chunked = 1;
        new_resp->chunk = NULL;
        /* Find where headers ended */
        cl = current_line;

        if (cl) {
            /* Skip over the CRLF chars */
            cl += sizeof(CRLF)-1;
        }

        /* We have a partial chunk and we aren't at the end. */
        if (cl && *cl && (cl - (char*)new_resp->rbuf) < new_resp->rbufsize) {
            int remaining;
    
            do {
                if (new_resp->chunk) {
                    /* If we have enough space to skip over the ending CRLF,
                     * do so. */
                    if (chunk_length + 2 <= remaining) {
                        new_resp->chunk += chunk_length + 2;
                    }
                    else {
                        /* We got more than a chunk, but not the full CRLF. */
                        chunk_length = -(remaining - chunk_length);
                        remaining = 0;
                        break;
                    }
                }
                else {
                    new_resp->chunk = cl;
                }

                if ((new_resp->chunk - (char*)new_resp->rbuf) <
                     new_resp->rbufsize && *new_resp->chunk) {
                    char *foo;
                    chunk_length = keepalive_read_chunk_size(new_resp->chunk);
                    /* Search for the beginning of the chunk. */
                    foo = strstr(new_resp->chunk, CRLF);
                    assert(foo);
                    new_resp->chunk = foo + 2;
                    remaining = new_resp->rbufsize - 
                                    (int)(new_resp->chunk - 
                                          (char*)new_resp->rbuf);
                }
                else {
                    new_resp->chunk = NULL;
                    remaining = 0;
                }
            }
            while (remaining > chunk_length);

            chunk_length -= remaining;
        }
    }
    else
    {
        header = apr_table_get(new_resp->headers, "Content-Length");
        if (!header)
        {
            new_resp->keepalive = 0; 
        }

        if (header)
        {
            cl = (char*)header;
            ecl = cl + strlen(cl);
            if (ecl && ecl - cl < 16)
            {
                strncpy(cls, cl, ecl - cl);
                cls[ecl-cl] = '\0';
                content_length = strtol(cls, &ecl, 10);
                if (*ecl != '\0')
                    new_resp->keepalive = 0; 
            }
        }

        if (new_resp->keepalive)
        {
            /* Find where we ended */
            ecl = current_line;

            /* We didn't get full headers.  Crap. */
            if (!ecl)
                new_resp->keepalive = 0; 
            {
                ecl += sizeof(CRLF) - 1;
                content_length -= new_resp->rbufsize - (ecl - (char*)new_resp->rbuf);
            } 
        }
    }
   
    if (ksock->wantresponse)
    {
        if (new_resp->keepalive)
            status = keepalive_load_resp(new_resp, ksock, content_length, pool);
        else
            status = keepalive_load_resp(new_resp, ksock, 0, pool);
    }
    else
    {
        char *b = apr_palloc(pool, MAX_DOC_LENGTH);
        if (new_resp->chunked)
        {
            status = keepalive_read_chunk(new_resp, ksock, chunk_length,
                                          &b, MAX_DOC_LENGTH - 1);
        }
        else if (new_resp->keepalive)
        {
            while (content_length && status != APR_EGENERAL &&
                   status != APR_EOF && status != APR_TIMEUP) {
                if (content_length > MAX_DOC_LENGTH - 1)
                    i = MAX_DOC_LENGTH - 1;
                else
                    i = content_length;

                status = ksock_read_socket(ksock, b, &i);

                content_length -= i;
            }
        }
        else
        {
            while (status != APR_EGENERAL && status != APR_EOF && 
                   status != APR_TIMEUP) {
                i = MAX_DOC_LENGTH - 1;
                status = ksock_read_socket(ksock, b, &i);
            }
        }
    }

    *resp = new_resp;

    return APR_SUCCESS;
}

/**
 * Keep-alive implementation for end_conn.
 */
apr_status_t keepalive_end_conn(socket_t *sock, request_t *req, response_t *resp)
{
    keepalive_socket_t *ksock = (keepalive_socket_t *)sock;

    if (resp->keepalive == 0) {
        ksock->ssl ? ssl_close_socket(ksock->s) : close_socket(ksock->s);
        ksock->reopen_socket = 1; /* we just closed it */
    }
        
    return APR_SUCCESS;
}

apr_status_t keepalive_socket_destroy(socket_t *sock)
{
    return APR_SUCCESS;
}
