From de1c43926b032954a91f7edf50bbf4f233bd791e Mon Sep 17 00:00:00 2001
From: Niels Provos <provos@gmail.com>
Date: Thu, 8 May 2008 06:15:04 +0000
Subject: [PATCH] migrate evhttp to event2; accessors are still missing

svn:r790
---
 ChangeLog                    |   1 +
 Doxyfile                     |   4 +-
 evhttp.h                     | 426 +----------------------------------
 evrpc.c                      |   4 +-
 http.c                       |  18 +-
 include/Makefile.am          |   6 +-
 include/event2/http.h        | 374 ++++++++++++++++++++++++++++++
 include/event2/http_compat.h |  91 ++++++++
 include/event2/http_struct.h | 119 ++++++++++
 9 files changed, 615 insertions(+), 428 deletions(-)
 create mode 100644 include/event2/http.h
 create mode 100644 include/event2/http_compat.h
 create mode 100644 include/event2/http_struct.h

diff --git a/ChangeLog b/ChangeLog
index 7e827109..2a74896c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -93,6 +93,7 @@ Changes in current version:
  o Build test directory correctly with CPPFLAGS set.
  o Provide an API for retrieving the supported event mechanisms.
  o event_base_new_with_config() and corresponding config APIs.
+ o migrate the evhttp header to event2/ but accessors are still missing.
 
 Changes in 1.4.0:
  o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.
diff --git a/Doxyfile b/Doxyfile
index c0f09578..a9cda1ad 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -57,7 +57,9 @@ SORT_BRIEF_DOCS        = YES
 INPUT                  = event.h evdns.h evhttp.h evrpc.h \
 		       include/event2/buffer.h include/event2/thread.h \
 		       include/event2/tag.h include/event2/bufferevent.h \
-		       include/event2/util.h
+		       include/event2/util.h \
+		       include/event2/http.h include/event2/http_struct.h \
+		       include/event2/http_compat.h
 
 #---------------------------------------------------------------------------
 # configuration options related to the HTML output
diff --git a/evhttp.h b/evhttp.h
index eba72721..60151cbd 100644
--- a/evhttp.h
+++ b/evhttp.h
@@ -27,428 +27,8 @@
 #ifndef _EVHTTP_H_
 #define _EVHTTP_H_
 
