/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
#include "android/proxy/proxy_http_int.h"

#include "android/utils/system.h"  /* strsep */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* this implements a transparent HTTP rewriting proxy
 *
 * this is needed because the HTTP spec mandates that
 * any query made to a proxy uses an absolute URI as
 * in:
 *
 *    GET http://www.example.com/index.html HTTP/1.1
 *
 * while the Android browser will think it's talking to
 * a normal web server and will issue a:
 *
 *    GET /index.html HTTP/1.1
 *    Host: www.example.com
 *
 * what we do here is thus the following:
 *
 * - read the request header
 * - rewrite the request's URI to use absolute URI
 * - send the rewritten header to the proxy
 * - then read the rest of the request, and tunnel it to the
 *   proxy as well
 * - read the answer as-is and send it back to the system
 *
 * this sounds all easy, but the rules for computing the
 * sizes of HTTP Message Bodies makes the implementation
 * a *bit* funky.
 */

/* define D_ACTIVE to 1 to dump additionnal debugging
 * info when -debug-proxy is used. These are only needed
 * when debugging the proxy code.
 */
#define  D_ACTIVE  0

#if D_ACTIVE
#  define  D(...)   PROXY_LOG(__VA_ARGS__)
#else
#  define  D(...)   ((void)0)
#endif


/** *************************************************************
 **
 **   HTTP HEADERS
 **
 **/

/* HttpHeader is a simple structure used to hold a (key,value)
 * pair in a linked list.
 */
typedef struct HttpHeader {
    struct HttpHeader*  next;
    const char*         key;
    const char*         value;
} HttpHeader;

static void
http_header_free( HttpHeader*  h )
{
    if (h) {
        free((char*)h->value);
        free(h);
    }
}

static int
http_header_append( HttpHeader*  h, const char*  value )
{
    int    old = strlen(h->value);
    int    new = strlen(value);
    char*  s   = realloc((char*)h->value, old+new+1);
    if (s == NULL)
        return -1;
    memcpy(s + old, value, new+1);
    h->value = (const char*)s;
    return 0;
}

static HttpHeader*
http_header_alloc( const char*  key, const char*  value )
{
    int          len = strlen(key)+1;
    HttpHeader*  h   = malloc(sizeof(*h) + len+1);
    if (h) {
        h->next  = NULL;
        h->key   = (const char*)(h+1);
        memcpy( (char*)h->key, key, len );
        h->value = strdup(value);
    }
    return h;
}

/** *************************************************************
 **
 **   HTTP HEADERS LIST
 **
 **/

typedef struct {
    HttpHeader*   first;
    HttpHeader*   last;
} HttpHeaderList;

static void
http_header_list_init( HttpHeaderList*  l )
{
    l->first = l->last = NULL;
}

static void
http_header_list_done( HttpHeaderList*  l )
{
    while (l->first) {
        HttpHeader*  h = l->first;
        l->first = h->next;
        http_header_free(h);
    }
    l->last = NULL;
}

static void
http_header_list_add( HttpHeaderList*  l,
                      HttpHeader*      h )
{
    if (!l->first) {
        l->first = h;
    } else {
        l->last->next = h;
    }
    h->next = NULL;
    l->last = h;
}

static const char*
http_header_list_find( HttpHeaderList*  l,
                       const char*      key )
{
    HttpHeader*  h;
    for (h = l->first; h; h = h->next)
        if (!strcasecmp(h->key, key))
            return h->value;

    return NULL;
}

/** *************************************************************
 **
 **   HTTP REQUEST AND REPLY
 **
 **/

typedef enum {
    HTTP_REQUEST_UNSUPPORTED = 0,
    HTTP_REQUEST_GET,
    HTTP_REQUEST_HEAD,
    HTTP_REQUEST_POST,
    HTTP_REQUEST_PUT,
    HTTP_REQUEST_DELETE,
} HttpRequestType;

/* HttpRequest is used both to store information about a specific
 * request and the corresponding reply
 */
typedef struct {
    HttpRequestType   req_type;     /* request type */
    char*             req_method;   /* "GET", "POST", "HEAD", etc... */
    char*             req_uri;      /* the request URI */
    char*             req_version;  /* "HTTP/1.0" or "HTTP/1.1" */
    char*             rep_version;  /* reply version string */
    int               rep_code;     /* reply code as decimal */
    char*             rep_readable; /* human-friendly reply/error message */
    HttpHeaderList    headers[1];   /* headers */
} HttpRequest;


