Annotation of embedaddon/libevent/http.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (c) 2002-2006 Niels Provos <provos@citi.umich.edu>
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. The name of the author may not be used to endorse or promote products
                     14:  *    derived from this software without specific prior written permission.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     17:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     18:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     19:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     20:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     21:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     22:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     23:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     24:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     25:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     26:  */
                     27: 
                     28: #ifdef HAVE_CONFIG_H
                     29: #include "config.h"
                     30: #endif
                     31: 
                     32: #ifdef HAVE_SYS_PARAM_H
                     33: #include <sys/param.h>
                     34: #endif
                     35: #ifdef HAVE_SYS_TYPES_H
                     36: #include <sys/types.h>
                     37: #endif
                     38: 
                     39: #ifdef HAVE_SYS_TIME_H
                     40: #include <sys/time.h>
                     41: #endif
                     42: #ifdef HAVE_SYS_IOCCOM_H
                     43: #include <sys/ioccom.h>
                     44: #endif
                     45: 
                     46: #ifndef WIN32
                     47: #include <sys/resource.h>
                     48: #include <sys/socket.h>
                     49: #include <sys/stat.h>
                     50: #include <sys/wait.h>
                     51: #endif
                     52: 
                     53: #include <sys/queue.h>
                     54: 
                     55: #ifndef WIN32
                     56: #include <netinet/in.h>
                     57: #include <netdb.h>
                     58: #endif
                     59: 
                     60: #ifdef WIN32
                     61: #include <winsock2.h>
                     62: #endif
                     63: 
                     64: #include <assert.h>
                     65: #include <ctype.h>
                     66: #include <errno.h>
                     67: #include <stdio.h>
                     68: #include <stdlib.h>
                     69: #include <string.h>
                     70: #ifndef WIN32
                     71: #include <syslog.h>
                     72: #endif
                     73: #include <signal.h>
                     74: #include <time.h>
                     75: #ifdef HAVE_UNISTD_H
                     76: #include <unistd.h>
                     77: #endif
                     78: #ifdef HAVE_FCNTL_H
                     79: #include <fcntl.h>
                     80: #endif
                     81: 
                     82: #undef timeout_pending
                     83: #undef timeout_initialized
                     84: 
                     85: #include "strlcpy-internal.h"
                     86: #include "event.h"
                     87: #include "evhttp.h"
                     88: #include "evutil.h"
                     89: #include "log.h"
                     90: #include "http-internal.h"
                     91: 
                     92: #ifdef WIN32
                     93: #define strcasecmp _stricmp
                     94: #define strncasecmp _strnicmp
                     95: #define strdup _strdup
                     96: #endif
                     97: 
                     98: #ifndef HAVE_GETNAMEINFO
                     99: #define NI_MAXSERV 32
                    100: #define NI_MAXHOST 1025
                    101: 
                    102: #define NI_NUMERICHOST 1
                    103: #define NI_NUMERICSERV 2
                    104: 
                    105: static int
                    106: fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, 
                    107:        size_t hostlen, char *serv, size_t servlen, int flags)
                    108: {
                    109:         struct sockaddr_in *sin = (struct sockaddr_in *)sa;
                    110:         
                    111:         if (serv != NULL) {
                    112:                                char tmpserv[16];
                    113:                                evutil_snprintf(tmpserv, sizeof(tmpserv),
                    114:                                        "%d", ntohs(sin->sin_port));
                    115:                 if (strlcpy(serv, tmpserv, servlen) >= servlen)
                    116:                         return (-1);
                    117:         }
                    118: 
                    119:         if (host != NULL) {
                    120:                 if (flags & NI_NUMERICHOST) {
                    121:                         if (strlcpy(host, inet_ntoa(sin->sin_addr),
                    122:                             hostlen) >= hostlen)
                    123:                                 return (-1);
                    124:                         else
                    125:                                 return (0);
                    126:                 } else {
                    127:                                                struct hostent *hp;
                    128:                         hp = gethostbyaddr((char *)&sin->sin_addr, 
                    129:                             sizeof(struct in_addr), AF_INET);
                    130:                         if (hp == NULL)
                    131:                                 return (-2);
                    132:                         
                    133:                         if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
                    134:                                 return (-1);
                    135:                         else
                    136:                                 return (0);
                    137:                 }
                    138:         }
                    139:         return (0);
                    140: }
                    141: 
                    142: #endif
                    143: 
                    144: #ifndef HAVE_GETADDRINFO
                    145: struct addrinfo {
                    146:        int ai_family;
                    147:        int ai_socktype;
                    148:        int ai_protocol;
                    149:        size_t ai_addrlen;
                    150:        struct sockaddr *ai_addr;
                    151:        struct addrinfo *ai_next;
                    152: };
                    153: static int
                    154: fake_getaddrinfo(const char *hostname, struct addrinfo *ai)
                    155: {
                    156:        struct hostent *he = NULL;
                    157:        struct sockaddr_in *sa;
                    158:        if (hostname) {
                    159:                he = gethostbyname(hostname);
                    160:                if (!he)
                    161:                        return (-1);
                    162:        }
                    163:        ai->ai_family = he ? he->h_addrtype : AF_INET;
                    164:        ai->ai_socktype = SOCK_STREAM;
                    165:        ai->ai_protocol = 0;
                    166:        ai->ai_addrlen = sizeof(struct sockaddr_in);
                    167:        if (NULL == (ai->ai_addr = malloc(ai->ai_addrlen)))
                    168:                return (-1);
                    169:        sa = (struct sockaddr_in*)ai->ai_addr;
                    170:        memset(sa, 0, ai->ai_addrlen);
                    171:        if (he) {
                    172:                sa->sin_family = he->h_addrtype;
                    173:                memcpy(&sa->sin_addr, he->h_addr_list[0], he->h_length);
                    174:        } else {
                    175:                sa->sin_family = AF_INET;
                    176:                sa->sin_addr.s_addr = INADDR_ANY;
                    177:        }
                    178:        ai->ai_next = NULL;
                    179:        return (0);
                    180: }
                    181: static void
                    182: fake_freeaddrinfo(struct addrinfo *ai)
                    183: {
                    184:        free(ai->ai_addr);
                    185: }
                    186: #endif
                    187: 
                    188: #ifndef MIN
                    189: #define MIN(a,b) (((a)<(b))?(a):(b))
                    190: #endif
                    191: 
                    192: /* wrapper for setting the base from the http server */
                    193: #define EVHTTP_BASE_SET(x, y) do { \
                    194:        if ((x)->base != NULL) event_base_set((x)->base, y);    \
                    195: } while (0) 
                    196: 
                    197: extern int debug;
                    198: 
                    199: static int socket_connect(int fd, const char *address, unsigned short port);
                    200: static int bind_socket_ai(struct addrinfo *, int reuse);
                    201: static int bind_socket(const char *, u_short, int reuse);
                    202: static void name_from_addr(struct sockaddr *, socklen_t, char **, char **);
                    203: static int evhttp_associate_new_request_with_connection(
                    204:        struct evhttp_connection *evcon);
                    205: static void evhttp_connection_start_detectclose(
                    206:        struct evhttp_connection *evcon);
                    207: static void evhttp_connection_stop_detectclose(
                    208:        struct evhttp_connection *evcon);
                    209: static void evhttp_request_dispatch(struct evhttp_connection* evcon);
                    210: static void evhttp_read_firstline(struct evhttp_connection *evcon,
                    211:                                  struct evhttp_request *req);
                    212: static void evhttp_read_header(struct evhttp_connection *evcon,
                    213:     struct evhttp_request *req);
                    214: static int evhttp_add_header_internal(struct evkeyvalq *headers,
                    215:     const char *key, const char *value);
                    216: static int evhttp_decode_uri_internal(const char *uri, size_t length,
                    217:     char *ret, int always_decode_plus);
                    218: 
                    219: void evhttp_read(int, short, void *);
                    220: void evhttp_write(int, short, void *);
                    221: 
                    222: #ifndef HAVE_STRSEP
                    223: /* strsep replacement for platforms that lack it.  Only works if
                    224:  * del is one character long. */
                    225: static char *
                    226: strsep(char **s, const char *del)
                    227: {
                    228:        char *d, *tok;
                    229:        assert(strlen(del) == 1);
                    230:        if (!s || !*s)
                    231:                return NULL;
                    232:        tok = *s;
                    233:        d = strstr(tok, del);
                    234:        if (d) {
                    235:                *d = '\0';
                    236:                *s = d + 1;
                    237:        } else
                    238:                *s = NULL;
                    239:        return tok;
                    240: }
                    241: #endif
                    242: 
                    243: static const char *
                    244: html_replace(char ch, char *buf)
                    245: {
                    246:        switch (ch) {
                    247:        case '<':
                    248:                return "&lt;";
                    249:        case '>':
                    250:                return "&gt;";
                    251:        case '"':
                    252:                return "&quot;";
                    253:        case '\'':
                    254:                return "&#039;";
                    255:        case '&':
                    256:                return "&amp;";
                    257:        default:
                    258:                break;
                    259:        }
                    260: 
                    261:        /* Echo the character back */
                    262:        buf[0] = ch;
                    263:        buf[1] = '\0';
                    264:        
                    265:        return buf;
                    266: }
                    267: 
                    268: /*
                    269:  * Replaces <, >, ", ' and & with &lt;, &gt;, &quot;,
                    270:  * &#039; and &amp; correspondingly.
                    271:  *
                    272:  * The returned string needs to be freed by the caller.
                    273:  */
                    274: 
                    275: char *
                    276: evhttp_htmlescape(const char *html)
                    277: {
                    278:        int i, new_size = 0, old_size = strlen(html);
                    279:        char *escaped_html, *p;
                    280:        char scratch_space[2];
                    281:        
                    282:        for (i = 0; i < old_size; ++i)
                    283:           new_size += strlen(html_replace(html[i], scratch_space));
                    284: 
                    285:        p = escaped_html = malloc(new_size + 1);
                    286:        if (escaped_html == NULL)
                    287:                event_err(1, "%s: malloc(%d)", __func__, new_size + 1);
                    288:        for (i = 0; i < old_size; ++i) {
                    289:                const char *replaced = html_replace(html[i], scratch_space);
                    290:                /* this is length checked */
                    291:                strcpy(p, replaced);
                    292:                p += strlen(replaced);
                    293:        }
                    294: 
                    295:        *p = '\0';
                    296: 
                    297:        return (escaped_html);
                    298: }
                    299: 
                    300: static const char *
                    301: evhttp_method(enum evhttp_cmd_type type)
                    302: {
                    303:        const char *method;
                    304: 
                    305:        switch (type) {
                    306:        case EVHTTP_REQ_GET:
                    307:                method = "GET";
                    308:                break;
                    309:        case EVHTTP_REQ_POST:
                    310:                method = "POST";
                    311:                break;
                    312:        case EVHTTP_REQ_HEAD:
                    313:                method = "HEAD";
                    314:                break;
                    315:        default:
                    316:                method = NULL;
                    317:                break;
                    318:        }
                    319: 
                    320:        return (method);
                    321: }
                    322: 
                    323: static void
                    324: evhttp_add_event(struct event *ev, int timeout, int default_timeout)
                    325: {
                    326:        if (timeout != 0) {
                    327:                struct timeval tv;
                    328:                
                    329:                evutil_timerclear(&tv);
                    330:                tv.tv_sec = timeout != -1 ? timeout : default_timeout;
                    331:                event_add(ev, &tv);
                    332:        } else {
                    333:                event_add(ev, NULL);
                    334:        }
                    335: }
                    336: 
                    337: void
                    338: evhttp_write_buffer(struct evhttp_connection *evcon,
                    339:     void (*cb)(struct evhttp_connection *, void *), void *arg)
                    340: {
                    341:        event_debug(("%s: preparing to write buffer\n", __func__));
                    342: 
                    343:        /* Set call back */
                    344:        evcon->cb = cb;
                    345:        evcon->cb_arg = arg;
                    346: 
                    347:        /* check if the event is already pending */
                    348:        if (event_pending(&evcon->ev, EV_WRITE|EV_TIMEOUT, NULL))
                    349:                event_del(&evcon->ev);
                    350: 
                    351:        event_set(&evcon->ev, evcon->fd, EV_WRITE, evhttp_write, evcon);
                    352:        EVHTTP_BASE_SET(evcon, &evcon->ev);
                    353:        evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_WRITE_TIMEOUT);
                    354: }
                    355: 
                    356: static int
                    357: evhttp_connected(struct evhttp_connection *evcon)
                    358: {
                    359:        switch (evcon->state) {
                    360:        case EVCON_DISCONNECTED:
                    361:        case EVCON_CONNECTING:
                    362:                return (0);
                    363:        case EVCON_IDLE:
                    364:        case EVCON_READING_FIRSTLINE:
                    365:        case EVCON_READING_HEADERS:
                    366:        case EVCON_READING_BODY:
                    367:        case EVCON_READING_TRAILER:
                    368:        case EVCON_WRITING:
                    369:        default:
                    370:                return (1);
                    371:        }
                    372: }
                    373: 
                    374: /*
                    375:  * Create the headers needed for an HTTP request
                    376:  */
                    377: static void
                    378: evhttp_make_header_request(struct evhttp_connection *evcon,
                    379:     struct evhttp_request *req)
                    380: {
                    381:        const char *method;
                    382:        
                    383:        evhttp_remove_header(req->output_headers, "Proxy-Connection");
                    384: 
                    385:        /* Generate request line */
                    386:        method = evhttp_method(req->type);
                    387:        evbuffer_add_printf(evcon->output_buffer, "%s %s HTTP/%d.%d\r\n",
                    388:            method, req->uri, req->major, req->minor);
                    389: 
                    390:        /* Add the content length on a post request if missing */
                    391:        if (req->type == EVHTTP_REQ_POST &&
                    392:            evhttp_find_header(req->output_headers, "Content-Length") == NULL){
                    393:                char size[12];
                    394:                evutil_snprintf(size, sizeof(size), "%ld",
                    395:                    (long)EVBUFFER_LENGTH(req->output_buffer));
                    396:                evhttp_add_header(req->output_headers, "Content-Length", size);
                    397:        }
                    398: }
                    399: 
                    400: static int
                    401: evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
                    402: {
                    403:        if (flags & EVHTTP_PROXY_REQUEST) {
                    404:                /* proxy connection */
                    405:                const char *connection = evhttp_find_header(headers, "Proxy-Connection");
                    406:                return (connection == NULL || strcasecmp(connection, "keep-alive") != 0);
                    407:        } else {
                    408:                const char *connection = evhttp_find_header(headers, "Connection");
                    409:                return (connection != NULL && strcasecmp(connection, "close") == 0);
                    410:        }
                    411: }
                    412: 
                    413: static int
                    414: evhttp_is_connection_keepalive(struct evkeyvalq* headers)
                    415: {
                    416:        const char *connection = evhttp_find_header(headers, "Connection");
                    417:        return (connection != NULL 
                    418:            && strncasecmp(connection, "keep-alive", 10) == 0);
                    419: }
                    420: 
                    421: static void
                    422: evhttp_maybe_add_date_header(struct evkeyvalq *headers)
                    423: {
                    424:        if (evhttp_find_header(headers, "Date") == NULL) {
                    425:                char date[50];
                    426: #ifndef WIN32
                    427:                struct tm cur;
                    428: #endif
                    429:                struct tm *cur_p;
                    430:                time_t t = time(NULL);
                    431: #ifdef WIN32
                    432:                cur_p = gmtime(&t);
                    433: #else
                    434:                gmtime_r(&t, &cur);
                    435:                cur_p = &cur;
                    436: #endif
                    437:                if (strftime(date, sizeof(date),
                    438:                        "%a, %d %b %Y %H:%M:%S GMT", cur_p) != 0) {
                    439:                        evhttp_add_header(headers, "Date", date);
                    440:                }
                    441:        }
                    442: }
                    443: 
                    444: static void
                    445: evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
                    446:     long content_length)
                    447: {
                    448:        if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
                    449:            evhttp_find_header(headers, "Content-Length") == NULL) {
                    450:                char len[12];
                    451:                evutil_snprintf(len, sizeof(len), "%ld", content_length);
                    452:                evhttp_add_header(headers, "Content-Length", len);
                    453:        }
                    454: }
                    455: 
                    456: /*
                    457:  * Create the headers needed for an HTTP reply
                    458:  */
                    459: 
                    460: static void
                    461: evhttp_make_header_response(struct evhttp_connection *evcon,
                    462:     struct evhttp_request *req)
                    463: {
                    464:        int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
                    465:        evbuffer_add_printf(evcon->output_buffer, "HTTP/%d.%d %d %s\r\n",
                    466:            req->major, req->minor, req->response_code,
                    467:            req->response_code_line);
                    468: 
                    469:        if (req->major == 1) {
                    470:                if (req->minor == 1)
                    471:                        evhttp_maybe_add_date_header(req->output_headers);
                    472: 
                    473:                /*
                    474:                 * if the protocol is 1.0; and the connection was keep-alive
                    475:                 * we need to add a keep-alive header, too.
                    476:                 */
                    477:                if (req->minor == 0 && is_keepalive)
                    478:                        evhttp_add_header(req->output_headers,
                    479:                            "Connection", "keep-alive");
                    480: 
                    481:                if (req->minor == 1 || is_keepalive) {
                    482:                        /* 
                    483:                         * we need to add the content length if the
                    484:                         * user did not give it, this is required for
                    485:                         * persistent connections to work.
                    486:                         */
                    487:                        evhttp_maybe_add_content_length_header(
                    488:                                req->output_headers,
                    489:                                (long)EVBUFFER_LENGTH(req->output_buffer));
                    490:                }
                    491:        }
                    492: 
                    493:        /* Potentially add headers for unidentified content. */
                    494:        if (EVBUFFER_LENGTH(req->output_buffer)) {
                    495:                if (evhttp_find_header(req->output_headers,
                    496:                        "Content-Type") == NULL) {
                    497:                        evhttp_add_header(req->output_headers,
                    498:                            "Content-Type", "text/html; charset=ISO-8859-1");
                    499:                }
                    500:        }
                    501: 
                    502:        /* if the request asked for a close, we send a close, too */
                    503:        if (evhttp_is_connection_close(req->flags, req->input_headers)) {
                    504:                evhttp_remove_header(req->output_headers, "Connection");
                    505:                if (!(req->flags & EVHTTP_PROXY_REQUEST))
                    506:                    evhttp_add_header(req->output_headers, "Connection", "close");
                    507:                evhttp_remove_header(req->output_headers, "Proxy-Connection");
                    508:        }
                    509: }
                    510: 
                    511: void
                    512: evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
                    513: {
                    514:        struct evkeyval *header;
                    515: 
                    516:        /*
                    517:         * Depending if this is a HTTP request or response, we might need to
                    518:         * add some new headers or remove existing headers.
                    519:         */
                    520:        if (req->kind == EVHTTP_REQUEST) {
                    521:                evhttp_make_header_request(evcon, req);
                    522:        } else {
                    523:                evhttp_make_header_response(evcon, req);
                    524:        }
                    525: 
                    526:        TAILQ_FOREACH(header, req->output_headers, next) {
                    527:                evbuffer_add_printf(evcon->output_buffer, "%s: %s\r\n",
                    528:                    header->key, header->value);
                    529:        }
                    530:        evbuffer_add(evcon->output_buffer, "\r\n", 2);
                    531: 
                    532:        if (EVBUFFER_LENGTH(req->output_buffer) > 0) {
                    533:                /*
                    534:                 * For a request, we add the POST data, for a reply, this
                    535:                 * is the regular data.
                    536:                 */
                    537:                evbuffer_add_buffer(evcon->output_buffer, req->output_buffer);
                    538:        }
                    539: }
                    540: 
                    541: /* Separated host, port and file from URI */
                    542: 
                    543: int
                    544: evhttp_hostportfile(char *url, char **phost, u_short *pport, char **pfile)
                    545: {
                    546:        /* XXX not threadsafe. */
                    547:        static char host[1024];
                    548:        static char file[1024];
                    549:        char *p;
                    550:        const char *p2;
                    551:        int len;
                    552:        u_short port;
                    553: 
                    554:        len = strlen(HTTP_PREFIX);
                    555:        if (strncasecmp(url, HTTP_PREFIX, len))
                    556:                return (-1);
                    557: 
                    558:        url += len;
                    559: 
                    560:        /* We might overrun */
                    561:        if (strlcpy(host, url, sizeof (host)) >= sizeof(host))
                    562:                return (-1);
                    563: 
                    564:        p = strchr(host, '/');
                    565:        if (p != NULL) {
                    566:                *p = '\0';
                    567:                p2 = p + 1;
                    568:        } else
                    569:                p2 = NULL;
                    570: 
                    571:        if (pfile != NULL) {
                    572:                /* Generate request file */
                    573:                if (p2 == NULL)
                    574:                        p2 = "";
                    575:                evutil_snprintf(file, sizeof(file), "/%s", p2);
                    576:        }
                    577: 
                    578:        p = strchr(host, ':');
                    579:        if (p != NULL) {
                    580:                *p = '\0';
                    581:                port = atoi(p + 1);
                    582: 
                    583:                if (port == 0)
                    584:                        return (-1);
                    585:        } else
                    586:                port = HTTP_DEFAULTPORT;
                    587: 
                    588:        if (phost != NULL)
                    589:                *phost = host;
                    590:        if (pport != NULL)
                    591:                *pport = port;
                    592:        if (pfile != NULL)
                    593:                *pfile = file;
                    594: 
                    595:        return (0);
                    596: }
                    597: 
                    598: static int
                    599: evhttp_connection_incoming_fail(struct evhttp_request *req,
                    600:     enum evhttp_connection_error error)
                    601: {
                    602:        switch (error) {
                    603:        case EVCON_HTTP_TIMEOUT:
                    604:        case EVCON_HTTP_EOF:
                    605:                /* 
                    606:                 * these are cases in which we probably should just
                    607:                 * close the connection and not send a reply.  this
                    608:                 * case may happen when a browser keeps a persistent
                    609:                 * connection open and we timeout on the read.  when
                    610:                 * the request is still being used for sending, we
                    611:                 * need to disassociated it from the connection here.
                    612:                 */
                    613:                if (!req->userdone) {
                    614:                        /* remove it so that it will not be freed */
                    615:                        TAILQ_REMOVE(&req->evcon->requests, req, next);
                    616:                        /* indicate that this request no longer has a
                    617:                         * connection object
                    618:                         */
                    619:                        req->evcon = NULL;
                    620:                }
                    621:                return (-1);
                    622:        case EVCON_HTTP_INVALID_HEADER:
                    623:        default:        /* xxx: probably should just error on default */
                    624:                /* the callback looks at the uri to determine errors */
                    625:                if (req->uri) {
                    626:                        free(req->uri);
                    627:                        req->uri = NULL;
                    628:                }
                    629: 
                    630:                /* 
                    631:                 * the callback needs to send a reply, once the reply has
                    632:                 * been send, the connection should get freed.
                    633:                 */
                    634:                (*req->cb)(req, req->cb_arg);
                    635:        }
                    636:        
                    637:        return (0);
                    638: }
                    639: 
                    640: void
                    641: evhttp_connection_fail(struct evhttp_connection *evcon,
                    642:     enum evhttp_connection_error error)
                    643: {
                    644:        struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
                    645:        void (*cb)(struct evhttp_request *, void *);
                    646:        void *cb_arg;
                    647:        assert(req != NULL);
                    648:        
                    649:        if (evcon->flags & EVHTTP_CON_INCOMING) {
                    650:                /* 
                    651:                 * for incoming requests, there are two different
                    652:                 * failure cases.  it's either a network level error
                    653:                 * or an http layer error. for problems on the network
                    654:                 * layer like timeouts we just drop the connections.
                    655:                 * For HTTP problems, we might have to send back a
                    656:                 * reply before the connection can be freed.
                    657:                 */
                    658:                if (evhttp_connection_incoming_fail(req, error) == -1)
                    659:                        evhttp_connection_free(evcon);
                    660:                return;
                    661:        }
                    662: 
                    663:        /* save the callback for later; the cb might free our object */
                    664:        cb = req->cb;
                    665:        cb_arg = req->cb_arg;
                    666: 
                    667:        /* do not fail all requests; the next request is going to get
                    668:         * send over a new connection.   when a user cancels a request,
                    669:         * all other pending requests should be processed as normal
                    670:         */
                    671:        TAILQ_REMOVE(&evcon->requests, req, next);
                    672:        evhttp_request_free(req);
                    673: 
                    674:        /* reset the connection */
                    675:        evhttp_connection_reset(evcon);
                    676:        
                    677:        /* We are trying the next request that was queued on us */
                    678:        if (TAILQ_FIRST(&evcon->requests) != NULL)
                    679:                evhttp_connection_connect(evcon);
                    680: 
                    681:        /* inform the user */
                    682:        if (cb != NULL)
                    683:                (*cb)(NULL, cb_arg);
                    684: }
                    685: 
                    686: void
                    687: evhttp_write(int fd, short what, void *arg)
                    688: {
                    689:        struct evhttp_connection *evcon = arg;
                    690:        int n;
                    691: 
                    692:        if (what == EV_TIMEOUT) {
                    693:                evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
                    694:                return;
                    695:        }
                    696: 
                    697:        n = evbuffer_write(evcon->output_buffer, fd);
                    698:        if (n == -1) {
                    699:                event_debug(("%s: evbuffer_write", __func__));
                    700:                evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
                    701:                return;
                    702:        }
                    703: 
                    704:        if (n == 0) {
                    705:                event_debug(("%s: write nothing", __func__));
                    706:                evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
                    707:                return;
                    708:        }
                    709: 
                    710:        if (EVBUFFER_LENGTH(evcon->output_buffer) != 0) {
                    711:                evhttp_add_event(&evcon->ev, 
                    712:                    evcon->timeout, HTTP_WRITE_TIMEOUT);
                    713:                return;
                    714:        }
                    715: 
                    716:        /* Activate our call back */
                    717:        if (evcon->cb != NULL)
                    718:                (*evcon->cb)(evcon, evcon->cb_arg);
                    719: }
                    720: 
                    721: /**
                    722:  * Advance the connection state.
                    723:  * - If this is an outgoing connection, we've just processed the response;
                    724:  *   idle or close the connection.
                    725:  * - If this is an incoming connection, we've just processed the request;
                    726:  *   respond.
                    727:  */
                    728: static void
                    729: evhttp_connection_done(struct evhttp_connection *evcon)
                    730: {
                    731:        struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
                    732:        int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
                    733: 
                    734:        if (con_outgoing) {
                    735:                /* idle or close the connection */
                    736:                int need_close;
                    737:                TAILQ_REMOVE(&evcon->requests, req, next);
                    738:                req->evcon = NULL;
                    739: 
                    740:                evcon->state = EVCON_IDLE;
                    741: 
                    742:                need_close = 
                    743:                    evhttp_is_connection_close(req->flags, req->input_headers)||
                    744:                    evhttp_is_connection_close(req->flags, req->output_headers);
                    745: 
                    746:                /* check if we got asked to close the connection */
                    747:                if (need_close)
                    748:                        evhttp_connection_reset(evcon);
                    749: 
                    750:                if (TAILQ_FIRST(&evcon->requests) != NULL) {
                    751:                        /*
                    752:                         * We have more requests; reset the connection
                    753:                         * and deal with the next request.
                    754:                         */
                    755:                        if (!evhttp_connected(evcon))
                    756:                                evhttp_connection_connect(evcon);
                    757:                        else
                    758:                                evhttp_request_dispatch(evcon);
                    759:                } else if (!need_close) {
                    760:                        /*
                    761:                         * The connection is going to be persistent, but we
                    762:                         * need to detect if the other side closes it.
                    763:                         */
                    764:                        evhttp_connection_start_detectclose(evcon);
                    765:                }
                    766:        } else if (evcon->state != EVCON_DISCONNECTED) {
                    767:                /*
                    768:                 * incoming connection - we need to leave the request on the
                    769:                 * connection so that we can reply to it.
                    770:                 */
                    771:                evcon->state = EVCON_WRITING;
                    772:        }
                    773: 
                    774:        /* notify the user of the request */
                    775:        (*req->cb)(req, req->cb_arg);
                    776: 
                    777:        /* if this was an outgoing request, we own and it's done. so free it */
                    778:        if (con_outgoing) {
                    779:                evhttp_request_free(req);
                    780:        }
                    781: }
                    782: 
                    783: /*
                    784:  * Handles reading from a chunked request.
                    785:  *   return ALL_DATA_READ:
                    786:  *     all data has been read
                    787:  *   return MORE_DATA_EXPECTED:
                    788:  *     more data is expected
                    789:  *   return DATA_CORRUPTED:
                    790:  *     data is corrupted
                    791:  *   return REQUEST_CANCLED:
                    792:  *     request was canceled by the user calling evhttp_cancel_request
                    793:  */
                    794: 
                    795: static enum message_read_status
                    796: evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
                    797: {
                    798:        int len;
                    799: 
                    800:        while ((len = EVBUFFER_LENGTH(buf)) > 0) {
                    801:                if (req->ntoread < 0) {
                    802:                        /* Read chunk size */
                    803:                        ev_int64_t ntoread;
                    804:                        char *p = evbuffer_readline(buf);
                    805:                        char *endp;
                    806:                        int error;
                    807:                        if (p == NULL)
                    808:                                break;
                    809:                        /* the last chunk is on a new line? */
                    810:                        if (strlen(p) == 0) {
                    811:                                free(p);
                    812:                                continue;
                    813:                        }
                    814:                        ntoread = evutil_strtoll(p, &endp, 16);
                    815:                        error = (*p == '\0' ||
                    816:                            (*endp != '\0' && *endp != ' ') ||
                    817:                            ntoread < 0);
                    818:                        free(p);
                    819:                        if (error) {
                    820:                                /* could not get chunk size */
                    821:                                return (DATA_CORRUPTED);
                    822:                        }
                    823:                        req->ntoread = ntoread;
                    824:                        if (req->ntoread == 0) {
                    825:                                /* Last chunk */
                    826:                                return (ALL_DATA_READ);
                    827:                        }
                    828:                        continue;
                    829:                }
                    830: 
                    831:                /* don't have enough to complete a chunk; wait for more */
                    832:                if (len < req->ntoread)
                    833:                        return (MORE_DATA_EXPECTED);
                    834: 
                    835:                /* Completed chunk */
                    836:                evbuffer_add(req->input_buffer,
                    837:                    EVBUFFER_DATA(buf), (size_t)req->ntoread);
                    838:                evbuffer_drain(buf, (size_t)req->ntoread);
                    839:                req->ntoread = -1;
                    840:                if (req->chunk_cb != NULL) {
                    841:                        (*req->chunk_cb)(req, req->cb_arg);
                    842:                        evbuffer_drain(req->input_buffer,
                    843:                            EVBUFFER_LENGTH(req->input_buffer));
                    844:                }
                    845:        }
                    846: 
                    847:        return (MORE_DATA_EXPECTED);
                    848: }
                    849: 
                    850: static void
                    851: evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
                    852: {
                    853:        struct evbuffer *buf = evcon->input_buffer;
                    854: 
                    855:        switch (evhttp_parse_headers(req, buf)) {
                    856:        case DATA_CORRUPTED:
                    857:                evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
                    858:                break;
                    859:        case ALL_DATA_READ:
                    860:                event_del(&evcon->ev);
                    861:                evhttp_connection_done(evcon);
                    862:                break;
                    863:        case MORE_DATA_EXPECTED:
                    864:        default:
                    865:                evhttp_add_event(&evcon->ev, evcon->timeout,
                    866:                    HTTP_READ_TIMEOUT);
                    867:                break;
                    868:        }
                    869: }
                    870: 
                    871: static void
                    872: evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
                    873: {
                    874:        struct evbuffer *buf = evcon->input_buffer;
                    875:        
                    876:        if (req->chunked) {
                    877:                switch (evhttp_handle_chunked_read(req, buf)) {
                    878:                case ALL_DATA_READ:
                    879:                        /* finished last chunk */
                    880:                        evcon->state = EVCON_READING_TRAILER;
                    881:                        evhttp_read_trailer(evcon, req);
                    882:                        return;
                    883:                case DATA_CORRUPTED:
                    884:                        /* corrupted data */
                    885:                        evhttp_connection_fail(evcon,
                    886:                            EVCON_HTTP_INVALID_HEADER);
                    887:                        return;
                    888:                case REQUEST_CANCELED:
                    889:                        /* request canceled */
                    890:                        evhttp_request_free(req);
                    891:                        return;
                    892:                case MORE_DATA_EXPECTED:
                    893:                default:
                    894:                        break;
                    895:                }
                    896:        } else if (req->ntoread < 0) {
                    897:                /* Read until connection close. */
                    898:                evbuffer_add_buffer(req->input_buffer, buf);
                    899:        } else if (EVBUFFER_LENGTH(buf) >= req->ntoread) {
                    900:                /* Completed content length */
                    901:                evbuffer_add(req->input_buffer, EVBUFFER_DATA(buf),
                    902:                    (size_t)req->ntoread);
                    903:                evbuffer_drain(buf, (size_t)req->ntoread);
                    904:                req->ntoread = 0;
                    905:                evhttp_connection_done(evcon);
                    906:                return;
                    907:        }
                    908:        /* Read more! */
                    909:        event_set(&evcon->ev, evcon->fd, EV_READ, evhttp_read, evcon);
                    910:        EVHTTP_BASE_SET(evcon, &evcon->ev);
                    911:        evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_READ_TIMEOUT);
                    912: }
                    913: 
                    914: /*
                    915:  * Reads data into a buffer structure until no more data
                    916:  * can be read on the file descriptor or we have read all
                    917:  * the data that we wanted to read.
                    918:  * Execute callback when done.
                    919:  */
                    920: 
                    921: void
                    922: evhttp_read(int fd, short what, void *arg)
                    923: {
                    924:        struct evhttp_connection *evcon = arg;
                    925:        struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
                    926:        struct evbuffer *buf = evcon->input_buffer;
                    927:        int n, len;
                    928: 
                    929:        if (what == EV_TIMEOUT) {
                    930:                evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
                    931:                return;
                    932:        }
                    933:        n = evbuffer_read(buf, fd, -1);
                    934:        len = EVBUFFER_LENGTH(buf);
                    935:        event_debug(("%s: got %d on %d\n", __func__, n, fd));
                    936:        
                    937:        if (n == -1) {
                    938:                if (errno != EINTR && errno != EAGAIN) {
                    939:                        event_debug(("%s: evbuffer_read", __func__));
                    940:                        evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
                    941:                } else {
                    942:                        evhttp_add_event(&evcon->ev, evcon->timeout,
                    943:                            HTTP_READ_TIMEOUT);        
                    944:                }
                    945:                return;
                    946:        } else if (n == 0) {
                    947:                /* Connection closed */
                    948:                evcon->state = EVCON_DISCONNECTED;
                    949:                evhttp_connection_done(evcon);
                    950:                return;
                    951:        }
                    952: 
                    953:        switch (evcon->state) {
                    954:        case EVCON_READING_FIRSTLINE:
                    955:                evhttp_read_firstline(evcon, req);
                    956:                break;
                    957:        case EVCON_READING_HEADERS:
                    958:                evhttp_read_header(evcon, req);
                    959:                break;
                    960:        case EVCON_READING_BODY:
                    961:                evhttp_read_body(evcon, req);
                    962:                break;
                    963:        case EVCON_READING_TRAILER:
                    964:                evhttp_read_trailer(evcon, req);
                    965:                break;
                    966:        case EVCON_DISCONNECTED:
                    967:        case EVCON_CONNECTING:
                    968:        case EVCON_IDLE:
                    969:        case EVCON_WRITING:
                    970:        default:
                    971:                event_errx(1, "%s: illegal connection state %d",
                    972:                           __func__, evcon->state);
                    973:        }
                    974: }
                    975: 
                    976: static void
                    977: evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
                    978: {
                    979:        /* This is after writing the request to the server */
                    980:        struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
                    981:        assert(req != NULL);
                    982: 
                    983:        assert(evcon->state == EVCON_WRITING);
                    984: 
                    985:        /* We are done writing our header and are now expecting the response */
                    986:        req->kind = EVHTTP_RESPONSE;
                    987: 
                    988:        evhttp_start_read(evcon);
                    989: }
                    990: 
                    991: /*
                    992:  * Clean up a connection object
                    993:  */
                    994: 
                    995: void
                    996: evhttp_connection_free(struct evhttp_connection *evcon)
                    997: {
                    998:        struct evhttp_request *req;
                    999: 
                   1000:        /* notify interested parties that this connection is going down */
                   1001:        if (evcon->fd != -1) {
                   1002:                if (evhttp_connected(evcon) && evcon->closecb != NULL)
                   1003:                        (*evcon->closecb)(evcon, evcon->closecb_arg);
                   1004:        }
                   1005: 
                   1006:        /* remove all requests that might be queued on this
                   1007:         * connection.  for server connections, this should be empty.
                   1008:         * because it gets dequeued either in evhttp_connection_done or
                   1009:         * evhttp_connection_fail.
                   1010:         */
                   1011:        while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
                   1012:                TAILQ_REMOVE(&evcon->requests, req, next);
                   1013:                evhttp_request_free(req);
                   1014:        }
                   1015: 
                   1016:        if (evcon->http_server != NULL) {
                   1017:                struct evhttp *http = evcon->http_server;
                   1018:                TAILQ_REMOVE(&http->connections, evcon, next);
                   1019:        }
                   1020: 
                   1021:        if (event_initialized(&evcon->close_ev))
                   1022:                event_del(&evcon->close_ev);
                   1023: 
                   1024:        if (event_initialized(&evcon->ev))
                   1025:                event_del(&evcon->ev);
                   1026:        
                   1027:        if (evcon->fd != -1)
                   1028:                EVUTIL_CLOSESOCKET(evcon->fd);
                   1029: 
                   1030:        if (evcon->bind_address != NULL)
                   1031:                free(evcon->bind_address);
                   1032: 
                   1033:        if (evcon->address != NULL)
                   1034:                free(evcon->address);
                   1035: 
                   1036:        if (evcon->input_buffer != NULL)
                   1037:                evbuffer_free(evcon->input_buffer);
                   1038: 
                   1039:        if (evcon->output_buffer != NULL)
                   1040:                evbuffer_free(evcon->output_buffer);
                   1041: 
                   1042:        free(evcon);
                   1043: }
                   1044: 
                   1045: void
                   1046: evhttp_connection_set_local_address(struct evhttp_connection *evcon,
                   1047:     const char *address)
                   1048: {
                   1049:        assert(evcon->state == EVCON_DISCONNECTED);
                   1050:        if (evcon->bind_address)
                   1051:                free(evcon->bind_address);
                   1052:        if ((evcon->bind_address = strdup(address)) == NULL)
                   1053:                event_err(1, "%s: strdup", __func__);
                   1054: }
                   1055: 
                   1056: void
                   1057: evhttp_connection_set_local_port(struct evhttp_connection *evcon,
                   1058:     unsigned short port)
                   1059: {
                   1060:        assert(evcon->state == EVCON_DISCONNECTED);
                   1061:        evcon->bind_port = port;
                   1062: }
                   1063: 
                   1064: static void
                   1065: evhttp_request_dispatch(struct evhttp_connection* evcon)
                   1066: {
                   1067:        struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
                   1068:        
                   1069:        /* this should not usually happy but it's possible */
                   1070:        if (req == NULL)
                   1071:                return;
                   1072: 
                   1073:        /* delete possible close detection events */
                   1074:        evhttp_connection_stop_detectclose(evcon);
                   1075:        
                   1076:        /* we assume that the connection is connected already */
                   1077:        assert(evcon->state == EVCON_IDLE);
                   1078: 
                   1079:        evcon->state = EVCON_WRITING;
                   1080: 
                   1081:        /* Create the header from the store arguments */
                   1082:        evhttp_make_header(evcon, req);
                   1083: 
                   1084:        evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
                   1085: }
                   1086: 
                   1087: /* Reset our connection state */
                   1088: void
                   1089: evhttp_connection_reset(struct evhttp_connection *evcon)
                   1090: {
                   1091:        if (event_initialized(&evcon->ev))
                   1092:                event_del(&evcon->ev);
                   1093: 
                   1094:        if (evcon->fd != -1) {
                   1095:                /* inform interested parties about connection close */
                   1096:                if (evhttp_connected(evcon) && evcon->closecb != NULL)
                   1097:                        (*evcon->closecb)(evcon, evcon->closecb_arg);
                   1098: 
                   1099:                EVUTIL_CLOSESOCKET(evcon->fd);
                   1100:                evcon->fd = -1;
                   1101:        }
                   1102:        evcon->state = EVCON_DISCONNECTED;
                   1103: 
                   1104:        evbuffer_drain(evcon->input_buffer,
                   1105:            EVBUFFER_LENGTH(evcon->input_buffer));
                   1106:        evbuffer_drain(evcon->output_buffer,
                   1107:            EVBUFFER_LENGTH(evcon->output_buffer));
                   1108: }
                   1109: 
                   1110: static void
                   1111: evhttp_detect_close_cb(int fd, short what, void *arg)
                   1112: {
                   1113:        struct evhttp_connection *evcon = arg;
                   1114:        evhttp_connection_reset(evcon);
                   1115: }
                   1116: 
                   1117: static void
                   1118: evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
                   1119: {
                   1120:        evcon->flags |= EVHTTP_CON_CLOSEDETECT;
                   1121: 
                   1122:        if (event_initialized(&evcon->close_ev))
                   1123:                event_del(&evcon->close_ev);
                   1124:        event_set(&evcon->close_ev, evcon->fd, EV_READ,
                   1125:            evhttp_detect_close_cb, evcon);
                   1126:        EVHTTP_BASE_SET(evcon, &evcon->close_ev);
                   1127:        event_add(&evcon->close_ev, NULL);
                   1128: }
                   1129: 
                   1130: static void
                   1131: evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
                   1132: {
                   1133:        evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
                   1134:        event_del(&evcon->close_ev);
                   1135: }
                   1136: 
                   1137: static void
                   1138: evhttp_connection_retry(int fd, short what, void *arg)
                   1139: {
                   1140:        struct evhttp_connection *evcon = arg;
                   1141: 
                   1142:        evcon->state = EVCON_DISCONNECTED;
                   1143:        evhttp_connection_connect(evcon);
                   1144: }
                   1145: 
                   1146: /*
                   1147:  * Call back for asynchronous connection attempt.
                   1148:  */
                   1149: 
                   1150: static void
                   1151: evhttp_connectioncb(int fd, short what, void *arg)
                   1152: {
                   1153:        struct evhttp_connection *evcon = arg;
                   1154:        int error;
                   1155:        socklen_t errsz = sizeof(error);
                   1156:                
                   1157:        if (what == EV_TIMEOUT) {
                   1158:                event_debug(("%s: connection timeout for \"%s:%d\" on %d",
                   1159:                        __func__, evcon->address, evcon->port, evcon->fd));
                   1160:                goto cleanup;
                   1161:        }
                   1162: 
                   1163:        /* Check if the connection completed */
                   1164:        if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
                   1165:                       &errsz) == -1) {
                   1166:                event_debug(("%s: getsockopt for \"%s:%d\" on %d",
                   1167:                        __func__, evcon->address, evcon->port, evcon->fd));
                   1168:                goto cleanup;
                   1169:        }
                   1170: 
                   1171:        if (error) {
                   1172:                event_debug(("%s: connect failed for \"%s:%d\" on %d: %s",
                   1173:                    __func__, evcon->address, evcon->port, evcon->fd,
                   1174:                        strerror(error)));
                   1175:                goto cleanup;
                   1176:        }
                   1177: 
                   1178:        /* We are connected to the server now */
                   1179:        event_debug(("%s: connected to \"%s:%d\" on %d\n",
                   1180:                        __func__, evcon->address, evcon->port, evcon->fd));
                   1181: 
                   1182:        /* Reset the retry count as we were successful in connecting */
                   1183:        evcon->retry_cnt = 0;
                   1184:        evcon->state = EVCON_IDLE;
                   1185: 
                   1186:        /* try to start requests that have queued up on this connection */
                   1187:        evhttp_request_dispatch(evcon);
                   1188:        return;
                   1189: 
                   1190:  cleanup:
                   1191:        if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
                   1192:                evtimer_set(&evcon->ev, evhttp_connection_retry, evcon);
                   1193:                EVHTTP_BASE_SET(evcon, &evcon->ev);
                   1194:                evhttp_add_event(&evcon->ev, MIN(3600, 2 << evcon->retry_cnt),
                   1195:                    HTTP_CONNECT_TIMEOUT);
                   1196:                evcon->retry_cnt++;
                   1197:                return;
                   1198:        }
                   1199:        evhttp_connection_reset(evcon);
                   1200: 
                   1201:        /* for now, we just signal all requests by executing their callbacks */
                   1202:        while (TAILQ_FIRST(&evcon->requests) != NULL) {
                   1203:                struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
                   1204:                TAILQ_REMOVE(&evcon->requests, request, next);
                   1205:                request->evcon = NULL;
                   1206: 
                   1207:                /* we might want to set an error here */
                   1208:                request->cb(request, request->cb_arg);
                   1209:                evhttp_request_free(request);
                   1210:        }
                   1211: }
                   1212: 
                   1213: /*
                   1214:  * Check if we got a valid response code.
                   1215:  */
                   1216: 
                   1217: static int
                   1218: evhttp_valid_response_code(int code)
                   1219: {
                   1220:        if (code == 0)
                   1221:                return (0);
                   1222: 
                   1223:        return (1);
                   1224: }
                   1225: 
                   1226: /* Parses the status line of a web server */
                   1227: 
                   1228: static int
                   1229: evhttp_parse_response_line(struct evhttp_request *req, char *line)
                   1230: {
                   1231:        char *protocol;
                   1232:        char *number;
                   1233:        const char *readable = "";
                   1234: 
                   1235:        protocol = strsep(&line, " ");
                   1236:        if (line == NULL)
                   1237:                return (-1);
                   1238:        number = strsep(&line, " ");
                   1239:        if (line != NULL)
                   1240:                readable = line;
                   1241: 
                   1242:        if (strcmp(protocol, "HTTP/1.0") == 0) {
                   1243:                req->major = 1;
                   1244:                req->minor = 0;
                   1245:        } else if (strcmp(protocol, "HTTP/1.1") == 0) {
                   1246:                req->major = 1;
                   1247:                req->minor = 1;
                   1248:        } else {
                   1249:                event_debug(("%s: bad protocol \"%s\"",
                   1250:                        __func__, protocol));
                   1251:                return (-1);
                   1252:        }
                   1253: 
                   1254:        req->response_code = atoi(number);
                   1255:        if (!evhttp_valid_response_code(req->response_code)) {
                   1256:                event_debug(("%s: bad response code \"%s\"",
                   1257:                        __func__, number));
                   1258:                return (-1);
                   1259:        }
                   1260: 
                   1261:        if ((req->response_code_line = strdup(readable)) == NULL)
                   1262:                event_err(1, "%s: strdup", __func__);
                   1263: 
                   1264:        return (0);
                   1265: }
                   1266: 
                   1267: /* Parse the first line of a HTTP request */
                   1268: 
                   1269: static int
                   1270: evhttp_parse_request_line(struct evhttp_request *req, char *line)
                   1271: {
                   1272:        char *method;
                   1273:        char *uri;
                   1274:        char *version;
                   1275: 
                   1276:        /* Parse the request line */
                   1277:        method = strsep(&line, " ");
                   1278:        if (line == NULL)
                   1279:                return (-1);
                   1280:        uri = strsep(&line, " ");
                   1281:        if (line == NULL)
                   1282:                return (-1);
                   1283:        version = strsep(&line, " ");
                   1284:        if (line != NULL)
                   1285:                return (-1);
                   1286: 
                   1287:        /* First line */
                   1288:        if (strcmp(method, "GET") == 0) {
                   1289:                req->type = EVHTTP_REQ_GET;
                   1290:        } else if (strcmp(method, "POST") == 0) {
                   1291:                req->type = EVHTTP_REQ_POST;
                   1292:        } else if (strcmp(method, "HEAD") == 0) {
                   1293:                req->type = EVHTTP_REQ_HEAD;
                   1294:        } else {
                   1295:                event_debug(("%s: bad method %s on request %p from %s",
                   1296:                        __func__, method, req, req->remote_host));
                   1297:                return (-1);
                   1298:        }
                   1299: 
                   1300:        if (strcmp(version, "HTTP/1.0") == 0) {
                   1301:                req->major = 1;
                   1302:                req->minor = 0;
                   1303:        } else if (strcmp(version, "HTTP/1.1") == 0) {
                   1304:                req->major = 1;
                   1305:                req->minor = 1;
                   1306:        } else {
                   1307:                event_debug(("%s: bad version %s on request %p from %s",
                   1308:                        __func__, version, req, req->remote_host));
                   1309:                return (-1);
                   1310:        }
                   1311: 
                   1312:        if ((req->uri = strdup(uri)) == NULL) {
                   1313:                event_debug(("%s: strdup", __func__));
                   1314:                return (-1);
                   1315:        }
                   1316: 
                   1317:        /* determine if it's a proxy request */
                   1318:        if (strlen(req->uri) > 0 && req->uri[0] != '/')
                   1319:                req->flags |= EVHTTP_PROXY_REQUEST;
                   1320: 
                   1321:        return (0);
                   1322: }
                   1323: 
                   1324: const char *
                   1325: evhttp_find_header(const struct evkeyvalq *headers, const char *key)
                   1326: {
                   1327:        struct evkeyval *header;
                   1328: 
                   1329:        TAILQ_FOREACH(header, headers, next) {
                   1330:                if (strcasecmp(header->key, key) == 0)
                   1331:                        return (header->value);
                   1332:        }
                   1333: 
                   1334:        return (NULL);
                   1335: }
                   1336: 
                   1337: void
                   1338: evhttp_clear_headers(struct evkeyvalq *headers)
                   1339: {
                   1340:        struct evkeyval *header;
                   1341: 
                   1342:        for (header = TAILQ_FIRST(headers);
                   1343:            header != NULL;
                   1344:            header = TAILQ_FIRST(headers)) {
                   1345:                TAILQ_REMOVE(headers, header, next);
                   1346:                free(header->key);
                   1347:                free(header->value);
                   1348:                free(header);
                   1349:        }
                   1350: }
                   1351: 
                   1352: /*
                   1353:  * Returns 0,  if the header was successfully removed.
                   1354:  * Returns -1, if the header could not be found.
                   1355:  */
                   1356: 
                   1357: int
                   1358: evhttp_remove_header(struct evkeyvalq *headers, const char *key)
                   1359: {
                   1360:        struct evkeyval *header;
                   1361: 
                   1362:        TAILQ_FOREACH(header, headers, next) {
                   1363:                if (strcasecmp(header->key, key) == 0)
                   1364:                        break;
                   1365:        }
                   1366: 
                   1367:        if (header == NULL)
                   1368:                return (-1);
                   1369: 
                   1370:        /* Free and remove the header that we found */
                   1371:        TAILQ_REMOVE(headers, header, next);
                   1372:        free(header->key);
                   1373:        free(header->value);
                   1374:        free(header);
                   1375: 
                   1376:        return (0);
                   1377: }
                   1378: 
                   1379: static int
                   1380: evhttp_header_is_valid_value(const char *value)
                   1381: {
                   1382:        const char *p = value;
                   1383: 
                   1384:        while ((p = strpbrk(p, "\r\n")) != NULL) {
                   1385:                /* we really expect only one new line */
                   1386:                p += strspn(p, "\r\n");
                   1387:                /* we expect a space or tab for continuation */
                   1388:                if (*p != ' ' && *p != '\t')
                   1389:                        return (0);
                   1390:        }
                   1391:        return (1);
                   1392: }
                   1393: 
                   1394: int
                   1395: evhttp_add_header(struct evkeyvalq *headers,
                   1396:     const char *key, const char *value)
                   1397: {
                   1398:        event_debug(("%s: key: %s val: %s\n", __func__, key, value));
                   1399: 
                   1400:        if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
                   1401:                /* drop illegal headers */
                   1402:                event_debug(("%s: dropping illegal header key\n", __func__));
                   1403:                return (-1);
                   1404:        }
                   1405:        
                   1406:        if (!evhttp_header_is_valid_value(value)) {
                   1407:                event_debug(("%s: dropping illegal header value\n", __func__));
                   1408:                return (-1);
                   1409:        }
                   1410: 
                   1411:        return (evhttp_add_header_internal(headers, key, value));
                   1412: }
                   1413: 
                   1414: static int
                   1415: evhttp_add_header_internal(struct evkeyvalq *headers,
                   1416:     const char *key, const char *value)
                   1417: {
                   1418:        struct evkeyval *header = calloc(1, sizeof(struct evkeyval));
                   1419:        if (header == NULL) {
                   1420:                event_warn("%s: calloc", __func__);
                   1421:                return (-1);
                   1422:        }
                   1423:        if ((header->key = strdup(key)) == NULL) {
                   1424:                free(header);
                   1425:                event_warn("%s: strdup", __func__);
                   1426:                return (-1);
                   1427:        }
                   1428:        if ((header->value = strdup(value)) == NULL) {
                   1429:                free(header->key);
                   1430:                free(header);
                   1431:                event_warn("%s: strdup", __func__);
                   1432:                return (-1);
                   1433:        }
                   1434: 
                   1435:        TAILQ_INSERT_TAIL(headers, header, next);
                   1436: 
                   1437:        return (0);
                   1438: }
                   1439: 
                   1440: /*
                   1441:  * Parses header lines from a request or a response into the specified
                   1442:  * request object given an event buffer.
                   1443:  *
                   1444:  * Returns
                   1445:  *   DATA_CORRUPTED      on error
                   1446:  *   MORE_DATA_EXPECTED  when we need to read more headers
                   1447:  *   ALL_DATA_READ       when all headers have been read.
                   1448:  */
                   1449: 
                   1450: enum message_read_status
                   1451: evhttp_parse_firstline(struct evhttp_request *req, struct evbuffer *buffer)
                   1452: {
                   1453:        char *line;
                   1454:        enum message_read_status status = ALL_DATA_READ;
                   1455: 
                   1456:        line = evbuffer_readline(buffer);
                   1457:        if (line == NULL)
                   1458:                return (MORE_DATA_EXPECTED);
                   1459: 
                   1460:        switch (req->kind) {
                   1461:        case EVHTTP_REQUEST:
                   1462:                if (evhttp_parse_request_line(req, line) == -1)
                   1463:                        status = DATA_CORRUPTED;
                   1464:                break;
                   1465:        case EVHTTP_RESPONSE:
                   1466:                if (evhttp_parse_response_line(req, line) == -1)
                   1467:                        status = DATA_CORRUPTED;
                   1468:                break;
                   1469:        default:
                   1470:                status = DATA_CORRUPTED;
                   1471:        }
                   1472: 
                   1473:        free(line);
                   1474:        return (status);
                   1475: }
                   1476: 
                   1477: static int
                   1478: evhttp_append_to_last_header(struct evkeyvalq *headers, const char *line)
                   1479: {
                   1480:        struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
                   1481:        char *newval;
                   1482:        size_t old_len, line_len;
                   1483: 
                   1484:        if (header == NULL)
                   1485:                return (-1);
                   1486: 
                   1487:        old_len = strlen(header->value);
                   1488:        line_len = strlen(line);
                   1489: 
                   1490:        newval = realloc(header->value, old_len + line_len + 1);
                   1491:        if (newval == NULL)
                   1492:                return (-1);
                   1493: 
                   1494:        memcpy(newval + old_len, line, line_len + 1);
                   1495:        header->value = newval;
                   1496: 
                   1497:        return (0);
                   1498: }
                   1499: 
                   1500: enum message_read_status
                   1501: evhttp_parse_headers(struct evhttp_request *req, struct evbuffer* buffer)
                   1502: {
                   1503:        char *line;
                   1504:        enum message_read_status status = MORE_DATA_EXPECTED;
                   1505: 
                   1506:        struct evkeyvalq* headers = req->input_headers;
                   1507:        while ((line = evbuffer_readline(buffer))
                   1508:               != NULL) {
                   1509:                char *skey, *svalue;
                   1510: 
                   1511:                if (*line == '\0') { /* Last header - Done */
                   1512:                        status = ALL_DATA_READ;
                   1513:                        free(line);
                   1514:                        break;
                   1515:                }
                   1516: 
                   1517:                /* Check if this is a continuation line */
                   1518:                if (*line == ' ' || *line == '\t') {
                   1519:                        if (evhttp_append_to_last_header(headers, line) == -1)
                   1520:                                goto error;
                   1521:                        free(line);
                   1522:                        continue;
                   1523:                }
                   1524: 
                   1525:                /* Processing of header lines */
                   1526:                svalue = line;
                   1527:                skey = strsep(&svalue, ":");
                   1528:                if (svalue == NULL)
                   1529:                        goto error;
                   1530: 
                   1531:                svalue += strspn(svalue, " ");
                   1532: 
                   1533:                if (evhttp_add_header(headers, skey, svalue) == -1)
                   1534:                        goto error;
                   1535: 
                   1536:                free(line);
                   1537:        }
                   1538: 
                   1539:        return (status);
                   1540: 
                   1541:  error:
                   1542:        free(line);
                   1543:        return (DATA_CORRUPTED);
                   1544: }
                   1545: 
                   1546: static int
                   1547: evhttp_get_body_length(struct evhttp_request *req)
                   1548: {
                   1549:        struct evkeyvalq *headers = req->input_headers;
                   1550:        const char *content_length;
                   1551:        const char *connection;
                   1552: 
                   1553:        content_length = evhttp_find_header(headers, "Content-Length");
                   1554:        connection = evhttp_find_header(headers, "Connection");
                   1555:                
                   1556:        if (content_length == NULL && connection == NULL)
                   1557:                req->ntoread = -1;
                   1558:        else if (content_length == NULL &&
                   1559:            strcasecmp(connection, "Close") != 0) {
                   1560:                /* Bad combination, we don't know when it will end */
                   1561:                event_warnx("%s: we got no content length, but the "
                   1562:                    "server wants to keep the connection open: %s.",
                   1563:                    __func__, connection);
                   1564:                return (-1);
                   1565:        } else if (content_length == NULL) {
                   1566:                req->ntoread = -1;
                   1567:        } else {
                   1568:                char *endp;
                   1569:                ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
                   1570:                if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
                   1571:                        event_debug(("%s: illegal content length: %s",
                   1572:                                __func__, content_length));
                   1573:                        return (-1);
                   1574:                }
                   1575:                req->ntoread = ntoread;
                   1576:        }
                   1577:                
                   1578:        event_debug(("%s: bytes to read: %lld (in buffer %ld)\n",
                   1579:                __func__, req->ntoread,
                   1580:                EVBUFFER_LENGTH(req->evcon->input_buffer)));
                   1581: 
                   1582:        return (0);
                   1583: }
                   1584: 
                   1585: static void
                   1586: evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
                   1587: {
                   1588:        const char *xfer_enc;
                   1589:        
                   1590:        /* If this is a request without a body, then we are done */
                   1591:        if (req->kind == EVHTTP_REQUEST && req->type != EVHTTP_REQ_POST) {
                   1592:                evhttp_connection_done(evcon);
                   1593:                return;
                   1594:        }
                   1595:        evcon->state = EVCON_READING_BODY;
                   1596:        xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
                   1597:        if (xfer_enc != NULL && strcasecmp(xfer_enc, "chunked") == 0) {
                   1598:                req->chunked = 1;
                   1599:                req->ntoread = -1;
                   1600:        } else {
                   1601:                if (evhttp_get_body_length(req) == -1) {
                   1602:                        evhttp_connection_fail(evcon,
                   1603:                            EVCON_HTTP_INVALID_HEADER);
                   1604:                        return;
                   1605:                }
                   1606:        }
                   1607:        evhttp_read_body(evcon, req);
                   1608: }
                   1609: 
                   1610: static void
                   1611: evhttp_read_firstline(struct evhttp_connection *evcon,
                   1612:                      struct evhttp_request *req)
                   1613: {
                   1614:        enum message_read_status res;
                   1615: 
                   1616:        res = evhttp_parse_firstline(req, evcon->input_buffer);
                   1617:        if (res == DATA_CORRUPTED) {
                   1618:                /* Error while reading, terminate */
                   1619:                event_debug(("%s: bad header lines on %d\n",
                   1620:                        __func__, evcon->fd));
                   1621:                evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
                   1622:                return;
                   1623:        } else if (res == MORE_DATA_EXPECTED) {
                   1624:                /* Need more header lines */
                   1625:                evhttp_add_event(&evcon->ev, 
                   1626:                     evcon->timeout, HTTP_READ_TIMEOUT);
                   1627:                return;
                   1628:        }
                   1629: 
                   1630:        evcon->state = EVCON_READING_HEADERS;
                   1631:        evhttp_read_header(evcon, req);
                   1632: }
                   1633: 
                   1634: static void
                   1635: evhttp_read_header(struct evhttp_connection *evcon, struct evhttp_request *req)
                   1636: {
                   1637:        enum message_read_status res;
                   1638:        int fd = evcon->fd;
                   1639: 
                   1640:        res = evhttp_parse_headers(req, evcon->input_buffer);
                   1641:        if (res == DATA_CORRUPTED) {
                   1642:                /* Error while reading, terminate */
                   1643:                event_debug(("%s: bad header lines on %d\n", __func__, fd));
                   1644:                evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
                   1645:                return;
                   1646:        } else if (res == MORE_DATA_EXPECTED) {
                   1647:                /* Need more header lines */
                   1648:                evhttp_add_event(&evcon->ev, 
                   1649:                    evcon->timeout, HTTP_READ_TIMEOUT);
                   1650:                return;
                   1651:        }
                   1652: 
                   1653:        /* Done reading headers, do the real work */
                   1654:        switch (req->kind) {
                   1655:        case EVHTTP_REQUEST:
                   1656:                event_debug(("%s: checking for post data on %d\n",
                   1657:                                __func__, fd));
                   1658:                evhttp_get_body(evcon, req);
                   1659:                break;
                   1660: 
                   1661:        case EVHTTP_RESPONSE:
                   1662:                if (req->response_code == HTTP_NOCONTENT ||
                   1663:                    req->response_code == HTTP_NOTMODIFIED ||
                   1664:                    (req->response_code >= 100 && req->response_code < 200)) {
                   1665:                        event_debug(("%s: skipping body for code %d\n",
                   1666:                                        __func__, req->response_code));
                   1667:                        evhttp_connection_done(evcon);
                   1668:                } else {
                   1669:                        event_debug(("%s: start of read body for %s on %d\n",
                   1670:                                __func__, req->remote_host, fd));
                   1671:                        evhttp_get_body(evcon, req);
                   1672:                }
                   1673:                break;
                   1674: 
                   1675:        default:
                   1676:                event_warnx("%s: bad header on %d", __func__, fd);
                   1677:                evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
                   1678:                break;
                   1679:        }
                   1680: }
                   1681: 
                   1682: /*
                   1683:  * Creates a TCP connection to the specified port and executes a callback
                   1684:  * when finished.  Failure or sucess is indicate by the passed connection
                   1685:  * object.
                   1686:  *
                   1687:  * Although this interface accepts a hostname, it is intended to take
                   1688:  * only numeric hostnames so that non-blocking DNS resolution can
                   1689:  * happen elsewhere.
                   1690:  */
                   1691: 
                   1692: struct evhttp_connection *
                   1693: evhttp_connection_new(const char *address, unsigned short port)
                   1694: {
                   1695:        struct evhttp_connection *evcon = NULL;
                   1696:        
                   1697:        event_debug(("Attempting connection to %s:%d\n", address, port));
                   1698: 
                   1699:        if ((evcon = calloc(1, sizeof(struct evhttp_connection))) == NULL) {
                   1700:                event_warn("%s: calloc failed", __func__);
                   1701:                goto error;
                   1702:        }
                   1703: 
                   1704:        evcon->fd = -1;
                   1705:        evcon->port = port;
                   1706: 
                   1707:        evcon->timeout = -1;
                   1708:        evcon->retry_cnt = evcon->retry_max = 0;
                   1709: 
                   1710:        if ((evcon->address = strdup(address)) == NULL) {
                   1711:                event_warn("%s: strdup failed", __func__);
                   1712:                goto error;
                   1713:        }
                   1714: 
                   1715:        if ((evcon->input_buffer = evbuffer_new()) == NULL) {
                   1716:                event_warn("%s: evbuffer_new failed", __func__);
                   1717:                goto error;
                   1718:        }
                   1719: 
                   1720:        if ((evcon->output_buffer = evbuffer_new()) == NULL) {
                   1721:                event_warn("%s: evbuffer_new failed", __func__);
                   1722:                goto error;
                   1723:        }
                   1724:        
                   1725:        evcon->state = EVCON_DISCONNECTED;
                   1726:        TAILQ_INIT(&evcon->requests);
                   1727: 
                   1728:        return (evcon);
                   1729:        
                   1730:  error:
                   1731:        if (evcon != NULL)
                   1732:                evhttp_connection_free(evcon);
                   1733:        return (NULL);
                   1734: }
                   1735: 
                   1736: void evhttp_connection_set_base(struct evhttp_connection *evcon,
                   1737:     struct event_base *base)
                   1738: {
                   1739:        assert(evcon->base == NULL);
                   1740:        assert(evcon->state == EVCON_DISCONNECTED);
                   1741:        evcon->base = base;
                   1742: }
                   1743: 
                   1744: void
                   1745: evhttp_connection_set_timeout(struct evhttp_connection *evcon,
                   1746:     int timeout_in_secs)
                   1747: {
                   1748:        evcon->timeout = timeout_in_secs;
                   1749: }
                   1750: 
                   1751: void
                   1752: evhttp_connection_set_retries(struct evhttp_connection *evcon,
                   1753:     int retry_max)
                   1754: {
                   1755:        evcon->retry_max = retry_max;
                   1756: }
                   1757: 
                   1758: void
                   1759: evhttp_connection_set_closecb(struct evhttp_connection *evcon,
                   1760:     void (*cb)(struct evhttp_connection *, void *), void *cbarg)
                   1761: {
                   1762:        evcon->closecb = cb;
                   1763:        evcon->closecb_arg = cbarg;
                   1764: }
                   1765: 
                   1766: void
                   1767: evhttp_connection_get_peer(struct evhttp_connection *evcon,
                   1768:     char **address, u_short *port)
                   1769: {
                   1770:        *address = evcon->address;
                   1771:        *port = evcon->port;
                   1772: }
                   1773: 
                   1774: int
                   1775: evhttp_connection_connect(struct evhttp_connection *evcon)
                   1776: {
                   1777:        if (evcon->state == EVCON_CONNECTING)
                   1778:                return (0);
                   1779:        
                   1780:        evhttp_connection_reset(evcon);
                   1781: 
                   1782:        assert(!(evcon->flags & EVHTTP_CON_INCOMING));
                   1783:        evcon->flags |= EVHTTP_CON_OUTGOING;
                   1784:        
                   1785:        evcon->fd = bind_socket(
                   1786:                evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
                   1787:        if (evcon->fd == -1) {
                   1788:                event_debug(("%s: failed to bind to \"%s\"",
                   1789:                        __func__, evcon->bind_address));
                   1790:                return (-1);
                   1791:        }
                   1792: 
                   1793:        if (socket_connect(evcon->fd, evcon->address, evcon->port) == -1) {
                   1794:                EVUTIL_CLOSESOCKET(evcon->fd); evcon->fd = -1;
                   1795:                return (-1);
                   1796:        }
                   1797: 
                   1798:        /* Set up a callback for successful connection setup */
                   1799:        event_set(&evcon->ev, evcon->fd, EV_WRITE, evhttp_connectioncb, evcon);
                   1800:        EVHTTP_BASE_SET(evcon, &evcon->ev);
                   1801:        evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_CONNECT_TIMEOUT);
                   1802: 
                   1803:        evcon->state = EVCON_CONNECTING;
                   1804:        
                   1805:        return (0);
                   1806: }
                   1807: 
                   1808: /*
                   1809:  * Starts an HTTP request on the provided evhttp_connection object.
                   1810:  * If the connection object is not connected to the web server already,
                   1811:  * this will start the connection.
                   1812:  */
                   1813: 
                   1814: int
                   1815: evhttp_make_request(struct evhttp_connection *evcon,
                   1816:     struct evhttp_request *req,
                   1817:     enum evhttp_cmd_type type, const char *uri)
                   1818: {
                   1819:        /* We are making a request */
                   1820:        req->kind = EVHTTP_REQUEST;
                   1821:        req->type = type;
                   1822:        if (req->uri != NULL)
                   1823:                free(req->uri);
                   1824:        if ((req->uri = strdup(uri)) == NULL)
                   1825:                event_err(1, "%s: strdup", __func__);
                   1826: 
                   1827:        /* Set the protocol version if it is not supplied */
                   1828:        if (!req->major && !req->minor) {
                   1829:                req->major = 1;
                   1830:                req->minor = 1;
                   1831:        }
                   1832:        
                   1833:        assert(req->evcon == NULL);
                   1834:        req->evcon = evcon;
                   1835:        assert(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
                   1836:        
                   1837:        TAILQ_INSERT_TAIL(&evcon->requests, req, next);
                   1838: 
                   1839:        /* If the connection object is not connected; make it so */
                   1840:        if (!evhttp_connected(evcon))
                   1841:                return (evhttp_connection_connect(evcon));
                   1842: 
                   1843:        /*
                   1844:         * If it's connected already and we are the first in the queue,
                   1845:         * then we can dispatch this request immediately.  Otherwise, it
                   1846:         * will be dispatched once the pending requests are completed.
                   1847:         */
                   1848:        if (TAILQ_FIRST(&evcon->requests) == req)
                   1849:                evhttp_request_dispatch(evcon);
                   1850: 
                   1851:        return (0);
                   1852: }
                   1853: 
                   1854: /*
                   1855:  * Reads data from file descriptor into request structure
                   1856:  * Request structure needs to be set up correctly.
                   1857:  */
                   1858: 
                   1859: void
                   1860: evhttp_start_read(struct evhttp_connection *evcon)
                   1861: {
                   1862:        /* Set up an event to read the headers */
                   1863:        if (event_initialized(&evcon->ev))
                   1864:                event_del(&evcon->ev);
                   1865:        event_set(&evcon->ev, evcon->fd, EV_READ, evhttp_read, evcon);
                   1866:        EVHTTP_BASE_SET(evcon, &evcon->ev);
                   1867:        
                   1868:        evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_READ_TIMEOUT);
                   1869:        evcon->state = EVCON_READING_FIRSTLINE;
                   1870: }
                   1871: 
                   1872: static void
                   1873: evhttp_send_done(struct evhttp_connection *evcon, void *arg)
                   1874: {
                   1875:        int need_close;
                   1876:        struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
                   1877:        TAILQ_REMOVE(&evcon->requests, req, next);
                   1878: 
                   1879:        /* delete possible close detection events */
                   1880:        evhttp_connection_stop_detectclose(evcon);
                   1881:        
                   1882:        need_close =
                   1883:            (req->minor == 0 &&
                   1884:                !evhttp_is_connection_keepalive(req->input_headers))||
                   1885:            evhttp_is_connection_close(req->flags, req->input_headers) ||
                   1886:            evhttp_is_connection_close(req->flags, req->output_headers);
                   1887: 
                   1888:        assert(req->flags & EVHTTP_REQ_OWN_CONNECTION);
                   1889:        evhttp_request_free(req);
                   1890: 
                   1891:        if (need_close) {
                   1892:                evhttp_connection_free(evcon);
                   1893:                return;
                   1894:        } 
                   1895: 
                   1896:        /* we have a persistent connection; try to accept another request. */
                   1897:        if (evhttp_associate_new_request_with_connection(evcon) == -1)
                   1898:                evhttp_connection_free(evcon);
                   1899: }
                   1900: 
                   1901: /*
                   1902:  * Returns an error page.
                   1903:  */
                   1904: 
                   1905: void
                   1906: evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
                   1907: {
                   1908: #define ERR_FORMAT "<HTML><HEAD>\n" \
                   1909:            "<TITLE>%d %s</TITLE>\n" \
                   1910:            "</HEAD><BODY>\n" \
                   1911:            "<H1>Method Not Implemented</H1>\n" \
                   1912:            "Invalid method in request<P>\n" \
                   1913:            "</BODY></HTML>\n"
                   1914: 
                   1915:        struct evbuffer *buf = evbuffer_new();
                   1916: 
                   1917:        /* close the connection on error */
                   1918:        evhttp_add_header(req->output_headers, "Connection", "close");
                   1919: 
                   1920:        evhttp_response_code(req, error, reason);
                   1921: 
                   1922:        evbuffer_add_printf(buf, ERR_FORMAT, error, reason);
                   1923: 
                   1924:        evhttp_send_page(req, buf);
                   1925: 
                   1926:        evbuffer_free(buf);
                   1927: #undef ERR_FORMAT
                   1928: }
                   1929: 
                   1930: /* Requires that headers and response code are already set up */
                   1931: 
                   1932: static inline void
                   1933: evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
                   1934: {
                   1935:        struct evhttp_connection *evcon = req->evcon;
                   1936: 
                   1937:        if (evcon == NULL) {
                   1938:                evhttp_request_free(req);
                   1939:                return;
                   1940:        }
                   1941: 
                   1942:        assert(TAILQ_FIRST(&evcon->requests) == req);
                   1943: 
                   1944:        /* we expect no more calls form the user on this request */
                   1945:        req->userdone = 1;
                   1946: 
                   1947:        /* xxx: not sure if we really should expose the data buffer this way */
                   1948:        if (databuf != NULL)
                   1949:                evbuffer_add_buffer(req->output_buffer, databuf);
                   1950:        
                   1951:        /* Adds headers to the response */
                   1952:        evhttp_make_header(evcon, req);
                   1953: 
                   1954:        evhttp_write_buffer(evcon, evhttp_send_done, NULL);
                   1955: }
                   1956: 
                   1957: void
                   1958: evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
                   1959:     struct evbuffer *databuf)
                   1960: {
                   1961:        evhttp_response_code(req, code, reason);
                   1962:        
                   1963:        evhttp_send(req, databuf);
                   1964: }
                   1965: 
                   1966: void
                   1967: evhttp_send_reply_start(struct evhttp_request *req, int code,
                   1968:     const char *reason)
                   1969: {
                   1970:        evhttp_response_code(req, code, reason);
                   1971:        if (req->major == 1 && req->minor == 1) {
                   1972:                /* use chunked encoding for HTTP/1.1 */
                   1973:                evhttp_add_header(req->output_headers, "Transfer-Encoding",
                   1974:                    "chunked");
                   1975:                req->chunked = 1;
                   1976:        }
                   1977:        evhttp_make_header(req->evcon, req);
                   1978:        evhttp_write_buffer(req->evcon, NULL, NULL);
                   1979: }
                   1980: 
                   1981: void
                   1982: evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
                   1983: {
                   1984:        struct evhttp_connection *evcon = req->evcon;
                   1985: 
                   1986:        if (evcon == NULL)
                   1987:                return;
                   1988: 
                   1989:        if (req->chunked) {
                   1990:                evbuffer_add_printf(evcon->output_buffer, "%x\r\n",
                   1991:                                    (unsigned)EVBUFFER_LENGTH(databuf));
                   1992:        }
                   1993:        evbuffer_add_buffer(evcon->output_buffer, databuf);
                   1994:        if (req->chunked) {
                   1995:                evbuffer_add(evcon->output_buffer, "\r\n", 2);
                   1996:        }
                   1997:        evhttp_write_buffer(evcon, NULL, NULL);
                   1998: }
                   1999: 
                   2000: void
                   2001: evhttp_send_reply_end(struct evhttp_request *req)
                   2002: {
                   2003:        struct evhttp_connection *evcon = req->evcon;
                   2004: 
                   2005:        if (evcon == NULL) {
                   2006:                evhttp_request_free(req);
                   2007:                return;
                   2008:        }
                   2009: 
                   2010:        /* we expect no more calls form the user on this request */
                   2011:        req->userdone = 1;
                   2012: 
                   2013:        if (req->chunked) {
                   2014:                evbuffer_add(req->evcon->output_buffer, "0\r\n\r\n", 5);
                   2015:                evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
                   2016:                req->chunked = 0;
                   2017:        } else if (!event_pending(&evcon->ev, EV_WRITE|EV_TIMEOUT, NULL)) {
                   2018:                /* let the connection know that we are done with the request */
                   2019:                evhttp_send_done(evcon, NULL);
                   2020:        } else {
                   2021:                /* make the callback execute after all data has been written */
                   2022:                evcon->cb = evhttp_send_done;
                   2023:                evcon->cb_arg = NULL;
                   2024:        }
                   2025: }
                   2026: 
                   2027: void
                   2028: evhttp_response_code(struct evhttp_request *req, int code, const char *reason)
                   2029: {
                   2030:        req->kind = EVHTTP_RESPONSE;
                   2031:        req->response_code = code;
                   2032:        if (req->response_code_line != NULL)
                   2033:                free(req->response_code_line);
                   2034:        req->response_code_line = strdup(reason);
                   2035: }
                   2036: 
                   2037: void
                   2038: evhttp_send_page(struct evhttp_request *req, struct evbuffer *databuf)
                   2039: {
                   2040:        if (!req->major || !req->minor) {
                   2041:                req->major = 1;
                   2042:                req->minor = 1;
                   2043:        }
                   2044:        
                   2045:        if (req->kind != EVHTTP_RESPONSE)
                   2046:                evhttp_response_code(req, 200, "OK");
                   2047: 
                   2048:        evhttp_clear_headers(req->output_headers);
                   2049:        evhttp_add_header(req->output_headers, "Content-Type", "text/html");
                   2050:        evhttp_add_header(req->output_headers, "Connection", "close");
                   2051: 
                   2052:        evhttp_send(req, databuf);
                   2053: }
                   2054: 
                   2055: static const char uri_chars[256] = {
                   2056:        0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
                   2057:        0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
                   2058:        0, 1, 0, 0, 1, 0, 0, 1,   1, 1, 1, 1, 1, 1, 1, 1,
                   2059:        1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 1, 0, 0,
                   2060:        /* 64 */
                   2061:        1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
                   2062:        1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 0, 0, 1,
                   2063:        0, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
                   2064:        1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 0, 1, 0,
                   2065:        /* 128 */
                   2066:        0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
                   2067:        0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
                   2068:        0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
                   2069:        0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
                   2070:        /* 192 */
                   2071:        0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
                   2072:        0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
                   2073:        0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
                   2074:        0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
                   2075: };
                   2076: 
                   2077: /*
                   2078:  * Helper functions to encode/decode a URI.
                   2079:  * The returned string must be freed by the caller.
                   2080:  */
                   2081: char *
                   2082: evhttp_encode_uri(const char *uri)
                   2083: {
                   2084:        struct evbuffer *buf = evbuffer_new();
                   2085:        char *p;
                   2086: 
                   2087:        for (p = (char *)uri; *p != '\0'; p++) {
                   2088:                if (uri_chars[(u_char)(*p)]) {
                   2089:                        evbuffer_add(buf, p, 1);
                   2090:                } else {
                   2091:                        evbuffer_add_printf(buf, "%%%02X", (u_char)(*p));
                   2092:                }
                   2093:        }
                   2094:        evbuffer_add(buf, "", 1);
                   2095:        p = strdup((char *)EVBUFFER_DATA(buf));
                   2096:        evbuffer_free(buf);
                   2097:        
                   2098:        return (p);
                   2099: }
                   2100: 
                   2101: /*
                   2102:  * @param always_decode_plus: when true we transform plus to space even
                   2103:  *     if we have not seen a ?.
                   2104:  */
                   2105: static int
                   2106: evhttp_decode_uri_internal(
                   2107:        const char *uri, size_t length, char *ret, int always_decode_plus)
                   2108: {
                   2109:        char c;
                   2110:        int i, j, in_query = always_decode_plus;
                   2111:        
                   2112:        for (i = j = 0; uri[i] != '\0'; i++) {
                   2113:                c = uri[i];
                   2114:                if (c == '?') {
                   2115:                        in_query = 1;
                   2116:                } else if (c == '+' && in_query) {
                   2117:                        c = ' ';
                   2118:                } else if (c == '%' && isxdigit((unsigned char)uri[i+1]) &&
                   2119:                    isxdigit((unsigned char)uri[i+2])) {
                   2120:                        char tmp[] = { uri[i+1], uri[i+2], '\0' };
                   2121:                        c = (char)strtol(tmp, NULL, 16);
                   2122:                        i += 2;
                   2123:                }
                   2124:                ret[j++] = c;
                   2125:        }
                   2126:        ret[j] = '\0';
                   2127: 
                   2128:        return (j);
                   2129: }
                   2130: 
                   2131: char *
                   2132: evhttp_decode_uri(const char *uri)
                   2133: {
                   2134:        char *ret;
                   2135: 
                   2136:        if ((ret = malloc(strlen(uri) + 1)) == NULL)
                   2137:                event_err(1, "%s: malloc(%lu)", __func__,
                   2138:                          (unsigned long)(strlen(uri) + 1));
                   2139: 
                   2140:        evhttp_decode_uri_internal(uri, strlen(uri),
                   2141:            ret, 0 /*always_decode_plus*/);
                   2142: 
                   2143:        return (ret);
                   2144: }
                   2145: 
                   2146: /* 
                   2147:  * Helper function to parse out arguments in a query.
                   2148:  * The arguments are separated by key and value.
                   2149:  */
                   2150: 
                   2151: void
                   2152: evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
                   2153: {
                   2154:        char *line;
                   2155:        char *argument;
                   2156:        char *p;
                   2157: 
                   2158:        TAILQ_INIT(headers);
                   2159: 
                   2160:        /* No arguments - we are done */
                   2161:        if (strchr(uri, '?') == NULL)
                   2162:                return;
                   2163: 
                   2164:        if ((line = strdup(uri)) == NULL)
                   2165:                event_err(1, "%s: strdup", __func__);
                   2166: 
                   2167: 
                   2168:        argument = line;
                   2169: 
                   2170:        /* We already know that there has to be a ? */
                   2171:        strsep(&argument, "?");
                   2172: 
                   2173:        p = argument;
                   2174:        while (p != NULL && *p != '\0') {
                   2175:                char *key, *value, *decoded_value;
                   2176:                argument = strsep(&p, "&");
                   2177: 
                   2178:                value = argument;
                   2179:                key = strsep(&value, "=");
                   2180:                if (value == NULL)
                   2181:                        goto error;
                   2182: 
                   2183:                if ((decoded_value = malloc(strlen(value) + 1)) == NULL)
                   2184:                        event_err(1, "%s: malloc", __func__);
                   2185: 
                   2186:                evhttp_decode_uri_internal(value, strlen(value),
                   2187:                    decoded_value, 1 /*always_decode_plus*/);
                   2188:                event_debug(("Query Param: %s -> %s\n", key, decoded_value));
                   2189:                evhttp_add_header_internal(headers, key, decoded_value);
                   2190:                free(decoded_value);
                   2191:        }
                   2192: 
                   2193:  error:
                   2194:        free(line);
                   2195: }
                   2196: 
                   2197: static struct evhttp_cb *
                   2198: evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
                   2199: {
                   2200:        struct evhttp_cb *cb;
                   2201:        size_t offset = 0;
                   2202: 
                   2203:        /* Test for different URLs */
                   2204:        char *p = strchr(req->uri, '?');
                   2205:        if (p != NULL)
                   2206:                offset = (size_t)(p - req->uri);
                   2207: 
                   2208:        TAILQ_FOREACH(cb, callbacks, next) {
                   2209:                int res = 0;
                   2210:                if (p == NULL) {
                   2211:                        res = strcmp(cb->what, req->uri) == 0;
                   2212:                } else {
                   2213:                        res = ((strncmp(cb->what, req->uri, offset) == 0) &&
                   2214:                                        (cb->what[offset] == '\0'));
                   2215:                }
                   2216: 
                   2217:                if (res)
                   2218:                        return (cb);
                   2219:        }
                   2220: 
                   2221:        return (NULL);
                   2222: }
                   2223: 
                   2224: static void
                   2225: evhttp_handle_request(struct evhttp_request *req, void *arg)
                   2226: {
                   2227:        struct evhttp *http = arg;
                   2228:        struct evhttp_cb *cb = NULL;
                   2229: 
                   2230:        event_debug(("%s: req->uri=%s", __func__, req->uri));
                   2231:        if (req->uri == NULL) {
                   2232:                event_debug(("%s: bad request", __func__));
                   2233:                if (req->evcon->state == EVCON_DISCONNECTED) {
                   2234:                        evhttp_connection_fail(req->evcon, EVCON_HTTP_EOF);
                   2235:                } else {
                   2236:                        event_debug(("%s: sending error", __func__));
                   2237:                        evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
                   2238:                }
                   2239:                return;
                   2240:        }
                   2241: 
                   2242:        if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
                   2243:                (*cb->cb)(req, cb->cbarg);
                   2244:                return;
                   2245:        }
                   2246: 
                   2247:        /* Generic call back */
                   2248:        if (http->gencb) {
                   2249:                (*http->gencb)(req, http->gencbarg);
                   2250:                return;
                   2251:        } else {
                   2252:                /* We need to send a 404 here */
                   2253: #define ERR_FORMAT "<html><head>" \
                   2254:                    "<title>404 Not Found</title>" \
                   2255:                    "</head><body>" \
                   2256:                    "<h1>Not Found</h1>" \
                   2257:                    "<p>The requested URL %s was not found on this server.</p>"\
                   2258:                    "</body></html>\n"
                   2259: 
                   2260:                char *escaped_html = evhttp_htmlescape(req->uri);
                   2261:                struct evbuffer *buf = evbuffer_new();
                   2262: 
                   2263:                evhttp_response_code(req, HTTP_NOTFOUND, "Not Found");
                   2264: 
                   2265:                evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
                   2266: 
                   2267:                free(escaped_html);
                   2268: 
                   2269:                evhttp_send_page(req, buf);
                   2270: 
                   2271:                evbuffer_free(buf);
                   2272: #undef ERR_FORMAT
                   2273:        }
                   2274: }
                   2275: 
                   2276: static void
                   2277: accept_socket(int fd, short what, void *arg)
                   2278: {
                   2279:        struct evhttp *http = arg;
                   2280:        struct sockaddr_storage ss;
                   2281:        socklen_t addrlen = sizeof(ss);
                   2282:        int nfd;
                   2283: 
                   2284:        if ((nfd = accept(fd, (struct sockaddr *)&ss, &addrlen)) == -1) {
                   2285:                if (errno != EAGAIN && errno != EINTR)
                   2286:                        event_warn("%s: bad accept", __func__);
                   2287:                return;
                   2288:        }
                   2289:        if (evutil_make_socket_nonblocking(nfd) < 0)
                   2290:                return;
                   2291: 
                   2292:        evhttp_get_request(http, nfd, (struct sockaddr *)&ss, addrlen);
                   2293: }
                   2294: 
                   2295: int
                   2296: evhttp_bind_socket(struct evhttp *http, const char *address, u_short port)
                   2297: {
                   2298:        int fd;
                   2299:        int res;
                   2300: 
                   2301:        if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
                   2302:                return (-1);
                   2303: 
                   2304:        if (listen(fd, 128) == -1) {
                   2305:                event_warn("%s: listen", __func__);
                   2306:                EVUTIL_CLOSESOCKET(fd);
                   2307:                return (-1);
                   2308:        }
                   2309: 
                   2310:        res = evhttp_accept_socket(http, fd);
                   2311:        
                   2312:        if (res != -1)
                   2313:                event_debug(("Bound to port %d - Awaiting connections ... ",
                   2314:                        port));
                   2315: 
                   2316:        return (res);
                   2317: }
                   2318: 
                   2319: int
                   2320: evhttp_accept_socket(struct evhttp *http, int fd)
                   2321: {
                   2322:        struct evhttp_bound_socket *bound;
                   2323:        struct event *ev;
                   2324:        int res;
                   2325: 
                   2326:        bound = malloc(sizeof(struct evhttp_bound_socket));
                   2327:        if (bound == NULL)
                   2328:                return (-1);
                   2329: 
                   2330:        ev = &bound->bind_ev;
                   2331: 
                   2332:        /* Schedule the socket for accepting */
                   2333:        event_set(ev, fd, EV_READ | EV_PERSIST, accept_socket, http);
                   2334:        EVHTTP_BASE_SET(http, ev);
                   2335: 
                   2336:        res = event_add(ev, NULL);
                   2337: 
                   2338:        if (res == -1) {
                   2339:                free(bound);
                   2340:                return (-1);
                   2341:        }
                   2342: 
                   2343:        TAILQ_INSERT_TAIL(&http->sockets, bound, next);
                   2344: 
                   2345:        return (0);
                   2346: }
                   2347: 
                   2348: static struct evhttp*
                   2349: evhttp_new_object(void)
                   2350: {
                   2351:        struct evhttp *http = NULL;
                   2352: 
                   2353:        if ((http = calloc(1, sizeof(struct evhttp))) == NULL) {
                   2354:                event_warn("%s: calloc", __func__);
                   2355:                return (NULL);
                   2356:        }
                   2357: 
                   2358:        http->timeout = -1;
                   2359: 
                   2360:        TAILQ_INIT(&http->sockets);
                   2361:        TAILQ_INIT(&http->callbacks);
                   2362:        TAILQ_INIT(&http->connections);
                   2363: 
                   2364:        return (http);
                   2365: }
                   2366: 
                   2367: struct evhttp *
                   2368: evhttp_new(struct event_base *base)
                   2369: {
                   2370:        struct evhttp *http = evhttp_new_object();
                   2371: 
                   2372:        http->base = base;
                   2373: 
                   2374:        return (http);
                   2375: }
                   2376: 
                   2377: /*
                   2378:  * Start a web server on the specified address and port.
                   2379:  */
                   2380: 
                   2381: struct evhttp *
                   2382: evhttp_start(const char *address, u_short port)
                   2383: {
                   2384:        struct evhttp *http = evhttp_new_object();
                   2385: 
                   2386:        if (evhttp_bind_socket(http, address, port) == -1) {
                   2387:                free(http);
                   2388:                return (NULL);
                   2389:        }
                   2390: 
                   2391:        return (http);
                   2392: }
                   2393: 
                   2394: void
                   2395: evhttp_free(struct evhttp* http)
                   2396: {
                   2397:        struct evhttp_cb *http_cb;
                   2398:        struct evhttp_connection *evcon;
                   2399:        struct evhttp_bound_socket *bound;
                   2400:        int fd;
                   2401: 
                   2402:        /* Remove the accepting part */
                   2403:        while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
                   2404:                TAILQ_REMOVE(&http->sockets, bound, next);
                   2405: 
                   2406:                fd = bound->bind_ev.ev_fd;
                   2407:                event_del(&bound->bind_ev);
                   2408:                EVUTIL_CLOSESOCKET(fd);
                   2409: 
                   2410:                free(bound);
                   2411:        }
                   2412: 
                   2413:        while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
                   2414:                /* evhttp_connection_free removes the connection */
                   2415:                evhttp_connection_free(evcon);
                   2416:        }
                   2417: 
                   2418:        while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
                   2419:                TAILQ_REMOVE(&http->callbacks, http_cb, next);
                   2420:                free(http_cb->what);
                   2421:                free(http_cb);
                   2422:        }
                   2423:        
                   2424:        free(http);
                   2425: }
                   2426: 
                   2427: void
                   2428: evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
                   2429: {
                   2430:        http->timeout = timeout_in_secs;
                   2431: }
                   2432: 
                   2433: void
                   2434: evhttp_set_cb(struct evhttp *http, const char *uri,
                   2435:     void (*cb)(struct evhttp_request *, void *), void *cbarg)
                   2436: {
                   2437:        struct evhttp_cb *http_cb;
                   2438: 
                   2439:        if ((http_cb = calloc(1, sizeof(struct evhttp_cb))) == NULL)
                   2440:                event_err(1, "%s: calloc", __func__);
                   2441: 
                   2442:        http_cb->what = strdup(uri);
                   2443:        http_cb->cb = cb;
                   2444:        http_cb->cbarg = cbarg;
                   2445: 
                   2446:        TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
                   2447: }
                   2448: 
                   2449: int
                   2450: evhttp_del_cb(struct evhttp *http, const char *uri)
                   2451: {
                   2452:        struct evhttp_cb *http_cb;
                   2453: 
                   2454:        TAILQ_FOREACH(http_cb, &http->callbacks, next) {
                   2455:                if (strcmp(http_cb->what, uri) == 0)
                   2456:                        break;
                   2457:        }
                   2458:        if (http_cb == NULL)
                   2459:                return (-1);
                   2460: 
                   2461:        TAILQ_REMOVE(&http->callbacks, http_cb, next);
                   2462:        free(http_cb->what);
                   2463:        free(http_cb);
                   2464: 
                   2465:        return (0);
                   2466: }
                   2467: 
                   2468: void
                   2469: evhttp_set_gencb(struct evhttp *http,
                   2470:     void (*cb)(struct evhttp_request *, void *), void *cbarg)
                   2471: {
                   2472:        http->gencb = cb;
                   2473:        http->gencbarg = cbarg;
                   2474: }
                   2475: 
                   2476: /*
                   2477:  * Request related functions
                   2478:  */
                   2479: 
                   2480: struct evhttp_request *
                   2481: evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
                   2482: {
                   2483:        struct evhttp_request *req = NULL;
                   2484: 
                   2485:        /* Allocate request structure */
                   2486:        if ((req = calloc(1, sizeof(struct evhttp_request))) == NULL) {
                   2487:                event_warn("%s: calloc", __func__);
                   2488:                goto error;
                   2489:        }
                   2490: 
                   2491:        req->kind = EVHTTP_RESPONSE;
                   2492:        req->input_headers = calloc(1, sizeof(struct evkeyvalq));
                   2493:        if (req->input_headers == NULL) {
                   2494:                event_warn("%s: calloc", __func__);
                   2495:                goto error;
                   2496:        }
                   2497:        TAILQ_INIT(req->input_headers);
                   2498: 
                   2499:        req->output_headers = calloc(1, sizeof(struct evkeyvalq));
                   2500:        if (req->output_headers == NULL) {
                   2501:                event_warn("%s: calloc", __func__);
                   2502:                goto error;
                   2503:        }
                   2504:        TAILQ_INIT(req->output_headers);
                   2505: 
                   2506:        if ((req->input_buffer = evbuffer_new()) == NULL) {
                   2507:                event_warn("%s: evbuffer_new", __func__);
                   2508:                goto error;
                   2509:        }
                   2510: 
                   2511:        if ((req->output_buffer = evbuffer_new()) == NULL) {
                   2512:                event_warn("%s: evbuffer_new", __func__);
                   2513:                goto error;
                   2514:        }
                   2515: 
                   2516:        req->cb = cb;
                   2517:        req->cb_arg = arg;
                   2518: 
                   2519:        return (req);
                   2520: 
                   2521:  error:
                   2522:        if (req != NULL)
                   2523:                evhttp_request_free(req);
                   2524:        return (NULL);
                   2525: }
                   2526: 
                   2527: void
                   2528: evhttp_request_free(struct evhttp_request *req)
                   2529: {
                   2530:        if (req->remote_host != NULL)
                   2531:                free(req->remote_host);
                   2532:        if (req->uri != NULL)
                   2533:                free(req->uri);
                   2534:        if (req->response_code_line != NULL)
                   2535:                free(req->response_code_line);
                   2536: 
                   2537:        evhttp_clear_headers(req->input_headers);
                   2538:        free(req->input_headers);
                   2539: 
                   2540:        evhttp_clear_headers(req->output_headers);
                   2541:        free(req->output_headers);
                   2542: 
                   2543:        if (req->input_buffer != NULL)
                   2544:                evbuffer_free(req->input_buffer);
                   2545: 
                   2546:        if (req->output_buffer != NULL)
                   2547:                evbuffer_free(req->output_buffer);
                   2548: 
                   2549:        free(req);
                   2550: }
                   2551: 
                   2552: struct evhttp_connection *
                   2553: evhttp_request_get_connection(struct evhttp_request *req)
                   2554: {
                   2555:        return req->evcon;
                   2556: }
                   2557: 
                   2558: 
                   2559: void
                   2560: evhttp_request_set_chunked_cb(struct evhttp_request *req,
                   2561:     void (*cb)(struct evhttp_request *, void *))
                   2562: {
                   2563:        req->chunk_cb = cb;
                   2564: }
                   2565: 
                   2566: /*
                   2567:  * Allows for inspection of the request URI
                   2568:  */
                   2569: 
                   2570: const char *
                   2571: evhttp_request_uri(struct evhttp_request *req) {
                   2572:        if (req->uri == NULL)
                   2573:                event_debug(("%s: request %p has no uri\n", __func__, req));
                   2574:        return (req->uri);
                   2575: }
                   2576: 
                   2577: /*
                   2578:  * Takes a file descriptor to read a request from.
                   2579:  * The callback is executed once the whole request has been read.
                   2580:  */
                   2581: 
                   2582: static struct evhttp_connection*
                   2583: evhttp_get_request_connection(
                   2584:        struct evhttp* http,
                   2585:        int fd, struct sockaddr *sa, socklen_t salen)
                   2586: {
                   2587:        struct evhttp_connection *evcon;
                   2588:        char *hostname = NULL, *portname = NULL;
                   2589: 
                   2590:        name_from_addr(sa, salen, &hostname, &portname);
                   2591:        if (hostname == NULL || portname == NULL) {
                   2592:                if (hostname) free(hostname);
                   2593:                if (portname) free(portname);
                   2594:                return (NULL);
                   2595:        }
                   2596: 
                   2597:        event_debug(("%s: new request from %s:%s on %d\n",
                   2598:                        __func__, hostname, portname, fd));
                   2599: 
                   2600:        /* we need a connection object to put the http request on */
                   2601:        evcon = evhttp_connection_new(hostname, atoi(portname));
                   2602:        free(hostname);
                   2603:        free(portname);
                   2604:        if (evcon == NULL)
                   2605:                return (NULL);
                   2606: 
                   2607:        /* associate the base if we have one*/
                   2608:        evhttp_connection_set_base(evcon, http->base);
                   2609: 
                   2610:        evcon->flags |= EVHTTP_CON_INCOMING;
                   2611:        evcon->state = EVCON_READING_FIRSTLINE;
                   2612:        
                   2613:        evcon->fd = fd;
                   2614: 
                   2615:        return (evcon);
                   2616: }
                   2617: 
                   2618: static int
                   2619: evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
                   2620: {
                   2621:        struct evhttp *http = evcon->http_server;
                   2622:        struct evhttp_request *req;
                   2623:        if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
                   2624:                return (-1);
                   2625: 
                   2626:        req->evcon = evcon;     /* the request ends up owning the connection */
                   2627:        req->flags |= EVHTTP_REQ_OWN_CONNECTION;
                   2628:        
                   2629:        TAILQ_INSERT_TAIL(&evcon->requests, req, next);
                   2630:        
                   2631:        req->kind = EVHTTP_REQUEST;
                   2632:        
                   2633:        if ((req->remote_host = strdup(evcon->address)) == NULL)
                   2634:                event_err(1, "%s: strdup", __func__);
                   2635:        req->remote_port = evcon->port;
                   2636: 
                   2637:        evhttp_start_read(evcon);
                   2638:        
                   2639:        return (0);
                   2640: }
                   2641: 
                   2642: void
                   2643: evhttp_get_request(struct evhttp *http, int fd,
                   2644:     struct sockaddr *sa, socklen_t salen)
                   2645: {
                   2646:        struct evhttp_connection *evcon;
                   2647: 
                   2648:        evcon = evhttp_get_request_connection(http, fd, sa, salen);
                   2649:        if (evcon == NULL)
                   2650:                return;
                   2651: 
                   2652:        /* the timeout can be used by the server to close idle connections */
                   2653:        if (http->timeout != -1)
                   2654:                evhttp_connection_set_timeout(evcon, http->timeout);
                   2655: 
                   2656:        /* 
                   2657:         * if we want to accept more than one request on a connection,
                   2658:         * we need to know which http server it belongs to.
                   2659:         */
                   2660:        evcon->http_server = http;
                   2661:        TAILQ_INSERT_TAIL(&http->connections, evcon, next);
                   2662:        
                   2663:        if (evhttp_associate_new_request_with_connection(evcon) == -1)
                   2664:                evhttp_connection_free(evcon);
                   2665: }
                   2666: 
                   2667: 
                   2668: /*
                   2669:  * Network helper functions that we do not want to export to the rest of
                   2670:  * the world.
                   2671:  */
                   2672: #if 0 /* Unused */
                   2673: static struct addrinfo *
                   2674: addr_from_name(char *address)
                   2675: {
                   2676: #ifdef HAVE_GETADDRINFO
                   2677:         struct addrinfo ai, *aitop;
                   2678:         int ai_result;
                   2679: 
                   2680:         memset(&ai, 0, sizeof(ai));
                   2681:         ai.ai_family = AF_INET;
                   2682:         ai.ai_socktype = SOCK_RAW;
                   2683:         ai.ai_flags = 0;
                   2684:         if ((ai_result = getaddrinfo(address, NULL, &ai, &aitop)) != 0) {
                   2685:                 if ( ai_result == EAI_SYSTEM )
                   2686:                         event_warn("getaddrinfo");
                   2687:                 else
                   2688:                         event_warnx("getaddrinfo: %s", gai_strerror(ai_result));
                   2689:         }
                   2690: 
                   2691:        return (aitop);
                   2692: #else
                   2693:        assert(0);
                   2694:        return NULL; /* XXXXX Use gethostbyname, if this function is ever used. */
                   2695: #endif
                   2696: }
                   2697: #endif
                   2698: 
                   2699: static void
                   2700: name_from_addr(struct sockaddr *sa, socklen_t salen,
                   2701:     char **phost, char **pport)
                   2702: {
                   2703:        char ntop[NI_MAXHOST];
                   2704:        char strport[NI_MAXSERV];
                   2705:        int ni_result;
                   2706: 
                   2707: #ifdef HAVE_GETNAMEINFO
                   2708:        ni_result = getnameinfo(sa, salen,
                   2709:                ntop, sizeof(ntop), strport, sizeof(strport),
                   2710:                NI_NUMERICHOST|NI_NUMERICSERV);
                   2711:        
                   2712:        if (ni_result != 0) {
                   2713:                if (ni_result == EAI_SYSTEM)
                   2714:                        event_err(1, "getnameinfo failed");
                   2715:                else
                   2716:                        event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
                   2717:                return;
                   2718:        }
                   2719: #else
                   2720:        ni_result = fake_getnameinfo(sa, salen,
                   2721:                ntop, sizeof(ntop), strport, sizeof(strport),
                   2722:                NI_NUMERICHOST|NI_NUMERICSERV);
                   2723:        if (ni_result != 0)
                   2724:                        return;
                   2725: #endif
                   2726:        *phost = strdup(ntop);
                   2727:        *pport = strdup(strport);
                   2728: }
                   2729: 
                   2730: /* Create a non-blocking socket and bind it */
                   2731: /* todo: rename this function */
                   2732: static int
                   2733: bind_socket_ai(struct addrinfo *ai, int reuse)
                   2734: {
                   2735:         int fd, on = 1, r;
                   2736:        int serrno;
                   2737: 
                   2738:         /* Create listen socket */
                   2739:         fd = socket(AF_INET, SOCK_STREAM, 0);
                   2740:         if (fd == -1) {
                   2741:                 event_warn("socket");
                   2742:                 return (-1);
                   2743:         }
                   2744: 
                   2745:         if (evutil_make_socket_nonblocking(fd) < 0)
                   2746:                 goto out;
                   2747: 
                   2748: #ifndef WIN32
                   2749:         if (fcntl(fd, F_SETFD, 1) == -1) {
                   2750:                 event_warn("fcntl(F_SETFD)");
                   2751:                 goto out;
                   2752:         }
                   2753: #endif
                   2754: 
                   2755:         setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
                   2756:        if (reuse) {
                   2757:                setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
                   2758:                    (void *)&on, sizeof(on));
                   2759:        }
                   2760: 
                   2761:        if (ai != NULL) {
                   2762:                r = bind(fd, ai->ai_addr, ai->ai_addrlen);
                   2763:                if (r == -1)
                   2764:                        goto out;
                   2765:        }
                   2766: 
                   2767:        return (fd);
                   2768: 
                   2769:  out:
                   2770:        serrno = EVUTIL_SOCKET_ERROR();
                   2771:        EVUTIL_CLOSESOCKET(fd);
                   2772:        EVUTIL_SET_SOCKET_ERROR(serrno);
                   2773:        return (-1);
                   2774: }
                   2775: 
                   2776: static struct addrinfo *
                   2777: make_addrinfo(const char *address, u_short port)
                   2778: {
                   2779:         struct addrinfo *aitop = NULL;
                   2780: 
                   2781: #ifdef HAVE_GETADDRINFO
                   2782:         struct addrinfo ai;
                   2783:         char strport[NI_MAXSERV];
                   2784:         int ai_result;
                   2785: 
                   2786:         memset(&ai, 0, sizeof(ai));
                   2787:         ai.ai_family = AF_INET;
                   2788:         ai.ai_socktype = SOCK_STREAM;
                   2789:         ai.ai_flags = AI_PASSIVE;  /* turn NULL host name into INADDR_ANY */
                   2790:         evutil_snprintf(strport, sizeof(strport), "%d", port);
                   2791:         if ((ai_result = getaddrinfo(address, strport, &ai, &aitop)) != 0) {
                   2792:                 if ( ai_result == EAI_SYSTEM )
                   2793:                         event_warn("getaddrinfo");
                   2794:                 else
                   2795:                         event_warnx("getaddrinfo: %s", gai_strerror(ai_result));
                   2796:                return (NULL);
                   2797:         }
                   2798: #else
                   2799:        static int cur;
                   2800:        static struct addrinfo ai[2]; /* We will be returning the address of some of this memory so it has to last even after this call. */
                   2801:        if (++cur == 2) cur = 0;   /* allow calling this function twice */
                   2802: 
                   2803:        if (fake_getaddrinfo(address, &ai[cur]) < 0) {
                   2804:                event_warn("fake_getaddrinfo");
                   2805:                return (NULL);
                   2806:        }
                   2807:        aitop = &ai[cur];
                   2808:        ((struct sockaddr_in *) aitop->ai_addr)->sin_port = htons(port);
                   2809: #endif
                   2810: 
                   2811:        return (aitop);
                   2812: }
                   2813: 
                   2814: static int
                   2815: bind_socket(const char *address, u_short port, int reuse)
                   2816: {
                   2817:        int fd;
                   2818:        struct addrinfo *aitop = NULL;
                   2819: 
                   2820:        /* just create an unbound socket */
                   2821:        if (address == NULL && port == 0)
                   2822:                return bind_socket_ai(NULL, 0);
                   2823:                
                   2824:        aitop = make_addrinfo(address, port);
                   2825: 
                   2826:        if (aitop == NULL)
                   2827:                return (-1);
                   2828: 
                   2829:        fd = bind_socket_ai(aitop, reuse);
                   2830: 
                   2831: #ifdef HAVE_GETADDRINFO
                   2832:        freeaddrinfo(aitop);
                   2833: #else
                   2834:        fake_freeaddrinfo(aitop);
                   2835: #endif
                   2836: 
                   2837:        return (fd);
                   2838: }
                   2839: 
                   2840: static int
                   2841: socket_connect(int fd, const char *address, unsigned short port)
                   2842: {
                   2843:        struct addrinfo *ai = make_addrinfo(address, port);
                   2844:        int res = -1;
                   2845: 
                   2846:        if (ai == NULL) {
                   2847:                event_debug(("%s: make_addrinfo: \"%s:%d\"",
                   2848:                        __func__, address, port));
                   2849:                return (-1);
                   2850:        }
                   2851: 
                   2852:        if (connect(fd, ai->ai_addr, ai->ai_addrlen) == -1) {
                   2853: #ifdef WIN32
                   2854:                int tmp_error = WSAGetLastError();
                   2855:                if (tmp_error != WSAEWOULDBLOCK && tmp_error != WSAEINVAL &&
                   2856:                    tmp_error != WSAEINPROGRESS) {
                   2857:                        goto out;
                   2858:                }
                   2859: #else
                   2860:                if (errno != EINPROGRESS) {
                   2861:                        goto out;
                   2862:                }
                   2863: #endif
                   2864:        }
                   2865: 
                   2866:        /* everything is fine */
                   2867:        res = 0;
                   2868: 
                   2869: out:
                   2870: #ifdef HAVE_GETADDRINFO
                   2871:        freeaddrinfo(ai);
                   2872: #else
                   2873:        fake_freeaddrinfo(ai);
                   2874: #endif
                   2875: 
                   2876:        return (res);
                   2877: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>