"Fossies" - the Fresh Open Source Software Archive

Member "dovecot-2.3.8/src/lib-http/http-client-private.h" (8 Oct 2019, 21297 Bytes) of package /linux/misc/dovecot-2.3.8.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "http-client-private.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.3.7.2_vs_2.3.8.

    1 #ifndef HTTP_CLIENT_PRIVATE_H
    2 #define HTTP_CLIENT_PRIVATE_H
    3 
    4 #include "connection.h"
    5 
    6 #include "http-url.h"
    7 #include "http-client.h"
    8 
    9 /*
   10  * Defaults
   11  */
   12 
   13 #define HTTP_CLIENT_CONTINUE_TIMEOUT_MSECS (1000*2)
   14 #define HTTP_CLIENT_DEFAULT_REQUEST_TIMEOUT_MSECS (1000*60*1)
   15 #define HTTP_CLIENT_DEFAULT_DNS_LOOKUP_TIMEOUT_MSECS (1000*10)
   16 #define HTTP_CLIENT_DEFAULT_BACKOFF_TIME_MSECS (100)
   17 #define HTTP_CLIENT_DEFAULT_BACKOFF_MAX_TIME_MSECS (1000*60)
   18 #define HTTP_CLIENT_DEFAULT_DNS_TTL_MSECS (1000*60*30)
   19 
   20 /*
   21  * Types
   22  */
   23 
   24 struct http_client_connection;
   25 struct http_client_peer_pool;
   26 struct http_client_peer_shared;
   27 struct http_client_peer;
   28 struct http_client_queue;
   29 struct http_client_host_shared;
   30 struct http_client_host;
   31 
   32 ARRAY_DEFINE_TYPE(http_client_request,
   33     struct http_client_request *);
   34 ARRAY_DEFINE_TYPE(http_client_connection,
   35     struct http_client_connection *);
   36 ARRAY_DEFINE_TYPE(http_client_peer,
   37     struct http_client_peer *);
   38 ARRAY_DEFINE_TYPE(http_client_peer_shared,
   39     struct http_client_peer_shared *);
   40 ARRAY_DEFINE_TYPE(http_client_peer_pool,
   41     struct http_client_peer_pool *);
   42 ARRAY_DEFINE_TYPE(http_client_queue,
   43     struct http_client_queue *);
   44 ARRAY_DEFINE_TYPE(http_client_host,
   45     struct http_client_host_shared *);
   46 
   47 HASH_TABLE_DEFINE_TYPE(http_client_peer_shared,
   48     const struct http_client_peer_addr *,
   49     struct http_client_peer_shared *);
   50 HASH_TABLE_DEFINE_TYPE(http_client_host_shared,
   51     const char *, struct http_client_host_shared *);
   52 
   53 enum http_client_peer_addr_type {
   54     HTTP_CLIENT_PEER_ADDR_HTTP = 0,
   55     HTTP_CLIENT_PEER_ADDR_HTTPS,
   56     HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL,
   57     HTTP_CLIENT_PEER_ADDR_RAW,
   58     HTTP_CLIENT_PEER_ADDR_UNIX,
   59 };
   60 
   61 struct http_client_peer_addr {
   62     enum http_client_peer_addr_type type;
   63     union {
   64         struct {
   65             const char *https_name; /* TLS SNI */
   66             struct ip_addr ip;
   67             in_port_t port;
   68         } tcp;
   69         struct {
   70             const char *path;
   71         } un;
   72     } a;
   73 };
   74 
   75 /*
   76  * Objects
   77  */
   78 
   79 struct http_client_request {
   80     pool_t pool;
   81     unsigned int refcount;
   82     const char *label;
   83     unsigned int id;
   84 
   85     struct http_client_request *prev, *next;
   86 
   87     const char *method, *target;
   88     struct http_url origin_url;
   89     const char *username, *password;
   90 
   91     const char *host_socket;
   92     const struct http_url *host_url;
   93     const char *authority;
   94 
   95     struct http_client *client;
   96     struct http_client_host *host;
   97     struct http_client_queue *queue;
   98     struct http_client_peer *peer;
   99     struct http_client_connection *conn;
  100 
  101     struct event *event;
  102     unsigned int last_status;
  103 
  104     string_t *headers;
  105     time_t date;
  106 
  107     struct istream *payload_input;
  108     uoff_t payload_size, payload_offset;
  109     struct ostream *payload_output;
  110 
  111     struct timeval release_time;
  112     struct timeval submit_time;
  113     struct timeval first_sent_time;
  114     struct timeval sent_time;
  115     struct timeval response_time;
  116     struct timeval timeout_time;
  117     unsigned int timeout_msecs;
  118     unsigned int attempt_timeout_msecs;
  119     unsigned int max_attempts;
  120 
  121     uoff_t response_offset, request_offset;
  122     uoff_t bytes_in, bytes_out;
  123 
  124     unsigned int attempts, send_attempts;
  125     unsigned int redirects;
  126     uint64_t sent_global_ioloop_usecs;
  127     uint64_t sent_http_ioloop_usecs;
  128     uint64_t sent_lock_usecs;
  129 
  130     unsigned int delayed_error_status;
  131     const char *delayed_error;
  132 
  133     http_client_request_callback_t *callback;
  134     void *context;
  135 
  136     void (*destroy_callback)(void *);
  137     void *destroy_context;
  138 
  139     enum http_request_state state;
  140 
  141     bool have_hdr_authorization:1;
  142     bool have_hdr_body_spec:1;
  143     bool have_hdr_connection:1;
  144     bool have_hdr_date:1;
  145     bool have_hdr_expect:1;
  146     bool have_hdr_host:1;
  147     bool have_hdr_user_agent:1;
  148 
  149     bool payload_sync:1;
  150     bool payload_sync_continue:1;
  151     bool payload_chunked:1;
  152     bool payload_wait:1;
  153     bool payload_empty:1;
  154     bool urgent:1;
  155     bool submitted:1;
  156     bool listed:1;
  157     bool connect_tunnel:1;
  158     bool connect_direct:1;
  159     bool ssl_tunnel:1;
  160     bool preserve_exact_reason:1;
  161 };
  162 
  163 struct http_client_connection {
  164     struct connection conn;
  165     struct event *event;
  166     unsigned int refcount;
  167 
  168     struct http_client_peer_pool *ppool;
  169     struct http_client_peer *peer;
  170 
  171     int connect_errno;
  172     struct timeval connect_start_timestamp;
  173     struct timeval connected_timestamp;
  174     struct http_client_request *connect_request;
  175 
  176     struct ssl_iostream *ssl_iostream;
  177     struct http_response_parser *http_parser;
  178     struct timeout *to_connect, *to_input, *to_idle, *to_response;
  179     struct timeout *to_requests;
  180 
  181     struct http_client_request *pending_request;
  182     struct istream *incoming_payload;
  183     struct io *io_req_payload;
  184     struct ioloop *last_ioloop;
  185     struct io_wait_timer *io_wait_timer;
  186 
  187     /* requests that have been sent, waiting for response */
  188     ARRAY_TYPE(http_client_request) request_wait_list;
  189 
  190     bool connected:1;           /* connection is connected */
  191     bool tunneling:1;           /* last sent request turns this
  192                                    connection into tunnel */
  193     bool connect_succeeded:1;   /* connection succeeded including SSL */
  194     bool connect_failed:1;      /* connection failed */
  195     bool lost_prematurely:1;    /* lost connection before receiving any data */
  196     bool closing:1;
  197     bool disconnected:1;
  198     bool close_indicated:1;
  199     bool output_locked:1;       /* output is locked; no pipelining */
  200     bool output_broken:1;       /* output is broken; no more requests */
  201     bool in_req_callback:1;     /* performing request callback (busy) */
  202     bool debug:1;
  203 };
  204 
  205 struct http_client_peer_shared {
  206     unsigned int refcount;
  207     struct http_client_peer_addr addr;
  208     char *addr_name;
  209     struct event *event;
  210 
  211     char *label;
  212 
  213     struct http_client_context *cctx;
  214     struct http_client_peer_shared *prev, *next;
  215 
  216     struct http_client_peer_pool *pools_list;
  217 
  218     struct http_client_peer *peers_list;
  219     unsigned int peers_count;
  220 
  221     /* connection retry */
  222     struct timeval last_failure;
  223     struct timeout *to_backoff;
  224     unsigned int backoff_initial_time_msecs;
  225     unsigned int backoff_current_time_msecs;
  226     unsigned int backoff_max_time_msecs;
  227 
  228     bool no_payload_sync:1;  /* expect: 100-continue failed before */
  229     bool seen_100_response:1;/* expect: 100-continue succeeded before */
  230     bool allows_pipelining:1;/* peer is known to allow persistent
  231                                 connections */
  232 };
  233 
  234 struct http_client_peer_pool {
  235     unsigned int refcount;
  236     struct http_client_peer_shared *peer;
  237     struct http_client_peer_pool *prev, *next;
  238     struct event *event;
  239 
  240     /* all connections to this peer */
  241     ARRAY_TYPE(http_client_connection) conns;
  242 
  243     /* pending connections (not ready connecting) */
  244     ARRAY_TYPE(http_client_connection) pending_conns;
  245 
  246     /* available connections to this peer */
  247     ARRAY_TYPE(http_client_connection) idle_conns;
  248 
  249     /* distinguishing settings for these connections */
  250     struct ssl_iostream_context *ssl_ctx;
  251     char *rawlog_dir;
  252     struct pcap_output *pcap_output;
  253 
  254     bool destroyed:1;        /* peer pool is being destroyed */
  255 };
  256 
  257 struct http_client_peer {
  258     unsigned int refcount;
  259     struct http_client_peer_shared *shared;
  260     struct http_client_peer *shared_prev, *shared_next;
  261 
  262     struct http_client *client;
  263     struct http_client_peer *client_prev, *client_next;
  264 
  265     struct http_client_peer_pool *ppool;
  266     struct event *event;
  267 
  268     /* queues using this peer */
  269     ARRAY_TYPE(http_client_queue) queues;
  270 
  271     /* active connections to this peer */
  272     ARRAY_TYPE(http_client_connection) conns;
  273     /* pending connections (not ready connecting) */
  274     ARRAY_TYPE(http_client_connection) pending_conns;
  275 
  276     /* zero time-out for consolidating request handling */
  277     struct timeout *to_req_handling;
  278 
  279     bool connect_failed:1;   /* last connection attempt failed */
  280     bool connect_backoff:1;  /* peer is waiting for backoff timout*/
  281     bool disconnected:1;     /* peer is already disconnected */
  282     bool handling_requests:1;/* currently running request handler */
  283 };
  284 
  285 struct http_client_queue {
  286     struct http_client *client;
  287     struct http_client_queue *prev, *next;
  288 
  289     struct http_client_host *host;
  290     char *name;
  291     struct event *event;
  292 
  293     struct http_client_peer_addr addr;
  294     char *addr_name;
  295 
  296     /* current index in host->ips */
  297     unsigned int ips_connect_idx;
  298     /* the first IP that started the current round of connection attempts.
  299        initially 0, and later set to the ip index of the last successful
  300        connected IP */
  301     unsigned int ips_connect_start_idx;
  302 
  303     struct timeval first_connect_time;
  304     unsigned int connect_attempts;
  305 
  306     /* peers we are trying to connect to;
  307        this can be more than one when soft connect timeouts are enabled */
  308     ARRAY_TYPE(http_client_peer) pending_peers;
  309 
  310     /* currently active peer */
  311     struct http_client_peer *cur_peer;
  312 
  313     /* all requests associated to this queue
  314        (ordered by earliest timeout first) */
  315     ARRAY_TYPE(http_client_request) requests; 
  316 
  317     /* delayed requests waiting to be released after delay */
  318     ARRAY_TYPE(http_client_request) delayed_requests;
  319 
  320     /* requests pending in queue to be picked up by connections */
  321     ARRAY_TYPE(http_client_request) queued_requests, queued_urgent_requests;
  322 
  323     struct timeout *to_connect, *to_request, *to_delayed;
  324 };
  325 
  326 struct http_client_host_shared {
  327     struct http_client_host_shared *prev, *next;
  328 
  329     struct http_client_context *cctx;
  330     char *name;
  331     struct event *event;
  332 
  333     /* the ip addresses DNS returned for this host */
  334     unsigned int ips_count;
  335     struct ip_addr *ips;
  336     struct timeval ips_timeout;
  337 
  338     /* private instance for each client that uses this host */
  339     struct http_client_host *hosts_list;
  340 
  341     /* active DNS lookup */
  342     struct dns_lookup *dns_lookup;
  343 
  344     /* timeouts */
  345     struct timeout *to_idle;
  346 
  347     bool destroyed:1;   /* shared host object is being destroyed */
  348     bool unix_local:1;
  349     bool explicit_ip:1;
  350 };
  351 
  352 struct http_client_host {
  353     struct http_client_host_shared *shared;
  354     struct http_client_host *shared_prev, *shared_next;
  355 
  356     struct http_client *client;
  357     struct http_client_host *client_prev, *client_next;
  358 
  359     /* separate queue for each host port */
  360     ARRAY_TYPE(http_client_queue) queues;
  361 };
  362 
  363 struct http_client {
  364     pool_t pool;
  365     struct http_client_context *cctx;
  366     struct http_client_settings set;
  367 
  368     struct http_client *prev, *next;
  369 
  370     struct event *event;
  371     struct ioloop *ioloop;
  372     struct ssl_iostream_context *ssl_ctx;
  373 
  374     /* list of failed requests that are waiting for ioloop */
  375     ARRAY(struct http_client_request *) delayed_failing_requests;
  376     struct timeout *to_failing_requests;
  377 
  378     struct http_client_host *hosts_list;
  379     struct http_client_peer *peers_list;
  380 
  381     struct http_client_request *requests_list;
  382     unsigned int requests_count;
  383 
  384     bool waiting:1;
  385 };
  386 
  387 struct http_client_context {
  388     pool_t pool;
  389     unsigned int refcount;
  390     struct event *event;
  391     struct ioloop *ioloop;
  392 
  393     struct http_client_settings set;
  394 
  395     struct dns_client *dns_client;
  396     const char *dns_client_socket_path;
  397     unsigned int dns_ttl_msecs;
  398     unsigned int dns_lookup_timeout_msecs;
  399 
  400     struct http_client *clients_list;
  401     struct connection_list *conn_list;
  402 
  403     HASH_TABLE_TYPE(http_client_peer_shared) peers;
  404     struct http_client_peer_shared *peers_list;
  405     HASH_TABLE_TYPE(http_client_host_shared) hosts;
  406     struct http_client_host_shared *unix_host;
  407     struct http_client_host_shared *hosts_list;
  408 };
  409 
  410 /*
  411  * Peer address
  412  */
  413 
  414 static inline bool
  415 http_client_peer_addr_is_https(const struct http_client_peer_addr *addr)
  416 {
  417     switch (addr->type) {
  418     case HTTP_CLIENT_PEER_ADDR_HTTPS:
  419     case HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL:
  420         return TRUE;
  421     default:
  422         break;
  423     }
  424     return FALSE;
  425 }
  426 
  427 static inline const char *
  428 http_client_peer_addr_get_https_name(const struct http_client_peer_addr *addr)
  429 {
  430     switch (addr->type) {
  431     case HTTP_CLIENT_PEER_ADDR_HTTPS:
  432     case HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL:
  433         return addr->a.tcp.https_name;
  434     default:
  435         break;
  436     }
  437     return NULL;
  438 }
  439 
  440 static inline const char *
  441 http_client_peer_addr2str(const struct http_client_peer_addr *addr)
  442 {
  443     switch (addr->type) {
  444     case HTTP_CLIENT_PEER_ADDR_HTTP:
  445     case HTTP_CLIENT_PEER_ADDR_HTTPS:
  446     case HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL:
  447     case HTTP_CLIENT_PEER_ADDR_RAW:
  448         if (addr->a.tcp.ip.family == AF_INET6) {
  449             return t_strdup_printf("[%s]:%u",
  450                 net_ip2addr(&addr->a.tcp.ip), addr->a.tcp.port);
  451         }
  452         return t_strdup_printf("%s:%u",
  453             net_ip2addr(&addr->a.tcp.ip), addr->a.tcp.port);
  454     case HTTP_CLIENT_PEER_ADDR_UNIX:
  455         return t_strdup_printf("unix:%s", addr->a.un.path);
  456     default:
  457         break;
  458     }
  459     i_unreached();
  460     return "";
  461 }
  462 
  463 /*
  464  * Request
  465  */
  466 
  467 static inline bool
  468 http_client_request_to_proxy(const struct http_client_request *req)
  469 {
  470     return (req->host_url != &req->origin_url);
  471 }
  472 
  473 const char *
  474 http_client_request_label(struct http_client_request *req);
  475 
  476 void http_client_request_ref(struct http_client_request *req);
  477 /* Returns FALSE if unrefing destroyed the request entirely */
  478 bool http_client_request_unref(struct http_client_request **_req);
  479 void http_client_request_destroy(struct http_client_request **_req);
  480 
  481 void http_client_request_get_peer_addr(const struct http_client_request *req,
  482     struct http_client_peer_addr *addr);
  483 enum http_response_payload_type
  484 http_client_request_get_payload_type(struct http_client_request *req);
  485 int http_client_request_send(struct http_client_request *req,
  486                 bool pipelined);
  487 int http_client_request_send_more(struct http_client_request *req,
  488                   bool pipelined);
  489 bool http_client_request_callback(struct http_client_request *req,
  490     struct http_response *response);
  491 void http_client_request_connect_callback(struct http_client_request *req,
  492                  const struct http_client_tunnel *tunnel,
  493                  struct http_response *response);
  494 void http_client_request_resubmit(struct http_client_request *req);
  495 void http_client_request_retry(struct http_client_request *req,
  496     unsigned int status, const char *error);
  497 void http_client_request_error_delayed(struct http_client_request **_req);
  498 void http_client_request_error(struct http_client_request **req,
  499     unsigned int status, const char *error);
  500 void http_client_request_redirect(struct http_client_request *req,
  501     unsigned int status, const char *location);
  502 void http_client_request_finish(struct http_client_request *req);
  503 
  504 /*
  505  * Connection
  506  */
  507 
  508 struct connection_list *http_client_connection_list_init(void);
  509 
  510 struct http_client_connection *
  511 http_client_connection_create(struct http_client_peer *peer);
  512 void http_client_connection_ref(struct http_client_connection *conn);
  513 /* Returns FALSE if unrefing destroyed the connection entirely */
  514 bool http_client_connection_unref(struct http_client_connection **_conn);
  515 void http_client_connection_close(struct http_client_connection **_conn);
  516 
  517 void http_client_connection_lost(struct http_client_connection **_conn,
  518                  const char *error) ATTR_NULL(2);
  519 
  520 void http_client_connection_peer_closed(struct http_client_connection **_conn);
  521 void http_client_connection_request_destroyed(
  522     struct http_client_connection *conn, struct http_client_request *req);
  523 
  524 void http_client_connection_handle_output_error(
  525     struct http_client_connection *conn);
  526 int http_client_connection_output(struct http_client_connection *conn);
  527 void http_client_connection_start_request_timeout(
  528     struct http_client_connection *conn);
  529 void http_client_connection_reset_request_timeout(
  530     struct http_client_connection *conn);
  531 void http_client_connection_stop_request_timeout(
  532     struct http_client_connection *conn);
  533 unsigned int
  534 http_client_connection_count_pending(struct http_client_connection *conn);
  535 int http_client_connection_check_ready(struct http_client_connection *conn);
  536 bool http_client_connection_is_idle(struct http_client_connection *conn);
  537 bool http_client_connection_is_active(struct http_client_connection *conn);
  538 int http_client_connection_next_request(struct http_client_connection *conn);
  539 void http_client_connection_check_idle(struct http_client_connection *conn);
  540 void http_client_connection_switch_ioloop(struct http_client_connection *conn);
  541 void http_client_connection_start_tunnel(struct http_client_connection **_conn,
  542     struct http_client_tunnel *tunnel);
  543 void http_client_connection_lost_peer(struct http_client_connection *conn);
  544 void http_client_connection_claim_idle(struct http_client_connection *conn,
  545     struct http_client_peer *peer);
  546 
  547 /*
  548  * Peer
  549  */
  550 
  551 /* address */
  552 
  553 unsigned int http_client_peer_addr_hash
  554     (const struct http_client_peer_addr *peer) ATTR_PURE;
  555 int http_client_peer_addr_cmp
  556     (const struct http_client_peer_addr *peer1,
  557         const struct http_client_peer_addr *peer2) ATTR_PURE;
  558 
  559 /* connection pool */
  560 
  561 void http_client_peer_pool_ref(struct http_client_peer_pool *ppool);
  562 void http_client_peer_pool_unref(struct http_client_peer_pool **_ppool);
  563 
  564 void http_client_peer_pool_close(struct http_client_peer_pool **_ppool);
  565 
  566 /* peer (shared) */
  567 
  568 const char *
  569 http_client_peer_shared_label(struct http_client_peer_shared *pshared);
  570 
  571 void http_client_peer_shared_ref(struct http_client_peer_shared *pshared);
  572 void http_client_peer_shared_unref(struct http_client_peer_shared **_pshared);
  573 void http_client_peer_shared_close(struct http_client_peer_shared **_pshared);
  574 
  575 void http_client_peer_shared_switch_ioloop(struct http_client_peer_shared *pshared);
  576 
  577 unsigned int
  578 http_client_peer_shared_max_connections(struct http_client_peer_shared *pshared);
  579 
  580 /* peer */
  581 
  582 struct http_client_peer *
  583 http_client_peer_get(struct http_client *client,
  584     const struct http_client_peer_addr *addr);
  585 void http_client_peer_ref(struct http_client_peer *peer);
  586 bool http_client_peer_unref(struct http_client_peer **_peer);
  587 void http_client_peer_close(struct http_client_peer **_peer);
  588 
  589 bool http_client_peer_have_queue(struct http_client_peer *peer,
  590                 struct http_client_queue *queue);
  591 void http_client_peer_link_queue(struct http_client_peer *peer,
  592     struct http_client_queue *queue);
  593 void http_client_peer_unlink_queue(struct http_client_peer *peer,
  594                 struct http_client_queue *queue);
  595 struct http_client_request *
  596     http_client_peer_claim_request(struct http_client_peer *peer,
  597         bool no_urgent);
  598 void http_client_peer_trigger_request_handler(struct http_client_peer *peer);
  599 void http_client_peer_connection_success(struct http_client_peer *peer);
  600 void http_client_peer_connection_failure(struct http_client_peer *peer,
  601                      const char *reason);
  602 void http_client_peer_connection_lost(struct http_client_peer *peer,
  603     bool premature);
  604 bool http_client_peer_is_connected(struct http_client_peer *peer);
  605 unsigned int
  606 http_client_peer_idle_connections(struct http_client_peer *peer);
  607 unsigned int
  608 http_client_peer_active_connections(struct http_client_peer *peer);
  609 unsigned int
  610 http_client_peer_pending_connections(struct http_client_peer *peer);
  611 void http_client_peer_switch_ioloop(struct http_client_peer *peer);
  612 
  613 /*
  614  * Queue
  615  */
  616 
  617 struct http_client_queue *
  618 http_client_queue_get(struct http_client_host *host,
  619     const struct http_client_peer_addr *addr);
  620 void http_client_queue_free(struct http_client_queue *queue);
  621 void http_client_queue_connection_setup(struct http_client_queue *queue);
  622 unsigned int
  623 http_client_queue_host_lookup_done(struct http_client_queue *queue);
  624 void http_client_queue_host_lookup_failure(
  625     struct http_client_queue *queue, const char *error);
  626 void http_client_queue_submit_request(struct http_client_queue *queue,
  627     struct http_client_request *req);
  628 void http_client_queue_drop_request(struct http_client_queue *queue,
  629     struct http_client_request *req);
  630 struct http_client_request *
  631 http_client_queue_claim_request(struct http_client_queue *queue,
  632     const struct http_client_peer_addr *addr, bool no_urgent);
  633 unsigned int
  634 http_client_queue_requests_pending(struct http_client_queue *queue,
  635     unsigned int *num_urgent_r) ATTR_NULL(2);
  636 unsigned int
  637 http_client_queue_requests_active(struct http_client_queue *queue);
  638 void http_client_queue_connection_success(struct http_client_queue *queue,
  639                      struct http_client_peer *peer);
  640 void http_client_queue_connection_failure(struct http_client_queue *queue,
  641         struct http_client_peer *peer, const char *reason);
  642 void http_client_queue_peer_disconnected(struct http_client_queue *queue,
  643     struct http_client_peer *peer);
  644 void http_client_queue_switch_ioloop(struct http_client_queue *queue);
  645 
  646 /*
  647  * Host
  648  */
  649 
  650 /* host (shared) */
  651 
  652 void http_client_host_shared_free(
  653     struct http_client_host_shared **_hshared);
  654 void http_client_host_shared_switch_ioloop(
  655     struct http_client_host_shared *hshared);
  656 
  657 /* host */
  658 
  659 static inline unsigned int
  660 http_client_host_get_ips_count(struct http_client_host *host)
  661 {
  662     return host->shared->ips_count;
  663 }
  664 
  665 static inline const struct ip_addr *
  666 http_client_host_get_ip(struct http_client_host *host,
  667     unsigned int idx)
  668 {
  669     i_assert(idx < host->shared->ips_count);
  670     return &host->shared->ips[idx];
  671 }
  672 
  673 static inline bool
  674 http_client_host_ready(struct http_client_host *host)
  675 {
  676     return host->shared->dns_lookup == NULL;
  677 }
  678 
  679 struct http_client_host *
  680 http_client_host_get(struct http_client *client,
  681     const struct http_url *host_url);
  682 void http_client_host_free(struct http_client_host **_host);
  683 void http_client_host_submit_request(struct http_client_host *host,
  684     struct http_client_request *req);
  685 void http_client_host_switch_ioloop(struct http_client_host *host);
  686 void http_client_host_check_idle(struct http_client_host *host);
  687 int http_client_host_refresh(struct http_client_host *host);
  688 bool http_client_host_get_ip_idx(struct http_client_host *host,
  689     const struct ip_addr *ip, unsigned int *idx_r);
  690 
  691 /*
  692  * Client
  693  */
  694 
  695 int http_client_init_ssl_ctx(struct http_client *client,
  696     const char **error_r);
  697 
  698 void http_client_delay_request_error(struct http_client *client,
  699     struct http_client_request *req);
  700 void http_client_remove_request_error(struct http_client *client,
  701     struct http_client_request *req);
  702 
  703 /*
  704  * Client shared context
  705  */
  706 
  707 void http_client_context_switch_ioloop(struct http_client_context *cctx);
  708 
  709 #endif