mirror of
https://github.com/libevent/libevent.git
synced 2025-01-31 09:12:55 +08:00
migrate evhttp to event2; accessors are still missing
svn:r790
This commit is contained in:
parent
3f56e364b7
commit
de1c43926b
@ -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.
|
||||
|
4
Doxyfile
4
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
|
||||
|
426
evhttp.h
426
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 <, >, ",
|
||||
* ' and & 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_ */
|
||||
|
4
evrpc.c
4
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"
|
||||
|
18
http.c
18
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)
|
||||
{
|
||||
|
@ -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
|
||||
|
374
include/event2/http.h
Normal file
374
include/event2/http.h
Normal file
@ -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 <, >, ",
|
||||
* ' and & 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_ */
|
91
include/event2/http_compat.h
Normal file
91
include/event2/http_compat.h
Normal file
@ -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_ */
|
119
include/event2/http_struct.h
Normal file
119
include/event2/http_struct.h
Normal file
@ -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_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user