http-client-private.h revision 57c339f4e3404355a8924103317a6158a709ecf1
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#define HTTP_CLIENT_CONTINUE_TIMEOUT_MSECS (1000*2)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#define HTTP_CLIENT_DEFAULT_REQUEST_TIMEOUT_MSECS (1000*60*1)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#define HTTP_CLIENT_DEFAULT_DNS_LOOKUP_TIMEOUT_MSECS (1000*10)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#define HTTP_CLIENT_DEFAULT_BACKOFF_TIME_MSECS (100)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#define HTTP_CLIENT_DEFAULT_BACKOFF_MAX_TIME_MSECS (1000*60)
1df39b899804fd1dbc560f75382364822935c857Timo SirainenARRAY_DEFINE_TYPE(http_client_host, struct http_client_host *);
c13fce16374a6fa8d127742c527498d38e777789Timo SirainenARRAY_DEFINE_TYPE(http_client_queue, struct http_client_queue *);
c13fce16374a6fa8d127742c527498d38e777789Timo SirainenARRAY_DEFINE_TYPE(http_client_peer, struct http_client_peer *);
c13fce16374a6fa8d127742c527498d38e777789Timo SirainenARRAY_DEFINE_TYPE(http_client_connection, struct http_client_connection *);
c13fce16374a6fa8d127742c527498d38e777789Timo SirainenARRAY_DEFINE_TYPE(http_client_request, struct http_client_request *);
c13fce16374a6fa8d127742c527498d38e777789Timo SirainenHASH_TABLE_DEFINE_TYPE(http_client_host, const char *,
c13fce16374a6fa8d127742c527498d38e777789Timo SirainenHASH_TABLE_DEFINE_TYPE(http_client_peer, const struct http_client_peer_addr *,
a356c4736fe6041142c6096045bc00c15a80af4eTimo Sirainen unsigned int id;
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen void (*destroy_callback)(void *);
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen unsigned int id; // DEBUG: identify parallel connections
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct timeout *to_connect, *to_input, *to_idle, *to_response;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* requests that have been sent, waiting for response */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ARRAY_TYPE(http_client_request) request_wait_list;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen unsigned int connected:1; /* connection is connected */
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen unsigned int tunneling:1; /* last sent request turns this
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen connection into tunnel */
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen unsigned int connect_initialized:1; /* connection was initialized */
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen unsigned int output_locked:1; /* output is locked; no pipelining */
42401be443f96c91a20fc976d66ca626fa6e14ecTimo Sirainen unsigned int output_broken:1; /* output is broken; no more requests */
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen unsigned int in_req_callback:1; /* performin request callback (busy) */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen /* queues using this peer */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen /* active connections to this peer */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen /* zero time-out for consolidating request handling */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen /* connection retry */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen unsigned int disconnected:1; /* peer is already disconnected */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen unsigned int no_payload_sync:1; /* expect: 100-continue failed before */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen unsigned int seen_100_response:1;/* expect: 100-continue succeeded before */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen unsigned int allows_pipelining:1;/* peer is known to allow persistent
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen connections */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen unsigned int handling_requests:1;/* currently running request handler */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* current index in host->ips */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* the first IP that started the current round of connection attempts.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen initially 0, and later set to the ip index of the last successful
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen connected IP */
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen /* peers we are trying to connect to;
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen this can be more than one when soft connect timeouts are enabled */
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen /* all requests associated to this queue
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen (ordered by earliest timeout first) */
8e1ecc6542da1e14c14e2e59d39dbccdbf68e2b5Timo Sirainen /* delayed requests waiting to be released after delay */
8e1ecc6542da1e14c14e2e59d39dbccdbf68e2b5Timo Sirainen ARRAY_TYPE(http_client_request) delayed_requests;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen /* requests pending in queue to be picked up by connections */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen ARRAY_TYPE(http_client_request) queued_requests, queued_urgent_requests;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct timeout *to_connect, *to_request, *to_delayed;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen /* the ip addresses DNS returned for this host */
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen /* requests are managed on a per-port basis */
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen /* active DNS lookup */
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen /* list of failed requests that are waiting for ioloop */
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen ARRAY(struct http_client_request *) delayed_failing_requests;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen * Peer address
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenstatic inline bool
42401be443f96c91a20fc976d66ca626fa6e14ecTimo Sirainenhttp_client_peer_addr_is_https(const struct http_client_peer_addr *addr)
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenstatic inline const char *
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenhttp_client_peer_addr_get_https_name(const struct http_client_peer_addr *addr)
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenstatic inline const char *
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenhttp_client_peer_addr2str(const struct http_client_peer_addr *addr)
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen net_ip2addr(&addr->a.tcp.ip), addr->a.tcp.port);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen net_ip2addr(&addr->a.tcp.ip), addr->a.tcp.port);
f64b5bc9e73bedc63ba3c072c286542c29c69e43Timo Sirainen return t_strdup_printf("unix:%s", addr->a.un.path);
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainenstatic inline bool
468c28dfb03613ab8d487b5aebc985a969193aceTimo Sirainenhttp_client_request_to_proxy(const struct http_client_request *req)
58b8a301b7b36047f10a592751094fbed86d6f0cTimo Sirainenhttp_client_request_label(struct http_client_request *req);
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainenvoid http_client_request_ref(struct http_client_request *req);
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainen/* Returns FALSE if unrefing destroyed the request entirely */
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainenbool http_client_request_unref(struct http_client_request **_req);
ee3362f3b78827a2c9a7e9ddee83f5a429c06213Timo Sirainenvoid http_client_request_destroy(struct http_client_request **_req);
468c28dfb03613ab8d487b5aebc985a969193aceTimo Sirainenint http_client_request_delay_from_response(struct http_client_request *req,
abe29107f5dce932d28a00912d2d75a01021bef1Timo Sirainenvoid http_client_request_get_peer_addr(const struct http_client_request *req,
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainenhttp_client_request_get_payload_type(struct http_client_request *req);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenint http_client_request_send(struct http_client_request *req,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenint http_client_request_send_more(struct http_client_request *req,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenbool http_client_request_callback(struct http_client_request *req,
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainenvoid http_client_request_connect_callback(struct http_client_request *req,
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenvoid http_client_request_resubmit(struct http_client_request *req);
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenvoid http_client_request_retry(struct http_client_request *req,
468c28dfb03613ab8d487b5aebc985a969193aceTimo Sirainenvoid http_client_request_error_delayed(struct http_client_request **_req);
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainenvoid http_client_request_error(struct http_client_request **req,
abe29107f5dce932d28a00912d2d75a01021bef1Timo Sirainenvoid http_client_request_redirect(struct http_client_request *req,
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenvoid http_client_request_finish(struct http_client_request *req);
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenstruct connection_list *http_client_connection_list_init(void);
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainen http_client_connection_create(struct http_client_peer *peer);
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenvoid http_client_connection_ref(struct http_client_connection *conn);
3a7a0c35c9f827f86fb437e640287f3a467ef692Timo Sirainen/* Returns FALSE if unrefing destroyed the connection entirely */
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenbool http_client_connection_unref(struct http_client_connection **_conn);
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenvoid http_client_connection_close(struct http_client_connection **_conn);
152db3f90f298b7fb2dbbd4276f0fc30a9bc30f6Timo Sirainenvoid http_client_connection_peer_closed(struct http_client_connection **_conn);
152db3f90f298b7fb2dbbd4276f0fc30a9bc30f6Timo Sirainenint http_client_connection_output(struct http_client_connection *conn);
152db3f90f298b7fb2dbbd4276f0fc30a9bc30f6Timo Sirainenvoid http_client_connection_start_request_timeout(
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenvoid http_client_connection_reset_request_timeout(
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenvoid http_client_connection_stop_request_timeout(
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenhttp_client_connection_count_pending(struct http_client_connection *conn);
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenint http_client_connection_check_ready(struct http_client_connection *conn);
152db3f90f298b7fb2dbbd4276f0fc30a9bc30f6Timo Sirainenbool http_client_connection_is_idle(struct http_client_connection *conn);
152db3f90f298b7fb2dbbd4276f0fc30a9bc30f6Timo Sirainenint http_client_connection_next_request(struct http_client_connection *conn);
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainenvoid http_client_connection_check_idle(struct http_client_connection *conn);
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainenvoid http_client_connection_switch_ioloop(struct http_client_connection *conn);
002f2544421891472dc9aeb79d3abdde6a8ed4c8Timo Sirainenvoid http_client_connection_start_tunnel(struct http_client_connection **_conn,
002f2544421891472dc9aeb79d3abdde6a8ed4c8Timo Sirainen (const struct http_client_peer_addr *peer) ATTR_PURE;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen const struct http_client_peer_addr *peer2) ATTR_PURE;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenhttp_client_peer_label(struct http_client_peer *peer);
465fb89a877b778f68734f6cc36db9ce2a4a0a71Timo Sirainen http_client_peer_get(struct http_client *client,
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenvoid http_client_peer_ref(struct http_client_peer *peer);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenbool http_client_peer_unref(struct http_client_peer **_peer);
1df39b899804fd1dbc560f75382364822935c857Timo Sirainenvoid http_client_peer_close(struct http_client_peer **_peer);
1df39b899804fd1dbc560f75382364822935c857Timo Sirainenbool http_client_peer_have_queue(struct http_client_peer *peer,
f64b5bc9e73bedc63ba3c072c286542c29c69e43Timo Sirainenvoid http_client_peer_link_queue(struct http_client_peer *peer,
f64b5bc9e73bedc63ba3c072c286542c29c69e43Timo Sirainenvoid http_client_peer_unlink_queue(struct http_client_peer *peer,
f64b5bc9e73bedc63ba3c072c286542c29c69e43Timo Sirainen http_client_peer_claim_request(struct http_client_peer *peer,
abe29107f5dce932d28a00912d2d75a01021bef1Timo Sirainenvoid http_client_peer_trigger_request_handler(struct http_client_peer *peer);
abe29107f5dce932d28a00912d2d75a01021bef1Timo Sirainenvoid http_client_peer_connection_success(struct http_client_peer *peer);
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainenvoid http_client_peer_connection_failure(struct http_client_peer *peer,
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainen const char *reason);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenvoid http_client_peer_connection_lost(struct http_client_peer *peer);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenbool http_client_peer_is_connected(struct http_client_peer *peer);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenhttp_client_peer_idle_connections(struct http_client_peer *peer);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenhttp_client_peer_pending_connections(struct http_client_peer *peer);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenvoid http_client_peer_switch_ioloop(struct http_client_peer *peer);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenhttp_client_queue_create(struct http_client_host *host,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenvoid http_client_queue_free(struct http_client_queue *queue);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenvoid http_client_queue_fail(struct http_client_queue *queue,
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenvoid http_client_queue_connection_setup(struct http_client_queue *queue);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenvoid http_client_queue_submit_request(struct http_client_queue *queue,
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenhttp_client_queue_drop_request(struct http_client_queue *queue,
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenhttp_client_queue_claim_request(struct http_client_queue *queue,
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen const struct http_client_peer_addr *addr, bool no_urgent);
027f58ea63a1822bbf13d99ee5572e5f8b9e8d8bTimo Sirainenhttp_client_queue_requests_pending(struct http_client_queue *queue,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenhttp_client_queue_connection_success(struct http_client_queue *queue,
027f58ea63a1822bbf13d99ee5572e5f8b9e8d8bTimo Sirainenvoid http_client_queue_connection_failure(struct http_client_queue *queue,
027f58ea63a1822bbf13d99ee5572e5f8b9e8d8bTimo Sirainen const struct http_client_peer_addr *addr, const char *reason);
027f58ea63a1822bbf13d99ee5572e5f8b9e8d8bTimo Sirainenvoid http_client_queue_switch_ioloop(struct http_client_queue *queue);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenstatic inline unsigned int
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenhttp_client_host_get_ip_idx(struct http_client_host *host,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen unsigned int i;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenhttp_client_host_get(struct http_client *client,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenvoid http_client_host_free(struct http_client_host **_host);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenvoid http_client_host_submit_request(struct http_client_host *host,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenvoid http_client_host_switch_ioloop(struct http_client_host *host);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenint http_client_init_ssl_ctx(struct http_client *client,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen const char **error_r);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenvoid http_client_delay_request_error(struct http_client *client,