-#include <event.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <winsock2.h>
-#undef WIN32_LEAN_AND_MEAN
-#endif
-
-/* For int types. */
-#include <evutil.h>
-
-/** @file evhttp.h
- *
- * Basic support for HTTP serving.
- *
- * As libevent is a library for dealing with event notification and most
- * interesting applications are networked today, I have often found the
- * need to write HTTP code.  The following prototypes and definitions provide
- * an application with a minimal interface for making HTTP requests and for
- * creating a very simple HTTP server.
- */
-
-/* Response codes */
-#define HTTP_OK			200	/**< request completed ok */
-#define HTTP_NOCONTENT		204	/**< request does not have content */
-#define HTTP_MOVEPERM		301	/**< the uri moved permanently */
-#define HTTP_MOVETEMP		302	/**< the uri moved temporarily */
-#define HTTP_NOTMODIFIED	304	/**< page was not modified from last */
-#define HTTP_BADREQUEST		400	/**< invalid http request was made */
-#define HTTP_NOTFOUND		404	/**< could not find content for uri */
-#define HTTP_SERVUNAVAIL	503	/**< the server is not available */ 
-
-struct evhttp;
-struct evhttp_request;
-struct evkeyvalq;
-
-/** Create a new HTTP server
- *
- * @param base (optional) the event base to receive the HTTP events
- * @return a pointer to a newly initialized evhttp server structure
- */
-struct evhttp *evhttp_new(struct event_base *base);
-
-/**
- * Binds an HTTP server on the specified address and port.
- *
- * Can be called multiple times to bind the same http server
- * to multiple different ports.
- *
- * @param http a pointer to an evhttp object
- * @param address a string containing the IP address to listen(2) on
- * @param port the port number to listen on
- * @return 0 on success, -1 on failure.
- * @see evhttp_free(), evhttp_accept_socket()
- */
-int evhttp_bind_socket(struct evhttp *http, const char *address, u_short port);
-
-/**
- * Makes an HTTP server accept connections on the specified socket
- *
- * This may be useful to create a socket and then fork multiple instances
- * of an http server, or when a socket has been communicated via file
- * descriptor passing in situations where an http servers does not have
- * permissions to bind to a low-numbered port.
- *
- * Can be called multiple times to have the http server listen to
- * multiple different sockets.
- *
- * @param http a pointer to an evhttp object
- * @param fd a socket fd that is ready for accepting connections
- * @return 0 on success, -1 on failure.
- * @see evhttp_free(), evhttp_bind_socket()
- */
-int evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd);
-
-/**
- * Free the previously created HTTP server.
- *
- * Works only if no requests are currently being served.
- *
- * @param http the evhttp server object to be freed
- * @see evhttp_start()
- */
-void evhttp_free(struct evhttp* http);
-
-/** Set a callback for a specified URI */
-void evhttp_set_cb(struct evhttp *, const char *,
-    void (*)(struct evhttp_request *, void *), void *);
-
-/** Removes the callback for a specified URI */
-int evhttp_del_cb(struct evhttp *, const char *);
-
-/** 
-    Set a callback for all requests that are not caught by specific callbacks
-
-    Invokes the specified callback for all requests that do not match any of
-    the previously specified request paths.  This is catchall for requests not
-    specifically configured with evhttp_set_cb().
-
-    @param http the evhttp server object for which to set the callback
-    @param cb the callback to invoke for any unmatched requests
-    @param arg an context argument for the callback
-*/
-void evhttp_set_gencb(struct evhttp *http,
-    void (*cb)(struct evhttp_request *, void *), void *arg);
-
-/**
-   Adds a virtual host to the http server.
-
-   A virtual host is a newly initialized evhttp object that has request
-   callbacks set on it via evhttp_set_cb() or evhttp_set_gencb().  It
-   most not have any listing sockets associated with it.
-
-   If the virtual host has not been removed by the time that evhttp_free()
-   is called on the main http server, it will be automatically freed, too.
-
-   It is possible to have hierarchical vhosts.  For example: A vhost
-   with the pattern *.example.com may have other vhosts with patterns
-   foo.example.com and bar.example.com associated with it.
-
-   @param http the evhttp object to which to add a virtual host
-   @param pattern the glob pattern against which the hostname is matched.
-     The match is case insensitive and follows otherwise regular shell
-     matching.
-   @param vhost the virtual host to add the regular http server.
-   @return 0 on success, -1 on failure
-   @see evhttp_remove_virtual_host()
-*/
-int evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
-    struct evhttp* vhost);
-
-/**
-   Removes a virtual host from the http server.
-
-   @param http the evhttp object from which to remove the virtual host
-   @param vhost the virtual host to remove from the regular http server.
-   @return 0 on success, -1 on failure
-   @see evhttp_add_virtual_host()
-*/
-int evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost);
-
-/**
- * Set the timeout for an HTTP request.
- *
- * @param http an evhttp object
- * @param timeout_in_secs the timeout, in seconds
- */
-void evhttp_set_timeout(struct evhttp *http, int timeout_in_secs);
-
-/* Request/Response functionality */
-
-/**
- * Send an HTML error message to the client.
- *
- * @param req a request object
- * @param error the HTTP error code
- * @param reason a brief explanation of the error
- */
-void evhttp_send_error(struct evhttp_request *req, int error,
-    const char *reason);
-
-/**
- * Send an HTML reply to the client.
- *
- * @param req a request object
- * @param code the HTTP response code to send
- * @param reason a brief message to send with the response code
- * @param databuf the body of the response
- */
-void evhttp_send_reply(struct evhttp_request *req, int code,
-    const char *reason, struct evbuffer *databuf);
-
-/* Low-level response interface, for streaming/chunked replies */
-void evhttp_send_reply_start(struct evhttp_request *, int, const char *);
-void evhttp_send_reply_chunk(struct evhttp_request *, struct evbuffer *);
-void evhttp_send_reply_end(struct evhttp_request *);
-
-/**
- * Start an HTTP server on the specified address and port
- *
- * DEPRECATED: it does not allow an event base to be specified
- *
- * @param address the address to which the HTTP server should be bound
- * @param port the port number on which the HTTP server should listen
- * @return an struct evhttp object
- */
-struct evhttp *evhttp_start(const char *address, u_short port);
-
-/*
- * Interfaces for making requests
- */
-enum evhttp_cmd_type { EVHTTP_REQ_GET, EVHTTP_REQ_POST, EVHTTP_REQ_HEAD, EVHTTP_REQ_PUT, EVHTTP_REQ_DELETE };
-
-enum evhttp_request_kind { EVHTTP_REQUEST, EVHTTP_RESPONSE };
-
-/**
- * the request structure that a server receives.
- * WARNING: expect this structure to change.  I will try to provide
- * reasonable accessors.
- */
-struct evhttp_request {
-#if defined(TAILQ_ENTRY)
-	TAILQ_ENTRY(evhttp_request) next;
-#else
-struct {
-	struct evhttp_request *tqe_next;
-	struct evhttp_request **tqe_prev;
-}       next;
-#endif
-
-	/* the connection object that this request belongs to */
-	struct evhttp_connection *evcon;
-	int flags;
-/** The request obj owns the evhttp connection and needs to free it */
-#define EVHTTP_REQ_OWN_CONNECTION	0x0001
-/** Request was made via a proxy */
-#define EVHTTP_PROXY_REQUEST		0x0002
-/** The request object is owned by the user; the user must free it */
-#define EVHTTP_USER_OWNED		0x0004
-
-	struct evkeyvalq *input_headers;
-	struct evkeyvalq *output_headers;
-
-	/* address of the remote host and the port connection came from */
-	char *remote_host;
-	u_short remote_port;
-
-	enum evhttp_request_kind kind;
-	enum evhttp_cmd_type type;
-
-	char *uri;			/* uri after HTTP request was parsed */
-
-	char major;			/* HTTP Major number */
-	char minor;			/* HTTP Minor number */
-
-	int got_firstline;
-	int response_code;		/* HTTP Response code */
-	char *response_code_line;	/* Readable response */
-
-	struct evbuffer *input_buffer;	/* read data */
-	ev_int64_t ntoread;
-	int chunked;
-
-	struct evbuffer *output_buffer;	/* outgoing post or data */
-
-	/* Callback */
-	void (*cb)(struct evhttp_request *, void *);
-	void *cb_arg;
-
-	/*
-	 * Chunked data callback - call for each completed chunk if
-	 * specified.  If not specified, all the data is delivered via
-	 * the regular callback.
-	 */
-	void (*chunk_cb)(struct evhttp_request *, void *);
-};
-
-/**
- * Creates a new request object that needs to be filled in with the request
- * parameters.  The callback is executed when the request completed or an
- * error occurred.
- */
-struct evhttp_request *evhttp_request_new(
-	void (*cb)(struct evhttp_request *, void *), void *arg);
-
-/** enable delivery of chunks to requestor */
-void evhttp_request_set_chunked_cb(struct evhttp_request *,
-    void (*cb)(struct evhttp_request *, void *));
-
-/** Frees the request object and removes associated events. */
-void evhttp_request_free(struct evhttp_request *req);
-
-/** Takes ownership of the request object
- *
- * Can be used in a request callback to keep onto the request until
- * evhttp_request_free() is explicitly called by the user.
- */
-void evhttp_request_own(struct evhttp_request *req);
-
-/** Returns 1 if the request is owned by the user */
-int evhttp_request_is_owned(struct evhttp_request *req);
-
-/**
- * A connection object that can be used to for making HTTP requests.  The
- * connection object tries to establish the connection when it is given an
- * http request object.
- */
-struct evhttp_connection *evhttp_connection_new(
-	const char *address, unsigned short port);
-
-/** Frees an http connection */
-void evhttp_connection_free(struct evhttp_connection *evcon);
-
-/** sets the ip address from which http connections are made */
-void evhttp_connection_set_local_address(struct evhttp_connection *evcon,
-    const char *address);
-
-/** Sets the timeout for events related to this connection */
-void evhttp_connection_set_timeout(struct evhttp_connection *evcon,
-    int timeout_in_secs);
-
-/** Sets the retry limit for this connection - -1 repeats indefnitely */
-void evhttp_connection_set_retries(struct evhttp_connection *evcon,
-    int retry_max);
-
-/** Set a callback for connection close. */
-void evhttp_connection_set_closecb(struct evhttp_connection *evcon,
-    void (*)(struct evhttp_connection *, void *), void *);
-
-/**
- * Associates an event base with the connection - can only be called
- * on a freshly created connection object that has not been used yet.
- */
-void evhttp_connection_set_base(struct evhttp_connection *evcon,
-    struct event_base *base);
-
-/** Get the remote address and port associated with this connection. */
-void evhttp_connection_get_peer(struct evhttp_connection *evcon,
-    char **address, u_short *port);
-
-/** The connection gets ownership of the request */
-int evhttp_make_request(struct evhttp_connection *evcon,
-    struct evhttp_request *req,
-    enum evhttp_cmd_type type, const char *uri);
-
-const char *evhttp_request_uri(struct evhttp_request *req);
-
-/* Interfaces for dealing with HTTP headers */
-
-/**
-   Finds the value belonging to a header.
-    
-   @param headers the evkeyvalq object in which to find the header
-   @param key the name of the header to find
-   @returns a pointer to the value for the header or NULL if the header
-     count not be found.
-   @see evhttp_add_header(), evhttp_remove_header()
-*/
-const char *evhttp_find_header(const struct evkeyvalq *headers,
-    const char *key);
-
-/**
-   Removes a header from a list of exisiting headers.
-    
-   @param headers the evkeyvalq object from which to remove a header
-   @param key the name of the header to remove
-   @returns 0 if the header was removed, -1  otherwise.
-   @see evhttp_find_header(), evhttp_add_header()
-*/
-int evhttp_remove_header(struct evkeyvalq *headers, const char *key);
-
-/**
-   Adds a header to a list of exisiting headers.
-    
-   @param headers the evkeyvalq object to which to add a header
-   @param key the name of the header
-   @param value the value belonging to the header
-   @returns 0 on success, -1  otherwise.
-   @see evhttp_find_header(), evhttp_clear_headers()
-*/
-int evhttp_add_header(struct evkeyvalq *headers, const char *key, const char *value);
-
-/**
-   Removes all headers from the header list.
-
-   @param headers the evkeyvalq object from which to remove all headers
-*/
-void evhttp_clear_headers(struct evkeyvalq *headers);
-
-/* Miscellaneous utility functions */
-
-
-/**
-  Helper function to encode a URI.
-
-  The returned string must be freed by the caller.
-
-  @param uri an unencoded URI
-  @return a newly allocated URI-encoded string
- */
-char *evhttp_encode_uri(const char *uri);
-
-
-/**
-  Helper function to decode a URI.
-
-  The returned string must be freed by the caller.
-
-  @param uri an encoded URI
-  @return a newly allocated unencoded URI
- */
-char *evhttp_decode_uri(const char *uri);
-
-
-/**
- * Helper function to parse out arguments in a query.
- * The arguments are separated by key and value.
- * URI should already be decoded.
- */
-void evhttp_parse_query(const char *uri, struct evkeyvalq *);
-
-
-/**
- * Escape HTML character entities in a string.
- *
- * Replaces <, >, ", ' and & with &lt;, &gt;, &quot;,
- * &#039; and &amp; correspondingly.
- *
- * The returned string needs to be freed by the caller.
- *
- * @param html an unescaped HTML string
- * @return an escaped HTML string
- */
-char *evhttp_htmlescape(const char *html);
-
-#ifdef __cplusplus
-}
-#endif
+#include <event2/http.h>
+#include <event2/http_struct.h>
+#include <event2/http_compat.h>
 
 #endif /* _EVHTTP_H_ */