static HttpRequest*
http_request_alloc( const char*      method,
                    const char*      uri,
                    const char*      version )
{
    HttpRequest*  r = malloc(sizeof(*r));

    r->req_method   = strdup(method);
    r->req_uri      = strdup(uri);
    r->req_version  = strdup(version);
    r->rep_version  = NULL;
    r->rep_code     = -1;
    r->rep_readable = NULL;

    if (!strcmp(method,"GET")) {
        r->req_type = HTTP_REQUEST_GET;
    } else if (!strcmp(method,"POST")) {
        r->req_type = HTTP_REQUEST_POST;
    } else if (!strcmp(method,"HEAD")) {
        r->req_type = HTTP_REQUEST_HEAD;
    } else if (!strcmp(method,"PUT")) {
        r->req_type = HTTP_REQUEST_PUT;
    } else if (!strcmp(method,"DELETE")) {
        r->req_type = HTTP_REQUEST_DELETE;
    } else
        r->req_type = HTTP_REQUEST_UNSUPPORTED;

    http_header_list_init(r->headers);
    return r;
}

static void
http_request_replace_uri( HttpRequest*  r,
                          const char*   uri )
{
    const char*  old = r->req_uri;
    r->req_uri = strdup(uri);
    free((char*)old);
}

static void
http_request_free( HttpRequest*  r )
{
    if (r) {
        http_header_list_done(r->headers);

        free(r->req_method);
        free(r->req_uri);
        free(r->req_version);
        free(r->rep_version);
        free(r->rep_readable);
        free(r);
    }
}

static char*
http_request_find_header( HttpRequest*  r,
                          const char*   key )
{
    return (char*)http_header_list_find(r->headers, key);
}


static int
http_request_add_header( HttpRequest*  r,
                         const char*   key,
                         const char*   value )
{
    HttpHeader*  h = http_header_alloc(key,value);
    if (h) {
        http_header_list_add(r->headers, h);
        return 0;
    }
    return -1;
}

static int
http_request_add_to_last_header( HttpRequest*  r,
                                 const char*   line )
{
    if (r->headers->last) {
        return http_header_append( r->headers->last, line );
    } else {
        return -1;
    }
}

static int
http_request_set_reply( HttpRequest*  r,
                        const char*   version,
                        const char*   code,
                        const char*   readable )
{
    if (strcmp(version,"HTTP/1.0") && strcmp(version,"HTTP/1.1")) {
        PROXY_LOG("%s: bad reply protocol: %s", __FUNCTION__, version);
        return -1;
    }
    r->rep_code = atoi(code);
    if (r->rep_code == 0) {
        PROXY_LOG("%s: bad reply code: %d", __FUNCTION__, code);
        return -1;
    }

    r->rep_version  = strdup(version);
    r->rep_readable = strdup(readable);

    /* reset the list of headers */
    http_header_list_done(r->headers);
    return 0;
}

/** *************************************************************
 **
 **   REWRITER CONNECTION
 **
 **/

typedef enum {
    STATE_CONNECTING = 0,
    STATE_CREATE_SOCKET_PAIR,
    STATE_REQUEST_FIRST_LINE,
    STATE_REQUEST_HEADERS,
    STATE_REQUEST_SEND,
    STATE_REQUEST_BODY,
    STATE_REPLY_FIRST_LINE,
    STATE_REPLY_HEADERS,
    STATE_REPLY_SEND,
    STATE_REPLY_BODY,
} ConnectionState;

/* root->socket is connected to the proxy server. while
 * slirp_fd is connected to the slirp code through a
 * socket_pair() we created for this specific purpose.
 */

typedef enum {
    BODY_NONE = 0,
    BODY_KNOWN_LENGTH,
    BODY_UNTIL_CLOSE,
    BODY_CHUNKED,
    BODY_MODE_MAX
} BodyMode;

static const char* const  body_mode_str[BODY_MODE_MAX] = {
    "NONE", "KNOWN_LENGTH", "UNTIL_CLOSE", "CHUNKED"
};

enum {
    CHUNK_HEADER,    // Waiting for a chunk header + CR LF
    CHUNK_DATA,      // Waiting for chunk data
    CHUNK_DATA_END,  // Waiting for the CR LF after the chunk data
    CHUNK_TRAILER    // Waiting for the chunk trailer + CR LF
};

typedef struct {
    ProxyConnection   root[1];
    LoopIo*           slirp_io;
    ConnectionState   state;
    HttpRequest*      request;
    BodyMode          body_mode;
    int64_t           body_length;
    int64_t           body_total;
    int64_t           body_sent;
    int64_t           chunk_length;
    int64_t           chunk_total;
    int               chunk_state;
    char              body_has_data;
    char              body_is_full;
    char              body_is_closed;
    char              parse_chunk_header;
    char              parse_chunk_trailer;
} RewriteConnection;

