1*0a6a1f1dSLionel Sambuc /* $NetBSD: http.h,v 1.1.1.2 2015/01/29 06:38:28 spz Exp $ */ 2*0a6a1f1dSLionel Sambuc /* $NetBSD: http.h,v 1.1.1.2 2015/01/29 06:38:28 spz Exp $ */ 3e985b929SDavid van Moolenbroek /* 4e985b929SDavid van Moolenbroek * Copyright (c) 2000-2007 Niels Provos <provos@citi.umich.edu> 5e985b929SDavid van Moolenbroek * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 6e985b929SDavid van Moolenbroek * 7e985b929SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without 8e985b929SDavid van Moolenbroek * modification, are permitted provided that the following conditions 9e985b929SDavid van Moolenbroek * are met: 10e985b929SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright 11e985b929SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer. 12e985b929SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright 13e985b929SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the 14e985b929SDavid van Moolenbroek * documentation and/or other materials provided with the distribution. 15e985b929SDavid van Moolenbroek * 3. The name of the author may not be used to endorse or promote products 16e985b929SDavid van Moolenbroek * derived from this software without specific prior written permission. 17e985b929SDavid van Moolenbroek * 18e985b929SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19e985b929SDavid van Moolenbroek * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20e985b929SDavid van Moolenbroek * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21e985b929SDavid van Moolenbroek * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22e985b929SDavid van Moolenbroek * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23e985b929SDavid van Moolenbroek * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24e985b929SDavid van Moolenbroek * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25e985b929SDavid van Moolenbroek * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26e985b929SDavid van Moolenbroek * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27e985b929SDavid van Moolenbroek * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28e985b929SDavid van Moolenbroek */ 29e985b929SDavid van Moolenbroek #ifndef _EVENT2_HTTP_H_ 30e985b929SDavid van Moolenbroek #define _EVENT2_HTTP_H_ 31e985b929SDavid van Moolenbroek 32e985b929SDavid van Moolenbroek /* For int types. */ 33e985b929SDavid van Moolenbroek #include <event2/util.h> 34e985b929SDavid van Moolenbroek 35e985b929SDavid van Moolenbroek #ifdef __cplusplus 36e985b929SDavid van Moolenbroek extern "C" { 37e985b929SDavid van Moolenbroek #endif 38e985b929SDavid van Moolenbroek 39e985b929SDavid van Moolenbroek /* In case we haven't included the right headers yet. */ 40e985b929SDavid van Moolenbroek struct evbuffer; 41e985b929SDavid van Moolenbroek struct event_base; 42e985b929SDavid van Moolenbroek 43e985b929SDavid van Moolenbroek /** @file event2/http.h 44e985b929SDavid van Moolenbroek * 45e985b929SDavid van Moolenbroek * Basic support for HTTP serving. 46e985b929SDavid van Moolenbroek * 47e985b929SDavid van Moolenbroek * As Libevent is a library for dealing with event notification and most 48e985b929SDavid van Moolenbroek * interesting applications are networked today, I have often found the 49e985b929SDavid van Moolenbroek * need to write HTTP code. The following prototypes and definitions provide 50e985b929SDavid van Moolenbroek * an application with a minimal interface for making HTTP requests and for 51e985b929SDavid van Moolenbroek * creating a very simple HTTP server. 52e985b929SDavid van Moolenbroek */ 53e985b929SDavid van Moolenbroek 54e985b929SDavid van Moolenbroek /* Response codes */ 55e985b929SDavid van Moolenbroek #define HTTP_OK 200 /**< request completed ok */ 56e985b929SDavid van Moolenbroek #define HTTP_NOCONTENT 204 /**< request does not have content */ 57e985b929SDavid van Moolenbroek #define HTTP_MOVEPERM 301 /**< the uri moved permanently */ 58e985b929SDavid van Moolenbroek #define HTTP_MOVETEMP 302 /**< the uri moved temporarily */ 59e985b929SDavid van Moolenbroek #define HTTP_NOTMODIFIED 304 /**< page was not modified from last */ 60e985b929SDavid van Moolenbroek #define HTTP_BADREQUEST 400 /**< invalid http request was made */ 61e985b929SDavid van Moolenbroek #define HTTP_NOTFOUND 404 /**< could not find content for uri */ 62e985b929SDavid van Moolenbroek #define HTTP_BADMETHOD 405 /**< method not allowed for this uri */ 63e985b929SDavid van Moolenbroek #define HTTP_ENTITYTOOLARGE 413 /**< */ 64e985b929SDavid van Moolenbroek #define HTTP_EXPECTATIONFAILED 417 /**< we can't handle this expectation */ 65e985b929SDavid van Moolenbroek #define HTTP_INTERNAL 500 /**< internal error */ 66e985b929SDavid van Moolenbroek #define HTTP_NOTIMPLEMENTED 501 /**< not implemented */ 67e985b929SDavid van Moolenbroek #define HTTP_SERVUNAVAIL 503 /**< the server is not available */ 68e985b929SDavid van Moolenbroek 69e985b929SDavid van Moolenbroek struct evhttp; 70e985b929SDavid van Moolenbroek struct evhttp_request; 71e985b929SDavid van Moolenbroek struct evkeyvalq; 72e985b929SDavid van Moolenbroek struct evhttp_bound_socket; 73e985b929SDavid van Moolenbroek struct evconnlistener; 74e985b929SDavid van Moolenbroek 75e985b929SDavid van Moolenbroek /** 76e985b929SDavid van Moolenbroek * Create a new HTTP server. 77e985b929SDavid van Moolenbroek * 78e985b929SDavid van Moolenbroek * @param base (optional) the event base to receive the HTTP events 79e985b929SDavid van Moolenbroek * @return a pointer to a newly initialized evhttp server structure 80e985b929SDavid van Moolenbroek * @see evhttp_free() 81e985b929SDavid van Moolenbroek */ 82e985b929SDavid van Moolenbroek struct evhttp *evhttp_new(struct event_base *base); 83e985b929SDavid van Moolenbroek 84e985b929SDavid van Moolenbroek /** 85e985b929SDavid van Moolenbroek * Binds an HTTP server on the specified address and port. 86e985b929SDavid van Moolenbroek * 87e985b929SDavid van Moolenbroek * Can be called multiple times to bind the same http server 88e985b929SDavid van Moolenbroek * to multiple different ports. 89e985b929SDavid van Moolenbroek * 90e985b929SDavid van Moolenbroek * @param http a pointer to an evhttp object 91e985b929SDavid van Moolenbroek * @param address a string containing the IP address to listen(2) on 92e985b929SDavid van Moolenbroek * @param port the port number to listen on 93e985b929SDavid van Moolenbroek * @return 0 on success, -1 on failure. 94e985b929SDavid van Moolenbroek * @see evhttp_accept_socket() 95e985b929SDavid van Moolenbroek */ 96e985b929SDavid van Moolenbroek int evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port); 97e985b929SDavid van Moolenbroek 98e985b929SDavid van Moolenbroek /** 99e985b929SDavid van Moolenbroek * Like evhttp_bind_socket(), but returns a handle for referencing the socket. 100e985b929SDavid van Moolenbroek * 101e985b929SDavid van Moolenbroek * The returned pointer is not valid after \a http is freed. 102e985b929SDavid van Moolenbroek * 103e985b929SDavid van Moolenbroek * @param http a pointer to an evhttp object 104e985b929SDavid van Moolenbroek * @param address a string containing the IP address to listen(2) on 105e985b929SDavid van Moolenbroek * @param port the port number to listen on 106e985b929SDavid van Moolenbroek * @return Handle for the socket on success, NULL on failure. 107e985b929SDavid van Moolenbroek * @see evhttp_bind_socket(), evhttp_del_accept_socket() 108e985b929SDavid van Moolenbroek */ 109e985b929SDavid van Moolenbroek struct evhttp_bound_socket *evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port); 110e985b929SDavid van Moolenbroek 111e985b929SDavid van Moolenbroek /** 112e985b929SDavid van Moolenbroek * Makes an HTTP server accept connections on the specified socket. 113e985b929SDavid van Moolenbroek * 114e985b929SDavid van Moolenbroek * This may be useful to create a socket and then fork multiple instances 115e985b929SDavid van Moolenbroek * of an http server, or when a socket has been communicated via file 116e985b929SDavid van Moolenbroek * descriptor passing in situations where an http servers does not have 117e985b929SDavid van Moolenbroek * permissions to bind to a low-numbered port. 118e985b929SDavid van Moolenbroek * 119e985b929SDavid van Moolenbroek * Can be called multiple times to have the http server listen to 120e985b929SDavid van Moolenbroek * multiple different sockets. 121e985b929SDavid van Moolenbroek * 122e985b929SDavid van Moolenbroek * @param http a pointer to an evhttp object 123e985b929SDavid van Moolenbroek * @param fd a socket fd that is ready for accepting connections 124e985b929SDavid van Moolenbroek * @return 0 on success, -1 on failure. 125e985b929SDavid van Moolenbroek * @see evhttp_bind_socket() 126e985b929SDavid van Moolenbroek */ 127e985b929SDavid van Moolenbroek int evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd); 128e985b929SDavid van Moolenbroek 129e985b929SDavid van Moolenbroek /** 130e985b929SDavid van Moolenbroek * Like evhttp_accept_socket(), but returns a handle for referencing the socket. 131e985b929SDavid van Moolenbroek * 132e985b929SDavid van Moolenbroek * The returned pointer is not valid after \a http is freed. 133e985b929SDavid van Moolenbroek * 134e985b929SDavid van Moolenbroek * @param http a pointer to an evhttp object 135e985b929SDavid van Moolenbroek * @param fd a socket fd that is ready for accepting connections 136e985b929SDavid van Moolenbroek * @return Handle for the socket on success, NULL on failure. 137e985b929SDavid van Moolenbroek * @see evhttp_accept_socket(), evhttp_del_accept_socket() 138e985b929SDavid van Moolenbroek */ 139e985b929SDavid van Moolenbroek struct evhttp_bound_socket *evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd); 140e985b929SDavid van Moolenbroek 141e985b929SDavid van Moolenbroek /** 142e985b929SDavid van Moolenbroek * The most low-level evhttp_bind/accept method: takes an evconnlistener, and 143e985b929SDavid van Moolenbroek * returns an evhttp_bound_socket. The listener will be freed when the bound 144e985b929SDavid van Moolenbroek * socket is freed. 145e985b929SDavid van Moolenbroek */ 146e985b929SDavid van Moolenbroek struct evhttp_bound_socket *evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener); 147e985b929SDavid van Moolenbroek 148e985b929SDavid van Moolenbroek /** 149e985b929SDavid van Moolenbroek * Return the listener used to implement a bound socket. 150e985b929SDavid van Moolenbroek */ 151e985b929SDavid van Moolenbroek struct evconnlistener *evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound); 152e985b929SDavid van Moolenbroek 153e985b929SDavid van Moolenbroek /** 154e985b929SDavid van Moolenbroek * Makes an HTTP server stop accepting connections on the specified socket 155e985b929SDavid van Moolenbroek * 156e985b929SDavid van Moolenbroek * This may be useful when a socket has been sent via file descriptor passing 157e985b929SDavid van Moolenbroek * and is no longer needed by the current process. 158e985b929SDavid van Moolenbroek * 159e985b929SDavid van Moolenbroek * If you created this bound socket with evhttp_bind_socket_with_handle or 160e985b929SDavid van Moolenbroek * evhttp_accept_socket_with_handle, this function closes the fd you provided. 161e985b929SDavid van Moolenbroek * If you created this bound socket with evhttp_bind_listener, this function 162e985b929SDavid van Moolenbroek * frees the listener you provided. 163e985b929SDavid van Moolenbroek * 164e985b929SDavid van Moolenbroek * \a bound_socket is an invalid pointer after this call returns. 165e985b929SDavid van Moolenbroek * 166e985b929SDavid van Moolenbroek * @param http a pointer to an evhttp object 167e985b929SDavid van Moolenbroek * @param bound_socket a handle returned by evhttp_{bind,accept}_socket_with_handle 168e985b929SDavid van Moolenbroek * @see evhttp_bind_socket_with_handle(), evhttp_accept_socket_with_handle() 169e985b929SDavid van Moolenbroek */ 170e985b929SDavid van Moolenbroek void evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound_socket); 171e985b929SDavid van Moolenbroek 172e985b929SDavid van Moolenbroek /** 173e985b929SDavid van Moolenbroek * Get the raw file descriptor referenced by an evhttp_bound_socket. 174e985b929SDavid van Moolenbroek * 175e985b929SDavid van Moolenbroek * @param bound_socket a handle returned by evhttp_{bind,accept}_socket_with_handle 176e985b929SDavid van Moolenbroek * @return the file descriptor used by the bound socket 177e985b929SDavid van Moolenbroek * @see evhttp_bind_socket_with_handle(), evhttp_accept_socket_with_handle() 178e985b929SDavid van Moolenbroek */ 179e985b929SDavid van Moolenbroek evutil_socket_t evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound_socket); 180e985b929SDavid van Moolenbroek 181e985b929SDavid van Moolenbroek /** 182e985b929SDavid van Moolenbroek * Free the previously created HTTP server. 183e985b929SDavid van Moolenbroek * 184e985b929SDavid van Moolenbroek * Works only if no requests are currently being served. 185e985b929SDavid van Moolenbroek * 186e985b929SDavid van Moolenbroek * @param http the evhttp server object to be freed 187e985b929SDavid van Moolenbroek * @see evhttp_start() 188e985b929SDavid van Moolenbroek */ 189e985b929SDavid van Moolenbroek void evhttp_free(struct evhttp* http); 190e985b929SDavid van Moolenbroek 191e985b929SDavid van Moolenbroek /** XXX Document. */ 192e985b929SDavid van Moolenbroek void evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size); 193e985b929SDavid van Moolenbroek /** XXX Document. */ 194e985b929SDavid van Moolenbroek void evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size); 195e985b929SDavid van Moolenbroek 196e985b929SDavid van Moolenbroek /** 197e985b929SDavid van Moolenbroek Sets the what HTTP methods are supported in requests accepted by this 198e985b929SDavid van Moolenbroek server, and passed to user callbacks. 199e985b929SDavid van Moolenbroek 200e985b929SDavid van Moolenbroek If not supported they will generate a "405 Method not allowed" response. 201e985b929SDavid van Moolenbroek 202e985b929SDavid van Moolenbroek By default this includes the following methods: GET, POST, HEAD, PUT, DELETE 203e985b929SDavid van Moolenbroek 204e985b929SDavid van Moolenbroek @param http the http server on which to set the methods 205e985b929SDavid van Moolenbroek @param methods bit mask constructed from evhttp_cmd_type values 206e985b929SDavid van Moolenbroek */ 207e985b929SDavid van Moolenbroek void evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods); 208e985b929SDavid van Moolenbroek 209e985b929SDavid van Moolenbroek /** 210e985b929SDavid van Moolenbroek Set a callback for a specified URI 211e985b929SDavid van Moolenbroek 212e985b929SDavid van Moolenbroek @param http the http sever on which to set the callback 213e985b929SDavid van Moolenbroek @param path the path for which to invoke the callback 214e985b929SDavid van Moolenbroek @param cb the callback function that gets invoked on requesting path 215e985b929SDavid van Moolenbroek @param cb_arg an additional context argument for the callback 216e985b929SDavid van Moolenbroek @return 0 on success, -1 if the callback existed already, -2 on failure 217e985b929SDavid van Moolenbroek */ 218e985b929SDavid van Moolenbroek int evhttp_set_cb(struct evhttp *http, const char *path, 219e985b929SDavid van Moolenbroek void (*cb)(struct evhttp_request *, void *), void *cb_arg); 220e985b929SDavid van Moolenbroek 221e985b929SDavid van Moolenbroek /** Removes the callback for a specified URI */ 222e985b929SDavid van Moolenbroek int evhttp_del_cb(struct evhttp *, const char *); 223e985b929SDavid van Moolenbroek 224e985b929SDavid van Moolenbroek /** 225e985b929SDavid van Moolenbroek Set a callback for all requests that are not caught by specific callbacks 226e985b929SDavid van Moolenbroek 227e985b929SDavid van Moolenbroek Invokes the specified callback for all requests that do not match any of 228e985b929SDavid van Moolenbroek the previously specified request paths. This is catchall for requests not 229e985b929SDavid van Moolenbroek specifically configured with evhttp_set_cb(). 230e985b929SDavid van Moolenbroek 231e985b929SDavid van Moolenbroek @param http the evhttp server object for which to set the callback 232e985b929SDavid van Moolenbroek @param cb the callback to invoke for any unmatched requests 233e985b929SDavid van Moolenbroek @param arg an context argument for the callback 234e985b929SDavid van Moolenbroek */ 235e985b929SDavid van Moolenbroek void evhttp_set_gencb(struct evhttp *http, 236e985b929SDavid van Moolenbroek void (*cb)(struct evhttp_request *, void *), void *arg); 237e985b929SDavid van Moolenbroek 238e985b929SDavid van Moolenbroek /** 239e985b929SDavid van Moolenbroek Adds a virtual host to the http server. 240e985b929SDavid van Moolenbroek 241e985b929SDavid van Moolenbroek A virtual host is a newly initialized evhttp object that has request 242e985b929SDavid van Moolenbroek callbacks set on it via evhttp_set_cb() or evhttp_set_gencb(). It 243e985b929SDavid van Moolenbroek most not have any listing sockets associated with it. 244e985b929SDavid van Moolenbroek 245e985b929SDavid van Moolenbroek If the virtual host has not been removed by the time that evhttp_free() 246e985b929SDavid van Moolenbroek is called on the main http server, it will be automatically freed, too. 247e985b929SDavid van Moolenbroek 248e985b929SDavid van Moolenbroek It is possible to have hierarchical vhosts. For example: A vhost 249e985b929SDavid van Moolenbroek with the pattern *.example.com may have other vhosts with patterns 250e985b929SDavid van Moolenbroek foo.example.com and bar.example.com associated with it. 251e985b929SDavid van Moolenbroek 252e985b929SDavid van Moolenbroek @param http the evhttp object to which to add a virtual host 253e985b929SDavid van Moolenbroek @param pattern the glob pattern against which the hostname is matched. 254e985b929SDavid van Moolenbroek The match is case insensitive and follows otherwise regular shell 255e985b929SDavid van Moolenbroek matching. 256e985b929SDavid van Moolenbroek @param vhost the virtual host to add the regular http server. 257e985b929SDavid van Moolenbroek @return 0 on success, -1 on failure 258e985b929SDavid van Moolenbroek @see evhttp_remove_virtual_host() 259e985b929SDavid van Moolenbroek */ 260e985b929SDavid van Moolenbroek int evhttp_add_virtual_host(struct evhttp* http, const char *pattern, 261e985b929SDavid van Moolenbroek struct evhttp* vhost); 262e985b929SDavid van Moolenbroek 263e985b929SDavid van Moolenbroek /** 264e985b929SDavid van Moolenbroek Removes a virtual host from the http server. 265e985b929SDavid van Moolenbroek 266e985b929SDavid van Moolenbroek @param http the evhttp object from which to remove the virtual host 267e985b929SDavid van Moolenbroek @param vhost the virtual host to remove from the regular http server. 268e985b929SDavid van Moolenbroek @return 0 on success, -1 on failure 269e985b929SDavid van Moolenbroek @see evhttp_add_virtual_host() 270e985b929SDavid van Moolenbroek */ 271e985b929SDavid van Moolenbroek int evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost); 272e985b929SDavid van Moolenbroek 273e985b929SDavid van Moolenbroek /** 274e985b929SDavid van Moolenbroek Add a server alias to an http object. The http object can be a virtual 275e985b929SDavid van Moolenbroek host or the main server. 276e985b929SDavid van Moolenbroek 277e985b929SDavid van Moolenbroek @param http the evhttp object 278e985b929SDavid van Moolenbroek @param alias the alias to add 279e985b929SDavid van Moolenbroek @see evhttp_add_remove_alias() 280e985b929SDavid van Moolenbroek */ 281e985b929SDavid van Moolenbroek int evhttp_add_server_alias(struct evhttp *http, const char *alias); 282e985b929SDavid van Moolenbroek 283e985b929SDavid van Moolenbroek /** 284e985b929SDavid van Moolenbroek Remove a server alias from an http object. 285e985b929SDavid van Moolenbroek 286e985b929SDavid van Moolenbroek @param http the evhttp object 287e985b929SDavid van Moolenbroek @param alias the alias to remove 288e985b929SDavid van Moolenbroek @see evhttp_add_server_alias() 289e985b929SDavid van Moolenbroek */ 290e985b929SDavid van Moolenbroek int evhttp_remove_server_alias(struct evhttp *http, const char *alias); 291e985b929SDavid van Moolenbroek 292e985b929SDavid van Moolenbroek /** 293e985b929SDavid van Moolenbroek * Set the timeout for an HTTP request. 294e985b929SDavid van Moolenbroek * 295e985b929SDavid van Moolenbroek * @param http an evhttp object 296e985b929SDavid van Moolenbroek * @param timeout_in_secs the timeout, in seconds 297e985b929SDavid van Moolenbroek */ 298e985b929SDavid van Moolenbroek void evhttp_set_timeout(struct evhttp *http, int timeout_in_secs); 299e985b929SDavid van Moolenbroek 300e985b929SDavid van Moolenbroek /* Request/Response functionality */ 301e985b929SDavid van Moolenbroek 302e985b929SDavid van Moolenbroek /** 303e985b929SDavid van Moolenbroek * Send an HTML error message to the client. 304e985b929SDavid van Moolenbroek * 305e985b929SDavid van Moolenbroek * @param req a request object 306e985b929SDavid van Moolenbroek * @param error the HTTP error code 307e985b929SDavid van Moolenbroek * @param reason a brief explanation of the error. If this is NULL, we'll 308e985b929SDavid van Moolenbroek * just use the standard meaning of the error code. 309e985b929SDavid van Moolenbroek */ 310e985b929SDavid van Moolenbroek void evhttp_send_error(struct evhttp_request *req, int error, 311e985b929SDavid van Moolenbroek const char *reason); 312e985b929SDavid van Moolenbroek 313e985b929SDavid van Moolenbroek /** 314e985b929SDavid van Moolenbroek * Send an HTML reply to the client. 315e985b929SDavid van Moolenbroek * 316e985b929SDavid van Moolenbroek * The body of the reply consists of the data in databuf. After calling 317e985b929SDavid van Moolenbroek * evhttp_send_reply() databuf will be empty, but the buffer is still 318e985b929SDavid van Moolenbroek * owned by the caller and needs to be deallocated by the caller if 319e985b929SDavid van Moolenbroek * necessary. 320e985b929SDavid van Moolenbroek * 321e985b929SDavid van Moolenbroek * @param req a request object 322e985b929SDavid van Moolenbroek * @param code the HTTP response code to send 323e985b929SDavid van Moolenbroek * @param reason a brief message to send with the response code 324e985b929SDavid van Moolenbroek * @param databuf the body of the response 325e985b929SDavid van Moolenbroek */ 326e985b929SDavid van Moolenbroek void evhttp_send_reply(struct evhttp_request *req, int code, 327e985b929SDavid van Moolenbroek const char *reason, struct evbuffer *databuf); 328e985b929SDavid van Moolenbroek 329e985b929SDavid van Moolenbroek /* Low-level response interface, for streaming/chunked replies */ 330e985b929SDavid van Moolenbroek 331e985b929SDavid van Moolenbroek /** 332e985b929SDavid van Moolenbroek Initiate a reply that uses Transfer-Encoding chunked. 333e985b929SDavid van Moolenbroek 334e985b929SDavid van Moolenbroek This allows the caller to stream the reply back to the client and is 335e985b929SDavid van Moolenbroek useful when either not all of the reply data is immediately available 336e985b929SDavid van Moolenbroek or when sending very large replies. 337e985b929SDavid van Moolenbroek 338e985b929SDavid van Moolenbroek The caller needs to supply data chunks with evhttp_send_reply_chunk() 339e985b929SDavid van Moolenbroek and complete the reply by calling evhttp_send_reply_end(). 340e985b929SDavid van Moolenbroek 341e985b929SDavid van Moolenbroek @param req a request object 342e985b929SDavid van Moolenbroek @param code the HTTP response code to send 343e985b929SDavid van Moolenbroek @param reason a brief message to send with the response code 344e985b929SDavid van Moolenbroek */ 345e985b929SDavid van Moolenbroek void evhttp_send_reply_start(struct evhttp_request *req, int code, 346e985b929SDavid van Moolenbroek const char *reason); 347e985b929SDavid van Moolenbroek 348e985b929SDavid van Moolenbroek /** 349e985b929SDavid van Moolenbroek Send another data chunk as part of an ongoing chunked reply. 350e985b929SDavid van Moolenbroek 351e985b929SDavid van Moolenbroek The reply chunk consists of the data in databuf. After calling 352e985b929SDavid van Moolenbroek evhttp_send_reply_chunk() databuf will be empty, but the buffer is 353e985b929SDavid van Moolenbroek still owned by the caller and needs to be deallocated by the caller 354e985b929SDavid van Moolenbroek if necessary. 355e985b929SDavid van Moolenbroek 356e985b929SDavid van Moolenbroek @param req a request object 357e985b929SDavid van Moolenbroek @param databuf the data chunk to send as part of the reply. 358e985b929SDavid van Moolenbroek */ 359e985b929SDavid van Moolenbroek void evhttp_send_reply_chunk(struct evhttp_request *req, 360e985b929SDavid van Moolenbroek struct evbuffer *databuf); 361e985b929SDavid van Moolenbroek /** 362e985b929SDavid van Moolenbroek Complete a chunked reply, freeing the request as appropriate. 363e985b929SDavid van Moolenbroek 364e985b929SDavid van Moolenbroek @param req a request object 365e985b929SDavid van Moolenbroek */ 366e985b929SDavid van Moolenbroek void evhttp_send_reply_end(struct evhttp_request *req); 367e985b929SDavid van Moolenbroek 368e985b929SDavid van Moolenbroek /* 369e985b929SDavid van Moolenbroek * Interfaces for making requests 370e985b929SDavid van Moolenbroek */ 371e985b929SDavid van Moolenbroek 372e985b929SDavid van Moolenbroek /** The different request types supported by evhttp. These are as specified 373e985b929SDavid van Moolenbroek * in RFC2616, except for PATCH which is specified by RFC5789. 374e985b929SDavid van Moolenbroek * 375e985b929SDavid van Moolenbroek * By default, only some of these methods are accepted and passed to user 376e985b929SDavid van Moolenbroek * callbacks; use evhttp_set_allowed_methods() to change which methods 377e985b929SDavid van Moolenbroek * are allowed. 378e985b929SDavid van Moolenbroek */ 379e985b929SDavid van Moolenbroek enum evhttp_cmd_type { 380e985b929SDavid van Moolenbroek EVHTTP_REQ_GET = 1 << 0, 381e985b929SDavid van Moolenbroek EVHTTP_REQ_POST = 1 << 1, 382e985b929SDavid van Moolenbroek EVHTTP_REQ_HEAD = 1 << 2, 383e985b929SDavid van Moolenbroek EVHTTP_REQ_PUT = 1 << 3, 384e985b929SDavid van Moolenbroek EVHTTP_REQ_DELETE = 1 << 4, 385e985b929SDavid van Moolenbroek EVHTTP_REQ_OPTIONS = 1 << 5, 386e985b929SDavid van Moolenbroek EVHTTP_REQ_TRACE = 1 << 6, 387e985b929SDavid van Moolenbroek EVHTTP_REQ_CONNECT = 1 << 7, 388e985b929SDavid van Moolenbroek EVHTTP_REQ_PATCH = 1 << 8 389e985b929SDavid van Moolenbroek }; 390e985b929SDavid van Moolenbroek 391e985b929SDavid van Moolenbroek /** a request object can represent either a request or a reply */ 392e985b929SDavid van Moolenbroek enum evhttp_request_kind { EVHTTP_REQUEST, EVHTTP_RESPONSE }; 393e985b929SDavid van Moolenbroek 394e985b929SDavid van Moolenbroek /** 395e985b929SDavid van Moolenbroek * Creates a new request object that needs to be filled in with the request 396e985b929SDavid van Moolenbroek * parameters. The callback is executed when the request completed or an 397e985b929SDavid van Moolenbroek * error occurred. 398e985b929SDavid van Moolenbroek */ 399e985b929SDavid van Moolenbroek struct evhttp_request *evhttp_request_new( 400e985b929SDavid van Moolenbroek void (*cb)(struct evhttp_request *, void *), void *arg); 401e985b929SDavid van Moolenbroek 402e985b929SDavid van Moolenbroek /** 403e985b929SDavid van Moolenbroek * Enable delivery of chunks to requestor. 404e985b929SDavid van Moolenbroek * @param cb will be called after every read of data with the same argument 405e985b929SDavid van Moolenbroek * as the completion callback. Will never be called on an empty 406e985b929SDavid van Moolenbroek * response. May drain the input buffer; it will be drained 407e985b929SDavid van Moolenbroek * automatically on return. 408e985b929SDavid van Moolenbroek */ 409e985b929SDavid van Moolenbroek void evhttp_request_set_chunked_cb(struct evhttp_request *, 410e985b929SDavid van Moolenbroek void (*cb)(struct evhttp_request *, void *)); 411e985b929SDavid van Moolenbroek 412e985b929SDavid van Moolenbroek /** Frees the request object and removes associated events. */ 413e985b929SDavid van Moolenbroek void evhttp_request_free(struct evhttp_request *req); 414e985b929SDavid van Moolenbroek 415e985b929SDavid van Moolenbroek struct evdns_base; 416e985b929SDavid van Moolenbroek 417e985b929SDavid van Moolenbroek /** 418e985b929SDavid van Moolenbroek * A connection object that can be used to for making HTTP requests. The 419e985b929SDavid van Moolenbroek * connection object tries to resolve address and establish the connection 420e985b929SDavid van Moolenbroek * when it is given an http request object. 421e985b929SDavid van Moolenbroek * 422e985b929SDavid van Moolenbroek * @param base the event_base to use for handling the connection 423e985b929SDavid van Moolenbroek * @param dnsbase the dns_base to use for resolving host names; if not 424e985b929SDavid van Moolenbroek * specified host name resolution will block. 425e985b929SDavid van Moolenbroek * @param address the address to which to connect 426e985b929SDavid van Moolenbroek * @param port the port to connect to 427e985b929SDavid van Moolenbroek * @return an evhttp_connection object that can be used for making requests 428e985b929SDavid van Moolenbroek */ 429e985b929SDavid van Moolenbroek struct evhttp_connection *evhttp_connection_base_new( 430e985b929SDavid van Moolenbroek struct event_base *base, struct evdns_base *dnsbase, 431e985b929SDavid van Moolenbroek const char *address, unsigned short port); 432e985b929SDavid van Moolenbroek 433e985b929SDavid van Moolenbroek /** 434e985b929SDavid van Moolenbroek * Return the bufferevent that an evhttp_connection is using. 435e985b929SDavid van Moolenbroek */ 436e985b929SDavid van Moolenbroek struct bufferevent *evhttp_connection_get_bufferevent( 437e985b929SDavid van Moolenbroek struct evhttp_connection *evcon); 438e985b929SDavid van Moolenbroek 439e985b929SDavid van Moolenbroek /** Takes ownership of the request object 440e985b929SDavid van Moolenbroek * 441e985b929SDavid van Moolenbroek * Can be used in a request callback to keep onto the request until 442e985b929SDavid van Moolenbroek * evhttp_request_free() is explicitly called by the user. 443e985b929SDavid van Moolenbroek */ 444e985b929SDavid van Moolenbroek void evhttp_request_own(struct evhttp_request *req); 445e985b929SDavid van Moolenbroek 446e985b929SDavid van Moolenbroek /** Returns 1 if the request is owned by the user */ 447e985b929SDavid van Moolenbroek int evhttp_request_is_owned(struct evhttp_request *req); 448e985b929SDavid van Moolenbroek 449e985b929SDavid van Moolenbroek /** 450e985b929SDavid van Moolenbroek * Returns the connection object associated with the request or NULL 451e985b929SDavid van Moolenbroek * 452e985b929SDavid van Moolenbroek * The user needs to either free the request explicitly or call 453e985b929SDavid van Moolenbroek * evhttp_send_reply_end(). 454e985b929SDavid van Moolenbroek */ 455e985b929SDavid van Moolenbroek struct evhttp_connection *evhttp_request_get_connection(struct evhttp_request *req); 456e985b929SDavid van Moolenbroek 457e985b929SDavid van Moolenbroek /** 458e985b929SDavid van Moolenbroek * Returns the underlying event_base for this connection 459e985b929SDavid van Moolenbroek */ 460e985b929SDavid van Moolenbroek struct event_base *evhttp_connection_get_base(struct evhttp_connection *req); 461e985b929SDavid van Moolenbroek 462e985b929SDavid van Moolenbroek void evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon, 463e985b929SDavid van Moolenbroek ev_ssize_t new_max_headers_size); 464e985b929SDavid van Moolenbroek 465e985b929SDavid van Moolenbroek void evhttp_connection_set_max_body_size(struct evhttp_connection* evcon, 466e985b929SDavid van Moolenbroek ev_ssize_t new_max_body_size); 467e985b929SDavid van Moolenbroek 468e985b929SDavid van Moolenbroek /** Frees an http connection */ 469e985b929SDavid van Moolenbroek void evhttp_connection_free(struct evhttp_connection *evcon); 470e985b929SDavid van Moolenbroek 471e985b929SDavid van Moolenbroek /** sets the ip address from which http connections are made */ 472e985b929SDavid van Moolenbroek void evhttp_connection_set_local_address(struct evhttp_connection *evcon, 473e985b929SDavid van Moolenbroek const char *address); 474e985b929SDavid van Moolenbroek 475e985b929SDavid van Moolenbroek /** sets the local port from which http connections are made */ 476e985b929SDavid van Moolenbroek void evhttp_connection_set_local_port(struct evhttp_connection *evcon, 477e985b929SDavid van Moolenbroek ev_uint16_t port); 478e985b929SDavid van Moolenbroek 479e985b929SDavid van Moolenbroek /** Sets the timeout for events related to this connection */ 480e985b929SDavid van Moolenbroek void evhttp_connection_set_timeout(struct evhttp_connection *evcon, 481e985b929SDavid van Moolenbroek int timeout_in_secs); 482e985b929SDavid van Moolenbroek 483e985b929SDavid van Moolenbroek /** Sets the retry limit for this connection - -1 repeats indefinitely */ 484e985b929SDavid van Moolenbroek void evhttp_connection_set_retries(struct evhttp_connection *evcon, 485e985b929SDavid van Moolenbroek int retry_max); 486e985b929SDavid van Moolenbroek 487e985b929SDavid van Moolenbroek /** Set a callback for connection close. */ 488e985b929SDavid van Moolenbroek void evhttp_connection_set_closecb(struct evhttp_connection *evcon, 489e985b929SDavid van Moolenbroek void (*)(struct evhttp_connection *, void *), void *); 490e985b929SDavid van Moolenbroek 491e985b929SDavid van Moolenbroek /** Get the remote address and port associated with this connection. */ 492e985b929SDavid van Moolenbroek void evhttp_connection_get_peer(struct evhttp_connection *evcon, 493e985b929SDavid van Moolenbroek char **address, ev_uint16_t *port); 494e985b929SDavid van Moolenbroek 495e985b929SDavid van Moolenbroek /** 496e985b929SDavid van Moolenbroek Make an HTTP request over the specified connection. 497e985b929SDavid van Moolenbroek 498e985b929SDavid van Moolenbroek The connection gets ownership of the request. On failure, the 499e985b929SDavid van Moolenbroek request object is no longer valid as it has been freed. 500e985b929SDavid van Moolenbroek 501e985b929SDavid van Moolenbroek @param evcon the evhttp_connection object over which to send the request 502e985b929SDavid van Moolenbroek @param req the previously created and configured request object 503e985b929SDavid van Moolenbroek @param type the request type EVHTTP_REQ_GET, EVHTTP_REQ_POST, etc. 504e985b929SDavid van Moolenbroek @param uri the URI associated with the request 505e985b929SDavid van Moolenbroek @return 0 on success, -1 on failure 506e985b929SDavid van Moolenbroek @see evhttp_cancel_request() 507e985b929SDavid van Moolenbroek */ 508e985b929SDavid van Moolenbroek int evhttp_make_request(struct evhttp_connection *evcon, 509e985b929SDavid van Moolenbroek struct evhttp_request *req, 510e985b929SDavid van Moolenbroek enum evhttp_cmd_type type, const char *uri); 511e985b929SDavid van Moolenbroek 512e985b929SDavid van Moolenbroek /** 513e985b929SDavid van Moolenbroek Cancels a pending HTTP request. 514e985b929SDavid van Moolenbroek 515e985b929SDavid van Moolenbroek Cancels an ongoing HTTP request. The callback associated with this request 516e985b929SDavid van Moolenbroek is not executed and the request object is freed. If the request is 517e985b929SDavid van Moolenbroek currently being processed, e.g. it is ongoing, the corresponding 518e985b929SDavid van Moolenbroek evhttp_connection object is going to get reset. 519e985b929SDavid van Moolenbroek 520e985b929SDavid van Moolenbroek A request cannot be canceled if its callback has executed already. A request 521e985b929SDavid van Moolenbroek may be canceled reentrantly from its chunked callback. 522e985b929SDavid van Moolenbroek 523e985b929SDavid van Moolenbroek @param req the evhttp_request to cancel; req becomes invalid after this call. 524e985b929SDavid van Moolenbroek */ 525e985b929SDavid van Moolenbroek void evhttp_cancel_request(struct evhttp_request *req); 526e985b929SDavid van Moolenbroek 527e985b929SDavid van Moolenbroek /** 528e985b929SDavid van Moolenbroek * A structure to hold a parsed URI or Relative-Ref conforming to RFC3986. 529e985b929SDavid van Moolenbroek */ 530e985b929SDavid van Moolenbroek struct evhttp_uri; 531e985b929SDavid van Moolenbroek 532e985b929SDavid van Moolenbroek /** Returns the request URI */ 533e985b929SDavid van Moolenbroek const char *evhttp_request_get_uri(const struct evhttp_request *req); 534e985b929SDavid van Moolenbroek /** Returns the request URI (parsed) */ 535e985b929SDavid van Moolenbroek const struct evhttp_uri *evhttp_request_get_evhttp_uri(const struct evhttp_request *req); 536e985b929SDavid van Moolenbroek /** Returns the request command */ 537e985b929SDavid van Moolenbroek enum evhttp_cmd_type evhttp_request_get_command(const struct evhttp_request *req); 538e985b929SDavid van Moolenbroek 539e985b929SDavid van Moolenbroek int evhttp_request_get_response_code(const struct evhttp_request *req); 540e985b929SDavid van Moolenbroek 541e985b929SDavid van Moolenbroek /** Returns the input headers */ 542e985b929SDavid van Moolenbroek struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req); 543e985b929SDavid van Moolenbroek /** Returns the output headers */ 544e985b929SDavid van Moolenbroek struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req); 545e985b929SDavid van Moolenbroek /** Returns the input buffer */ 546e985b929SDavid van Moolenbroek struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req); 547e985b929SDavid van Moolenbroek /** Returns the output buffer */ 548e985b929SDavid van Moolenbroek struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req); 549e985b929SDavid van Moolenbroek /** Returns the host associated with the request. If a client sends an absolute 550e985b929SDavid van Moolenbroek URI, the host part of that is preferred. Otherwise, the input headers are 551e985b929SDavid van Moolenbroek searched for a Host: header. NULL is returned if no absolute URI or Host: 552e985b929SDavid van Moolenbroek header is provided. */ 553e985b929SDavid van Moolenbroek const char *evhttp_request_get_host(struct evhttp_request *req); 554e985b929SDavid van Moolenbroek 555e985b929SDavid van Moolenbroek /* Interfaces for dealing with HTTP headers */ 556e985b929SDavid van Moolenbroek 557e985b929SDavid van Moolenbroek /** 558e985b929SDavid van Moolenbroek Finds the value belonging to a header. 559e985b929SDavid van Moolenbroek 560e985b929SDavid van Moolenbroek @param headers the evkeyvalq object in which to find the header 561e985b929SDavid van Moolenbroek @param key the name of the header to find 562e985b929SDavid van Moolenbroek @returns a pointer to the value for the header or NULL if the header 563e985b929SDavid van Moolenbroek count not be found. 564e985b929SDavid van Moolenbroek @see evhttp_add_header(), evhttp_remove_header() 565e985b929SDavid van Moolenbroek */ 566e985b929SDavid van Moolenbroek const char *evhttp_find_header(const struct evkeyvalq *headers, 567e985b929SDavid van Moolenbroek const char *key); 568e985b929SDavid van Moolenbroek 569e985b929SDavid van Moolenbroek /** 570e985b929SDavid van Moolenbroek Removes a header from a list of existing headers. 571e985b929SDavid van Moolenbroek 572e985b929SDavid van Moolenbroek @param headers the evkeyvalq object from which to remove a header 573e985b929SDavid van Moolenbroek @param key the name of the header to remove 574e985b929SDavid van Moolenbroek @returns 0 if the header was removed, -1 otherwise. 575e985b929SDavid van Moolenbroek @see evhttp_find_header(), evhttp_add_header() 576e985b929SDavid van Moolenbroek */ 577e985b929SDavid van Moolenbroek int evhttp_remove_header(struct evkeyvalq *headers, const char *key); 578e985b929SDavid van Moolenbroek 579e985b929SDavid van Moolenbroek /** 580e985b929SDavid van Moolenbroek Adds a header to a list of existing headers. 581e985b929SDavid van Moolenbroek 582e985b929SDavid van Moolenbroek @param headers the evkeyvalq object to which to add a header 583e985b929SDavid van Moolenbroek @param key the name of the header 584e985b929SDavid van Moolenbroek @param value the value belonging to the header 585e985b929SDavid van Moolenbroek @returns 0 on success, -1 otherwise. 586e985b929SDavid van Moolenbroek @see evhttp_find_header(), evhttp_clear_headers() 587e985b929SDavid van Moolenbroek */ 588e985b929SDavid van Moolenbroek int evhttp_add_header(struct evkeyvalq *headers, const char *key, const char *value); 589e985b929SDavid van Moolenbroek 590e985b929SDavid van Moolenbroek /** 591e985b929SDavid van Moolenbroek Removes all headers from the header list. 592e985b929SDavid van Moolenbroek 593e985b929SDavid van Moolenbroek @param headers the evkeyvalq object from which to remove all headers 594e985b929SDavid van Moolenbroek */ 595e985b929SDavid van Moolenbroek void evhttp_clear_headers(struct evkeyvalq *headers); 596e985b929SDavid van Moolenbroek 597e985b929SDavid van Moolenbroek /* Miscellaneous utility functions */ 598e985b929SDavid van Moolenbroek 599e985b929SDavid van Moolenbroek 600e985b929SDavid van Moolenbroek /** 601e985b929SDavid van Moolenbroek Helper function to encode a string for inclusion in a URI. All 602e985b929SDavid van Moolenbroek characters are replaced by their hex-escaped (%22) equivalents, 603e985b929SDavid van Moolenbroek except for characters explicitly unreserved by RFC3986 -- that is, 604e985b929SDavid van Moolenbroek ASCII alphanumeric characters, hyphen, dot, underscore, and tilde. 605e985b929SDavid van Moolenbroek 606e985b929SDavid van Moolenbroek The returned string must be freed by the caller. 607e985b929SDavid van Moolenbroek 608e985b929SDavid van Moolenbroek @param str an unencoded string 609e985b929SDavid van Moolenbroek @return a newly allocated URI-encoded string or NULL on failure 610e985b929SDavid van Moolenbroek */ 611e985b929SDavid van Moolenbroek char *evhttp_encode_uri(const char *str); 612e985b929SDavid van Moolenbroek 613e985b929SDavid van Moolenbroek /** 614e985b929SDavid van Moolenbroek As evhttp_encode_uri, but if 'size' is nonnegative, treat the string 615e985b929SDavid van Moolenbroek as being 'size' bytes long. This allows you to encode strings that 616e985b929SDavid van Moolenbroek may contain 0-valued bytes. 617e985b929SDavid van Moolenbroek 618e985b929SDavid van Moolenbroek The returned string must be freed by the caller. 619e985b929SDavid van Moolenbroek 620e985b929SDavid van Moolenbroek @param str an unencoded string 621e985b929SDavid van Moolenbroek @param size the length of the string to encode, or -1 if the string 622e985b929SDavid van Moolenbroek is NUL-terminated 623e985b929SDavid van Moolenbroek @param space_to_plus if true, space characters in 'str' are encoded 624e985b929SDavid van Moolenbroek as +, not %20. 625e985b929SDavid van Moolenbroek @return a newly allocate URI-encoded string, or NULL on failure. 626e985b929SDavid van Moolenbroek */ 627e985b929SDavid van Moolenbroek char *evhttp_uriencode(const char *str, ev_ssize_t size, int space_to_plus); 628e985b929SDavid van Moolenbroek 629e985b929SDavid van Moolenbroek /** 630e985b929SDavid van Moolenbroek Helper function to sort of decode a URI-encoded string. Unlike 631e985b929SDavid van Moolenbroek evhttp_get_decoded_uri, it decodes all plus characters that appear 632e985b929SDavid van Moolenbroek _after_ the first question mark character, but no plusses that occur 633e985b929SDavid van Moolenbroek before. This is not a good way to decode URIs in whole or in part. 634e985b929SDavid van Moolenbroek 635e985b929SDavid van Moolenbroek The returned string must be freed by the caller 636e985b929SDavid van Moolenbroek 637e985b929SDavid van Moolenbroek @deprecated This function is deprecated; you probably want to use 638e985b929SDavid van Moolenbroek evhttp_get_decoded_uri instead. 639e985b929SDavid van Moolenbroek 640e985b929SDavid van Moolenbroek @param uri an encoded URI 641e985b929SDavid van Moolenbroek @return a newly allocated unencoded URI or NULL on failure 642e985b929SDavid van Moolenbroek */ 643e985b929SDavid van Moolenbroek char *evhttp_decode_uri(const char *uri); 644e985b929SDavid van Moolenbroek 645e985b929SDavid van Moolenbroek /** 646e985b929SDavid van Moolenbroek Helper function to decode a URI-escaped string or HTTP parameter. 647e985b929SDavid van Moolenbroek 648e985b929SDavid van Moolenbroek If 'decode_plus' is 1, then we decode the string as an HTTP parameter 649e985b929SDavid van Moolenbroek value, and convert all plus ('+') characters to spaces. If 650e985b929SDavid van Moolenbroek 'decode_plus' is 0, we leave all plus characters unchanged. 651e985b929SDavid van Moolenbroek 652e985b929SDavid van Moolenbroek The returned string must be freed by the caller. 653e985b929SDavid van Moolenbroek 654e985b929SDavid van Moolenbroek @param uri a URI-encode encoded URI 655e985b929SDavid van Moolenbroek @param decode_plus determines whether we convert '+' to sapce. 656e985b929SDavid van Moolenbroek @param size_out if size_out is not NULL, *size_out is set to the size of the 657e985b929SDavid van Moolenbroek returned string 658e985b929SDavid van Moolenbroek @return a newly allocated unencoded URI or NULL on failure 659e985b929SDavid van Moolenbroek */ 660e985b929SDavid van Moolenbroek char *evhttp_uridecode(const char *uri, int decode_plus, 661e985b929SDavid van Moolenbroek size_t *size_out); 662e985b929SDavid van Moolenbroek 663e985b929SDavid van Moolenbroek /** 664e985b929SDavid van Moolenbroek Helper function to parse out arguments in a query. 665e985b929SDavid van Moolenbroek 666e985b929SDavid van Moolenbroek Parsing a URI like 667e985b929SDavid van Moolenbroek 668e985b929SDavid van Moolenbroek http://foo.com/?q=test&s=some+thing 669e985b929SDavid van Moolenbroek 670e985b929SDavid van Moolenbroek will result in two entries in the key value queue. 671e985b929SDavid van Moolenbroek 672e985b929SDavid van Moolenbroek The first entry is: key="q", value="test" 673e985b929SDavid van Moolenbroek The second entry is: key="s", value="some thing" 674e985b929SDavid van Moolenbroek 675e985b929SDavid van Moolenbroek @deprecated This function is deprecated as of Libevent 2.0.9. Use 676e985b929SDavid van Moolenbroek evhttp_uri_parse and evhttp_parse_query_str instead. 677e985b929SDavid van Moolenbroek 678e985b929SDavid van Moolenbroek @param uri the request URI 679e985b929SDavid van Moolenbroek @param headers the head of the evkeyval queue 680e985b929SDavid van Moolenbroek @return 0 on success, -1 on failure 681e985b929SDavid van Moolenbroek */ 682e985b929SDavid van Moolenbroek int evhttp_parse_query(const char *uri, struct evkeyvalq *headers); 683e985b929SDavid van Moolenbroek 684e985b929SDavid van Moolenbroek /** 685e985b929SDavid van Moolenbroek Helper function to parse out arguments from the query portion of an 686e985b929SDavid van Moolenbroek HTTP URI. 687e985b929SDavid van Moolenbroek 688e985b929SDavid van Moolenbroek Parsing a query string like 689e985b929SDavid van Moolenbroek 690e985b929SDavid van Moolenbroek q=test&s=some+thing 691e985b929SDavid van Moolenbroek 692e985b929SDavid van Moolenbroek will result in two entries in the key value queue. 693e985b929SDavid van Moolenbroek 694e985b929SDavid van Moolenbroek The first entry is: key="q", value="test" 695e985b929SDavid van Moolenbroek The second entry is: key="s", value="some thing" 696e985b929SDavid van Moolenbroek 697e985b929SDavid van Moolenbroek @param query_parse the query portion of the URI 698e985b929SDavid van Moolenbroek @param headers the head of the evkeyval queue 699e985b929SDavid van Moolenbroek @return 0 on success, -1 on failure 700e985b929SDavid van Moolenbroek */ 701e985b929SDavid van Moolenbroek int evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers); 702e985b929SDavid van Moolenbroek 703e985b929SDavid van Moolenbroek /** 704e985b929SDavid van Moolenbroek * Escape HTML character entities in a string. 705e985b929SDavid van Moolenbroek * 706e985b929SDavid van Moolenbroek * Replaces <, >, ", ' and & with <, >, ", 707e985b929SDavid van Moolenbroek * ' and & correspondingly. 708e985b929SDavid van Moolenbroek * 709e985b929SDavid van Moolenbroek * The returned string needs to be freed by the caller. 710e985b929SDavid van Moolenbroek * 711e985b929SDavid van Moolenbroek * @param html an unescaped HTML string 712e985b929SDavid van Moolenbroek * @return an escaped HTML string or NULL on error 713e985b929SDavid van Moolenbroek */ 714e985b929SDavid van Moolenbroek char *evhttp_htmlescape(const char *html); 715e985b929SDavid van Moolenbroek 716e985b929SDavid van Moolenbroek /** 717e985b929SDavid van Moolenbroek * Return a new empty evhttp_uri with no fields set. 718e985b929SDavid van Moolenbroek */ 719e985b929SDavid van Moolenbroek struct evhttp_uri *evhttp_uri_new(void); 720e985b929SDavid van Moolenbroek 721e985b929SDavid van Moolenbroek /** 722e985b929SDavid van Moolenbroek * Changes the flags set on a given URI. See EVHTTP_URI_* for 723e985b929SDavid van Moolenbroek * a list of flags. 724e985b929SDavid van Moolenbroek **/ 725e985b929SDavid van Moolenbroek void evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags); 726e985b929SDavid van Moolenbroek 727e985b929SDavid van Moolenbroek /** Return the scheme of an evhttp_uri, or NULL if there is no scheme has 728e985b929SDavid van Moolenbroek * been set and the evhttp_uri contains a Relative-Ref. */ 729e985b929SDavid van Moolenbroek const char *evhttp_uri_get_scheme(const struct evhttp_uri *uri); 730e985b929SDavid van Moolenbroek /** 731e985b929SDavid van Moolenbroek * Return the userinfo part of an evhttp_uri, or NULL if it has no userinfo 732e985b929SDavid van Moolenbroek * set. 733e985b929SDavid van Moolenbroek */ 734e985b929SDavid van Moolenbroek const char *evhttp_uri_get_userinfo(const struct evhttp_uri *uri); 735e985b929SDavid van Moolenbroek /** 736e985b929SDavid van Moolenbroek * Return the host part of an evhttp_uri, or NULL if it has no host set. 737e985b929SDavid van Moolenbroek * The host may either be a regular hostname (conforming to the RFC 3986 738e985b929SDavid van Moolenbroek * "regname" production), or an IPv4 address, or the empty string, or a 739e985b929SDavid van Moolenbroek * bracketed IPv6 address, or a bracketed 'IP-Future' address. 740e985b929SDavid van Moolenbroek * 741e985b929SDavid van Moolenbroek * Note that having a NULL host means that the URI has no authority 742e985b929SDavid van Moolenbroek * section, but having an empty-string host means that the URI has an 743e985b929SDavid van Moolenbroek * authority section with no host part. For example, 744e985b929SDavid van Moolenbroek * "mailto:user@example.com" has a host of NULL, but "file:///etc/motd" 745e985b929SDavid van Moolenbroek * has a host of "". 746e985b929SDavid van Moolenbroek */ 747e985b929SDavid van Moolenbroek const char *evhttp_uri_get_host(const struct evhttp_uri *uri); 748e985b929SDavid van Moolenbroek /** Return the port part of an evhttp_uri, or -1 if there is no port set. */ 749e985b929SDavid van Moolenbroek int evhttp_uri_get_port(const struct evhttp_uri *uri); 750e985b929SDavid van Moolenbroek /** Return the path part of an evhttp_uri, or NULL if it has no path set */ 751e985b929SDavid van Moolenbroek const char *evhttp_uri_get_path(const struct evhttp_uri *uri); 752e985b929SDavid van Moolenbroek /** Return the query part of an evhttp_uri (excluding the leading "?"), or 753e985b929SDavid van Moolenbroek * NULL if it has no query set */ 754e985b929SDavid van Moolenbroek const char *evhttp_uri_get_query(const struct evhttp_uri *uri); 755e985b929SDavid van Moolenbroek /** Return the fragment part of an evhttp_uri (excluding the leading "#"), 756e985b929SDavid van Moolenbroek * or NULL if it has no fragment set */ 757e985b929SDavid van Moolenbroek const char *evhttp_uri_get_fragment(const struct evhttp_uri *uri); 758e985b929SDavid van Moolenbroek 759e985b929SDavid van Moolenbroek /** Set the scheme of an evhttp_uri, or clear the scheme if scheme==NULL. 760e985b929SDavid van Moolenbroek * Returns 0 on success, -1 if scheme is not well-formed. */ 761e985b929SDavid van Moolenbroek int evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme); 762e985b929SDavid van Moolenbroek /** Set the userinfo of an evhttp_uri, or clear the userinfo if userinfo==NULL. 763e985b929SDavid van Moolenbroek * Returns 0 on success, -1 if userinfo is not well-formed. */ 764e985b929SDavid van Moolenbroek int evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo); 765e985b929SDavid van Moolenbroek /** Set the host of an evhttp_uri, or clear the host if host==NULL. 766e985b929SDavid van Moolenbroek * Returns 0 on success, -1 if host is not well-formed. */ 767e985b929SDavid van Moolenbroek int evhttp_uri_set_host(struct evhttp_uri *uri, const char *host); 768e985b929SDavid van Moolenbroek /** Set the port of an evhttp_uri, or clear the port if port==-1. 769e985b929SDavid van Moolenbroek * Returns 0 on success, -1 if port is not well-formed. */ 770e985b929SDavid van Moolenbroek int evhttp_uri_set_port(struct evhttp_uri *uri, int port); 771e985b929SDavid van Moolenbroek /** Set the path of an evhttp_uri, or clear the path if path==NULL. 772e985b929SDavid van Moolenbroek * Returns 0 on success, -1 if path is not well-formed. */ 773e985b929SDavid van Moolenbroek int evhttp_uri_set_path(struct evhttp_uri *uri, const char *path); 774e985b929SDavid van Moolenbroek /** Set the query of an evhttp_uri, or clear the query if query==NULL. 775e985b929SDavid van Moolenbroek * The query should not include a leading "?". 776e985b929SDavid van Moolenbroek * Returns 0 on success, -1 if query is not well-formed. */ 777e985b929SDavid van Moolenbroek int evhttp_uri_set_query(struct evhttp_uri *uri, const char *query); 778e985b929SDavid van Moolenbroek /** Set the fragment of an evhttp_uri, or clear the fragment if fragment==NULL. 779e985b929SDavid van Moolenbroek * The fragment should not include a leading "#". 780e985b929SDavid van Moolenbroek * Returns 0 on success, -1 if fragment is not well-formed. */ 781e985b929SDavid van Moolenbroek int evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment); 782e985b929SDavid van Moolenbroek 783e985b929SDavid van Moolenbroek /** 784e985b929SDavid van Moolenbroek * Helper function to parse a URI-Reference as specified by RFC3986. 785e985b929SDavid van Moolenbroek * 786e985b929SDavid van Moolenbroek * This function matches the URI-Reference production from RFC3986, 787e985b929SDavid van Moolenbroek * which includes both URIs like 788e985b929SDavid van Moolenbroek * 789e985b929SDavid van Moolenbroek * scheme://[[userinfo]@]foo.com[:port]]/[path][?query][#fragment] 790e985b929SDavid van Moolenbroek * 791e985b929SDavid van Moolenbroek * and relative-refs like 792e985b929SDavid van Moolenbroek * 793e985b929SDavid van Moolenbroek * [path][?query][#fragment] 794e985b929SDavid van Moolenbroek * 795e985b929SDavid van Moolenbroek * Any optional elements portions not present in the original URI are 796e985b929SDavid van Moolenbroek * left set to NULL in the resulting evhttp_uri. If no port is 797e985b929SDavid van Moolenbroek * specified, the port is set to -1. 798e985b929SDavid van Moolenbroek * 799e985b929SDavid van Moolenbroek * Note that no decoding is performed on percent-escaped characters in 800e985b929SDavid van Moolenbroek * the string; if you want to parse them, use evhttp_uridecode or 801e985b929SDavid van Moolenbroek * evhttp_parse_query_str as appropriate. 802e985b929SDavid van Moolenbroek * 803e985b929SDavid van Moolenbroek * Note also that most URI schemes will have additional constraints that 804e985b929SDavid van Moolenbroek * this function does not know about, and cannot check. For example, 805e985b929SDavid van Moolenbroek * mailto://www.example.com/cgi-bin/fortune.pl is not a reasonable 806e985b929SDavid van Moolenbroek * mailto url, http://www.example.com:99999/ is not a reasonable HTTP 807e985b929SDavid van Moolenbroek * URL, and ftp:username@example.com is not a reasonable FTP URL. 808e985b929SDavid van Moolenbroek * Nevertheless, all of these URLs conform to RFC3986, and this function 809e985b929SDavid van Moolenbroek * accepts all of them as valid. 810e985b929SDavid van Moolenbroek * 811e985b929SDavid van Moolenbroek * @param source_uri the request URI 812e985b929SDavid van Moolenbroek * @param flags Zero or more EVHTTP_URI_* flags to affect the behavior 813e985b929SDavid van Moolenbroek * of the parser. 814e985b929SDavid van Moolenbroek * @return uri container to hold parsed data, or NULL if there is error 815e985b929SDavid van Moolenbroek * @see evhttp_uri_free() 816e985b929SDavid van Moolenbroek */ 817e985b929SDavid van Moolenbroek struct evhttp_uri *evhttp_uri_parse_with_flags(const char *source_uri, 818e985b929SDavid van Moolenbroek unsigned flags); 819e985b929SDavid van Moolenbroek 820e985b929SDavid van Moolenbroek /** Tolerate URIs that do not conform to RFC3986. 821e985b929SDavid van Moolenbroek * 822e985b929SDavid van Moolenbroek * Unfortunately, some HTTP clients generate URIs that, according to RFC3986, 823e985b929SDavid van Moolenbroek * are not conformant URIs. If you need to support these URIs, you can 824e985b929SDavid van Moolenbroek * do so by passing this flag to evhttp_uri_parse_with_flags. 825e985b929SDavid van Moolenbroek * 826e985b929SDavid van Moolenbroek * Currently, these changes are: 827e985b929SDavid van Moolenbroek * <ul> 828e985b929SDavid van Moolenbroek * <li> Nonconformant URIs are allowed to contain otherwise unreasonable 829e985b929SDavid van Moolenbroek * characters in their path, query, and fragment components. 830e985b929SDavid van Moolenbroek * </ul> 831e985b929SDavid van Moolenbroek */ 832e985b929SDavid van Moolenbroek #define EVHTTP_URI_NONCONFORMANT 0x01 833e985b929SDavid van Moolenbroek 834e985b929SDavid van Moolenbroek /** Alias for evhttp_uri_parse_with_flags(source_uri, 0) */ 835e985b929SDavid van Moolenbroek struct evhttp_uri *evhttp_uri_parse(const char *source_uri); 836e985b929SDavid van Moolenbroek 837e985b929SDavid van Moolenbroek /** 838e985b929SDavid van Moolenbroek * Free all memory allocated for a parsed uri. Only use this for URIs 839e985b929SDavid van Moolenbroek * generated by evhttp_uri_parse. 840e985b929SDavid van Moolenbroek * 841e985b929SDavid van Moolenbroek * @param uri container with parsed data 842e985b929SDavid van Moolenbroek * @see evhttp_uri_parse() 843e985b929SDavid van Moolenbroek */ 844e985b929SDavid van Moolenbroek void evhttp_uri_free(struct evhttp_uri *uri); 845e985b929SDavid van Moolenbroek 846e985b929SDavid van Moolenbroek /** 847e985b929SDavid van Moolenbroek * Join together the uri parts from parsed data to form a URI-Reference. 848e985b929SDavid van Moolenbroek * 849e985b929SDavid van Moolenbroek * Note that no escaping of reserved characters is done on the members 850e985b929SDavid van Moolenbroek * of the evhttp_uri, so the generated string might not be a valid URI 851e985b929SDavid van Moolenbroek * unless the members of evhttp_uri are themselves valid. 852e985b929SDavid van Moolenbroek * 853e985b929SDavid van Moolenbroek * @param uri container with parsed data 854e985b929SDavid van Moolenbroek * @param buf destination buffer 855e985b929SDavid van Moolenbroek * @param limit destination buffer size 856e985b929SDavid van Moolenbroek * @return an joined uri as string or NULL on error 857e985b929SDavid van Moolenbroek * @see evhttp_uri_parse() 858e985b929SDavid van Moolenbroek */ 859e985b929SDavid van Moolenbroek char *evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit); 860e985b929SDavid van Moolenbroek 861e985b929SDavid van Moolenbroek #ifdef __cplusplus 862e985b929SDavid van Moolenbroek } 863e985b929SDavid van Moolenbroek #endif 864e985b929SDavid van Moolenbroek 865e985b929SDavid van Moolenbroek #endif /* _EVENT2_HTTP_H_ */ 866