diff --git a/evrpc.c b/evrpc.c
index 24e32ad7..4aad0957 100644
--- a/evrpc.c
+++ b/evrpc.c
@@ -58,7 +58,9 @@
 #include "event2/event_struct.h"
 #include "evrpc.h"
 #include "evrpc-internal.h"
-#include "evhttp.h"
+#include "event2/http.h"
+#include "event2/http_struct.h"
+#include "event2/http_compat.h"
 #include "evutil.h"
 #include "log.h"
 #include "mm-internal.h"
diff --git a/http.c b/http.c
index 2b98674f..4ef750a4 100644
--- a/http.c
+++ b/http.c
@@ -89,7 +89,9 @@
 
 #include "strlcpy-internal.h"
 #include "event2/event.h"
-#include "evhttp.h"
+#include "event2/http.h"
+#include "event2/http_struct.h"
+#include "event2/http_compat.h"
 #include "evutil.h"
 #include "log.h"
 #include "http-internal.h"
@@ -1385,6 +1387,20 @@ evhttp_read_header_cb(struct bufferevent *bufev, void *arg)
  * happen elsewhere.
  */
 
+struct evhttp_connection *
+evhttp_connection_base_new(struct event_base *base,
+    const char *address, unsigned short port)
+{
+	struct evhttp_connection *evcon = evhttp_connection_new(address, port);
+	if (evcon == NULL)
+		return (NULL);
+
+	if (base != NULL)
+		evhttp_connection_set_base(evcon, base);
+
+	return (evcon);
+}
+
 struct evhttp_connection *
 evhttp_connection_new(const char *address, unsigned short port)
 {
diff --git a/include/Makefile.am b/include/Makefile.am
index f4c8255c..471dd696 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -2,9 +2,11 @@ AUTOMAKE_OPTIONS = foreign
 
 EXTRA_SRC = event2/buffer.h event2/thread.h event2/bufferevent.h \
         event2/bufferevent_struct.h event2/event.h event2/event_compat.h \
-        event2/event_struct.h event2/tag.h event2/util.h
+        event2/event_struct.h event2/tag.h event2/util.h \
+	event2/http.h event2/http_struct.h event2/http_compat.h
 
 nobase_include_HEADERS = \
         event2/buffer.h event2/thread.h event2/bufferevent.h \
         event2/bufferevent_struct.h event2/event.h event2/event_compat.h \
-        event2/event_struct.h event2/tag.h event2/util.h
+        event2/event_struct.h event2/tag.h event2/util.h \
+	event2/http.h event2/http_struct.h event2/http_compat.h
diff --git a/include/event2/http.h b/include/event2/http.h
new file mode 100644
index 00000000..b11303cd
--- /dev/null
+++ b/include/event2/http.h
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _EVENT2_HTTP_H_
+#define _EVENT2_HTTP_H_
+
+#include <event.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winsock2.h>
+#undef WIN32_LEAN_AND_MEAN
+#endif
+
+/* For int types. */
+#include <evutil.h>
+
+/** @file evhttp.h
+ *
+ * Basic support for HTTP serving.
+ *
+ * As libevent is a library for dealing with event notification and most
+ * interesting applications are networked today, I have often found the
+ * need to write HTTP code.  The following prototypes and definitions provide
+ * an application with a minimal interface for making HTTP requests and for
+ * creating a very simple HTTP server.
+ */
+
+/* Response codes */
+#define HTTP_OK			200	/**< request completed ok */
+#define HTTP_NOCONTENT		204	/**< request does not have content */
+#define HTTP_MOVEPERM		301	/**< the uri moved permanently */
+#define HTTP_MOVETEMP		302	/**< the uri moved temporarily */
+#define HTTP_NOTMODIFIED	304	/**< page was not modified from last */
+#define HTTP_BADREQUEST		400	/**< invalid http request was made */
+#define HTTP_NOTFOUND		404	/**< could not find content for uri */
+#define HTTP_SERVUNAVAIL	503	/**< the server is not available */ 
+
+struct evhttp;
+struct evhttp_request;
+struct evkeyvalq;
+
+/** Create a new HTTP server
+ *
+ * @param base (optional) the event base to receive the HTTP events
+ * @return a pointer to a newly initialized evhttp server structure
+ */
+struct evhttp *evhttp_new(struct event_base *base);
+
+/**
+ * Binds an HTTP server on the specified address and port.
+ *
+ * Can be called multiple times to bind the same http server
+ * to multiple different ports.
+ *
+ * @param http a pointer to an evhttp object
+ * @param address a string containing the IP address to listen(2) on
+ * @param port the port number to listen on
+ * @return 0 on success, -1 on failure.
+ * @see evhttp_free(), evhttp_accept_socket()
+ */
+int evhttp_bind_socket(struct evhttp *http, const char *address, u_short port);
+
+/**
+ * Makes an HTTP server accept connections on the specified socket
+ *
+ * This may be useful to create a socket and then fork multiple instances
+ * of an http server, or when a socket has been communicated via file
+ * descriptor passing in situations where an http servers does not have
+ * permissions to bind to a low-numbered port.
+ *
+ * Can be called multiple times to have the http server listen to
+ * multiple different sockets.
+ *
+ * @param http a pointer to an evhttp object
+ * @param fd a socket fd that is ready for accepting connections
+ * @return 0 on success, -1 on failure.
+ * @see evhttp_free(), evhttp_bind_socket()
+ */
+int evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd);
+
+/**
+ * Free the previously created HTTP server.
+ *
+ * Works only if no requests are currently being served.
+ *
+ * @param http the evhttp server object to be freed
+ * @see evhttp_start()
+ */
+void evhttp_free(struct evhttp* http);
+
+/** Set a callback for a specified URI */
+void evhttp_set_cb(struct evhttp *, const char *,
+    void (*)(struct evhttp_request *, void *), void *);
+
+/** Removes the callback for a specified URI */
+int evhttp_del_cb(struct evhttp *, const char *);
+
+/** 
+    Set a callback for all requests that are not caught by specific callbacks
+
+    Invokes the specified callback for all requests that do not match any of
+    the previously specified request paths.  This is catchall for requests not
+    specifically configured with evhttp_set_cb().
+
+    @param http the evhttp server object for which to set the callback
+    @param cb the callback to invoke for any unmatched requests
+    @param arg an context argument for the callback
+*/
+void evhttp_set_gencb(struct evhttp *http,
+    void (*cb)(struct evhttp_request *, void *), void *arg);
+
+/**
+   Adds a virtual host to the http server.
+
+   A virtual host is a newly initialized evhttp object that has request
+   callbacks set on it via evhttp_set_cb() or evhttp_set_gencb().  It
+   most not have any listing sockets associated with it.
+
+   If the virtual host has not been removed by the time that evhttp_free()
+   is called on the main http server, it will be automatically freed, too.
+
+   It is possible to have hierarchical vhosts.  For example: A vhost
+   with the pattern *.example.com may have other vhosts with patterns
+   foo.example.com and bar.example.com associated with it.
+
+   @param http the evhttp object to which to add a virtual host
+   @param pattern the glob pattern against which the hostname is matched.
+     The match is case insensitive and follows otherwise regular shell
+     matching.
+   @param vhost the virtual host to add the regular http server.
+   @return 0 on success, -1 on failure
+   @see evhttp_remove_virtual_host()
+*/
+int evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
+    struct evhttp* vhost);
+
+/**
+   Removes a virtual host from the http server.
+
+   @param http the evhttp object from which to remove the virtual host
+   @param vhost the virtual host to remove from the regular http server.
+   @return 0 on success, -1 on failure
+   @see evhttp_add_virtual_host()
+*/
+int evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost);
+
+/**
+ * Set the timeout for an HTTP request.
+ *
+ * @param http an evhttp object
+ * @param timeout_in_secs the timeout, in seconds
+ */
+void evhttp_set_timeout(struct evhttp *http, int timeout_in_secs);
+
+/* Request/Response functionality */
+
+/**
+ * Send an HTML error message to the client.
+ *
+ * @param req a request object
+ * @param error the HTTP error code
+ * @param reason a brief explanation of the error
+ */
+void evhttp_send_error(struct evhttp_request *req, int error,
+    const char *reason);
+
+/**
+ * Send an HTML reply to the client.
+ *
+ * @param req a request object
+ * @param code the HTTP response code to send
+ * @param reason a brief message to send with the response code
+ * @param databuf the body of the response
+ */
+void evhttp_send_reply(struct evhttp_request *req, int code,
+    const char *reason, struct evbuffer *databuf);
+
+/* Low-level response interface, for streaming/chunked replies */
+void evhttp_send_reply_start(struct evhttp_request *, int, const char *);
+void evhttp_send_reply_chunk(struct evhttp_request *, struct evbuffer *);
+void evhttp_send_reply_end(struct evhttp_request *);
+
+/*
+ * Interfaces for making requests
+ */
+enum evhttp_cmd_type { EVHTTP_REQ_GET, EVHTTP_REQ_POST, EVHTTP_REQ_HEAD, EVHTTP_REQ_PUT, EVHTTP_REQ_DELETE };
+
+enum evhttp_request_kind { EVHTTP_REQUEST, EVHTTP_RESPONSE };
+
+/**
+ * Creates a new request object that needs to be filled in with the request
+ * parameters.  The callback is executed when the request completed or an
+ * error occurred.
+ */
+struct evhttp_request *evhttp_request_new(
+	void (*cb)(struct evhttp_request *, void *), void *arg);
+
+/** enable delivery of chunks to requestor */
+void evhttp_request_set_chunked_cb(struct evhttp_request *,
+    void (*cb)(struct evhttp_request *, void *));
+
+/** Frees the request object and removes associated events. */
+void evhttp_request_free(struct evhttp_request *req);
+
+/**
+ * A connection object that can be used to for making HTTP requests.  The
+ * connection object tries to establish the connection when it is given an
+ * http request object.
+ */
+struct evhttp_connection *evhttp_connection_base_new(
+	struct event_base *base, const char *address, unsigned short port);
+
+/** Takes ownership of the request object
+ *
+ * Can be used in a request callback to keep onto the request until
+ * evhttp_request_free() is explicitly called by the user.
+ */
+void evhttp_request_own(struct evhttp_request *req);
+
+/** Returns 1 if the request is owned by the user */
+int evhttp_request_is_owned(struct evhttp_request *req);
+
+/** Frees an http connection */
+void evhttp_connection_free(struct evhttp_connection *evcon);
+
+/** sets the ip address from which http connections are made */
+void evhttp_connection_set_local_address(struct evhttp_connection *evcon,
+    const char *address);
+
+/** Sets the timeout for events related to this connection */
+void evhttp_connection_set_timeout(struct evhttp_connection *evcon,
+    int timeout_in_secs);
+
+/** Sets the retry limit for this connection - -1 repeats indefnitely */
+void evhttp_connection_set_retries(struct evhttp_connection *evcon,
+    int retry_max);
+
+/** Set a callback for connection close. */
+void evhttp_connection_set_closecb(struct evhttp_connection *evcon,
+    void (*)(struct evhttp_connection *, void *), void *);
+
+/** Get the remote address and port associated with this connection. */
+void evhttp_connection_get_peer(struct evhttp_connection *evcon,
+    char **address, u_short *port);
+
+/** The connection gets ownership of the request */
+int evhttp_make_request(struct evhttp_connection *evcon,
+    struct evhttp_request *req,
+    enum evhttp_cmd_type type, const char *uri);
+
+const char *evhttp_request_uri(struct evhttp_request *req);
+
+/* Interfaces for dealing with HTTP headers */
+
+/**
+   Finds the value belonging to a header.
+    
+   @param headers the evkeyvalq object in which to find the header
+   @param key the name of the header to find
+   @returns a pointer to the value for the header or NULL if the header
+     count not be found.
+   @see evhttp_add_header(), evhttp_remove_header()
+*/
+const char *evhttp_find_header(const struct evkeyvalq *headers,
+    const char *key);
+
+/**
+   Removes a header from a list of exisiting headers.
+    
+   @param headers the evkeyvalq object from which to remove a header
+   @param key the name of the header to remove
+   @returns 0 if the header was removed, -1  otherwise.
+   @see evhttp_find_header(), evhttp_add_header()
+*/
+int evhttp_remove_header(struct evkeyvalq *headers, const char *key);
+
+/**
+   Adds a header to a list of exisiting headers.
+    
+   @param headers the evkeyvalq object to which to add a header
+   @param key the name of the header
+   @param value the value belonging to the header
+   @returns 0 on success, -1  otherwise.
+   @see evhttp_find_header(), evhttp_clear_headers()
+*/
+int evhttp_add_header(struct evkeyvalq *headers, const char *key, const char *value);
+
+/**
+   Removes all headers from the header list.
+
+   @param headers the evkeyvalq object from which to remove all headers
+*/
+void evhttp_clear_headers(struct evkeyvalq *headers);
+
+/* Miscellaneous utility functions */
+
+
+/**
+  Helper function to encode a URI.
+
+  The returned string must be freed by the caller.
+
+  @param uri an unencoded URI
+  @return a newly allocated URI-encoded string
+ */
+char *evhttp_encode_uri(const char *uri);
+
+
+/**
+  Helper function to decode a URI.
+
+  The returned string must be freed by the caller.
+
+  @param uri an encoded URI
+  @return a newly allocated unencoded URI
+ */
+char *evhttp_decode_uri(const char *uri);
+
+
+/**
+ * Helper function to parse out arguments in a query.
+ * The arguments are separated by key and value.
+ * URI should already be decoded.
+ */
+void evhttp_parse_query(const char *uri, struct evkeyvalq *);
+
+
+/**
+ * Escape HTML character entities in a string.
+ *
+ * Replaces <, >, ", ' and & with &lt;, &gt;, &quot;,
+ * &#039; and &amp; correspondingly.
+ *
+ * The returned string needs to be freed by the caller.
+ *
+ * @param html an unescaped HTML string
+ * @return an escaped HTML string
+ */
+char *evhttp_htmlescape(const char *html);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _EVENT2_HTTP_H_ */
diff --git a/include/event2/http_compat.h b/include/event2/http_compat.h
new file mode 100644
index 00000000..9c792eb7
--- /dev/null
+++ b/include/event2/http_compat.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2000-2007 Niels Provos <provos@citi.umich.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _EVENT2_HTTP_COMPAT_H_
+#define _EVENT2_HTTP_COMPAT_H_
+
+/** @file http_compat.h
+
+  Potentially non-threadsafe versions of the functions in http.h: provided
+  only for backwards compatibility.
+
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <event-config.h>
+#ifdef _EVENT_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef _EVENT_HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+/* For int types. */
+#include <event2/util.h>
+
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+#endif
+
+/**
+ * Start an HTTP server on the specified address and port
+ *
+ * DEPRECATED: it does not allow an event base to be specified
+ *
+ * @param address the address to which the HTTP server should be bound
+ * @param port the port number on which the HTTP server should listen
+ * @return an struct evhttp object
+ */
+struct evhttp *evhttp_start(const char *address, u_short port);
+
+/**
+ * A connection object that can be used to for making HTTP requests.  The
+ * connection object tries to establish the connection when it is given an
+ * http request object.
+ */
+struct evhttp_connection *evhttp_connection_new(
+	const char *address, unsigned short port);
+
+/**
+ * Associates an event base with the connection - can only be called
+ * on a freshly created connection object that has not been used yet.
+ */
+void evhttp_connection_set_base(struct evhttp_connection *evcon,
+    struct event_base *base);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _EVENT2_EVENT_COMPAT_H_ */
diff --git a/include/event2/http_struct.h b/include/event2/http_struct.h
new file mode 100644
index 00000000..a6320aa2
--- /dev/null
+++ b/include/event2/http_struct.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2000-2007 Niels Provos <provos@citi.umich.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _EVENT2_HTTP_STRUCT_H_
+#define _EVENT2_HTTP_STRUCT_H_
+
+/** @file http_struct.h
+
+  Data structures for http.  Using these structures may hurt forward
+  compatibility with later versions of libevent: be careful!
+
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <event-config.h>
+#ifdef _EVENT_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef _EVENT_HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+/* For int types. */
+#include <event2/util.h>
+
+/**
+ * the request structure that a server receives.
+ * WARNING: expect this structure to change.  I will try to provide
+ * reasonable accessors.
+ */
+struct evhttp_request {
+#if defined(TAILQ_ENTRY)
+	TAILQ_ENTRY(evhttp_request) next;
+#else
+struct {
+	struct evhttp_request *tqe_next;
+	struct evhttp_request **tqe_prev;
+}       next;
+#endif
+
+	/* the connection object that this request belongs to */
+	struct evhttp_connection *evcon;
+	int flags;
+/** The request obj owns the evhttp connection and needs to free it */
+#define EVHTTP_REQ_OWN_CONNECTION	0x0001
+/** Request was made via a proxy */
+#define EVHTTP_PROXY_REQUEST		0x0002
+/** The request object is owned by the user; the user must free it */
+#define EVHTTP_USER_OWNED		0x0004
+
+	struct evkeyvalq *input_headers;
+	struct evkeyvalq *output_headers;
+
+	/* address of the remote host and the port connection came from */
+	char *remote_host;
+	u_short remote_port;
+
+	enum evhttp_request_kind kind;
+	enum evhttp_cmd_type type;
+
+	char *uri;			/* uri after HTTP request was parsed */
+
+	char major;			/* HTTP Major number */
+	char minor;			/* HTTP Minor number */
+
+	int got_firstline;
+	int response_code;		/* HTTP Response code */
+	char *response_code_line;	/* Readable response */
+
+	struct evbuffer *input_buffer;	/* read data */
+	ev_int64_t ntoread;
+	int chunked;
+
+	struct evbuffer *output_buffer;	/* outgoing post or data */
+
+	/* Callback */
+	void (*cb)(struct evhttp_request *, void *);
+	void *cb_arg;
+
+	/*
+	 * Chunked data callback - call for each completed chunk if
+	 * specified.  If not specified, all the data is delivered via
+	 * the regular callback.
+	 */
+	void (*chunk_cb)(struct evhttp_request *, void *);
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _EVENT2_HTTP_STRUCT_H_ */
+
-- 
2.40.0