// Forward declarations.
static void rewrite_connection_set_state(RewriteConnection* conn,
                                         ConnectionState state);

static void rewrite_connection_io_event(void* opaque, int fd, unsigned events);

static void
rewrite_connection_free( ProxyConnection*  root )
{
    RewriteConnection*  conn = (RewriteConnection*)root;

    if (conn->slirp_io) {
        int fd = loopIo_fd(conn->slirp_io);
        loopIo_free(conn->slirp_io);
        conn->slirp_io = NULL;
        socket_close(fd);
    }
    http_request_free(conn->request);
    proxy_connection_done(root);
    free(conn);
}


static int
rewrite_connection_init( RewriteConnection*   conn )
{
    HttpService*      service = (HttpService*) conn->root->service;
    ProxyConnection*  root    = conn->root;
    int proxy_fd = loopIo_fd(root->io);

    conn->slirp_io = NULL;
    conn->state    = STATE_CONNECTING;

    if (socket_connect(proxy_fd, &service->server_addr ) == 0) {
        PROXY_LOG("%s: immediate connection", root->name);
        rewrite_connection_set_state(conn, STATE_CREATE_SOCKET_PAIR);
        return 0;
    }
    if (errno != EINPROGRESS && errno != EWOULDBLOCK && errno != EAGAIN) {
        PROXY_LOG("%s: cannot connect to proxy: %s", root->name, errno_str);
        return -1;
    }
    PROXY_LOG("%s: connecting", conn->root->name);
    loopIo_wantWrite(root->io);
    return 0;
}

static int
rewrite_connection_create_sockets( RewriteConnection*  conn )
{
    /* immediate connection to the proxy. now create a socket
        * pair and send a 'success' event to slirp */
    int               slirp_1, slirp_2;
    ProxyConnection*  root = conn->root;

    if (socket_pair( &slirp_1, &slirp_2 ) < 0) {
        PROXY_LOG("%s: coult not create socket pair: %s",
                    root->name, errno_str);
        return -1;
    }

    conn->slirp_io = loopIo_new(looper_getForThread(),
                                slirp_2,
                                rewrite_connection_io_event,
                                conn);
    root->ev_func( root->ev_opaque, slirp_1, PROXY_EVENT_CONNECTED );
    return 0;
}


/* read the first line of a given HTTP request. returns -1/0/+1 */
static DataStatus
rewrite_connection_read_request( RewriteConnection*  conn )
{
    ProxyConnection*  root = conn->root;
    DataStatus        ret;

    ret = proxy_connection_receive_line(root, loopIo_fd(conn->slirp_io));
    if (ret == DATA_COMPLETED) {
        /* now parse the first line to see if we can handle it */
        char*  line   = root->str->s;
        char*  method;
        char*  uri;
        char*  version;
        char*  p = line;

        method = strsep(&p, " ");
        if (p == NULL) {
            PROXY_LOG("%s: can't parse method in '%'",
                      root->name, line);
            return DATA_ERROR;
        }
        uri = strsep(&p, " ");
        if (p == NULL) {
            PROXY_LOG( "%s: can't parse URI in '%s'",
                       root->name, line);
            return DATA_ERROR;
        }
        version = strsep(&p, " ");
        if (p != NULL) {
            PROXY_LOG( "%s: extra data after version in '%s'",
                       root->name, line);
            return DATA_ERROR;
        }
        if (conn->request)
            http_request_free(conn->request);

        conn->request = http_request_alloc( method, uri, version );
        if (!conn->request)
            return DATA_ERROR;

        proxy_connection_rewind(root);
    }
    return ret;
}


static DataStatus
rewrite_connection_read_reply( RewriteConnection*  conn, int fd )
{
    ProxyConnection*  root = conn->root;
    DataStatus        ret;

    ret = proxy_connection_receive_line( root, fd );
    if (ret == DATA_COMPLETED) {
        HttpRequest*  request = conn->request;

        char*  line = stralloc_cstr( root->str );
        char*  p = line;
        char*  protocol;
        char*  number;
        char*  readable;

        protocol = strsep(&p, " ");
        if (p == NULL) {
            PROXY_LOG("%s: can't parse response protocol: '%s'",
                      root->name, line);
            return DATA_ERROR;
        }
        number = strsep(&p, " ");
        if (p == NULL) {
            PROXY_LOG("%s: can't parse response number: '%s'",
                      root->name, line);
            return DATA_ERROR;
        }
        readable = p;

        if (http_request_set_reply(request, protocol, number, readable) < 0)
            return DATA_ERROR;

        proxy_connection_rewind(root);
    }
    return ret;
}


static DataStatus
rewrite_connection_read_headers( RewriteConnection*   conn,
                                 int                  fd )
{
    int               ret;
    ProxyConnection*  root = conn->root;

    for (;;) {
        char*        line;
        stralloc_t*  str = root->str;

        ret = proxy_connection_receive_line(root, fd);
        if (ret != DATA_COMPLETED)
            break;

        str->n = 0;
        line   = str->s;

        if (line[0] == 0) {
            /* an empty line means the end of headers */
            ret = 1;
            break;
        }

        /* it this a continuation ? */
        if (line[0] == ' ' || line[0] == '\t') {
            ret = http_request_add_to_last_header( conn->request, line );
        }
        else {
            char*  key;
            char*  value;

            value = line;
            key   = strsep(&value, ":");
            if (value == NULL) {
                PROXY_LOG("%s: can't parse header '%s'", root->name, line);
                ret = -1;
                break;
            }
            value += strspn(value, " ");
            if (http_request_add_header(conn->request, key, value) < 0)
                ret = -1;
        }
        if (ret == DATA_ERROR)
            break;
    }
    return ret;
}

static int
rewrite_connection_rewrite_request( RewriteConnection*  conn )
{
    ProxyConnection* root    = conn->root;
    HttpService*     service = (HttpService*) root->service;
    HttpRequest*     r       = conn->request;
    stralloc_t*      str     = root->str;
    HttpHeader*      h;

    proxy_connection_rewind(conn->root);

    /* only rewrite the URI if it is not absolute */
    if (r->req_uri[0] == '/') {
        char*  host = http_request_find_header(r, "Host");
        if (host == NULL) {
            PROXY_LOG("%s: uh oh, not Host: in request ?", root->name);
        } else {
            /* now create new URI */
            stralloc_add_str(str, "http://");
            stralloc_add_str(str, host);
            stralloc_add_str(str, r->req_uri);
            http_request_replace_uri(r, stralloc_cstr(str));
            proxy_connection_rewind(root);
        }
    }

    stralloc_format( str, "%s %s %s\r\n", r->req_method, r->req_uri, r->req_version );
    for (h = r->headers->first; h; h = h->next) {
        stralloc_add_format( str, "%s: %s\r\n", h->key, h->value );
    }
    /* add the service's footer - includes final \r\n */
    stralloc_add_bytes( str, service->footer, service->footer_len );

    return 0;
}

static int
rewrite_connection_rewrite_reply( RewriteConnection*  conn )
{
    HttpRequest*     r    = conn->request;
    ProxyConnection* root = conn->root;
    stralloc_t*      str  = root->str;
    HttpHeader*      h;

    proxy_connection_rewind(root);
    stralloc_format(str, "%s %d %s\r\n", r->rep_version, r->rep_code, r->rep_readable);
    for (h = r->headers->first; h; h = h->next) {
        stralloc_add_format(str, "%s: %s\r\n", h->key, h->value);
    }
    stralloc_add_str(str, "\r\n");

    return 0;
}


static int
rewrite_connection_get_body_length( RewriteConnection*  conn,
                                    int                 is_request )
{
    HttpRequest*      r    = conn->request;
    ProxyConnection*  root = conn->root;
    char*             content_length;
    char*             transfer_encoding;

    conn->body_mode      = BODY_NONE;
    conn->body_length    = 0;
    conn->body_total     = 0;
    conn->body_sent      = 0;
    conn->body_is_closed = 0;
    conn->body_is_full   = 0;
    conn->body_has_data  = 0;

    proxy_connection_rewind(root);

    if (is_request) {
        /* only POST and PUT should have a body */
        if (r->req_type != HTTP_REQUEST_POST &&
            r->req_type != HTTP_REQUEST_PUT)
        {
            return 0;
        }
    } else {
        /* HTTP 1.1 Section 4.3 Message Body states that HEAD requests must not have
        * a message body, as well as any 1xx, 204 and 304 replies */
        if (r->req_type == HTTP_REQUEST_HEAD || r->rep_code/100 == 1 ||
            r->rep_code == 204 || r->rep_code == 304)
            return 0;
    }

    content_length = http_request_find_header(r, "Content-Length");
    if (content_length != NULL) {
        char*    end;
        int64_t  body_len = strtoll( content_length, &end, 10 );
        if (*end != '\0' || *content_length == '\0' || body_len < 0) {
            PROXY_LOG("%s: bad content length: %s", root->name, content_length);
            return DATA_ERROR;
        }
        if (body_len > 0) {
            conn->body_mode   = BODY_KNOWN_LENGTH;
            conn->body_length = body_len;
        }
    } else {
        transfer_encoding = http_request_find_header(r, "Transfer-Encoding");
        if (transfer_encoding && !strcasecmp(transfer_encoding, "Chunked")) {
            conn->body_mode           = BODY_CHUNKED;
            conn->parse_chunk_header  = 0;
            conn->parse_chunk_trailer = 0;
            conn->chunk_length        = -1;
            conn->chunk_total         = 0;
            conn->chunk_state         = CHUNK_HEADER;
        }
    }
    if (conn->body_mode == BODY_NONE) {
        char*  connection = http_request_find_header(r, "Proxy-Connection");

        if (!connection)
            connection = http_request_find_header(r, "Connection");

        if (!connection || strcasecmp(connection, "Close")) {
            /* hum, we can't support this at all */
            PROXY_LOG("%s: can't determine content length, and client wants"
                        " to keep connection opened",
                        root->name);
            return -1;
        }
        /* a negative value means that the data ends when the client
         * disconnects the connection.
         */
        conn->body_mode = BODY_UNTIL_CLOSE;
    }
    D("%s: body_length=%lld body_mode=%s",
      root->name, conn->body_length,
      body_mode_str[conn->body_mode]);

    proxy_connection_rewind(root);
    return 0;
}

