1290001Sglebius/*
2290001Sglebius * Copyright 2001-2007 Niels Provos <provos@citi.umich.edu>
3290001Sglebius * Copyright 2007-2012 Niels Provos and Nick Mathewson
4290001Sglebius *
5290001Sglebius * This header file contains definitions for dealing with HTTP requests
6290001Sglebius * that are internal to libevent.  As user of the library, you should not
7290001Sglebius * need to know about these.
8290001Sglebius */
9290001Sglebius
10290001Sglebius#ifndef HTTP_INTERNAL_H_INCLUDED_
11290001Sglebius#define HTTP_INTERNAL_H_INCLUDED_
12290001Sglebius
13290001Sglebius#include "event2/event_struct.h"
14290001Sglebius#include "util-internal.h"
15290001Sglebius#include "defer-internal.h"
16290001Sglebius
17290001Sglebius#define HTTP_CONNECT_TIMEOUT	45
18290001Sglebius#define HTTP_WRITE_TIMEOUT	50
19290001Sglebius#define HTTP_READ_TIMEOUT	50
20290001Sglebius
21290001Sglebius#define HTTP_PREFIX		"http://"
22290001Sglebius#define HTTP_DEFAULTPORT	80
23290001Sglebius
24290001Sglebiusenum message_read_status {
25290001Sglebius	ALL_DATA_READ = 1,
26290001Sglebius	MORE_DATA_EXPECTED = 0,
27290001Sglebius	DATA_CORRUPTED = -1,
28290001Sglebius	REQUEST_CANCELED = -2,
29290001Sglebius	DATA_TOO_LONG = -3
30290001Sglebius};
31290001Sglebius
32290001Sglebiusstruct evbuffer;
33290001Sglebiusstruct addrinfo;
34290001Sglebiusstruct evhttp_request;
35290001Sglebius
36290001Sglebius/* Indicates an unknown request method. */
37290001Sglebius#define EVHTTP_REQ_UNKNOWN_ (1<<15)
38290001Sglebius
39290001Sglebiusenum evhttp_connection_state {
40290001Sglebius	EVCON_DISCONNECTED,	/**< not currently connected not trying either*/
41290001Sglebius	EVCON_CONNECTING,	/**< tries to currently connect */
42290001Sglebius	EVCON_IDLE,		/**< connection is established */
43290001Sglebius	EVCON_READING_FIRSTLINE,/**< reading Request-Line (incoming conn) or
44290001Sglebius				 **< Status-Line (outgoing conn) */
45290001Sglebius	EVCON_READING_HEADERS,	/**< reading request/response headers */
46290001Sglebius	EVCON_READING_BODY,	/**< reading request/response body */
47290001Sglebius	EVCON_READING_TRAILER,	/**< reading request/response chunked trailer */
48290001Sglebius	EVCON_WRITING		/**< writing request/response headers/body */
49290001Sglebius};
50290001Sglebius
51290001Sglebiusstruct event_base;
52290001Sglebius
53290001Sglebius/* A client or server connection. */
54290001Sglebiusstruct evhttp_connection {
55290001Sglebius	/* we use this tailq only if this connection was created for an http
56290001Sglebius	 * server */
57290001Sglebius	TAILQ_ENTRY(evhttp_connection) next;
58290001Sglebius
59290001Sglebius	evutil_socket_t fd;
60290001Sglebius	struct bufferevent *bufev;
61290001Sglebius
62290001Sglebius	struct event retry_ev;		/* for retrying connects */
63290001Sglebius
64290001Sglebius	char *bind_address;		/* address to use for binding the src */
65290001Sglebius	u_short bind_port;		/* local port for binding the src */
66290001Sglebius
67290001Sglebius	char *address;			/* address to connect to */
68290001Sglebius	u_short port;
69290001Sglebius
70290001Sglebius	size_t max_headers_size;
71290001Sglebius	ev_uint64_t max_body_size;
72290001Sglebius
73290001Sglebius	int flags;
74290001Sglebius#define EVHTTP_CON_INCOMING	0x0001	/* only one request on it ever */
75290001Sglebius#define EVHTTP_CON_OUTGOING	0x0002  /* multiple requests possible */
76290001Sglebius#define EVHTTP_CON_CLOSEDETECT  0x0004  /* detecting if persistent close */
77290001Sglebius#define EVHTTP_CON_AUTOFREE 0x0008  /* set when we want to auto free the connection */
78290001Sglebius
79290001Sglebius	struct timeval timeout;		/* timeout for events */
80290001Sglebius	int retry_cnt;			/* retry count */
81290001Sglebius	int retry_max;			/* maximum number of retries */
82290001Sglebius	struct timeval initial_retry_timeout; /* Timeout for low long to wait
83290001Sglebius					       * after first failing attempt
84290001Sglebius					       * before retry */
85290001Sglebius
86290001Sglebius	enum evhttp_connection_state state;
87290001Sglebius
88290001Sglebius	/* for server connections, the http server they are connected with */
89290001Sglebius	struct evhttp *http_server;
90290001Sglebius
91290001Sglebius	TAILQ_HEAD(evcon_requestq, evhttp_request) requests;
92290001Sglebius
93290001Sglebius	void (*cb)(struct evhttp_connection *, void *);
94290001Sglebius	void *cb_arg;
95290001Sglebius
96290001Sglebius	void (*closecb)(struct evhttp_connection *, void *);
97290001Sglebius	void *closecb_arg;
98290001Sglebius
99290001Sglebius	struct event_callback read_more_deferred_cb;
100290001Sglebius
101290001Sglebius	struct event_base *base;
102290001Sglebius	struct evdns_base *dns_base;
103290001Sglebius	int ai_family;
104290001Sglebius
105290001Sglebius	/* Saved conn_addr, to extract IP address from it.
106290001Sglebius	 *
107290001Sglebius	 * Because some servers may reset/close connection without waiting clients,
108290001Sglebius	 * in that case we can't extract IP address even in close_cb.
109290001Sglebius	 * So we need to save it, just after we connected to remote server. */
110290001Sglebius	struct sockaddr_storage *conn_address;
111290001Sglebius};
112290001Sglebius
113290001Sglebius/* A callback for an http server */
114290001Sglebiusstruct evhttp_cb {
115290001Sglebius	TAILQ_ENTRY(evhttp_cb) next;
116290001Sglebius
117290001Sglebius	char *what;
118290001Sglebius
119290001Sglebius	void (*cb)(struct evhttp_request *req, void *);
120290001Sglebius	void *cbarg;
121290001Sglebius};
122290001Sglebius
123290001Sglebius/* both the http server as well as the rpc system need to queue connections */
124290001SglebiusTAILQ_HEAD(evconq, evhttp_connection);
125290001Sglebius
126290001Sglebius/* each bound socket is stored in one of these */
127290001Sglebiusstruct evhttp_bound_socket {
128290001Sglebius	TAILQ_ENTRY(evhttp_bound_socket) next;
129290001Sglebius
130290001Sglebius	struct evconnlistener *listener;
131290001Sglebius};
132290001Sglebius
133290001Sglebius/* server alias list item. */
134290001Sglebiusstruct evhttp_server_alias {
135290001Sglebius	TAILQ_ENTRY(evhttp_server_alias) next;
136290001Sglebius
137290001Sglebius	char *alias; /* the server alias. */
138290001Sglebius};
139290001Sglebius
140290001Sglebiusstruct evhttp {
141290001Sglebius	/* Next vhost, if this is a vhost. */
142290001Sglebius	TAILQ_ENTRY(evhttp) next_vhost;
143290001Sglebius
144290001Sglebius	/* All listeners for this host */
145290001Sglebius	TAILQ_HEAD(boundq, evhttp_bound_socket) sockets;
146290001Sglebius
147290001Sglebius	TAILQ_HEAD(httpcbq, evhttp_cb) callbacks;
148290001Sglebius
149290001Sglebius	/* All live connections on this host. */
150290001Sglebius	struct evconq connections;
151290001Sglebius
152290001Sglebius	TAILQ_HEAD(vhostsq, evhttp) virtualhosts;
153290001Sglebius
154290001Sglebius	TAILQ_HEAD(aliasq, evhttp_server_alias) aliases;
155290001Sglebius
156290001Sglebius	/* NULL if this server is not a vhost */
157290001Sglebius	char *vhost_pattern;
158290001Sglebius
159290001Sglebius	struct timeval timeout;
160290001Sglebius
161290001Sglebius	size_t default_max_headers_size;
162290001Sglebius	ev_uint64_t default_max_body_size;
163290001Sglebius	const char *default_content_type;
164290001Sglebius
165290001Sglebius	/* Bitmask of all HTTP methods that we accept and pass to user
166290001Sglebius	 * callbacks. */
167290001Sglebius	ev_uint16_t allowed_methods;
168290001Sglebius
169290001Sglebius	/* Fallback callback if all the other callbacks for this connection
170290001Sglebius	   don't match. */
171290001Sglebius	void (*gencb)(struct evhttp_request *req, void *);
172290001Sglebius	void *gencbarg;
173290001Sglebius	struct bufferevent* (*bevcb)(struct event_base *, void *);
174290001Sglebius	void *bevcbarg;
175290001Sglebius
176290001Sglebius	struct event_base *base;
177290001Sglebius};
178290001Sglebius
179290001Sglebius/* XXX most of these functions could be static. */
180290001Sglebius
181290001Sglebius/* resets the connection; can be reused for more requests */
182290001Sglebiusvoid evhttp_connection_reset_(struct evhttp_connection *);
183290001Sglebius
184290001Sglebius/* connects if necessary */
185290001Sglebiusint evhttp_connection_connect_(struct evhttp_connection *);
186290001Sglebius
187290001Sglebiusenum evhttp_request_error;
188290001Sglebius/* notifies the current request that it failed; resets connection */
189290001Sglebiusvoid evhttp_connection_fail_(struct evhttp_connection *,
190290001Sglebius    enum evhttp_request_error error);
191290001Sglebius
192290001Sglebiusenum message_read_status;
193290001Sglebius
194290001Sglebiusenum message_read_status evhttp_parse_firstline_(struct evhttp_request *, struct evbuffer*);
195290001Sglebiusenum message_read_status evhttp_parse_headers_(struct evhttp_request *, struct evbuffer*);
196290001Sglebius
197290001Sglebiusvoid evhttp_start_read_(struct evhttp_connection *);
198290001Sglebius
199290001Sglebius/* response sending HTML the data in the buffer */
200290001Sglebiusvoid evhttp_response_code_(struct evhttp_request *, int, const char *);
201290001Sglebiusvoid evhttp_send_page_(struct evhttp_request *, struct evbuffer *);
202290001Sglebius
203290001Sglebiusint evhttp_decode_uri_internal(const char *uri, size_t length,
204290001Sglebius    char *ret, int decode_plus);
205290001Sglebius
206290001Sglebius#endif /* _HTTP_H */
207