http-client-private.h revision 63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4f
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#ifndef HTTP_CLIENT_PRIVATE_H
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#define HTTP_CLIENT_PRIVATE_H
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "connection.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch#include "http-url.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "http-client.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch/*
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch * Defaults
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch */
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#define HTTP_DEFAULT_PORT 80
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#define HTTPS_DEFAULT_PORT 443
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#define HTTP_CLIENT_CONTINUE_TIMEOUT_MSECS (1000*2)
5257840e8d31a6cb7051703b4cb0931c82aba638Stephan Bosch#define HTTP_CLIENT_DEFAULT_REQUEST_TIMEOUT_MSECS (1000*60*1)
5257840e8d31a6cb7051703b4cb0931c82aba638Stephan Bosch#define HTTP_CLIENT_DEFAULT_DNS_LOOKUP_TIMEOUT_MSECS (1000*10)
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch#define HTTP_CLIENT_DEFAULT_BACKOFF_TIME_MSECS (100)
94d1b08c9e20d637db568a3eab3dfc2b9e96e62aStephan Bosch#define HTTP_CLIENT_DEFAULT_BACKOFF_MAX_TIME_MSECS (1000*60)
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch#define HTTP_CLIENT_DEFAULT_DNS_TTL_MSECS (1000*60*30)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch/*
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch * Types
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch */
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct http_client_connection;
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Boschstruct http_client_peer;
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Boschstruct http_client_queue;
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Boschstruct http_client_host;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan BoschARRAY_DEFINE_TYPE(http_client_request,
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Bosch struct http_client_request *);
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan BoschARRAY_DEFINE_TYPE(http_client_connection,
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Bosch struct http_client_connection *);
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan BoschARRAY_DEFINE_TYPE(http_client_peer,
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Bosch struct http_client_peer *);
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan BoschARRAY_DEFINE_TYPE(http_client_queue,
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Bosch struct http_client_queue *);
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan BoschARRAY_DEFINE_TYPE(http_client_host,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct http_client_host *);
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Bosch
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan BoschHASH_TABLE_DEFINE_TYPE(http_client_peer,
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Bosch const struct http_client_peer_addr *,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct http_client_peer *);
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan BoschHASH_TABLE_DEFINE_TYPE(http_client_host,
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Bosch const char *, struct http_client_host *);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Boschenum http_client_peer_addr_type {
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch HTTP_CLIENT_PEER_ADDR_HTTP = 0,
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch HTTP_CLIENT_PEER_ADDR_HTTPS,
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL,
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch HTTP_CLIENT_PEER_ADDR_RAW,
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch HTTP_CLIENT_PEER_ADDR_UNIX,
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch};
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Boschstruct http_client_peer_addr {
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch enum http_client_peer_addr_type type;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch union {
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch struct {
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch const char *https_name; /* TLS SNI */
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch struct ip_addr ip;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch in_port_t port;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch } tcp;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch struct {
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch const char *path;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch } un;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch } a;
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch};
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch/*
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch * Objects
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch */
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct http_client_request {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch pool_t pool;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int refcount;
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch const char *label;
47a53a80656dc400ff8effdc1432a69fbf5ae8baTimo Sirainen unsigned int id;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
a991cfe2157e58ee43bc580f517ce9ef0dfb7acfStephan Bosch struct http_client_request *prev, *next;
a991cfe2157e58ee43bc580f517ce9ef0dfb7acfStephan Bosch
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch const char *method, *target;
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch struct http_url origin_url;
30f35cf5d1e1374d7fab4231e86144fc106a8e79Stephan Bosch const char *username, *password;
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch const char *host_socket;
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch const struct http_url *host_url;
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch const char *authority;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct http_client *client;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct http_client_host *host;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client_queue *queue;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct http_client_peer *peer;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct http_client_connection *conn;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch string_t *headers;
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch time_t date;
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen struct istream *payload_input;
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen uoff_t payload_size, payload_offset;
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen struct ostream *payload_output;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch struct timeval release_time;
31fa529029f35f65451fb1d119ed1d5435b62e46Timo Sirainen struct timeval submit_time;
f0452e0b310ddc74d84c2492f72fea41ffcb96a8Timo Sirainen struct timeval first_sent_time;
31fa529029f35f65451fb1d119ed1d5435b62e46Timo Sirainen struct timeval sent_time;
31fa529029f35f65451fb1d119ed1d5435b62e46Timo Sirainen struct timeval response_time;
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch struct timeval timeout_time;
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch unsigned int timeout_msecs;
5b6bfa39481f719c1fd6ed3febeaf7f0be9e8886Timo Sirainen unsigned int attempt_timeout_msecs;
5b6bfa39481f719c1fd6ed3febeaf7f0be9e8886Timo Sirainen unsigned int max_attempts;
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int attempts;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int redirects;
86ab71bf134573e45dd9ab6bde9d55da4c44fc48Timo Sirainen uint64_t sent_global_ioloop_usecs;
92f66f98f64ee3febbfba6618c4e144080d81a66Timo Sirainen uint64_t sent_http_ioloop_usecs;
86ab71bf134573e45dd9ab6bde9d55da4c44fc48Timo Sirainen uint64_t sent_lock_usecs;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen unsigned int delayed_error_status;
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen const char *delayed_error;
6bc9fb43cc1ac24693d030a6cbfa43bc7cbc82cbTimo Sirainen
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch http_client_request_callback_t *callback;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch void *context;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
4124bebe6daab2cd05acb0416096fc47cb9abd92Timo Sirainen void (*destroy_callback)(void *);
4124bebe6daab2cd05acb0416096fc47cb9abd92Timo Sirainen void *destroy_context;
4124bebe6daab2cd05acb0416096fc47cb9abd92Timo Sirainen
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch enum http_request_state state;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool have_hdr_authorization:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool have_hdr_body_spec:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool have_hdr_connection:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool have_hdr_date:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool have_hdr_expect:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool have_hdr_host:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool have_hdr_user_agent:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool payload_sync:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool payload_sync_continue:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool payload_chunked:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool payload_wait:1;
4d1cc687f40dc2697005a4977e7ac40dda3d7dcfStephan Bosch bool payload_empty:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool urgent:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool submitted:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool listed:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool connect_tunnel:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool connect_direct:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool ssl_tunnel:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool preserve_exact_reason:1;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch};
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschstruct http_client_connection {
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct connection conn;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client_peer *peer;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client *client;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch unsigned int refcount;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch char *label;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch unsigned int id; // DEBUG: identify parallel connections
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch int connect_errno;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct timeval connect_start_timestamp;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct timeval connected_timestamp;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client_request *connect_request;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct ssl_iostream *ssl_iostream;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_response_parser *http_parser;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct timeout *to_connect, *to_input, *to_idle, *to_response;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct timeout *to_requests;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client_request *pending_request;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct istream *incoming_payload;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct io *io_req_payload;
22215c2d7538f4367c93e2d8b6ec4722463ac757Stephan Bosch struct ioloop *last_ioloop;
92f66f98f64ee3febbfba6618c4e144080d81a66Timo Sirainen struct io_wait_timer *io_wait_timer;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch /* requests that have been sent, waiting for response */
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch ARRAY_TYPE(http_client_request) request_wait_list;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool connected:1; /* connection is connected */
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Bosch bool tunneling:1; /* last sent request turns this
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Bosch connection into tunnel */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool connect_initialized:1; /* connection was initialized */
bad9931efd293ea9a676ce99e82c539e9d215e0dStephan Bosch bool connect_succeeded:1; /* connection succeeded including SSL */
bad9931efd293ea9a676ce99e82c539e9d215e0dStephan Bosch bool connect_failed:1; /* connection failed */
f17ac27e5989d6b3b3e4f4fb249bef4b06833ab7Stephan Bosch bool lost_prematurely:1; /* lost connection before receiving any data */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool closing:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool disconnected:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool close_indicated:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool output_locked:1; /* output is locked; no pipelining */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool output_broken:1; /* output is broken; no more requests */
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Bosch bool in_req_callback:1; /* performing request callback (busy) */
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch};
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschstruct http_client_peer {
ebe0f5e387744621b73c4db79d5891ccbe0a1321Stephan Bosch unsigned int refcount;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client_peer_addr addr;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch char *addr_name;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch char *label;
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client *client;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client_peer *prev, *next;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch /* queues using this peer */
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch ARRAY_TYPE(http_client_queue) queues;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch /* active connections to this peer */
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch ARRAY_TYPE(http_client_connection) conns;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch /* zero time-out for consolidating request handling */
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct timeout *to_req_handling;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch /* connection retry */
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch struct timeval last_failure;
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch struct timeout *to_backoff;
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch unsigned int backoff_time_msecs;
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool disconnected:1; /* peer is already disconnected */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool no_payload_sync:1; /* expect: 100-continue failed before */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool seen_100_response:1;/* expect: 100-continue succeeded before */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool allows_pipelining:1;/* peer is known to allow persistent
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Bosch connections */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool handling_requests:1;/* currently running request handler */
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch};
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschstruct http_client_queue {
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client *client;
70505f4839520ac67895992621c97d2480c22e7fTimo Sirainen struct http_client_host *host;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch char *name;
70505f4839520ac67895992621c97d2480c22e7fTimo Sirainen
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch struct http_client_peer_addr addr;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch char *addr_name;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* current index in host->ips */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int ips_connect_idx;
1a64096dcbea2765f370c9d35a3480d0e60c643bTimo Sirainen /* the first IP that started the current round of connection attempts.
524d89a40565709964b7ee5e8324a400dc53656bTimo Sirainen initially 0, and later set to the ip index of the last successful
1a64096dcbea2765f370c9d35a3480d0e60c643bTimo Sirainen connected IP */
1a64096dcbea2765f370c9d35a3480d0e60c643bTimo Sirainen unsigned int ips_connect_start_idx;
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch
9284599e2d12b08170be81441bcfc53fa5b71a73Timo Sirainen struct timeval first_connect_time;
9d746c6785d17e421c3f3c74cf29d059ae2ab233Stephan Bosch unsigned int connect_attempts;
9d746c6785d17e421c3f3c74cf29d059ae2ab233Stephan Bosch
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch /* peers we are trying to connect to;
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch this can be more than one when soft connect timeouts are enabled */
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch ARRAY_TYPE(http_client_peer) pending_peers;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
57d86b6fd46cb6d37bfc28f67ae4be80296ad35aStephan Bosch /* currently active peer */
57d86b6fd46cb6d37bfc28f67ae4be80296ad35aStephan Bosch struct http_client_peer *cur_peer;
57d86b6fd46cb6d37bfc28f67ae4be80296ad35aStephan Bosch
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch /* all requests associated to this queue
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch (ordered by earliest timeout first) */
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch ARRAY_TYPE(http_client_request) requests;
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch /* delayed requests waiting to be released after delay */
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch ARRAY_TYPE(http_client_request) delayed_requests;
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* requests pending in queue to be picked up by connections */
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch ARRAY_TYPE(http_client_request) queued_requests, queued_urgent_requests;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch struct timeout *to_connect, *to_request, *to_delayed;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch};
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct http_client_host {
aacf2a69acc59e9382578d6f4e030788abc79706Timo Sirainen struct http_client_host *prev, *next;
aacf2a69acc59e9382578d6f4e030788abc79706Timo Sirainen
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct http_client *client;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch char *name;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* the ip addresses DNS returned for this host */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int ips_count;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct ip_addr *ips;
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Bosch struct timeval ips_timeout;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* requests are managed on a per-port basis */
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch ARRAY_TYPE(http_client_queue) queues;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* active DNS lookup */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct dns_lookup *dns_lookup;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch /* timeouts */
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch struct timeout *to_idle;
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Bosch
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool unix_local:1;
c936df07cf490f090f2f336f40ca386cc953b055Stephan Bosch bool explicit_ip:1;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch};
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct http_client {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch pool_t pool;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct http_client_settings set;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct ioloop *ioloop;
415e16c3dc185578695b7d88e561a52de6c8b1b1Timo Sirainen struct ssl_iostream_context *ssl_ctx;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch /* list of failed requests that are waiting for ioloop */
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch ARRAY(struct http_client_request *) delayed_failing_requests;
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch struct timeout *to_failing_requests;
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct connection_list *conn_list;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch HASH_TABLE_TYPE(http_client_host) hosts;
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch struct http_client_host *unix_host;
aacf2a69acc59e9382578d6f4e030788abc79706Timo Sirainen struct http_client_host *hosts_list;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch HASH_TABLE_TYPE(http_client_peer) peers;
9dc01e0d10a61cab14867b26bf0d2d1dcf8ad978Timo Sirainen struct http_client_peer *peers_list;
a991cfe2157e58ee43bc580f517ce9ef0dfb7acfStephan Bosch struct http_client_request *requests_list;
a991cfe2157e58ee43bc580f517ce9ef0dfb7acfStephan Bosch unsigned int requests_count;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch};
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch/*
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch * Peer address
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch */
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschstatic inline bool
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschhttp_client_peer_addr_is_https(const struct http_client_peer_addr *addr)
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch{
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch switch (addr->type) {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch case HTTP_CLIENT_PEER_ADDR_HTTPS:
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch case HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL:
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch return TRUE;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch default:
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch break;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch return FALSE;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch}
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschstatic inline const char *
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschhttp_client_peer_addr_get_https_name(const struct http_client_peer_addr *addr)
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch{
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch switch (addr->type) {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch case HTTP_CLIENT_PEER_ADDR_HTTPS:
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch case HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL:
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch return addr->a.tcp.https_name;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch default:
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch break;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch return NULL;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch}
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschstatic inline const char *
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschhttp_client_peer_addr2str(const struct http_client_peer_addr *addr)
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch{
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch switch (addr->type) {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch case HTTP_CLIENT_PEER_ADDR_HTTP:
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch case HTTP_CLIENT_PEER_ADDR_HTTPS:
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch case HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL:
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch case HTTP_CLIENT_PEER_ADDR_RAW:
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch if (addr->a.tcp.ip.family == AF_INET6) {
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch return t_strdup_printf("[%s]:%u",
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch net_ip2addr(&addr->a.tcp.ip), addr->a.tcp.port);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch return t_strdup_printf("%s:%u",
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch net_ip2addr(&addr->a.tcp.ip), addr->a.tcp.port);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch case HTTP_CLIENT_PEER_ADDR_UNIX:
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch return t_strdup_printf("unix:%s", addr->a.un.path);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch default:
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch break;
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch }
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch i_unreached();
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch return "";
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch}
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch/*
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch * Request
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch */
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschstatic inline bool
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschhttp_client_request_to_proxy(const struct http_client_request *req)
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch{
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch return (req->host_url != &req->origin_url);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch}
415e16c3dc185578695b7d88e561a52de6c8b1b1Timo Sirainen
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Boschconst char *
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Boschhttp_client_request_label(struct http_client_request *req);
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvoid http_client_request_ref(struct http_client_request *req);
d1f964d3f1dd9c5868b134c4f44dd63f3722eef7Timo Sirainen/* Returns FALSE if unrefing destroyed the request entirely */
d1f964d3f1dd9c5868b134c4f44dd63f3722eef7Timo Sirainenbool http_client_request_unref(struct http_client_request **_req);
79f8a20424633e806447bc9375a5ab403aabc758Stephan Boschvoid http_client_request_destroy(struct http_client_request **_req);
79f8a20424633e806447bc9375a5ab403aabc758Stephan Bosch
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Boschint http_client_request_delay_from_response(struct http_client_request *req,
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Bosch const struct http_response *response);
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Boschvoid http_client_request_get_peer_addr(const struct http_client_request *req,
ede750711f27ca9d9037a7ab9f016411b57f1ad9Stephan Bosch struct http_client_peer_addr *addr);
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Boschenum http_response_payload_type
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Boschhttp_client_request_get_payload_type(struct http_client_request *req);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainenint http_client_request_send(struct http_client_request *req,
173d53863744e8ed87e8fa4c32dfcf3759e2ceb0Stephan Bosch bool pipelined, const char **error_r);
99feb6521535a7dc59d8dda89981ceac084b3e88Timo Sirainenint http_client_request_send_more(struct http_client_request *req,
173d53863744e8ed87e8fa4c32dfcf3759e2ceb0Stephan Bosch bool pipelined, const char **error_r);
6c768e0e1ca2da178e79f7435c32ced01f6bcb24Timo Sirainenbool http_client_request_callback(struct http_client_request *req,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct http_response *response);
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Boschvoid http_client_request_connect_callback(struct http_client_request *req,
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch const struct http_client_tunnel *tunnel,
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch struct http_response *response);
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvoid http_client_request_resubmit(struct http_client_request *req);
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvoid http_client_request_retry(struct http_client_request *req,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int status, const char *error);
129596c93692b21d6c6b1313b389774af24c2983Stephan Boschvoid http_client_request_error_delayed(struct http_client_request **_req);
d5c665cf2989d49922b63439ac45714e9755838aTimo Sirainenvoid http_client_request_error(struct http_client_request **req,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int status, const char *error);
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvoid http_client_request_redirect(struct http_client_request *req,
50a6d26bd9041f44b4cad0c0357c0c604c132cc8Stephan Bosch unsigned int status, const char *location);
d1f964d3f1dd9c5868b134c4f44dd63f3722eef7Timo Sirainenvoid http_client_request_finish(struct http_client_request *req);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch/*
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch * Connection
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch */
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct connection_list *http_client_connection_list_init(void);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct http_client_connection *
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Boschhttp_client_connection_create(struct http_client_peer *peer);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Boschvoid http_client_connection_ref(struct http_client_connection *conn);
1dead6eacb9302a8419bfc8f4b571ea9a3c00296Timo Sirainen/* Returns FALSE if unrefing destroyed the connection entirely */
1dead6eacb9302a8419bfc8f4b571ea9a3c00296Timo Sirainenbool http_client_connection_unref(struct http_client_connection **_conn);
60381d37ec7213c21bd6ada7babb769f572646f9Stephan Boschvoid http_client_connection_close(struct http_client_connection **_conn);
8a6dc50255a27bf887bbd9ed7c3a87bf629d4179Stephan Bosch
8a6dc50255a27bf887bbd9ed7c3a87bf629d4179Stephan Boschvoid http_client_connection_peer_closed(struct http_client_connection **_conn);
567d1c82e3e59a8e8acc2e1e01228585bab83bc6Stephan Boschvoid http_client_connection_request_destroyed(
567d1c82e3e59a8e8acc2e1e01228585bab83bc6Stephan Bosch struct http_client_connection *conn, struct http_client_request *req);
8a6dc50255a27bf887bbd9ed7c3a87bf629d4179Stephan Bosch
a4e186e3ef267fc7a6b592788067c8c9c87d0785Stephan Boschint http_client_connection_output(struct http_client_connection *conn);
3d1edb8e3a07d91860cc6b4b3cec8282caa70891Stephan Boschvoid http_client_connection_start_request_timeout(
3d1edb8e3a07d91860cc6b4b3cec8282caa70891Stephan Bosch struct http_client_connection *conn);
3d1edb8e3a07d91860cc6b4b3cec8282caa70891Stephan Boschvoid http_client_connection_reset_request_timeout(
3d1edb8e3a07d91860cc6b4b3cec8282caa70891Stephan Bosch struct http_client_connection *conn);
3d1edb8e3a07d91860cc6b4b3cec8282caa70891Stephan Boschvoid http_client_connection_stop_request_timeout(
3d1edb8e3a07d91860cc6b4b3cec8282caa70891Stephan Bosch struct http_client_connection *conn);
6a33d6385601c89fdaeb437537f714b3a01dcea4Timo Sirainenunsigned int
6a33d6385601c89fdaeb437537f714b3a01dcea4Timo Sirainenhttp_client_connection_count_pending(struct http_client_connection *conn);
57c339f4e3404355a8924103317a6158a709ecf1Stephan Boschint http_client_connection_check_ready(struct http_client_connection *conn);
eb325a5a90c1d2655e74972bde0de6a699d2c864Stephan Boschbool http_client_connection_is_idle(struct http_client_connection *conn);
2b9d522a3300fa84a1606e2108a159be7bb36154Stephan Boschbool http_client_connection_is_active(struct http_client_connection *conn);
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Boschint http_client_connection_next_request(struct http_client_connection *conn);
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Boschvoid http_client_connection_check_idle(struct http_client_connection *conn);
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvoid http_client_connection_switch_ioloop(struct http_client_connection *conn);
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Boschvoid http_client_connection_start_tunnel(struct http_client_connection **_conn,
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch struct http_client_tunnel *tunnel);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch/*
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch * Peer
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch */
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschunsigned int http_client_peer_addr_hash
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch (const struct http_client_peer_addr *peer) ATTR_PURE;
7384b4e78eaab44693c985192276e31322155e32Stephan Boschint http_client_peer_addr_cmp
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch (const struct http_client_peer_addr *peer1,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const struct http_client_peer_addr *peer2) ATTR_PURE;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Boschconst char *
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Boschhttp_client_peer_label(struct http_client_peer *peer);
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct http_client_peer *
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Boschhttp_client_peer_get(struct http_client *client,
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Bosch const struct http_client_peer_addr *addr);
ebe0f5e387744621b73c4db79d5891ccbe0a1321Stephan Boschvoid http_client_peer_ref(struct http_client_peer *peer);
ebe0f5e387744621b73c4db79d5891ccbe0a1321Stephan Boschbool http_client_peer_unref(struct http_client_peer **_peer);
ebe0f5e387744621b73c4db79d5891ccbe0a1321Stephan Boschvoid http_client_peer_close(struct http_client_peer **_peer);
ebe0f5e387744621b73c4db79d5891ccbe0a1321Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschbool http_client_peer_have_queue(struct http_client_peer *peer,
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client_queue *queue);
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschvoid http_client_peer_link_queue(struct http_client_peer *peer,
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client_queue *queue);
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschvoid http_client_peer_unlink_queue(struct http_client_peer *peer,
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client_queue *queue);
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct http_client_request *
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch http_client_peer_claim_request(struct http_client_peer *peer,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch bool no_urgent);
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Boschvoid http_client_peer_trigger_request_handler(struct http_client_peer *peer);
70505f4839520ac67895992621c97d2480c22e7fTimo Sirainenvoid http_client_peer_connection_success(struct http_client_peer *peer);
2a889fc596b12639ac55e657816b8a4f90440f88Timo Sirainenvoid http_client_peer_connection_failure(struct http_client_peer *peer,
2a889fc596b12639ac55e657816b8a4f90440f88Timo Sirainen const char *reason);
f17ac27e5989d6b3b3e4f4fb249bef4b06833ab7Stephan Boschvoid http_client_peer_connection_lost(struct http_client_peer *peer,
f17ac27e5989d6b3b3e4f4fb249bef4b06833ab7Stephan Bosch bool premature);
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Boschbool http_client_peer_is_connected(struct http_client_peer *peer);
a40a555561b3378c12a986b27f2651c632c8afa4Stephan Boschunsigned int
a40a555561b3378c12a986b27f2651c632c8afa4Stephan Boschhttp_client_peer_idle_connections(struct http_client_peer *peer);
a40a555561b3378c12a986b27f2651c632c8afa4Stephan Boschunsigned int
66ea898de7face7fc9c275e01e514fa002446975Stephan Boschhttp_client_peer_active_connections(struct http_client_peer *peer);
66ea898de7face7fc9c275e01e514fa002446975Stephan Boschunsigned int
a40a555561b3378c12a986b27f2651c632c8afa4Stephan Boschhttp_client_peer_pending_connections(struct http_client_peer *peer);
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Boschvoid http_client_peer_switch_ioloop(struct http_client_peer *peer);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch/*
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch * Queue
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch */
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschstruct http_client_queue *
8149ed57ae5abbb0c4ccfe88c1d7c58255dc85cfStephan Boschhttp_client_queue_get(struct http_client_host *host,
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch const struct http_client_peer_addr *addr);
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschvoid http_client_queue_free(struct http_client_queue *queue);
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschvoid http_client_queue_connection_setup(struct http_client_queue *queue);
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Boschunsigned int
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Boschhttp_client_queue_host_lookup_done(struct http_client_queue *queue);
5791d02c3672f6a525f1fcf0f4f375b4be0ccf4bStephan Boschvoid http_client_queue_host_lookup_failure(
5791d02c3672f6a525f1fcf0f4f375b4be0ccf4bStephan Bosch struct http_client_queue *queue, const char *error);
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschvoid http_client_queue_submit_request(struct http_client_queue *queue,
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client_request *req);
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Boschvoid http_client_queue_drop_request(struct http_client_queue *queue,
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch struct http_client_request *req);
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschstruct http_client_request *
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschhttp_client_queue_claim_request(struct http_client_queue *queue,
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch const struct http_client_peer_addr *addr, bool no_urgent);
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschunsigned int
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschhttp_client_queue_requests_pending(struct http_client_queue *queue,
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch unsigned int *num_urgent_r) ATTR_NULL(2);
c62f15cc134cc9701c391eec8e9ef92105aa6d33Stephan Boschunsigned int
c62f15cc134cc9701c391eec8e9ef92105aa6d33Stephan Boschhttp_client_queue_requests_active(struct http_client_queue *queue);
63a1359e6e7f6b1aebf58eb5d9f8187140ddcb4fStephan Boschvoid http_client_queue_connection_success(struct http_client_queue *queue,
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch const struct http_client_peer_addr *addr);
e4e4b8544a492cf90bd7a93c9a26e8285fc7c00bStephan Boschvoid http_client_queue_connection_failure(struct http_client_queue *queue,
e4e4b8544a492cf90bd7a93c9a26e8285fc7c00bStephan Bosch const struct http_client_peer_addr *addr, const char *reason);
c1423bdba971228a283653222ed0367f84ab6402Stephan Boschvoid http_client_queue_peer_disconnected(struct http_client_queue *queue,
c1423bdba971228a283653222ed0367f84ab6402Stephan Bosch struct http_client_peer *peer);
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschvoid http_client_queue_switch_ioloop(struct http_client_queue *queue);
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch/*
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch * Host
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch */
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
97a8fde13ea33b09163c45d978a4949043f189c5Stephan Boschstatic inline bool
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschhttp_client_host_get_ip_idx(struct http_client_host *host,
97a8fde13ea33b09163c45d978a4949043f189c5Stephan Bosch const struct ip_addr *ip, unsigned int *idx_r)
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch{
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch unsigned int i;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch for (i = 0; i < host->ips_count; i++) {
97a8fde13ea33b09163c45d978a4949043f189c5Stephan Bosch if (net_ip_compare(&host->ips[i], ip)) {
97a8fde13ea33b09163c45d978a4949043f189c5Stephan Bosch *idx_r = i;
97a8fde13ea33b09163c45d978a4949043f189c5Stephan Bosch return TRUE;
97a8fde13ea33b09163c45d978a4949043f189c5Stephan Bosch }
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch }
97a8fde13ea33b09163c45d978a4949043f189c5Stephan Bosch return FALSE;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch}
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschstruct http_client_host *
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschhttp_client_host_get(struct http_client *client,
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch const struct http_url *host_url);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschvoid http_client_host_free(struct http_client_host **_host);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschvoid http_client_host_submit_request(struct http_client_host *host,
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch struct http_client_request *req);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschvoid http_client_host_switch_ioloop(struct http_client_host *host);
c4b2dba355010a38f17b3cd84feb01ecb8b05a55Stephan Boschvoid http_client_host_check_idle(struct http_client_host *host);
1e63e30812158e6446d81cdbb2f45954794d4f8aStephan Boschint http_client_host_refresh(struct http_client_host *host);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch/*
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch * Client
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch */
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschint http_client_init_ssl_ctx(struct http_client *client,
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch const char **error_r);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschvoid http_client_delay_request_error(struct http_client *client,
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch struct http_client_request *req);
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Boschvoid http_client_remove_request_error(struct http_client *client,
5a37824675033747fcae3fe3fc3c0dd7ef0ca1cdStephan Bosch struct http_client_request *req);
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#endif