1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Copyright (c) 2003-2006 Niels Provos <provos@citi.umich.edu> 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * All rights reserved. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Redistribution and use in source and binary forms, with or without 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * modification, are permitted provided that the following conditions 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * are met: 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 1. Redistributions of source code must retain the above copyright 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * notice, this list of conditions and the following disclaimer. 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 2. Redistributions in binary form must reproduce the above copyright 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * notice, this list of conditions and the following disclaimer in the 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * documentation and/or other materials provided with the distribution. 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 3. The name of the author may not be used to endorse or promote products 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * derived from this software without specific prior written permission. 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef WIN32 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <winsock2.h> 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <windows.h> 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef HAVE_CONFIG_H 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "config.h" 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/types.h> 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/stat.h> 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef HAVE_SYS_TIME_H 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/time.h> 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/queue.h> 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef WIN32 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/socket.h> 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <signal.h> 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <unistd.h> 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <netdb.h> 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <fcntl.h> 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdlib.h> 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdio.h> 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string.h> 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <errno.h> 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "event.h" 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "evhttp.h" 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "log.h" 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "http-internal.h" 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottextern int pair[]; 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottextern int test_ok; 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct evhttp *http; 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* set if a test needs to call loopexit on a base */ 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct event_base *base; 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid http_suite(void); 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid http_basic_cb(struct evhttp_request *req, void *arg); 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void http_chunked_cb(struct evhttp_request *req, void *arg); 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid http_post_cb(struct evhttp_request *req, void *arg); 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid http_dispatcher_cb(struct evhttp_request *req, void *arg); 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void http_large_delay_cb(struct evhttp_request *req, void *arg); 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct evhttp * 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_setup(short *pport, struct event_base *base) 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int i; 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp *myhttp; 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott short port = -1; 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Try a few different ports */ 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott myhttp = evhttp_new(base); 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (i = 0; i < 50; ++i) { 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_bind_socket(myhttp, "127.0.0.1", 8080 + i) != -1) { 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott port = 8080 + i; 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (port == -1) 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_errx(1, "Could not start web server"); 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Register a callback for certain types of requests */ 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_set_cb(myhttp, "/test", http_basic_cb, NULL); 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_set_cb(myhttp, "/chunked", http_chunked_cb, NULL); 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_set_cb(myhttp, "/postit", http_post_cb, NULL); 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_set_cb(myhttp, "/largedelay", http_large_delay_cb, NULL); 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_set_cb(myhttp, "/", http_dispatcher_cb, NULL); 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *pport = port; 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (myhttp); 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NI_MAXSERV 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NI_MAXSERV 1024 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_connect(const char *address, u_short port) 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Stupid code for connecting */ 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef WIN32 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct hostent *he; 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct sockaddr_in sin; 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct addrinfo ai, *aitop; 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char strport[NI_MAXSERV]; 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct sockaddr *sa; 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int slen; 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd; 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef WIN32 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!(he = gethostbyname(address))) { 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_warn("gethostbyname"); 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(&sin.sin_addr, he->h_addr_list[0], he->h_length); 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sin.sin_family = AF_INET; 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sin.sin_port = htons(port); 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott slen = sizeof(struct sockaddr_in); 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sa = (struct sockaddr*)&sin; 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(&ai, 0, sizeof (ai)); 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ai.ai_family = AF_INET; 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ai.ai_socktype = SOCK_STREAM; 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott snprintf(strport, sizeof (strport), "%d", port); 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (getaddrinfo(address, strport, &ai, &aitop) != 0) { 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_warn("getaddrinfo"); 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (-1); 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sa = aitop->ai_addr; 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott slen = aitop->ai_addrlen; 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fd = socket(AF_INET, SOCK_STREAM, 0); 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (fd == -1) 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_err(1, "socket failed"); 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (connect(fd, sa, slen) == -1) 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_err(1, "connect failed"); 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef WIN32 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott freeaddrinfo(aitop); 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (fd); 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_readcb(struct bufferevent *bev, void *arg) 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *what = "This is funny"; 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_debug(("%s: %s\n", __func__, EVBUFFER_DATA(bev->input))); 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evbuffer_find(bev->input, 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (const unsigned char*) what, strlen(what)) != NULL) { 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_request *req = evhttp_request_new(NULL, NULL); 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum message_read_status done; 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req->kind = EVHTTP_RESPONSE; 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott done = evhttp_parse_firstline(req, bev->input); 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (done != ALL_DATA_READ) 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott done = evhttp_parse_headers(req, bev->input); 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (done != ALL_DATA_READ) 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (done == 1 && 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_find_header(req->input_headers, 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Content-Type") != NULL) 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok++; 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott out: 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_request_free(req); 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_disable(bev, EV_READ); 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (base) 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_base_loopexit(base, NULL); 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_loopexit(NULL); 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_writecb(struct bufferevent *bev, void *arg) 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (EVBUFFER_LENGTH(bev->output) == 0) { 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* enable reading of the reply */ 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_enable(bev, EV_READ); 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok++; 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_errorcb(struct bufferevent *bev, short what, void *arg) 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = -2; 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_loopexit(NULL); 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_basic_cb(struct evhttp_request *req, void *arg) 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evbuffer *evb = evbuffer_new(); 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int empty = evhttp_find_header(req->input_headers, "Empty") != NULL; 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_debug(("%s: called\n", __func__)); 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evbuffer_add_printf(evb, "This is funny"); 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* For multi-line headers test */ 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *multi = 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_find_header(req->input_headers,"X-multi"); 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (multi) { 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (strcmp("END", multi + strlen(multi) - 3) == 0) 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok++; 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_find_header(req->input_headers, "X-Last")) 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok++; 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* injecting a bad content-length */ 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_find_header(req->input_headers, "X-Negative")) 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_add_header(req->output_headers, 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Content-Length", "-100"); 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* allow sending of an empty reply */ 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_send_reply(req, HTTP_OK, "Everything is fine", 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !empty ? evb : NULL); 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evbuffer_free(evb); 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic char const* const CHUNKS[] = { 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "This is funny", 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "but not hilarious.", 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "bwv 1052" 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct chunk_req_state { 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_request *req; 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int i; 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_chunked_trickle_cb(int fd, short events, void *arg) 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evbuffer *evb = evbuffer_new(); 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct chunk_req_state *state = arg; 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct timeval when = { 0, 0 }; 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evbuffer_add_printf(evb, "%s", CHUNKS[state->i]); 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_send_reply_chunk(state->req, evb); 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evbuffer_free(evb); 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (++state->i < sizeof(CHUNKS)/sizeof(CHUNKS[0])) { 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_once(-1, EV_TIMEOUT, 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_chunked_trickle_cb, state, &when); 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_send_reply_end(state->req); 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(state); 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_chunked_cb(struct evhttp_request *req, void *arg) 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct timeval when = { 0, 0 }; 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct chunk_req_state *state = malloc(sizeof(struct chunk_req_state)); 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_debug(("%s: called\n", __func__)); 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(state, 0, sizeof(struct chunk_req_state)); 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott state->req = req; 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* generate a chunked reply */ 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_send_reply_start(req, HTTP_OK, "Everything is fine"); 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* but trickle it across several iterations to ensure we're not 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * assuming it comes all at once */ 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_once(-1, EV_TIMEOUT, http_chunked_trickle_cb, state, &when); 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_complete_write(int fd, short what, void *arg) 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct bufferevent *bev = arg; 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *http_request = "host\r\n" 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: close\r\n" 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "\r\n"; 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_write(bev, http_request, strlen(http_request)); 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_basic_test(void) 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct timeval tv; 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct bufferevent *bev; 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd; 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *http_request; 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott short port = -1; 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 0; 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Testing Basic HTTP Server: "); 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http = http_setup(&port, NULL); 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* bind to a second socket */ 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_bind_socket(http, "127.0.0.1", port + 1) == -1) { 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED (bind)\n"); 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fd = http_connect("127.0.0.1", port); 325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Stupid thing to send a request */ 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bev = bufferevent_new(fd, http_readcb, http_writecb, 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_errorcb, NULL); 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* first half of the http request */ 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_request = 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "GET /test HTTP/1.1\r\n" 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: some"; 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_write(bev, http_request, strlen(http_request)); 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott timerclear(&tv); 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott tv.tv_usec = 10000; 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_once(-1, EV_TIMEOUT, http_complete_write, bev, &tv); 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (test_ok != 3) { 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* connect to the second port */ 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_free(bev); 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EVUTIL_CLOSESOCKET(fd); 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fd = http_connect("127.0.0.1", port + 1); 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Stupid thing to send a request */ 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bev = bufferevent_new(fd, http_readcb, http_writecb, 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_errorcb, NULL); 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_request = 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "GET /test HTTP/1.1\r\n" 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: somehost\r\n" 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: close\r\n" 361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "\r\n"; 362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_write(bev, http_request, strlen(http_request)); 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_free(bev); 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EVUTIL_CLOSESOCKET(fd); 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_free(http); 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (test_ok != 5) { 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct evhttp_connection *delayed_client; 381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_delay_reply(int fd, short what, void *arg) 384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_request *req = arg; 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_send_reply(req, HTTP_OK, "Everything is fine", NULL); 388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ++test_ok; 390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_large_delay_cb(struct evhttp_request *req, void *arg) 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct timeval tv; 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott timerclear(&tv); 397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott tv.tv_sec = 3; 398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_once(-1, EV_TIMEOUT, http_delay_reply, req, &tv); 400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* here we close the client connection which will cause an EOF */ 402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_connection_fail(delayed_client, EVCON_HTTP_EOF); 403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid http_request_done(struct evhttp_request *, void *); 406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid http_request_empty_done(struct evhttp_request *, void *); 407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_connection_test(int persistent) 410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott short port = -1; 412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_connection *evcon = NULL; 413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_request *req = NULL; 414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 0; 416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Testing Request Connection Pipeline %s: ", 417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott persistent ? "(persistent)" : ""); 418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http = http_setup(&port, NULL); 420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evcon = evhttp_connection_new("127.0.0.1", port); 422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evcon == NULL) { 423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * At this point, we want to schedule a request to the HTTP 429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * server using our make request method. 430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req = evhttp_request_new(http_request_done, NULL); 433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Add the information that we care about */ 435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_add_header(req->output_headers, "Host", "somehost"); 436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* We give ownership of the request to the connection */ 438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { 439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (test_ok != 1) { 446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* try to make another request over the same connection */ 451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 0; 452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req = evhttp_request_new(http_request_done, NULL); 454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Add the information that we care about */ 456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_add_header(req->output_headers, "Host", "somehost"); 457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * if our connections are not supposed to be persistent; request 460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * a close from the server. 461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!persistent) 463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_add_header(req->output_headers, "Connection", "close"); 464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* We give ownership of the request to the connection */ 466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { 467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* make another request: request empty reply */ 474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 0; 475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req = evhttp_request_new(http_request_empty_done, NULL); 477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Add the information that we care about */ 479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_add_header(req->output_headers, "Empty", "itis"); 480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* We give ownership of the request to the connection */ 482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { 483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (test_ok != 1) { 490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_connection_free(evcon); 495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_free(http); 496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid 501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_request_done(struct evhttp_request *req, void *arg) 502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *what = "This is funny"; 504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (req->response_code != HTTP_OK) { 506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_find_header(req->input_headers, "Content-Type") == NULL) { 511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (EVBUFFER_LENGTH(req->input_buffer) != strlen(what)) { 516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (memcmp(EVBUFFER_DATA(req->input_buffer), what, strlen(what)) != 0) { 521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 1; 526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_loopexit(NULL); 527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* test date header and content length */ 530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid 532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_request_empty_done(struct evhttp_request *req, void *arg) 533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (req->response_code != HTTP_OK) { 535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_find_header(req->input_headers, "Date") == NULL) { 540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_find_header(req->input_headers, "Content-Length") == NULL) { 546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (strcmp(evhttp_find_header(req->input_headers, "Content-Length"), 551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "0")) { 552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (EVBUFFER_LENGTH(req->input_buffer) != 0) { 557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 1; 562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_loopexit(NULL); 563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* 566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * HTTP DISPATCHER test 567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid 570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_dispatcher_cb(struct evhttp_request *req, void *arg) 571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evbuffer *evb = evbuffer_new(); 574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_debug(("%s: called\n", __func__)); 575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evbuffer_add_printf(evb, "DISPATCHER_TEST"); 576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_send_reply(req, HTTP_OK, "Everything is fine", evb); 578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evbuffer_free(evb); 580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_dispatcher_test_done(struct evhttp_request *req, void *arg) 584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *what = "DISPATCHER_TEST"; 586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (req->response_code != HTTP_OK) { 588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_find_header(req->input_headers, "Content-Type") == NULL) { 593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED (content type)\n"); 594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (EVBUFFER_LENGTH(req->input_buffer) != strlen(what)) { 598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED (length %zu vs %zu)\n", 599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EVBUFFER_LENGTH(req->input_buffer), strlen(what)); 600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (memcmp(EVBUFFER_DATA(req->input_buffer), what, strlen(what)) != 0) { 604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED (data)\n"); 605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 1; 609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_loopexit(NULL); 610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_dispatcher_test(void) 614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott short port = -1; 616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_connection *evcon = NULL; 617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_request *req = NULL; 618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 0; 620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Testing HTTP Dispatcher: "); 621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http = http_setup(&port, NULL); 623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evcon = evhttp_connection_new("127.0.0.1", port); 625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evcon == NULL) { 626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* also bind to local host */ 631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_connection_set_local_address(evcon, "127.0.0.1"); 632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * At this point, we want to schedule an HTTP GET request 635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * server using our make request method. 636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req = evhttp_request_new(http_dispatcher_test_done, NULL); 639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (req == NULL) { 640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Add the information that we care about */ 645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_add_header(req->output_headers, "Host", "somehost"); 646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/?arg=val") == -1) { 648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_connection_free(evcon); 655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_free(http); 656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (test_ok != 1) { 658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED: %d\n", test_ok); 659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* 666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * HTTP POST test. 667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid http_postrequest_done(struct evhttp_request *, void *); 670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define POST_DATA "Okay. Not really printf" 672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_post_test(void) 675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott short port = -1; 677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_connection *evcon = NULL; 678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_request *req = NULL; 679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 0; 681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Testing HTTP POST Request: "); 682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http = http_setup(&port, NULL); 684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evcon = evhttp_connection_new("127.0.0.1", port); 686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evcon == NULL) { 687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * At this point, we want to schedule an HTTP POST request 693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * server using our make request method. 694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req = evhttp_request_new(http_postrequest_done, NULL); 697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (req == NULL) { 698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Add the information that we care about */ 703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_add_header(req->output_headers, "Host", "somehost"); 704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evbuffer_add_printf(req->output_buffer, POST_DATA); 705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/postit") == -1) { 707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_connection_free(evcon); 714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_free(http); 715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (test_ok != 1) { 717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED: %d\n", test_ok); 718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid 725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_post_cb(struct evhttp_request *req, void *arg) 726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evbuffer *evb; 728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_debug(("%s: called\n", __func__)); 729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Yes, we are expecting a post request */ 731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (req->type != EVHTTP_REQ_POST) { 732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED (post type)\n"); 733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (EVBUFFER_LENGTH(req->input_buffer) != strlen(POST_DATA)) { 737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED (length: %zu vs %zu)\n", 738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EVBUFFER_LENGTH(req->input_buffer), strlen(POST_DATA)); 739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (memcmp(EVBUFFER_DATA(req->input_buffer), POST_DATA, 743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott strlen(POST_DATA))) { 744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED (data)\n"); 745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Got :%s\n", EVBUFFER_DATA(req->input_buffer)); 746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Want:%s\n", POST_DATA); 747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evb = evbuffer_new(); 751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evbuffer_add_printf(evb, "This is funny"); 752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_send_reply(req, HTTP_OK, "Everything is fine", evb); 754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evbuffer_free(evb); 756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid 759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_postrequest_done(struct evhttp_request *req, void *arg) 760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *what = "This is funny"; 762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (req == NULL) { 764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED (timeout)\n"); 765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (req->response_code != HTTP_OK) { 769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED (response code)\n"); 771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_find_header(req->input_headers, "Content-Type") == NULL) { 775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED (content type)\n"); 776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (EVBUFFER_LENGTH(req->input_buffer) != strlen(what)) { 780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED (length %zu vs %zu)\n", 781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EVBUFFER_LENGTH(req->input_buffer), strlen(what)); 782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (memcmp(EVBUFFER_DATA(req->input_buffer), what, strlen(what)) != 0) { 786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED (data)\n"); 787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 1; 791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_loopexit(NULL); 792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_failure_readcb(struct bufferevent *bev, void *arg) 796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *what = "400 Bad Request"; 798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evbuffer_find(bev->input, (const unsigned char*) what, strlen(what)) != NULL) { 799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 2; 800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_disable(bev, EV_READ); 801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_loopexit(NULL); 802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* 806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Testing that the HTTP server can deal with a malformed request. 807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_failure_test(void) 810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct bufferevent *bev; 812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd; 813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *http_request; 814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott short port = -1; 815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 0; 817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Testing Bad HTTP Request: "); 818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http = http_setup(&port, NULL); 820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fd = http_connect("127.0.0.1", port); 822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Stupid thing to send a request */ 824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bev = bufferevent_new(fd, http_failure_readcb, http_writecb, 825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_errorcb, NULL); 826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_request = "illegal request\r\n"; 828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_write(bev, http_request, strlen(http_request)); 830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_free(bev); 834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EVUTIL_CLOSESOCKET(fd); 835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_free(http); 837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (test_ok != 2) { 839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclose_detect_done(struct evhttp_request *req, void *arg) 848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct timeval tv; 850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (req == NULL || req->response_code != HTTP_OK) { 851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 1; 857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott timerclear(&tv); 859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott tv.tv_sec = 3; /* longer than the http time out */ 860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_loopexit(&tv); 862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclose_detect_launch(int fd, short what, void *arg) 866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_connection *evcon = arg; 868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_request *req; 869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req = evhttp_request_new(close_detect_done, NULL); 871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Add the information that we care about */ 873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_add_header(req->output_headers, "Host", "somehost"); 874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* We give ownership of the request to the connection */ 876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { 877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclose_detect_cb(struct evhttp_request *req, void *arg) 884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_connection *evcon = arg; 886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct timeval tv; 887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (req != NULL && req->response_code != HTTP_OK) { 889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott timerclear(&tv); 895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott tv.tv_sec = 3; /* longer than the http time out */ 896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* launch a new request on the persistent connection in 6 seconds */ 898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_once(-1, EV_TIMEOUT, close_detect_launch, evcon, &tv); 899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_close_detection(int with_delay) 904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott short port = -1; 906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_connection *evcon = NULL; 907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_request *req = NULL; 908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 909c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 0; 910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Testing Connection Close Detection%s: ", 911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott with_delay ? " (with delay)" : ""); 912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http = http_setup(&port, NULL); 914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 2 second timeout */ 916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_set_timeout(http, 2); 917c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evcon = evhttp_connection_new("127.0.0.1", port); 919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evcon == NULL) { 920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 921c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delayed_client = evcon; 925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 926c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * At this point, we want to schedule a request to the HTTP 928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * server using our make request method. 929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req = evhttp_request_new(close_detect_cb, evcon); 932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Add the information that we care about */ 934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_add_header(req->output_headers, "Host", "somehost"); 935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* We give ownership of the request to the connection */ 937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_make_request(evcon, 938c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req, EVHTTP_REQ_GET, with_delay ? "/largedelay" : "/test") == -1) { 939c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 940c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 941c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 942c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 943c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 944c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 945c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (test_ok != 1) { 946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 947c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 949c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 950c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* at this point, the http server should have no connection */ 951c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (TAILQ_FIRST(&http->connections) != NULL) { 952c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED (left connections)\n"); 953c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 954c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 955c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_connection_free(evcon); 957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_free(http); 958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 962c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_highport_test(void) 964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int i = -1; 966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp *myhttp = NULL; 967c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 968c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Testing HTTP Server with high port: "); 969c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Try a few different ports */ 971c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (i = 0; i < 50; ++i) { 972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott myhttp = evhttp_start("127.0.0.1", 65535 - i); 973c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (myhttp != NULL) { 974c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 975c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_free(myhttp); 976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 978c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 979c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 980c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 982c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 983c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 984c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 985c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_bad_header_test(void) 986c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 987c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evkeyvalq headers; 988c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Testing HTTP Header filtering: "); 990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 991c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TAILQ_INIT(&headers); 992c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 993c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_add_header(&headers, "One", "Two") != 0) 994c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 995c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 996c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_add_header(&headers, "One\r", "Two") != -1) 997c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 998c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_add_header(&headers, "One", "Two") != 0) 999c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 1000c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_add_header(&headers, "One", "Two\r\n Three") != 0) 1001c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 1002c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_add_header(&headers, "One\r", "Two") != -1) 1003c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 1004c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_add_header(&headers, "One\n", "Two") != -1) 1005c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 1006c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_add_header(&headers, "One", "Two\r") != -1) 1007c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 1008c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_add_header(&headers, "One", "Two\n") != -1) 1009c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 1010c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1011c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_clear_headers(&headers); 1012c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1013c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 1014c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 1015c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottfail: 1016c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 1017c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1018c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int validate_header( 1021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const struct evkeyvalq* headers, 1022c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *key, const char *value) 1023c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1024c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *real_val = evhttp_find_header(headers, key); 1025c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (real_val == NULL) 1026c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (-1); 1027c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (strcmp(real_val, value) != 0) 1028c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (-1); 1029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (0); 1030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 1033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_parse_query_test(void) 1034c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1035c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evkeyvalq headers; 1036c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1037c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Testing HTTP query parsing: "); 1038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TAILQ_INIT(&headers); 1040c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_parse_query("http://www.test.com/?q=test", &headers); 1042c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (validate_header(&headers, "q", "test") != 0) 1043c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 1044c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_clear_headers(&headers); 1045c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1046c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_parse_query("http://www.test.com/?q=test&foo=bar", &headers); 1047c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (validate_header(&headers, "q", "test") != 0) 1048c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 1049c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (validate_header(&headers, "foo", "bar") != 0) 1050c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 1051c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_clear_headers(&headers); 1052c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1053c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_parse_query("http://www.test.com/?q=test+foo", &headers); 1054c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (validate_header(&headers, "q", "test foo") != 0) 1055c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 1056c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_clear_headers(&headers); 1057c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1058c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_parse_query("http://www.test.com/?q=test%0Afoo", &headers); 1059c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (validate_header(&headers, "q", "test\nfoo") != 0) 1060c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 1061c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_clear_headers(&headers); 1062c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1063c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_parse_query("http://www.test.com/?q=test%0Dfoo", &headers); 1064c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (validate_header(&headers, "q", "test\rfoo") != 0) 1065c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto fail; 1066c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_clear_headers(&headers); 1067c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1068c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 1069c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 1070c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottfail: 1071c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 1072c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1073c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1074c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1075c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 1076c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_base_test(void) 1077c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1078c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct bufferevent *bev; 1079c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd; 1080c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *http_request; 1081c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott short port = -1; 1082c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1083c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 0; 1084c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Testing HTTP Server Event Base: "); 1085c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1086c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base = event_init(); 1087c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1088c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 1089c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * create another bogus base - which is being used by all subsequen 1090c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * tests - yuck! 1091c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 1092c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_init(); 1093c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1094c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http = http_setup(&port, base); 1095c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1096c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fd = http_connect("127.0.0.1", port); 1097c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1098c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Stupid thing to send a request */ 1099c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bev = bufferevent_new(fd, http_readcb, http_writecb, 1100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_errorcb, NULL); 1101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_base_set(base, bev); 1102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_request = 1104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "GET /test HTTP/1.1\r\n" 1105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: somehost\r\n" 1106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: close\r\n" 1107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "\r\n"; 1108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_write(bev, http_request, strlen(http_request)); 1110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_base_dispatch(base); 1112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_free(bev); 1114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EVUTIL_CLOSESOCKET(fd); 1115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_free(http); 1117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_base_free(base); 1119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base = NULL; 1120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (test_ok != 2) { 1122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 1123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 1127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* 1130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * the server is going to reply with chunked data. 1131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 1132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 1134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_chunked_readcb(struct bufferevent *bev, void *arg) 1135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* nothing here */ 1137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 1140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_chunked_errorcb(struct bufferevent *bev, short what, void *arg) 1141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!test_ok) 1143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = -1; 1146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if ((what & EVBUFFER_EOF) != 0) { 1148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_request *req = evhttp_request_new(NULL, NULL); 1149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *header; 1150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum message_read_status done; 1151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req->kind = EVHTTP_RESPONSE; 1153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott done = evhttp_parse_firstline(req, EVBUFFER_INPUT(bev)); 1154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (done != ALL_DATA_READ) 1155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott done = evhttp_parse_headers(req, EVBUFFER_INPUT(bev)); 1158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (done != ALL_DATA_READ) 1159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott header = evhttp_find_header(req->input_headers, "Transfer-Encoding"); 1162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (header == NULL || strcmp(header, "chunked")) 1163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott header = evhttp_find_header(req->input_headers, "Connection"); 1166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (header == NULL || strcmp(header, "close")) 1167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott header = evbuffer_readline(EVBUFFER_INPUT(bev)); 1170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (header == NULL) 1171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 13 chars */ 1173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (strcmp(header, "d")) 1174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free((char*)header); 1176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (strncmp((char *)EVBUFFER_DATA(EVBUFFER_INPUT(bev)), 1178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "This is funny", 13)) 1179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evbuffer_drain(EVBUFFER_INPUT(bev), 13 + 2); 1182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott header = evbuffer_readline(EVBUFFER_INPUT(bev)); 1184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (header == NULL) 1185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 18 chars */ 1187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (strcmp(header, "12")) 1188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free((char *)header); 1190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (strncmp((char *)EVBUFFER_DATA(EVBUFFER_INPUT(bev)), 1192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "but not hilarious.", 18)) 1193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evbuffer_drain(EVBUFFER_INPUT(bev), 18 + 2); 1196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott header = evbuffer_readline(EVBUFFER_INPUT(bev)); 1198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (header == NULL) 1199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 8 chars */ 1201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (strcmp(header, "8")) 1202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free((char *)header); 1204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (strncmp((char *)EVBUFFER_DATA(EVBUFFER_INPUT(bev)), 1206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "bwv 1052.", 8)) 1207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evbuffer_drain(EVBUFFER_INPUT(bev), 8 + 2); 1210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott header = evbuffer_readline(EVBUFFER_INPUT(bev)); 1212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (header == NULL) 1213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 0 chars */ 1215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (strcmp(header, "0")) 1216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 1217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free((char *)header); 1218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 2; 1220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottout: 1223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_loopexit(NULL); 1224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 1227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_chunked_writecb(struct bufferevent *bev, void *arg) 1228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (EVBUFFER_LENGTH(EVBUFFER_OUTPUT(bev)) == 0) { 1230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* enable reading of the reply */ 1231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_enable(bev, EV_READ); 1232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok++; 1233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 1237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_chunked_request_done(struct evhttp_request *req, void *arg) 1238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (req->response_code != HTTP_OK) { 1240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 1241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_find_header(req->input_headers, 1245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Transfer-Encoding") == NULL) { 1246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 1247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (EVBUFFER_LENGTH(req->input_buffer) != 13 + 18 + 8) { 1251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 1252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (strncmp((char *)EVBUFFER_DATA(req->input_buffer), 1256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "This is funnybut not hilarious.bwv 1052", 1257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 13 + 18 + 8)) { 1258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 1259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 1; 1263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_loopexit(NULL); 1264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 1267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_chunked_test(void) 1268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct bufferevent *bev; 1270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd; 1271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *http_request; 1272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott short port = -1; 1273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct timeval tv_start, tv_end; 1274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_connection *evcon = NULL; 1275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_request *req = NULL; 1276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int i; 1277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 0; 1279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Testing Chunked HTTP Reply: "); 1280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http = http_setup(&port, NULL); 1282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fd = http_connect("127.0.0.1", port); 1284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Stupid thing to send a request */ 1286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bev = bufferevent_new(fd, 1287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_chunked_readcb, http_chunked_writecb, 1288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_chunked_errorcb, NULL); 1289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_request = 1291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "GET /chunked HTTP/1.1\r\n" 1292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: somehost\r\n" 1293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: close\r\n" 1294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "\r\n"; 1295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_write(bev, http_request, strlen(http_request)); 1297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evutil_gettimeofday(&tv_start, NULL); 1299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 1301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evutil_gettimeofday(&tv_end, NULL); 1303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evutil_timersub(&tv_end, &tv_start, &tv_end); 1304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (tv_end.tv_sec >= 1) { 1306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED (time)\n"); 1307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit (1); 1308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (test_ok != 2) { 1312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 1313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* now try again with the regular connection object */ 1317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evcon = evhttp_connection_new("127.0.0.1", port); 1318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evcon == NULL) { 1319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 1320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* make two requests to check the keepalive behavior */ 1324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (i = 0; i < 2; i++) { 1325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 0; 1326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req = evhttp_request_new(http_chunked_request_done, NULL); 1327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Add the information that we care about */ 1329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_add_header(req->output_headers, "Host", "somehost"); 1330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* We give ownership of the request to the connection */ 1332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_make_request(evcon, req, 1333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EVHTTP_REQ_GET, "/chunked") == -1) { 1334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 1335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 1339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (test_ok != 1) { 1341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 1342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_connection_free(evcon); 1347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_free(http); 1348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 1350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 1353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_multi_line_header_test(void) 1354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct bufferevent *bev; 1356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int fd; 1357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *http_start_request; 1358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott short port = -1; 1359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 0; 1361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Testing HTTP Server with multi line: "); 1362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http = http_setup(&port, NULL); 1364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fd = http_connect("127.0.0.1", port); 1366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Stupid thing to send a request */ 1368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bev = bufferevent_new(fd, http_readcb, http_writecb, 1369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_errorcb, NULL); 1370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_start_request = 1372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "GET /test HTTP/1.1\r\n" 1373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Host: somehost\r\n" 1374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Connection: close\r\n" 1375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "X-Multi: aaaaaaaa\r\n" 1376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott " a\r\n" 1377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "\tEND\r\n" 1378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "X-Last: last\r\n" 1379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "\r\n"; 1380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_write(bev, http_start_request, strlen(http_start_request)); 1382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 1384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bufferevent_free(bev); 1386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EVUTIL_CLOSESOCKET(fd); 1387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_free(http); 1389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (test_ok != 4) { 1391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 1392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 1396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 1399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_request_bad(struct evhttp_request *req, void *arg) 1400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (req != NULL) { 1402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "FAILED\n"); 1403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 1; 1407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_loopexit(NULL); 1408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 1411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_negative_content_length_test(void) 1412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott short port = -1; 1414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_connection *evcon = NULL; 1415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evhttp_request *req = NULL; 1416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott test_ok = 0; 1418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Testing HTTP Negative Content Length: "); 1419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http = http_setup(&port, NULL); 1421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evcon = evhttp_connection_new("127.0.0.1", port); 1423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evcon == NULL) { 1424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 1425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* 1429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * At this point, we want to schedule a request to the HTTP 1430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * server using our make request method. 1431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 1432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req = evhttp_request_new(http_request_bad, NULL); 1434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Cause the response to have a negative content-length */ 1436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_add_header(req->output_headers, "X-Negative", "makeitso"); 1437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* We give ownership of the request to the connection */ 1439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { 1440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 1441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 1445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evhttp_free(http); 1447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (test_ok != 1) { 1449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 1450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 1451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 1454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid 1457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotthttp_suite(void) 1458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 1459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_base_test(); 1460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_bad_header_test(); 1461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_parse_query_test(); 1462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_basic_test(); 1463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_connection_test(0 /* not-persistent */); 1464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_connection_test(1 /* persistent */); 1465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_close_detection(0 /* with delay */); 1466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_close_detection(1 /* with delay */); 1467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_post_test(); 1468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_failure_test(); 1469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_highport_test(); 1470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_dispatcher_test(); 1471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_multi_line_header_test(); 1473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_negative_content_length_test(); 1474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott http_chunked_test(); 1476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1477