http-client-private.h revision 57c339f4e3404355a8924103317a6158a709ecf1
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch#ifndef HTTP_CLIENT_PRIVATE_H
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#define HTTP_CLIENT_PRIVATE_H
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "connection.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "http-url.h"
09060303d565e15d54e42b4ef722f9d3c26f5336Timo Sirainen#include "http-client.h"
c3a2a487e23a282e59254b82deb9344ed0306bb2Timo Sirainen
15ab2452b0220a115f4351ad9d7fd5ec70ae7966Timo Sirainen/*
cf7857bce68a33cdabe88bb15568e21921eb5ac7Aki Tuomi * Defaults
cf7857bce68a33cdabe88bb15568e21921eb5ac7Aki Tuomi */
cf7857bce68a33cdabe88bb15568e21921eb5ac7Aki Tuomi
cf7857bce68a33cdabe88bb15568e21921eb5ac7Aki Tuomi#define HTTP_DEFAULT_PORT 80
cf7857bce68a33cdabe88bb15568e21921eb5ac7Aki Tuomi#define HTTPS_DEFAULT_PORT 443
de92873c366becfaea1554642f89b9169d7955e2Timo Sirainen
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)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
15ab2452b0220a115f4351ad9d7fd5ec70ae7966Timo Sirainen/*
cf7857bce68a33cdabe88bb15568e21921eb5ac7Aki Tuomi * Types
4fe3f07477bae6da3fb8d8fa9bab10ab82ada2bdTimo Sirainen */
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen
15ab2452b0220a115f4351ad9d7fd5ec70ae7966Timo Sirainenenum http_response_payload_type;
4865df74dad010a65ab63734b3ca1349ce38dc57Timo Sirainen
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainenstruct http_client_host;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainenstruct http_client_queue;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenstruct http_client_peer;
4fe3f07477bae6da3fb8d8fa9bab10ab82ada2bdTimo Sirainenstruct http_client_connection;
1df39b899804fd1dbc560f75382364822935c857Timo Sirainen
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 Sirainen
c13fce16374a6fa8d127742c527498d38e777789Timo SirainenHASH_TABLE_DEFINE_TYPE(http_client_host, const char *,
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen struct http_client_host *);
c13fce16374a6fa8d127742c527498d38e777789Timo SirainenHASH_TABLE_DEFINE_TYPE(http_client_peer, const struct http_client_peer_addr *,
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen struct http_client_peer *);
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen
c3a2a487e23a282e59254b82deb9344ed0306bb2Timo Sirainenenum http_client_peer_addr_type {
c3a2a487e23a282e59254b82deb9344ed0306bb2Timo Sirainen HTTP_CLIENT_PEER_ADDR_HTTP = 0,
c3a2a487e23a282e59254b82deb9344ed0306bb2Timo Sirainen HTTP_CLIENT_PEER_ADDR_HTTPS,
c3a2a487e23a282e59254b82deb9344ed0306bb2Timo Sirainen HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL,
c3a2a487e23a282e59254b82deb9344ed0306bb2Timo Sirainen HTTP_CLIENT_PEER_ADDR_RAW,
c3a2a487e23a282e59254b82deb9344ed0306bb2Timo Sirainen HTTP_CLIENT_PEER_ADDR_UNIX,
c3a2a487e23a282e59254b82deb9344ed0306bb2Timo Sirainen};
c3a2a487e23a282e59254b82deb9344ed0306bb2Timo Sirainen
cf7857bce68a33cdabe88bb15568e21921eb5ac7Aki Tuomistruct http_client_peer_addr {
cf7857bce68a33cdabe88bb15568e21921eb5ac7Aki Tuomi enum http_client_peer_addr_type type;
cf7857bce68a33cdabe88bb15568e21921eb5ac7Aki Tuomi union {
cf7857bce68a33cdabe88bb15568e21921eb5ac7Aki Tuomi struct {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *https_name; /* TLS SNI */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct ip_addr ip;
db623deb12c3566618faba5a35a44ceed83c3dc0Martti Rannanjärvi in_port_t port;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen } tcp;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct {
db623deb12c3566618faba5a35a44ceed83c3dc0Martti Rannanjärvi const char *path;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen } un;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen } a;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen};
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen/*
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen * Objects
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstruct http_client_request {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen pool_t pool;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int refcount;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *label;
a356c4736fe6041142c6096045bc00c15a80af4eTimo Sirainen unsigned int id;
a356c4736fe6041142c6096045bc00c15a80af4eTimo Sirainen
a356c4736fe6041142c6096045bc00c15a80af4eTimo Sirainen struct http_client_request *prev, *next;
a356c4736fe6041142c6096045bc00c15a80af4eTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *method, *target;
a356c4736fe6041142c6096045bc00c15a80af4eTimo Sirainen struct http_url origin_url;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *username, *password;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
c4900d31385344bfadaee53a897daeafdb3063d8Timo Sirainen const char *host_socket;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const struct http_url *host_url;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *authority;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct http_client *client;
34a45b80c8ed18861c6e343fe40adbe360fc6badTimo Sirainen struct http_client_host *host;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct http_client_queue *queue;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct http_client_peer *peer;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct http_client_connection *conn;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen string_t *headers;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen time_t date;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct istream *payload_input;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen uoff_t payload_size, payload_offset;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct ostream *payload_output;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct timeval release_time;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct timeval submit_time;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct timeval sent_time;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct timeval response_time;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct timeval timeout_time;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int timeout_msecs;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int attempts;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int redirects;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int delayed_error_status;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *delayed_error;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen http_client_request_callback_t *callback;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen void *context;
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen void (*destroy_callback)(void *);
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen void *destroy_context;
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen enum http_request_state state;
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen unsigned int have_hdr_authorization:1;
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen unsigned int have_hdr_body_spec:1;
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen unsigned int have_hdr_connection:1;
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen unsigned int have_hdr_date:1;
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen unsigned int have_hdr_expect:1;
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen unsigned int have_hdr_host:1;
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen unsigned int have_hdr_user_agent:1;
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int payload_sync:1;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int payload_sync_continue:1;
009217abb57a24a4076092e8e4e165545747839eStephan Bosch unsigned int payload_chunked:1;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int payload_wait:1;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int urgent:1;
caae18c876f81e261350e4957471efa453c0ea9fTimo Sirainen unsigned int submitted:1;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen unsigned int listed:1;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int connect_tunnel:1;
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen unsigned int connect_direct:1;
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen unsigned int ssl_tunnel:1;
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen unsigned int preserve_exact_reason:1;
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen};
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainenstruct http_client_connection {
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen struct connection conn;
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen struct http_client_peer *peer;
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen struct http_client *client;
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen unsigned int refcount;
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen char *label;
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen unsigned int id; // DEBUG: identify parallel connections
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen int connect_errno;
447653aca14335b7096fb2dd2c7103631b336094Timo Sirainen struct timeval connect_start_timestamp;
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen struct timeval connected_timestamp;
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen struct http_client_request *connect_request;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen struct ssl_iostream *ssl_iostream;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct http_response_parser *http_parser;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct timeout *to_connect, *to_input, *to_idle, *to_response;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct timeout *to_requests;
4c20178a7f70bfe43d252e50796013aac1d8c74aTimo Sirainen
4c20178a7f70bfe43d252e50796013aac1d8c74aTimo Sirainen struct http_client_request *pending_request;
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen struct istream *incoming_payload;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct io *io_req_payload;
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen struct ioloop *last_ioloop;
4fe3f07477bae6da3fb8d8fa9bab10ab82ada2bdTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* requests that have been sent, waiting for response */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ARRAY_TYPE(http_client_request) request_wait_list;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen
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 connect_succeeded:1;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen unsigned int closing:1;
42401be443f96c91a20fc976d66ca626fa6e14ecTimo Sirainen unsigned int disconnected:1;
42401be443f96c91a20fc976d66ca626fa6e14ecTimo Sirainen unsigned int close_indicated:1;
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) */
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen};
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenstruct http_client_peer {
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen unsigned int refcount;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen struct http_client_peer_addr addr;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen char *addr_name;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen char *label;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen struct http_client *client;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen struct http_client_peer *prev, *next;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen /* queues using this peer */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen ARRAY_TYPE(http_client_queue) queues;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen /* active connections to this peer */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen ARRAY_TYPE(http_client_connection) conns;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen /* zero time-out for consolidating request handling */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen struct timeout *to_req_handling;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen /* connection retry */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen struct timeval last_failure;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen struct timeout *to_backoff;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen unsigned int backoff_time_msecs;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen
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 */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen};
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstruct http_client_queue {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct http_client *client;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct http_client_host *host;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen char *name;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct http_client_peer_addr addr;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen char *addr_name;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* current index in host->ips */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int ips_connect_idx;
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 */
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen unsigned int ips_connect_start_idx;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen struct timeval first_connect_time;
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen unsigned int connect_attempts;
8e1ecc6542da1e14c14e2e59d39dbccdbf68e2b5Timo Sirainen
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 ARRAY_TYPE(http_client_peer) pending_peers;
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen /* all requests associated to this queue
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen (ordered by earliest timeout first) */
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen ARRAY_TYPE(http_client_request) requests;
8e1ecc6542da1e14c14e2e59d39dbccdbf68e2b5Timo Sirainen
8e1ecc6542da1e14c14e2e59d39dbccdbf68e2b5Timo Sirainen /* delayed requests waiting to be released after delay */
8e1ecc6542da1e14c14e2e59d39dbccdbf68e2b5Timo Sirainen ARRAY_TYPE(http_client_request) delayed_requests;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen /* requests pending in queue to be picked up by connections */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen ARRAY_TYPE(http_client_request) queued_requests, queued_urgent_requests;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct timeout *to_connect, *to_request, *to_delayed;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen};
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainenstruct http_client_host {
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen struct http_client_host *prev, *next;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen struct http_client *client;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen char *name;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen /* the ip addresses DNS returned for this host */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen unsigned int ips_count;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen struct ip_addr *ips;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen /* requests are managed on a per-port basis */
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen ARRAY_TYPE(http_client_queue) queues;
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen
dff32d11a411a24f3b76003c1ae22c5a960f180eTimo Sirainen /* active DNS lookup */
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen struct dns_lookup *dns_lookup;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen unsigned int unix_local:1;
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen};
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainenstruct http_client {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen pool_t pool;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen struct http_client_settings set;
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen struct ioloop *ioloop;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen struct ssl_iostream_context *ssl_ctx;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen /* list of failed requests that are waiting for ioloop */
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen ARRAY(struct http_client_request *) delayed_failing_requests;
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen struct timeout *to_failing_requests;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen struct connection_list *conn_list;
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen
1df39b899804fd1dbc560f75382364822935c857Timo Sirainen HASH_TABLE_TYPE(http_client_host) hosts;
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen struct http_client_host *unix_host;
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen struct http_client_host *hosts_list;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen HASH_TABLE_TYPE(http_client_peer) peers;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen struct http_client_peer *peers_list;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen struct http_client_request *requests_list;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen unsigned int requests_count;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen};
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen/*
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen * Peer address
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen */
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenstatic inline bool
42401be443f96c91a20fc976d66ca626fa6e14ecTimo Sirainenhttp_client_peer_addr_is_https(const struct http_client_peer_addr *addr)
42401be443f96c91a20fc976d66ca626fa6e14ecTimo Sirainen{
42401be443f96c91a20fc976d66ca626fa6e14ecTimo Sirainen switch (addr->type) {
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen case HTTP_CLIENT_PEER_ADDR_HTTPS:
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen case HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL:
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen return TRUE;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen default:
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen break;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen }
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen return FALSE;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen}
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenstatic inline const char *
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenhttp_client_peer_addr_get_https_name(const struct http_client_peer_addr *addr)
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen{
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen switch (addr->type) {
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen case HTTP_CLIENT_PEER_ADDR_HTTPS:
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen case HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL:
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen return addr->a.tcp.https_name;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen default:
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen break;
56c69b4b17af0b5a2c71705d5edae746f00780b9Timo Sirainen }
1574df6b0bc965212f1152e480e7a762cdaa8226Timo Sirainen return NULL;
1574df6b0bc965212f1152e480e7a762cdaa8226Timo Sirainen}
1574df6b0bc965212f1152e480e7a762cdaa8226Timo Sirainen
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenstatic inline const char *
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenhttp_client_peer_addr2str(const struct http_client_peer_addr *addr)
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen{
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen switch (addr->type) {
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen case HTTP_CLIENT_PEER_ADDR_HTTP:
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen case HTTP_CLIENT_PEER_ADDR_HTTPS:
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen case HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL:
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen case HTTP_CLIENT_PEER_ADDR_RAW:
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen if (addr->a.tcp.ip.family == AF_INET6) {
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen return t_strdup_printf("[%s]:%u",
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen net_ip2addr(&addr->a.tcp.ip), addr->a.tcp.port);
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen }
89d6cd658eabf46e07e40037b0e641ed9be1a2a3Timo Sirainen return t_strdup_printf("%s:%u",
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen net_ip2addr(&addr->a.tcp.ip), addr->a.tcp.port);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen case HTTP_CLIENT_PEER_ADDR_UNIX:
f64b5bc9e73bedc63ba3c072c286542c29c69e43Timo Sirainen return t_strdup_printf("unix:%s", addr->a.un.path);
f64b5bc9e73bedc63ba3c072c286542c29c69e43Timo Sirainen default:
f64b5bc9e73bedc63ba3c072c286542c29c69e43Timo Sirainen break;
f64b5bc9e73bedc63ba3c072c286542c29c69e43Timo Sirainen }
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainen i_unreached();
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainen return "";
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainen}
152db3f90f298b7fb2dbbd4276f0fc30a9bc30f6Timo Sirainen
8752573c44bcd139ae3ecc6d8e917c2c60bcb89fTimo Sirainen/*
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen * Request
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen */
4aab01f4eade3d278b61471516c062ce30a84b5fTimo Sirainen
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainenstatic inline bool
468c28dfb03613ab8d487b5aebc985a969193aceTimo Sirainenhttp_client_request_to_proxy(const struct http_client_request *req)
abe29107f5dce932d28a00912d2d75a01021bef1Timo Sirainen{
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainen return (req->host_url != &req->origin_url);
377dd19a90436b8f96902af741a3ea130bc3fe75Timo Sirainen}
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainen
58b8a301b7b36047f10a592751094fbed86d6f0cTimo Sirainenconst char *
58b8a301b7b36047f10a592751094fbed86d6f0cTimo Sirainenhttp_client_request_label(struct http_client_request *req);
58b8a301b7b36047f10a592751094fbed86d6f0cTimo Sirainen
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);
ee3362f3b78827a2c9a7e9ddee83f5a429c06213Timo Sirainen
468c28dfb03613ab8d487b5aebc985a969193aceTimo Sirainenint http_client_request_delay_from_response(struct http_client_request *req,
abe29107f5dce932d28a00912d2d75a01021bef1Timo Sirainen const struct http_response *response);
abe29107f5dce932d28a00912d2d75a01021bef1Timo Sirainenvoid http_client_request_get_peer_addr(const struct http_client_request *req,
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainen struct http_client_peer_addr *addr);
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainenenum http_response_payload_type
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainenhttp_client_request_get_payload_type(struct http_client_request *req);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenint http_client_request_send(struct http_client_request *req,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen bool pipelined, const char **error_r);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenint http_client_request_send_more(struct http_client_request *req,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen bool pipelined, const char **error_r);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenbool http_client_request_callback(struct http_client_request *req,
7be1a5530fcb414588fbe90eaed65eff83e84737Timo Sirainen struct http_response *response);
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainenvoid http_client_request_connect_callback(struct http_client_request *req,
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainen const struct http_client_tunnel *tunnel,
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainen struct http_response *response);
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenvoid http_client_request_resubmit(struct http_client_request *req);
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenvoid http_client_request_retry(struct http_client_request *req,
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainen unsigned int status, const char *error);
468c28dfb03613ab8d487b5aebc985a969193aceTimo Sirainenvoid http_client_request_error_delayed(struct http_client_request **_req);
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainenvoid http_client_request_error(struct http_client_request **req,
abe29107f5dce932d28a00912d2d75a01021bef1Timo Sirainen unsigned int status, const char *error);
abe29107f5dce932d28a00912d2d75a01021bef1Timo Sirainenvoid http_client_request_redirect(struct http_client_request *req,
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainen unsigned int status, const char *location);
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenvoid http_client_request_finish(struct http_client_request *req);
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainen
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainen/*
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainen * Connection
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainen */
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainen
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenstruct connection_list *http_client_connection_list_init(void);
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainen
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenstruct http_client_connection *
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 Sirainen
152db3f90f298b7fb2dbbd4276f0fc30a9bc30f6Timo Sirainenvoid http_client_connection_peer_closed(struct http_client_connection **_conn);
152db3f90f298b7fb2dbbd4276f0fc30a9bc30f6Timo Sirainen
152db3f90f298b7fb2dbbd4276f0fc30a9bc30f6Timo Sirainenint http_client_connection_output(struct http_client_connection *conn);
152db3f90f298b7fb2dbbd4276f0fc30a9bc30f6Timo Sirainenvoid http_client_connection_start_request_timeout(
152db3f90f298b7fb2dbbd4276f0fc30a9bc30f6Timo Sirainen struct http_client_connection *conn);
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenvoid http_client_connection_reset_request_timeout(
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainen struct http_client_connection *conn);
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenvoid http_client_connection_stop_request_timeout(
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainen struct http_client_connection *conn);
433f5c9cc560a8cbff47257513d0bacb1cf250f4Timo Sirainenunsigned int
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 struct http_client_tunnel *tunnel);
c88275be7fcb92b10f412cecdd6c2ceaae17917eTimo Sirainen
c88275be7fcb92b10f412cecdd6c2ceaae17917eTimo Sirainen/*
c88275be7fcb92b10f412cecdd6c2ceaae17917eTimo Sirainen * Peer
c88275be7fcb92b10f412cecdd6c2ceaae17917eTimo Sirainen */
c88275be7fcb92b10f412cecdd6c2ceaae17917eTimo Sirainen
002f2544421891472dc9aeb79d3abdde6a8ed4c8Timo Sirainenunsigned int http_client_peer_addr_hash
002f2544421891472dc9aeb79d3abdde6a8ed4c8Timo Sirainen (const struct http_client_peer_addr *peer) ATTR_PURE;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenint http_client_peer_addr_cmp
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen (const struct http_client_peer_addr *peer1,
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen const struct http_client_peer_addr *peer2) ATTR_PURE;
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenconst char *
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenhttp_client_peer_label(struct http_client_peer *peer);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen
465fb89a877b778f68734f6cc36db9ce2a4a0a71Timo Sirainenstruct http_client_peer *
465fb89a877b778f68734f6cc36db9ce2a4a0a71Timo Sirainen http_client_peer_get(struct http_client *client,
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen const struct http_client_peer_addr *addr);
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 Sirainen
1df39b899804fd1dbc560f75382364822935c857Timo Sirainenbool http_client_peer_have_queue(struct http_client_peer *peer,
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainen struct http_client_queue *queue);
f64b5bc9e73bedc63ba3c072c286542c29c69e43Timo Sirainenvoid http_client_peer_link_queue(struct http_client_peer *peer,
f64b5bc9e73bedc63ba3c072c286542c29c69e43Timo Sirainen struct http_client_queue *queue);
f64b5bc9e73bedc63ba3c072c286542c29c69e43Timo Sirainenvoid http_client_peer_unlink_queue(struct http_client_peer *peer,
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen struct http_client_queue *queue);
f64b5bc9e73bedc63ba3c072c286542c29c69e43Timo Sirainenstruct http_client_request *
f64b5bc9e73bedc63ba3c072c286542c29c69e43Timo Sirainen http_client_peer_claim_request(struct http_client_peer *peer,
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainen bool no_urgent);
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 Sirainenunsigned int
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenhttp_client_peer_idle_connections(struct http_client_peer *peer);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenunsigned int
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenhttp_client_peer_pending_connections(struct http_client_peer *peer);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenvoid http_client_peer_switch_ioloop(struct http_client_peer *peer);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen/*
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen * Queue
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen */
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenstruct http_client_queue *
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenhttp_client_queue_create(struct http_client_host *host,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen const struct http_client_peer_addr *addr);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenvoid http_client_queue_free(struct http_client_queue *queue);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenvoid http_client_queue_fail(struct http_client_queue *queue,
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen unsigned int status, const char *error);
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 Sirainen struct http_client_request *req);
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenvoid
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenhttp_client_queue_drop_request(struct http_client_queue *queue,
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen struct http_client_request *req);
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainenstruct http_client_request *
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainenhttp_client_queue_claim_request(struct http_client_queue *queue,
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen const struct http_client_peer_addr *addr, bool no_urgent);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenunsigned int
027f58ea63a1822bbf13d99ee5572e5f8b9e8d8bTimo Sirainenhttp_client_queue_requests_pending(struct http_client_queue *queue,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen unsigned int *num_urgent_r) ATTR_NULL(2);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenvoid
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenhttp_client_queue_connection_success(struct http_client_queue *queue,
027f58ea63a1822bbf13d99ee5572e5f8b9e8d8bTimo Sirainen const struct http_client_peer_addr *addr);
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);
027f58ea63a1822bbf13d99ee5572e5f8b9e8d8bTimo Sirainen
58b8a301b7b36047f10a592751094fbed86d6f0cTimo Sirainen/*
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen * Host
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen */
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenstatic inline unsigned int
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenhttp_client_host_get_ip_idx(struct http_client_host *host,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen const struct ip_addr *ip)
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen{
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen unsigned int i;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen for (i = 0; i < host->ips_count; i++) {
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen if (net_ip_compare(&host->ips[i], ip))
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen return i;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen }
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen i_unreached();
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen}
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenstruct http_client_host *
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenhttp_client_host_get(struct http_client *client,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen const struct http_url *host_url);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenvoid http_client_host_free(struct http_client_host **_host);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenvoid http_client_host_submit_request(struct http_client_host *host,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen struct http_client_request *req);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenvoid http_client_host_switch_ioloop(struct http_client_host *host);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen/*
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen * Client
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen */
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenint http_client_init_ssl_ctx(struct http_client *client,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen const char **error_r);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenvoid http_client_delay_request_error(struct http_client *client,
027f58ea63a1822bbf13d99ee5572e5f8b9e8d8bTimo Sirainen struct http_client_request *req);
027f58ea63a1822bbf13d99ee5572e5f8b9e8d8bTimo Sirainenvoid http_client_remove_request_error(struct http_client *client,
027f58ea63a1822bbf13d99ee5572e5f8b9e8d8bTimo Sirainen struct http_client_request *req);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen#endif
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen