/* 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 "proxy_http_int.h"
#include <stdio.h>
#include <string.h>
#include "qemu-common.h"
#include "android/utils/system.h"  /* strsep */

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

#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) {
        g_free((char*)h->value);
        g_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 = g_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   = g_strdup(method);
    r->req_uri      = g_strdup(uri);
    r->req_version  = g_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 = g_strdup(uri);
    g_free((char*)old);
}

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

        g_free(r->req_method);
        g_free(r->req_uri);
        g_free(r->req_version);
        g_free(r->rep_version);
        g_free(r->rep_readable);
        g_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  = g_strdup(version);
    r->rep_readable = g_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];
    int               slirp_fd;
    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;


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

    if (conn->slirp_fd >= 0) {
        socket_close(conn->slirp_fd);
        conn->slirp_fd = -1;
    }
    http_request_free(conn->request);
    proxy_connection_done(root);
    g_free(conn);
}


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

    conn->slirp_fd = -1;
    conn->state    = STATE_CONNECTING;

    if (socket_connect( root->socket, &service->server_addr ) < 0) {
        if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) {
            PROXY_LOG("%s: connecting", conn->root->name);
        }
        else {
            PROXY_LOG("%s: cannot connect to proxy: %s", root->name, errno_str);
            return -1;
        }
    }
    else {
        PROXY_LOG("%s: immediate connection", root->name);
        conn->state = STATE_CREATE_SOCKET_PAIR;
    }
    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;
    ProxyConnection*  root = conn->root;

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

    root->ev_func( root->ev_opaque, slirp_1, PROXY_EVENT_CONNECTED );
    conn->state = STATE_REQUEST_FIRST_LINE;
    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, conn->slirp_fd);
    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 )
{
    ProxyConnection*  root = conn->root;
    DataStatus        ret;

    ret = proxy_connection_receive_line( root, root->socket );
    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) {
        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)
                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)
                    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) {
                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)
                    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;
            }
            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);
        }
    }
    return ret;
}


static void
rewrite_connection_select( ProxyConnection*  root,
                           ProxySelect*      sel )
{
    RewriteConnection*  conn = (RewriteConnection*)root;
    int  slirp = conn->slirp_fd;
    int  proxy = root->socket;

    switch (conn->state) {
        case STATE_CONNECTING:
        case STATE_CREATE_SOCKET_PAIR:
            /* try to connect to the proxy server */
            proxy_select_set( sel, proxy, PROXY_SELECT_WRITE );
            break;

        case STATE_REQUEST_FIRST_LINE:
        case STATE_REQUEST_HEADERS:
            proxy_select_set( sel, slirp, PROXY_SELECT_READ );
            break;

        case STATE_REQUEST_SEND:
            proxy_select_set( sel, proxy, PROXY_SELECT_WRITE );
            break;

        case STATE_REQUEST_BODY:
            if (!conn->body_is_closed && !conn->body_is_full)
                proxy_select_set( sel, slirp, PROXY_SELECT_READ );

            if (conn->body_has_data)
                proxy_select_set( sel, proxy, PROXY_SELECT_WRITE );
            break;

        case STATE_REPLY_FIRST_LINE:
        case STATE_REPLY_HEADERS:
            proxy_select_set( sel, proxy, PROXY_SELECT_READ );
            break;

        case STATE_REPLY_SEND:
            proxy_select_set( sel, slirp, PROXY_SELECT_WRITE );
            break;

        case STATE_REPLY_BODY:
            if (conn->body_has_data)
                proxy_select_set( sel, slirp, PROXY_SELECT_WRITE );

            if (!conn->body_is_closed && !conn->body_is_full)
                proxy_select_set( sel, proxy, PROXY_SELECT_READ );
            break;
        default:
            ;
    };
}

static void
rewrite_connection_poll( ProxyConnection*  root,
                         ProxySelect*      sel )
{
    RewriteConnection*  conn = (RewriteConnection*)root;

    int         slirp     = conn->slirp_fd;
    int         proxy     = root->socket;
    int         has_slirp = proxy_select_poll(sel, slirp);
    int         has_proxy = proxy_select_poll(sel, proxy);
    DataStatus  ret       = DATA_NEED_MORE;

    switch (conn->state) {
        case STATE_CONNECTING:
            if (has_proxy) {
                PROXY_LOG("%s: connected to proxy", root->name);
                conn->state = 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);
                    conn->state = 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);
                    conn->state = 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
                        conn->state = 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);
                        conn->state = STATE_REQUEST_BODY;
                    } else {
                        PROXY_LOG("%s: request sent, waiting for reply",
                                  root->name);
                        conn->state = STATE_REPLY_FIRST_LINE;
                    }
                }
            }
            break;

        case STATE_REQUEST_BODY:
            if (has_slirp) {
                ret = rewrite_connection_read_body(conn, slirp);
            }
            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);
                    conn->state = STATE_REPLY_FIRST_LINE;
                }
            }
            break;

        case STATE_REPLY_FIRST_LINE:
            if (has_proxy) {
                ret = rewrite_connection_read_reply(conn);
                if (ret == DATA_COMPLETED) {
                    PROXY_LOG("%s: reply first line ok", root->name);
                    conn->state = 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
                        conn->state = 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);
                        conn->state = STATE_REPLY_BODY;
                    } else {
                        PROXY_LOG("%s: reply sent, looping to waiting request",
                                  root->name);
                        conn->state = STATE_REQUEST_FIRST_LINE;
                    }
                }
            }
            break;

        case STATE_REPLY_BODY:
            if (has_proxy) {
                ret = rewrite_connection_read_body(conn, proxy);
            }
            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);
                        conn->state = STATE_REQUEST_FIRST_LINE;
                    }
                }
            }
            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 = g_malloc0(sizeof(*conn));
    if (conn == NULL) {
        socket_close(s);
        return NULL;
    }

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

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

    return conn->root;
}