#define  MAX_BODY_BUFFER  65536

static DataStatus
rewrite_connection_read_body( RewriteConnection*  conn, int  fd )
{
    ProxyConnection*  root   = conn->root;
    stralloc_t*       str    = root->str;
    int               wanted = 0, current, avail;
    DataStatus        ret;

    if (conn->body_is_closed) {
        D("%s: read_body with closed!!?", root->name);
        return DATA_NEED_MORE;
    }

    /* first, determine how many bytes we want to read. */
    switch (conn->body_mode) {
    case BODY_NONE:
        D("%s: INTERNAL ERROR: SHOULDN'T BE THERE", root->name);
        return DATA_COMPLETED;

    case BODY_KNOWN_LENGTH:
        {
            if (conn->body_length == 0)
                return DATA_COMPLETED;

            if (conn->body_length > MAX_BODY_BUFFER)
                wanted = MAX_BODY_BUFFER;
            else
                wanted = (int)conn->body_length;
        }
        break;

    case BODY_UNTIL_CLOSE:
        wanted = MAX_BODY_BUFFER;
        break;

    case BODY_CHUNKED:
        if (conn->chunk_state == CHUNK_DATA_END) {
            /* We're waiting for the CR LF after the chunk data */
            ret = proxy_connection_receive_line(root, fd);
            if (ret != DATA_COMPLETED) {
                PROXY_LOG("%s: receive line too early ret=%d", root->name, ret);
                return ret;
            }

            if (str->s[0] != 0) { /* this should be an empty line */
                PROXY_LOG("%s: invalid chunk data end: '%s'",
                            root->name, str->s);
                return DATA_ERROR;
            }
            /* proxy_connection_receive_line() did remove the
            * trailing \r\n, but we must preserve it when we
            * send the chunk size end to the proxy.
            */
            stralloc_add_str(root->str, "\r\n");
            conn->chunk_state = CHUNK_HEADER;
            /* fall-through */
        }

        if (conn->chunk_state == CHUNK_HEADER) {
            char*      line;
            char*      end;
            long long  length;
            /* Ensure that the previous chunk was flushed before
             * accepting a new header */
            if (!conn->parse_chunk_header) {
                if (conn->body_has_data) {
                    D("%s: chunk state waiting for flush", root->name);
                    return DATA_NEED_MORE;
                }
                D("%s: waiting chunk header", root->name);
                conn->parse_chunk_header = 1;
            }
            ret = proxy_connection_receive_line(root, fd);
            if (ret != DATA_COMPLETED) {
                D("%s:%d", root->name, __LINE__);
                return ret;
            }
            conn->parse_chunk_header = 0;

            line   = str->s;
            length = strtoll(line, &end, 16);
            if (line[0] == ' ' || (end[0] != '\0' && end[0] != ';')) {
                PROXY_LOG("%s: invalid chunk header: %s",
                        root->name, line);
                return DATA_ERROR;
            }
            if (length < 0) {
                PROXY_LOG("%s: invalid chunk length %lld",
                        root->name, length);
                return DATA_ERROR;
            }
            /* proxy_connection_receive_line() did remove the
            * trailing \r\n, but we must preserve it when we
            * send the chunk size to the proxy.
            */
            stralloc_add_str(root->str, "\r\n");

            conn->chunk_length = length;
            conn->chunk_total  = 0;
            conn->chunk_state  = CHUNK_DATA;
            if (length == 0) {
                /* the last chunk, no we need to add the trailer */
                conn->chunk_state         = CHUNK_TRAILER;
                conn->parse_chunk_trailer = 0;
            }
        }

        if (conn->chunk_state == CHUNK_TRAILER) {
            /* ensure that 'str' is flushed before reading the trailer */
            if (!conn->parse_chunk_trailer) {
                if (conn->body_has_data) {
                    D("%s:%d", root->name, __LINE__);
                    return DATA_NEED_MORE;
                }
                conn->parse_chunk_trailer = 1;
            }
            ret = rewrite_connection_read_headers(conn, fd);
            if (ret == DATA_COMPLETED) {
                conn->body_is_closed = 1;
            }
            return ret;
        }

        /* if we get here, body_length > 0 */
        if (conn->chunk_length > MAX_BODY_BUFFER)
            wanted = MAX_BODY_BUFFER;
        else
            wanted = (int)conn->chunk_length;
        break;

    default:
        ;
    }

    /* we don't want more than MAX_BODY_BUFFER bytes in the
     * buffer we used to pass the body */
    current = str->n;
    avail   = MAX_BODY_BUFFER - current;
    if (avail <= 0) {
        /* wait for some flush */
        conn->body_is_full = 1;
        D("%s: waiting to flush %d bytes",
          root->name, current);
        return DATA_NEED_MORE;
    }

    if (wanted > avail)
        wanted = avail;

    ret = proxy_connection_receive(root, fd, wanted);
    conn->body_has_data = (str->n > 0);
    conn->body_is_full  = (str->n == MAX_BODY_BUFFER);

    if (ret == DATA_ERROR) {
        if (conn->body_mode == BODY_UNTIL_CLOSE) {
            /* a disconnection here is normal and signals the
             * end of the body */
            conn->body_total    += root->str_recv;
            D("%s: body completed by close (%lld bytes)",
                root->name, conn->body_total);
            conn->body_is_closed = 1;
            ret = DATA_COMPLETED;
        }
    } else {
        avail = root->str_recv;
        ret   = DATA_NEED_MORE;  /* we're not really done yet */

        switch (conn->body_mode) {
        case BODY_CHUNKED:
            conn->chunk_total  += avail;
            conn->chunk_length -= avail;

            if (conn->chunk_length == 0) {
                D("%s: chunk completed (%lld bytes)",
                    root->name, conn->chunk_total);
                conn->body_total  += conn->chunk_total;
                conn->chunk_total  = 0;
                conn->chunk_length = -1;
                conn->chunk_state  = CHUNK_DATA_END;
            }
            break;

        case BODY_KNOWN_LENGTH:
            conn->body_length -= avail;
            conn->body_total  += avail;

            if (conn->body_length == 0) {
                D("%s: body completed (%lld bytes)",
                    root->name, conn->body_total);
                conn->body_is_closed = 1;
                ret = DATA_COMPLETED;
            }
            break;

        case BODY_UNTIL_CLOSE:
            conn->body_total += avail;
            break;

        default:
            ;
        }
    }
    return ret;
}

