OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu> | |
3 * All rights reserved. | |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions | |
7 * are met: | |
8 * 1. Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * 2. Redistributions in binary form must reproduce the above copyright | |
11 * notice, this list of conditions and the following disclaimer in the | |
12 * documentation and/or other materials provided with the distribution. | |
13 * 3. The name of the author may not be used to endorse or promote products | |
14 * derived from this software without specific prior written permission. | |
15 * | |
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 */ | |
27 #ifndef _EVHTTP_H_ | |
28 #define _EVHTTP_H_ | |
29 | |
30 #include "event.h" | |
31 | |
32 #ifdef __cplusplus | |
33 extern "C" { | |
34 #endif | |
35 | |
36 #ifdef WIN32 | |
37 #define WIN32_LEAN_AND_MEAN | |
38 #include <winsock2.h> | |
39 #include <windows.h> | |
40 #undef WIN32_LEAN_AND_MEAN | |
41 #endif | |
42 | |
43 /** @file evhttp.h | |
44 * | |
45 * Basic support for HTTP serving. | |
46 * | |
47 * As libevent is a library for dealing with event notification and most | |
48 * interesting applications are networked today, I have often found the | |
49 * need to write HTTP code. The following prototypes and definitions provide | |
50 * an application with a minimal interface for making HTTP requests and for | |
51 * creating a very simple HTTP server. | |
52 */ | |
53 | |
54 /* Response codes */ | |
55 #define HTTP_OK 200 | |
56 #define HTTP_NOCONTENT 204 | |
57 #define HTTP_MOVEPERM 301 | |
58 #define HTTP_MOVETEMP 302 | |
59 #define HTTP_NOTMODIFIED 304 | |
60 #define HTTP_BADREQUEST 400 | |
61 #define HTTP_NOTFOUND 404 | |
62 #define HTTP_SERVUNAVAIL 503 | |
63 | |
64 struct evhttp; | |
65 struct evhttp_request; | |
66 struct evkeyvalq; | |
67 | |
68 /** Create a new HTTP server | |
69 * | |
70 * @param base (optional) the event base to receive the HTTP events | |
71 * @return a pointer to a newly initialized evhttp server structure | |
72 */ | |
73 struct evhttp *evhttp_new(struct event_base *base); | |
74 | |
75 /** | |
76 * Binds an HTTP server on the specified address and port. | |
77 * | |
78 * Can be called multiple times to bind the same http server | |
79 * to multiple different ports. | |
80 * | |
81 * @param http a pointer to an evhttp object | |
82 * @param address a string containing the IP address to listen(2) on | |
83 * @param port the port number to listen on | |
84 * @return 0 on success, -1 on failure | |
85 * @see evhttp_free() | |
86 */ | |
87 int evhttp_bind_socket(struct evhttp *http, const char *address, u_short port); | |
88 | |
89 /** | |
90 * Makes an HTTP server accept connections on the specified socket | |
91 * | |
92 * This may be useful to create a socket and then fork multiple instances | |
93 * of an http server, or when a socket has been communicated via file | |
94 * descriptor passing in situations where an http servers does not have | |
95 * permissions to bind to a low-numbered port. | |
96 * | |
97 * Can be called multiple times to have the http server listen to | |
98 * multiple different sockets. | |
99 * | |
100 * @param http a pointer to an evhttp object | |
101 * @param fd a socket fd that is ready for accepting connections | |
102 * @return 0 on success, -1 on failure. | |
103 * @see evhttp_free(), evhttp_bind_socket() | |
104 */ | |
105 int evhttp_accept_socket(struct evhttp *http, int fd); | |
106 | |
107 /** | |
108 * Free the previously created HTTP server. | |
109 * | |
110 * Works only if no requests are currently being served. | |
111 * | |
112 * @param http the evhttp server object to be freed | |
113 * @see evhttp_start() | |
114 */ | |
115 void evhttp_free(struct evhttp* http); | |
116 | |
117 /** Set a callback for a specified URI */ | |
118 void evhttp_set_cb(struct evhttp *, const char *, | |
119 void (*)(struct evhttp_request *, void *), void *); | |
120 | |
121 /** Removes the callback for a specified URI */ | |
122 int evhttp_del_cb(struct evhttp *, const char *); | |
123 | |
124 /** Set a callback for all requests that are not caught by specific callbacks | |
125 */ | |
126 void evhttp_set_gencb(struct evhttp *, | |
127 void (*)(struct evhttp_request *, void *), void *); | |
128 | |
129 /** | |
130 * Set the timeout for an HTTP request. | |
131 * | |
132 * @param http an evhttp object | |
133 * @param timeout_in_secs the timeout, in seconds | |
134 */ | |
135 void evhttp_set_timeout(struct evhttp *, int timeout_in_secs); | |
136 | |
137 /* Request/Response functionality */ | |
138 | |
139 /** | |
140 * Send an HTML error message to the client. | |
141 * | |
142 * @param req a request object | |
143 * @param error the HTTP error code | |
144 * @param reason a brief explanation of the error | |
145 */ | |
146 void evhttp_send_error(struct evhttp_request *req, int error, | |
147 const char *reason); | |
148 | |
149 /** | |
150 * Send an HTML reply to the client. | |
151 * | |
152 * @param req a request object | |
153 * @param code the HTTP response code to send | |
154 * @param reason a brief message to send with the response code | |
155 * @param databuf the body of the response | |
156 */ | |
157 void evhttp_send_reply(struct evhttp_request *req, int code, | |
158 const char *reason, struct evbuffer *databuf); | |
159 | |
160 /* Low-level response interface, for streaming/chunked replies */ | |
161 void evhttp_send_reply_start(struct evhttp_request *, int, const char *); | |
162 void evhttp_send_reply_chunk(struct evhttp_request *, struct evbuffer *); | |
163 void evhttp_send_reply_end(struct evhttp_request *); | |
164 | |
165 /** | |
166 * Start an HTTP server on the specified address and port | |
167 * | |
168 * DEPRECATED: it does not allow an event base to be specified | |
169 * | |
170 * @param address the address to which the HTTP server should be bound | |
171 * @param port the port number on which the HTTP server should listen | |
172 * @return an struct evhttp object | |
173 */ | |
174 struct evhttp *evhttp_start(const char *address, u_short port); | |
175 | |
176 /* | |
177 * Interfaces for making requests | |
178 */ | |
179 enum evhttp_cmd_type { EVHTTP_REQ_GET, EVHTTP_REQ_POST, EVHTTP_REQ_HEAD }; | |
180 | |
181 enum evhttp_request_kind { EVHTTP_REQUEST, EVHTTP_RESPONSE }; | |
182 | |
183 /** | |
184 * the request structure that a server receives. | |
185 * WARNING: expect this structure to change. I will try to provide | |
186 * reasonable accessors. | |
187 */ | |
188 struct evhttp_request { | |
189 #if defined(TAILQ_ENTRY) | |
190 TAILQ_ENTRY(evhttp_request) next; | |
191 #else | |
192 struct { | |
193 struct evhttp_request *tqe_next; | |
194 struct evhttp_request **tqe_prev; | |
195 } next; | |
196 #endif | |
197 | |
198 /* the connection object that this request belongs to */ | |
199 struct evhttp_connection *evcon; | |
200 int flags; | |
201 #define EVHTTP_REQ_OWN_CONNECTION 0x0001 | |
202 #define EVHTTP_PROXY_REQUEST 0x0002 | |
203 | |
204 struct evkeyvalq *input_headers; | |
205 struct evkeyvalq *output_headers; | |
206 | |
207 /* address of the remote host and the port connection came from */ | |
208 char *remote_host; | |
209 u_short remote_port; | |
210 | |
211 enum evhttp_request_kind kind; | |
212 enum evhttp_cmd_type type; | |
213 | |
214 char *uri; /* uri after HTTP request was parsed */ | |
215 | |
216 char major; /* HTTP Major number */ | |
217 char minor; /* HTTP Minor number */ | |
218 | |
219 int response_code; /* HTTP Response code */ | |
220 char *response_code_line; /* Readable response */ | |
221 | |
222 struct evbuffer *input_buffer; /* read data */ | |
223 ev_int64_t ntoread; | |
224 int chunked:1, /* a chunked request */ | |
225 userdone:1; /* the user has sent all data */ | |
226 | |
227 struct evbuffer *output_buffer; /* outgoing post or data */ | |
228 | |
229 /* Callback */ | |
230 void (*cb)(struct evhttp_request *, void *); | |
231 void *cb_arg; | |
232 | |
233 /* | |
234 * Chunked data callback - call for each completed chunk if | |
235 * specified. If not specified, all the data is delivered via | |
236 * the regular callback. | |
237 */ | |
238 void (*chunk_cb)(struct evhttp_request *, void *); | |
239 }; | |
240 | |
241 /** | |
242 * Creates a new request object that needs to be filled in with the request | |
243 * parameters. The callback is executed when the request completed or an | |
244 * error occurred. | |
245 */ | |
246 struct evhttp_request *evhttp_request_new( | |
247 void (*cb)(struct evhttp_request *, void *), void *arg); | |
248 | |
249 /** enable delivery of chunks to requestor */ | |
250 void evhttp_request_set_chunked_cb(struct evhttp_request *, | |
251 void (*cb)(struct evhttp_request *, void *)); | |
252 | |
253 /** Frees the request object and removes associated events. */ | |
254 void evhttp_request_free(struct evhttp_request *req); | |
255 | |
256 /** Returns the connection object associated with the request or NULL */ | |
257 struct evhttp_connection *evhttp_request_get_connection(struct evhttp_request *r
eq); | |
258 | |
259 /** | |
260 * A connection object that can be used to for making HTTP requests. The | |
261 * connection object tries to establish the connection when it is given an | |
262 * http request object. | |
263 */ | |
264 struct evhttp_connection *evhttp_connection_new( | |
265 const char *address, unsigned short port); | |
266 | |
267 /** Frees an http connection */ | |
268 void evhttp_connection_free(struct evhttp_connection *evcon); | |
269 | |
270 /** sets the ip address from which http connections are made */ | |
271 void evhttp_connection_set_local_address(struct evhttp_connection *evcon, | |
272 const char *address); | |
273 | |
274 /** sets the local port from which http connections are made */ | |
275 void evhttp_connection_set_local_port(struct evhttp_connection *evcon, | |
276 unsigned short port); | |
277 | |
278 /** Sets the timeout for events related to this connection */ | |
279 void evhttp_connection_set_timeout(struct evhttp_connection *evcon, | |
280 int timeout_in_secs); | |
281 | |
282 /** Sets the retry limit for this connection - -1 repeats indefnitely */ | |
283 void evhttp_connection_set_retries(struct evhttp_connection *evcon, | |
284 int retry_max); | |
285 | |
286 /** Set a callback for connection close. */ | |
287 void evhttp_connection_set_closecb(struct evhttp_connection *evcon, | |
288 void (*)(struct evhttp_connection *, void *), void *); | |
289 | |
290 /** | |
291 * Associates an event base with the connection - can only be called | |
292 * on a freshly created connection object that has not been used yet. | |
293 */ | |
294 void evhttp_connection_set_base(struct evhttp_connection *evcon, | |
295 struct event_base *base); | |
296 | |
297 /** Get the remote address and port associated with this connection. */ | |
298 void evhttp_connection_get_peer(struct evhttp_connection *evcon, | |
299 char **address, u_short *port); | |
300 | |
301 /** The connection gets ownership of the request */ | |
302 int evhttp_make_request(struct evhttp_connection *evcon, | |
303 struct evhttp_request *req, | |
304 enum evhttp_cmd_type type, const char *uri); | |
305 | |
306 const char *evhttp_request_uri(struct evhttp_request *req); | |
307 | |
308 /* Interfaces for dealing with HTTP headers */ | |
309 | |
310 const char *evhttp_find_header(const struct evkeyvalq *, const char *); | |
311 int evhttp_remove_header(struct evkeyvalq *, const char *); | |
312 int evhttp_add_header(struct evkeyvalq *, const char *, const char *); | |
313 void evhttp_clear_headers(struct evkeyvalq *); | |
314 | |
315 /* Miscellaneous utility functions */ | |
316 | |
317 | |
318 /** | |
319 Helper function to encode a URI. | |
320 | |
321 The returned string must be freed by the caller. | |
322 | |
323 @param uri an unencoded URI | |
324 @return a newly allocated URI-encoded string | |
325 */ | |
326 char *evhttp_encode_uri(const char *uri); | |
327 | |
328 | |
329 /** | |
330 Helper function to decode a URI. | |
331 | |
332 The returned string must be freed by the caller. | |
333 | |
334 @param uri an encoded URI | |
335 @return a newly allocated unencoded URI | |
336 */ | |
337 char *evhttp_decode_uri(const char *uri); | |
338 | |
339 | |
340 /** | |
341 * Helper function to parse out arguments in a query. | |
342 * | |
343 * Parsing a uri like | |
344 * | |
345 * http://foo.com/?q=test&s=some+thing | |
346 * | |
347 * will result in two entries in the key value queue. | |
348 | |
349 * The first entry is: key="q", value="test" | |
350 * The second entry is: key="s", value="some thing" | |
351 * | |
352 * @param uri the request URI | |
353 * @param headers the head of the evkeyval queue | |
354 */ | |
355 void evhttp_parse_query(const char *uri, struct evkeyvalq *headers); | |
356 | |
357 | |
358 /** | |
359 * Escape HTML character entities in a string. | |
360 * | |
361 * Replaces <, >, ", ' and & with <, >, ", | |
362 * ' and & correspondingly. | |
363 * | |
364 * The returned string needs to be freed by the caller. | |
365 * | |
366 * @param html an unescaped HTML string | |
367 * @return an escaped HTML string | |
368 */ | |
369 char *evhttp_htmlescape(const char *html); | |
370 | |
371 #ifdef __cplusplus | |
372 } | |
373 #endif | |
374 | |
375 #endif /* _EVHTTP_H_ */ | |
OLD | NEW |