1*eabc0478Schristos /* $NetBSD: http-internal.h,v 1.7 2024/08/18 20:47:21 christos Exp $ */ 28585484eSchristos 38585484eSchristos /* 48585484eSchristos * Copyright 2001-2007 Niels Provos <provos@citi.umich.edu> 58585484eSchristos * Copyright 2007-2012 Niels Provos and Nick Mathewson 68585484eSchristos * 78585484eSchristos * This header file contains definitions for dealing with HTTP requests 88585484eSchristos * that are internal to libevent. As user of the library, you should not 98585484eSchristos * need to know about these. 108585484eSchristos */ 118585484eSchristos 128585484eSchristos #ifndef HTTP_INTERNAL_H_INCLUDED_ 138585484eSchristos #define HTTP_INTERNAL_H_INCLUDED_ 148585484eSchristos 158585484eSchristos #include "event2/event_struct.h" 168585484eSchristos #include "util-internal.h" 178585484eSchristos #include "defer-internal.h" 188585484eSchristos 198585484eSchristos #define HTTP_CONNECT_TIMEOUT 45 208585484eSchristos #define HTTP_WRITE_TIMEOUT 50 218585484eSchristos #define HTTP_READ_TIMEOUT 50 228585484eSchristos 238585484eSchristos enum message_read_status { 248585484eSchristos ALL_DATA_READ = 1, 258585484eSchristos MORE_DATA_EXPECTED = 0, 268585484eSchristos DATA_CORRUPTED = -1, 278585484eSchristos REQUEST_CANCELED = -2, 288585484eSchristos DATA_TOO_LONG = -3 298585484eSchristos }; 308585484eSchristos 318585484eSchristos struct evbuffer; 328585484eSchristos struct addrinfo; 338585484eSchristos struct evhttp_request; 348585484eSchristos 358585484eSchristos /* Indicates an unknown request method. */ 368585484eSchristos #define EVHTTP_REQ_UNKNOWN_ (1<<15) 378585484eSchristos 388585484eSchristos enum evhttp_connection_state { 398585484eSchristos EVCON_DISCONNECTED, /**< not currently connected not trying either*/ 408585484eSchristos EVCON_CONNECTING, /**< tries to currently connect */ 418585484eSchristos EVCON_IDLE, /**< connection is established */ 428585484eSchristos EVCON_READING_FIRSTLINE,/**< reading Request-Line (incoming conn) or 438585484eSchristos **< Status-Line (outgoing conn) */ 448585484eSchristos EVCON_READING_HEADERS, /**< reading request/response headers */ 458585484eSchristos EVCON_READING_BODY, /**< reading request/response body */ 468585484eSchristos EVCON_READING_TRAILER, /**< reading request/response chunked trailer */ 478585484eSchristos EVCON_WRITING /**< writing request/response headers/body */ 488585484eSchristos }; 498585484eSchristos 508585484eSchristos struct event_base; 518585484eSchristos 528585484eSchristos /* A client or server connection. */ 538585484eSchristos struct evhttp_connection { 548585484eSchristos /* we use this tailq only if this connection was created for an http 558585484eSchristos * server */ 568585484eSchristos TAILQ_ENTRY(evhttp_connection) next; 578585484eSchristos 588585484eSchristos evutil_socket_t fd; 598585484eSchristos struct bufferevent *bufev; 608585484eSchristos 618585484eSchristos struct event retry_ev; /* for retrying connects */ 628585484eSchristos 638585484eSchristos char *bind_address; /* address to use for binding the src */ 64*eabc0478Schristos ev_uint16_t bind_port; /* local port for binding the src */ 658585484eSchristos 668585484eSchristos char *address; /* address to connect to */ 67*eabc0478Schristos ev_uint16_t port; 688585484eSchristos 698585484eSchristos size_t max_headers_size; 708585484eSchristos ev_uint64_t max_body_size; 718585484eSchristos 728585484eSchristos int flags; 738585484eSchristos #define EVHTTP_CON_INCOMING 0x0001 /* only one request on it ever */ 748585484eSchristos #define EVHTTP_CON_OUTGOING 0x0002 /* multiple requests possible */ 758585484eSchristos #define EVHTTP_CON_CLOSEDETECT 0x0004 /* detecting if persistent close */ 76*eabc0478Schristos /* set when we want to auto free the connection */ 77*eabc0478Schristos #define EVHTTP_CON_AUTOFREE EVHTTP_CON_PUBLIC_FLAGS_END 78*eabc0478Schristos /* Installed when attempt to read HTTP error after write failed, see 79*eabc0478Schristos * EVHTTP_CON_READ_ON_WRITE_ERROR */ 80*eabc0478Schristos #define EVHTTP_CON_READING_ERROR (EVHTTP_CON_AUTOFREE << 1) 818585484eSchristos 828585484eSchristos struct timeval timeout; /* timeout for events */ 838585484eSchristos int retry_cnt; /* retry count */ 848585484eSchristos int retry_max; /* maximum number of retries */ 858585484eSchristos struct timeval initial_retry_timeout; /* Timeout for low long to wait 868585484eSchristos * after first failing attempt 878585484eSchristos * before retry */ 888585484eSchristos 898585484eSchristos enum evhttp_connection_state state; 908585484eSchristos 918585484eSchristos /* for server connections, the http server they are connected with */ 928585484eSchristos struct evhttp *http_server; 938585484eSchristos 948585484eSchristos TAILQ_HEAD(evcon_requestq, evhttp_request) requests; 958585484eSchristos 968585484eSchristos void (*cb)(struct evhttp_connection *, void *); 978585484eSchristos void *cb_arg; 988585484eSchristos 998585484eSchristos void (*closecb)(struct evhttp_connection *, void *); 1008585484eSchristos void *closecb_arg; 1018585484eSchristos 1028585484eSchristos struct event_callback read_more_deferred_cb; 1038585484eSchristos 1048585484eSchristos struct event_base *base; 1058585484eSchristos struct evdns_base *dns_base; 1067476e6e4Schristos int ai_family; 1078585484eSchristos }; 1088585484eSchristos 1098585484eSchristos /* A callback for an http server */ 1108585484eSchristos struct evhttp_cb { 1118585484eSchristos TAILQ_ENTRY(evhttp_cb) next; 1128585484eSchristos 1138585484eSchristos char *what; 1148585484eSchristos 1158585484eSchristos void (*cb)(struct evhttp_request *req, void *); 1168585484eSchristos void *cbarg; 1178585484eSchristos }; 1188585484eSchristos 1198585484eSchristos /* both the http server as well as the rpc system need to queue connections */ 1208585484eSchristos TAILQ_HEAD(evconq, evhttp_connection); 1218585484eSchristos 1228585484eSchristos /* each bound socket is stored in one of these */ 1238585484eSchristos struct evhttp_bound_socket { 1248585484eSchristos TAILQ_ENTRY(evhttp_bound_socket) next; 1258585484eSchristos 1268585484eSchristos struct evconnlistener *listener; 1278585484eSchristos }; 1288585484eSchristos 1298585484eSchristos /* server alias list item. */ 1308585484eSchristos struct evhttp_server_alias { 1318585484eSchristos TAILQ_ENTRY(evhttp_server_alias) next; 1328585484eSchristos 1338585484eSchristos char *alias; /* the server alias. */ 1348585484eSchristos }; 1358585484eSchristos 1368585484eSchristos struct evhttp { 1378585484eSchristos /* Next vhost, if this is a vhost. */ 1388585484eSchristos TAILQ_ENTRY(evhttp) next_vhost; 1398585484eSchristos 1408585484eSchristos /* All listeners for this host */ 1418585484eSchristos TAILQ_HEAD(boundq, evhttp_bound_socket) sockets; 1428585484eSchristos 1438585484eSchristos TAILQ_HEAD(httpcbq, evhttp_cb) callbacks; 1448585484eSchristos 1458585484eSchristos /* All live connections on this host. */ 1468585484eSchristos struct evconq connections; 1478585484eSchristos 1488585484eSchristos TAILQ_HEAD(vhostsq, evhttp) virtualhosts; 1498585484eSchristos 1508585484eSchristos TAILQ_HEAD(aliasq, evhttp_server_alias) aliases; 1518585484eSchristos 1528585484eSchristos /* NULL if this server is not a vhost */ 1538585484eSchristos char *vhost_pattern; 1548585484eSchristos 1558585484eSchristos struct timeval timeout; 1568585484eSchristos 1578585484eSchristos size_t default_max_headers_size; 1588585484eSchristos ev_uint64_t default_max_body_size; 159*eabc0478Schristos int flags; 160b8ecfcfeSchristos const char *default_content_type; 1618585484eSchristos 1628585484eSchristos /* Bitmask of all HTTP methods that we accept and pass to user 1638585484eSchristos * callbacks. */ 1648585484eSchristos ev_uint16_t allowed_methods; 1658585484eSchristos 1668585484eSchristos /* Fallback callback if all the other callbacks for this connection 1678585484eSchristos don't match. */ 1688585484eSchristos void (*gencb)(struct evhttp_request *req, void *); 1698585484eSchristos void *gencbarg; 1708585484eSchristos struct bufferevent* (*bevcb)(struct event_base *, void *); 1718585484eSchristos void *bevcbarg; 1728585484eSchristos 1738585484eSchristos struct event_base *base; 1748585484eSchristos }; 1758585484eSchristos 1768585484eSchristos /* XXX most of these functions could be static. */ 1778585484eSchristos 1788585484eSchristos /* resets the connection; can be reused for more requests */ 1798585484eSchristos void evhttp_connection_reset_(struct evhttp_connection *); 1808585484eSchristos 1818585484eSchristos /* connects if necessary */ 1828585484eSchristos int evhttp_connection_connect_(struct evhttp_connection *); 1838585484eSchristos 184b8ecfcfeSchristos enum evhttp_request_error; 1858585484eSchristos /* notifies the current request that it failed; resets connection */ 186*eabc0478Schristos EVENT2_EXPORT_SYMBOL 1878585484eSchristos void evhttp_connection_fail_(struct evhttp_connection *, 188b8ecfcfeSchristos enum evhttp_request_error error); 1898585484eSchristos 1908585484eSchristos enum message_read_status; 1918585484eSchristos 192*eabc0478Schristos EVENT2_EXPORT_SYMBOL 1938585484eSchristos enum message_read_status evhttp_parse_firstline_(struct evhttp_request *, struct evbuffer*); 194*eabc0478Schristos EVENT2_EXPORT_SYMBOL 1958585484eSchristos enum message_read_status evhttp_parse_headers_(struct evhttp_request *, struct evbuffer*); 1968585484eSchristos 1978585484eSchristos void evhttp_start_read_(struct evhttp_connection *); 198*eabc0478Schristos void evhttp_start_write_(struct evhttp_connection *); 1998585484eSchristos 2008585484eSchristos /* response sending HTML the data in the buffer */ 2018585484eSchristos void evhttp_response_code_(struct evhttp_request *, int, const char *); 2028585484eSchristos void evhttp_send_page_(struct evhttp_request *, struct evbuffer *); 2038585484eSchristos 204*eabc0478Schristos EVENT2_EXPORT_SYMBOL 2058585484eSchristos int evhttp_decode_uri_internal(const char *uri, size_t length, 2068585484eSchristos char *ret, int decode_plus); 2078585484eSchristos 208*eabc0478Schristos #endif /* HTTP_INTERNAL_H_INCLUDED_ */ 209