static DataStatus
rewrite_connection_send_body( RewriteConnection*  conn, int  fd )
{
    ProxyConnection*  root   = conn->root;
    stralloc_t*       str    = root->str;
    DataStatus        ret    = DATA_NEED_MORE;

    if (conn->body_has_data) {
        ret = proxy_connection_send(root, fd);
        if (ret != DATA_ERROR) {
            int  pos = root->str_pos;

            memmove(str->s, str->s+pos, str->n-pos);
            str->n         -= pos;
            root->str_pos   = 0;
            conn->body_is_full  = (str->n == MAX_BODY_BUFFER);
            conn->body_has_data = (str->n > 0);
            conn->body_sent    += root->str_sent;

            /* ensure that we return DATA_COMPLETED only when
            * we have sent everything, and there is no more
            * body pieces to read */
            if (ret == DATA_COMPLETED) {
                if (!conn->body_is_closed || conn->body_has_data)
                    ret = DATA_NEED_MORE;
                else {
                    D("%s: sent all body (%lld bytes)",
                        root->name, conn->body_sent);
                }
            }
            D("%s: sent closed=%d data=%d n=%d ret=%d",
                root->name, conn->body_is_closed,
                conn->body_has_data, str->n,
                ret);
        }
    } else {
        PROXY_LOG("%s: send_body with no data!!?", root->name);
    }
    return ret;
}

// TODO(digit): Add this function to looper.h instead.
static void loopIo_setMask(LoopIo* io, unsigned events) {
    if (events & LOOP_IO_READ) {
        loopIo_wantRead(io);
    } else {
        loopIo_dontWantRead(io);
    }
    if (events & LOOP_IO_WRITE) {
        loopIo_wantWrite(io);
    } else {
        loopIo_dontWantWrite(io);
    }
}

