167754Smsmith/*
267754Smsmith * Copyright 2001-2007 Niels Provos <provos@citi.umich.edu>
367754Smsmith * Copyright 2007-2012 Niels Provos and Nick Mathewson
467754Smsmith *
567754Smsmith * This header file contains definitions for dealing with HTTP requests
667754Smsmith * that are internal to libevent.  As user of the library, you should not
7217365Sjkim * need to know about these.
8306536Sjkim */
970243Smsmith
1067754Smsmith#ifndef HTTP_INTERNAL_H_INCLUDED_
11217365Sjkim#define HTTP_INTERNAL_H_INCLUDED_
12217365Sjkim
13217365Sjkim#include "event2/event_struct.h"
14217365Sjkim#include "util-internal.h"
15217365Sjkim#include "defer-internal.h"
16217365Sjkim
17217365Sjkim#define HTTP_CONNECT_TIMEOUT	45
18217365Sjkim#define HTTP_WRITE_TIMEOUT	50
19217365Sjkim#define HTTP_READ_TIMEOUT	50
20217365Sjkim
21217365Sjkim#define HTTP_PREFIX		"http://"
22217365Sjkim#define HTTP_DEFAULTPORT	80
23217365Sjkim
24217365Sjkimenum message_read_status {
2567754Smsmith	ALL_DATA_READ = 1,
26217365Sjkim	MORE_DATA_EXPECTED = 0,
27217365Sjkim	DATA_CORRUPTED = -1,
28217365Sjkim	REQUEST_CANCELED = -2,
2967754Smsmith	DATA_TOO_LONG = -3
30217365Sjkim};
31217365Sjkim
32217365Sjkimstruct evbuffer;
33217365Sjkimstruct addrinfo;
34217365Sjkimstruct evhttp_request;
35217365Sjkim
36217365Sjkim/* Indicates an unknown request method. */
37217365Sjkim#define EVHTTP_REQ_UNKNOWN_ (1<<15)
38217365Sjkim
39217365Sjkimenum evhttp_connection_state {
40217365Sjkim	EVCON_DISCONNECTED,	/**< not currently connected not trying either*/
41217365Sjkim	EVCON_CONNECTING,	/**< tries to currently connect */
42217365Sjkim	EVCON_IDLE,		/**< connection is established */
4367754Smsmith	EVCON_READING_FIRSTLINE,/**< reading Request-Line (incoming conn) or
44193341Sjkim				 **< Status-Line (outgoing conn) */
45193341Sjkim	EVCON_READING_HEADERS,	/**< reading request/response headers */
46193341Sjkim	EVCON_READING_BODY,	/**< reading request/response body */
47193341Sjkim	EVCON_READING_TRAILER,	/**< reading request/response chunked trailer */
48193341Sjkim	EVCON_WRITING		/**< writing request/response headers/body */
49193341Sjkim};
5067754Smsmith
5177424Smsmithstruct event_base;
5291116Smsmith
5367754Smsmith/* A client or server connection. */
54151937Sjkimstruct evhttp_connection {
5567754Smsmith	/* we use this tailq only if this connection was created for an http
56151937Sjkim	 * server */
57151937Sjkim	TAILQ_ENTRY(evhttp_connection) next;
58151937Sjkim
59151937Sjkim	evutil_socket_t fd;
60151937Sjkim	struct bufferevent *bufev;
61151937Sjkim
62151937Sjkim	struct event retry_ev;		/* for retrying connects */
63151937Sjkim
64151937Sjkim	char *bind_address;		/* address to use for binding the src */
6567754Smsmith	u_short bind_port;		/* local port for binding the src */
6667754Smsmith
6767754Smsmith	char *address;			/* address to connect to */
6867754Smsmith	u_short port;
6967754Smsmith
7067754Smsmith	size_t max_headers_size;
71167802Sjkim	ev_uint64_t max_body_size;
7267754Smsmith
7367754Smsmith	int flags;
74167802Sjkim#define EVHTTP_CON_INCOMING	0x0001	/* only one request on it ever */
75167802Sjkim#define EVHTTP_CON_OUTGOING	0x0002  /* multiple requests possible */
7667754Smsmith#define EVHTTP_CON_CLOSEDETECT  0x0004  /* detecting if persistent close */
7767754Smsmith#define EVHTTP_CON_AUTOFREE 0x0008  /* set when we want to auto free the connection */
7867754Smsmith
79151937Sjkim	struct timeval timeout;		/* timeout for events */
8067754Smsmith	int retry_cnt;			/* retry count */
8167754Smsmith	int retry_max;			/* maximum number of retries */
8267754Smsmith	struct timeval initial_retry_timeout; /* Timeout for low long to wait
83167802Sjkim					       * after first failing attempt
84167802Sjkim					       * before retry */
85193267Sjkim
86167802Sjkim	enum evhttp_connection_state state;
8767754Smsmith
8867754Smsmith	/* for server connections, the http server they are connected with */
89167802Sjkim	struct evhttp *http_server;
9067754Smsmith
9167754Smsmith	TAILQ_HEAD(evcon_requestq, evhttp_request) requests;
92167802Sjkim
93167802Sjkim	void (*cb)(struct evhttp_connection *, void *);
94167802Sjkim	void *cb_arg;
95167802Sjkim
96167802Sjkim	void (*closecb)(struct evhttp_connection *, void *);
97193267Sjkim	void *closecb_arg;
9867754Smsmith
99167802Sjkim	struct event_callback read_more_deferred_cb;
100167802Sjkim
101167802Sjkim	struct event_base *base;
10267754Smsmith	struct evdns_base *dns_base;
103167802Sjkim	int ai_family;
104167802Sjkim
105167802Sjkim	/* Saved conn_addr, to extract IP address from it.
106167802Sjkim	 *
107167802Sjkim	 * Because some servers may reset/close connection without waiting clients,
108167802Sjkim	 * in that case we can't extract IP address even in close_cb.
109167802Sjkim	 * So we need to save it, just after we connected to remote server. */
110167802Sjkim	struct sockaddr_storage *conn_address;
11167754Smsmith};
112167802Sjkim
113167802Sjkim/* A callback for an http server */
114167802Sjkimstruct evhttp_cb {
11567754Smsmith	TAILQ_ENTRY(evhttp_cb) next;
116167802Sjkim
11767754Smsmith	char *what;
118167802Sjkim
119246849Sjkim	void (*cb)(struct evhttp_request *req, void *);
12067754Smsmith	void *cbarg;
12167754Smsmith};
12267754Smsmith
12367754Smsmith/* both the http server as well as the rpc system need to queue connections */
12467754SmsmithTAILQ_HEAD(evconq, evhttp_connection);
12567754Smsmith
12667754Smsmith/* each bound socket is stored in one of these */
12767754Smsmithstruct evhttp_bound_socket {
12867754Smsmith	TAILQ_ENTRY(evhttp_bound_socket) next;
12967754Smsmith
13067754Smsmith	struct evconnlistener *listener;
13167754Smsmith};
132241973Sjkim
13367754Smsmith/* server alias list item. */
13467754Smsmithstruct evhttp_server_alias {
13567754Smsmith	TAILQ_ENTRY(evhttp_server_alias) next;
13667754Smsmith
13767754Smsmith	char *alias; /* the server alias. */
13867754Smsmith};
13967754Smsmith
14067754Smsmithstruct evhttp {
141167802Sjkim	/* Next vhost, if this is a vhost. */
14267754Smsmith	TAILQ_ENTRY(evhttp) next_vhost;
14367754Smsmith
144167802Sjkim	/* All listeners for this host */
14567754Smsmith	TAILQ_HEAD(boundq, evhttp_bound_socket) sockets;
14667754Smsmith
147167802Sjkim	TAILQ_HEAD(httpcbq, evhttp_cb) callbacks;
148107325Siwasaki
149167802Sjkim	/* All live connections on this host. */
15067754Smsmith	struct evconq connections;
151167802Sjkim
15267754Smsmith	TAILQ_HEAD(vhostsq, evhttp) virtualhosts;
15367754Smsmith
15467754Smsmith	TAILQ_HEAD(aliasq, evhttp_server_alias) aliases;
15567754Smsmith
15667754Smsmith	/* NULL if this server is not a vhost */
15767754Smsmith	char *vhost_pattern;
15867754Smsmith
15967754Smsmith	struct timeval timeout;
16067754Smsmith
16167754Smsmith	size_t default_max_headers_size;
16267754Smsmith	ev_uint64_t default_max_body_size;
16367754Smsmith	const char *default_content_type;
164241973Sjkim
165241973Sjkim	/* Bitmask of all HTTP methods that we accept and pass to user
16667754Smsmith	 * callbacks. */
16767754Smsmith	ev_uint16_t allowed_methods;
16867754Smsmith
16967754Smsmith	/* Fallback callback if all the other callbacks for this connection
170114237Snjl	   don't match. */
17167754Smsmith	void (*gencb)(struct evhttp_request *req, void *);
17267754Smsmith	void *gencbarg;
17367754Smsmith	struct bufferevent* (*bevcb)(struct event_base *, void *);
17499679Siwasaki	void *bevcbarg;
17599679Siwasaki
17667754Smsmith	struct event_base *base;
17767754Smsmith};
178167802Sjkim
17967754Smsmith/* XXX most of these functions could be static. */
18067754Smsmith
181167802Sjkim/* resets the connection; can be reused for more requests */
18267754Smsmithvoid evhttp_connection_reset_(struct evhttp_connection *);
183245582Sjkim
184245582Sjkim/* connects if necessary */
18567754Smsmithint evhttp_connection_connect_(struct evhttp_connection *);
18667754Smsmith
18767754Smsmithenum evhttp_request_error;
18867754Smsmith/* notifies the current request that it failed; resets connection */
189167802Sjkimvoid evhttp_connection_fail_(struct evhttp_connection *,
19067754Smsmith    enum evhttp_request_error error);
191167802Sjkim
19267754Smsmithenum message_read_status;
19367754Smsmith
19467754Smsmithenum message_read_status evhttp_parse_firstline_(struct evhttp_request *, struct evbuffer*);
19567754Smsmithenum message_read_status evhttp_parse_headers_(struct evhttp_request *, struct evbuffer*);
19667754Smsmith
19767754Smsmithvoid evhttp_start_read_(struct evhttp_connection *);
19867754Smsmith
19967754Smsmith/* response sending HTML the data in the buffer */
20067754Smsmithvoid evhttp_response_code_(struct evhttp_request *, int, const char *);
20167754Smsmithvoid evhttp_send_page_(struct evhttp_request *, struct evbuffer *);
20267754Smsmith
20367754Smsmithint evhttp_decode_uri_internal(const char *uri, size_t length,
20467754Smsmith    char *ret, int decode_plus);
20567754Smsmith
20699679Siwasaki#endif /* _HTTP_H */
20767754Smsmith