static void
rewrite_connection_set_state(RewriteConnection* conn, ConnectionState state) {
    LoopIo* proxy_io = conn->root->io;
    LoopIo* slirp_io = conn->slirp_io;

    unsigned proxy_mask = 0U;
    unsigned slirp_mask = 0U;

    switch (state) {
        case STATE_CONNECTING:
        case STATE_CREATE_SOCKET_PAIR:
            proxy_mask |= LOOP_IO_WRITE;
            break;

        case STATE_REQUEST_FIRST_LINE:
        case STATE_REQUEST_HEADERS:
            slirp_mask |= LOOP_IO_READ;
            break;

        case STATE_REQUEST_SEND:
            proxy_mask |= LOOP_IO_WRITE;
            break;

        case STATE_REQUEST_BODY:
            if (!conn->body_is_closed && !conn->body_is_full) {
                slirp_mask |= LOOP_IO_READ;
            }
            if (conn->body_has_data) {
                proxy_mask |= LOOP_IO_WRITE;
            }
            break;

        case STATE_REPLY_FIRST_LINE:
        case STATE_REPLY_HEADERS:
            proxy_mask |= LOOP_IO_READ;
            break;

        case STATE_REPLY_SEND:
            slirp_mask |= LOOP_IO_WRITE;
            break;

        case STATE_REPLY_BODY:
            if (conn->body_has_data) {
                slirp_mask |= LOOP_IO_WRITE;
            }
            if (!conn->body_is_closed && !conn->body_is_full) {
                proxy_mask |= LOOP_IO_READ;
            }
            break;
        default:
            ;
    }
    D("%s: change state %d -> %d wanted events proxy=%s%s slirp=%s%s",
      conn->root->name,
      conn->state,
      state,
      (proxy_mask & LOOP_IO_READ) ? "R" : "",
      (proxy_mask & LOOP_IO_WRITE) ? "W" : "",
      (slirp_mask & LOOP_IO_READ) ? "R" : "",
      (slirp_mask & LOOP_IO_WRITE) ? "W" : "");

    loopIo_setMask(proxy_io, proxy_mask);
    if (slirp_io) {
        loopIo_setMask(slirp_io, slirp_mask);
    }
    conn->state = state;
}

static void
rewrite_connection_io_event(void* opaque, int fd, unsigned events) {
    ProxyConnection* root = opaque;
    RewriteConnection* conn = (RewriteConnection*)root;

    int         slirp     = conn->slirp_io ? loopIo_fd(conn->slirp_io) : -1;
    int         proxy     = loopIo_fd(root->io);
    int         has_slirp = (fd == slirp);
    int         has_proxy = (fd == proxy);
    DataStatus  ret       = DATA_NEED_MORE;

    D("%s: state=%d fd=%s events=%s%s",
      root->name,
      conn->state,
      has_slirp ? "slirp" : (has_proxy ? "proxy" : "none"),
      (events & LOOP_IO_READ) ? "R" : "",
      (events & LOOP_IO_WRITE) ? "W" : "");

    switch (conn->state) {
        case STATE_CONNECTING:
            if (has_proxy) {
                D("%s: connected", root->name);
                rewrite_connection_set_state(conn, STATE_CREATE_SOCKET_PAIR);
            }
            break;

        case STATE_CREATE_SOCKET_PAIR:
            if (has_proxy) {
                if (rewrite_connection_create_sockets(conn) < 0) {
                    ret = DATA_ERROR;
                } else {
                    D("%s: socket pair created", root->name);
                    rewrite_connection_set_state(conn,
                                                 STATE_REQUEST_FIRST_LINE);
                }
            }
            break;

        case STATE_REQUEST_FIRST_LINE:
            if (has_slirp) {
                ret = rewrite_connection_read_request(conn);
                if (ret == DATA_COMPLETED) {
                    PROXY_LOG("%s: request first line ok", root->name);
                    rewrite_connection_set_state(conn, STATE_REQUEST_HEADERS);
                }
            }
            break;

        case STATE_REQUEST_HEADERS:
            if (has_slirp) {
                ret = rewrite_connection_read_headers(conn, slirp);
                if (ret == DATA_COMPLETED) {
                    PROXY_LOG("%s: request headers ok", root->name);
                    if (rewrite_connection_rewrite_request(conn) < 0) {
                        ret = DATA_ERROR;
                    } else {
                        rewrite_connection_set_state(conn, STATE_REQUEST_SEND);
                    }
                }
            }
            break;

        case STATE_REQUEST_SEND:
            if (has_proxy) {
                ret = proxy_connection_send(root, proxy);
                if (ret == DATA_COMPLETED) {
                    if (rewrite_connection_get_body_length(conn, 1) < 0) {
                        ret = DATA_ERROR;
                    } else if (conn->body_mode != BODY_NONE) {
                        PROXY_LOG("%s: request sent, waiting for body",
                                   root->name);
                       rewrite_connection_set_state(conn, STATE_REQUEST_BODY);
                    } else {
                        PROXY_LOG("%s: request sent, waiting for reply",
                                  root->name);
                        rewrite_connection_set_state(conn,
                                                     STATE_REPLY_FIRST_LINE);
                    }
                }
            }
            break;

        case STATE_REQUEST_BODY:
            if (has_slirp) {
                ret = rewrite_connection_read_body(conn, slirp);
                if (ret != DATA_ERROR) {
                    rewrite_connection_set_state(conn, STATE_REQUEST_BODY);
                }
            }
            if (ret != DATA_ERROR && has_proxy) {
                ret = rewrite_connection_send_body(conn, proxy);
                if (ret == DATA_COMPLETED) {
                    PROXY_LOG("%s: request body ok, waiting for reply",
                              root->name);
                    rewrite_connection_set_state(conn, STATE_REPLY_FIRST_LINE);
                } else if (ret != DATA_ERROR) {
                    rewrite_connection_set_state(conn, STATE_REQUEST_BODY);
                }
            }
            break;

        case STATE_REPLY_FIRST_LINE:
            if (has_proxy) {
                ret = rewrite_connection_read_reply(conn, proxy);
                if (ret == DATA_COMPLETED) {
                    PROXY_LOG("%s: reply first line ok", root->name);
                    rewrite_connection_set_state(conn, STATE_REPLY_HEADERS);
                }
            }
            break;

        case STATE_REPLY_HEADERS:
            if (has_proxy) {
                ret = rewrite_connection_read_headers(conn, proxy);
                if (ret == DATA_COMPLETED) {
                    PROXY_LOG("%s: reply headers ok", root->name);
                    if (rewrite_connection_rewrite_reply(conn) < 0) {
                        ret = DATA_ERROR;
                    } else {
                        rewrite_connection_set_state(conn, STATE_REPLY_SEND);
                    }
                }
            }
            break;

        case STATE_REPLY_SEND:
            if (has_slirp) {
                ret = proxy_connection_send(conn->root, slirp);
                if (ret == DATA_COMPLETED) {
                    if (rewrite_connection_get_body_length(conn, 0) < 0) {
                        ret = DATA_ERROR;
                    } else if (conn->body_mode != BODY_NONE) {
                        PROXY_LOG("%s: reply sent, waiting for body",
                                  root->name);
                        rewrite_connection_set_state(conn, STATE_REPLY_BODY);
                    } else {
                        PROXY_LOG("%s: reply sent, looping to waiting request",
                                  root->name);
                        rewrite_connection_set_state(conn,
                                                     STATE_REQUEST_FIRST_LINE);
                    }
                }
            }
            break;

        case STATE_REPLY_BODY:
            if (has_proxy) {
                ret = rewrite_connection_read_body(conn, proxy);
                if (ret != DATA_ERROR) {
                    rewrite_connection_set_state(conn, STATE_REPLY_BODY);
                }
            }
            if (ret != DATA_ERROR && has_slirp) {
                ret = rewrite_connection_send_body(conn, slirp);
                if (ret == DATA_COMPLETED) {
                    if (conn->body_mode == BODY_UNTIL_CLOSE) {
                        PROXY_LOG("%s: closing connection", root->name);
                        ret = DATA_ERROR;
                    } else {
                        PROXY_LOG(
                                "%s: reply body ok, looping to waiting request",
                                root->name);
                        rewrite_connection_set_state(conn,
                                                     STATE_REQUEST_FIRST_LINE);
                    }
                } else if (ret != DATA_ERROR) {
                    rewrite_connection_set_state(conn, STATE_REPLY_BODY);
                }
            }
            break;

        default:
            ;
    }
    if (ret == DATA_ERROR)
        proxy_connection_free(root, 0, PROXY_EVENT_NONE);

    return;
}


ProxyConnection*
http_rewriter_connect( HttpService*  service,
                       SockAddress*  address )
{
    RewriteConnection*  conn;
    int                 s;

    s = socket_create(address->family, SOCKET_STREAM );
    if (s < 0)
        return NULL;

    conn = calloc(1, sizeof(*conn));
    if (conn == NULL) {
        socket_close(s);
        return NULL;
    }

    proxy_connection_init( conn->root,
                           s,
                           address,
                           service->root,
                           rewrite_connection_io_event,
                           rewrite_connection_free );

    if ( rewrite_connection_init( conn ) < 0 ) {
        rewrite_connection_free( conn->root );
        return NULL;
    }

    return conn->root;
}
