Lines Matching refs:conn
25 static void http_client_connection_ready(struct http_client_connection *conn);
29 http_client_connection_ref_request(struct http_client_connection *conn,
32 i_assert(req->conn == NULL);
33 req->conn = conn;
38 http_client_connection_unref_request(struct http_client_connection *conn,
43 i_assert(req->conn == conn);
44 req->conn = NULL;
49 http_client_connection_failure(struct http_client_connection *conn,
52 struct http_client_peer *peer = conn->peer;
54 conn->connect_failed = TRUE;
59 http_client_connection_count_pending(struct http_client_connection *conn)
61 unsigned int pending_count = array_count(&conn->request_wait_list);
63 if (conn->in_req_callback || conn->pending_request != NULL)
68 bool http_client_connection_is_idle(struct http_client_connection *conn)
70 return (conn->to_idle != NULL);
73 bool http_client_connection_is_active(struct http_client_connection *conn)
75 if (!conn->connected)
78 if (conn->in_req_callback || conn->pending_request != NULL)
81 return (array_is_created(&conn->request_wait_list) &&
82 array_count(&conn->request_wait_list) > 0);
86 http_client_connection_retry_requests(struct http_client_connection *conn,
89 const struct http_client_settings *set = &conn->peer->client->set;
92 if (!array_is_created(&conn->request_wait_list))
96 e_debug(conn->event, "Aborting pending requests with error");
98 e_debug(conn->event, "Retrying pending requests");
101 array_foreach_modifiable(&conn->request_wait_list, req_idx) {
104 if (!http_client_connection_unref_request(conn, req_idx))
114 array_clear(&conn->request_wait_list);
120 struct http_client_connection *conn = *_conn;
121 struct http_client_peer *peer = conn->peer;
125 e_debug(conn->event, "Server explicitly closed connection");
127 array_foreach_modifiable(&conn->request_wait_list, req_idx) {
130 if (!http_client_connection_unref_request(conn, req_idx))
136 array_clear(&conn->request_wait_list);
148 struct http_client_connection *conn = *_conn;
151 e_debug(conn->event, "Aborting connection: %s", error);
153 array_foreach_modifiable(&conn->request_wait_list, req_idx) {
157 if (!http_client_connection_unref_request(conn, req_idx))
162 array_clear(&conn->request_wait_list);
167 http_client_connection_abort_any_requests(struct http_client_connection *conn)
171 if (array_is_created(&conn->request_wait_list)) {
172 array_foreach_modifiable(&conn->request_wait_list, req_idx) {
176 if (!http_client_connection_unref_request(conn, req_idx))
183 array_clear(&conn->request_wait_list);
185 if (conn->pending_request != NULL) {
186 req = conn->pending_request;
188 if (http_client_connection_unref_request(conn, &conn->pending_request)) {
198 http_client_connection_get_timing_info(struct http_client_connection *conn)
204 if (array_count(&conn->request_wait_list) > 0) {
205 requestp = array_idx(&conn->request_wait_list, 0);
211 if (conn->conn.last_input != 0) {
213 (int)(ioloop_time - conn->conn.last_input));
216 connected_msecs = timeval_diff_msecs(&ioloop_timeval, &conn->connected_timestamp);
226 struct http_client_connection *conn = *_conn;
229 http_client_connection_get_timing_info(conn));
231 e_debug(conn->event,
234 http_client_connection_retry_requests(conn, status, error);
241 struct http_client_connection *conn = *_conn;
249 if (conn->ssl_iostream != NULL) {
250 sslerr = ssl_iostream_get_last_error(conn->ssl_iostream);
255 if (ssl_iostream_has_handshake_failed(conn->ssl_iostream)) {
265 conn->lost_prematurely = (conn->conn.input != NULL &&
266 conn->conn.input->v_offset == 0 &&
267 i_stream_get_data_size(conn->conn.input) == 0);
273 struct http_client_connection *conn)
275 struct ostream *output = conn->conn.output;
279 http_client_connection_lost(&conn,
284 http_client_connection_lost(&conn,
289 int http_client_connection_check_ready(struct http_client_connection *conn)
291 const struct http_client_settings *set = &conn->peer->client->set;
294 if (conn->in_req_callback) {
303 if (!conn->connected || conn->output_locked || conn->output_broken ||
304 conn->close_indicated || conn->tunneling ||
305 http_client_connection_count_pending(conn) >=
309 if (conn->last_ioloop != NULL && conn->last_ioloop != current_ioloop) {
310 conn->last_ioloop = current_ioloop;
314 if ((ret=i_stream_read(conn->conn.input)) == -1) {
315 int stream_errno = conn->conn.input->stream_errno;
317 i_assert(conn->conn.input->stream_errno != 0 || conn->conn.input->eof);
318 http_client_connection_lost(&conn,
320 i_stream_get_name(conn->conn.input),
322 i_stream_get_error(conn->conn.input) :
328 if (i_stream_get_data_size(conn->conn.input) > 0)
329 i_stream_set_input_pending(conn->conn.input, TRUE);
335 http_client_connection_detach_peer(struct http_client_connection *conn)
337 struct http_client_peer *peer = conn->peer;
348 if (*conn_idx == conn) {
357 conn->peer = NULL;
358 e_debug(conn->event, "Detached peer");
360 if (conn->connect_succeeded)
361 http_client_peer_connection_lost(peer, conn->lost_prematurely);
366 http_client_connection_idle_timeout(struct http_client_connection *conn)
368 e_debug(conn->event, "Idle connection timed out");
371 i_assert(conn->connect_succeeded);
373 http_client_connection_close(&conn);
376 void http_client_connection_lost_peer(struct http_client_connection *conn)
378 struct http_client_peer *peer = conn->peer;
381 struct http_client_peer_pool *ppool = conn->ppool;
385 if (!conn->connected) {
386 http_client_connection_unref(&conn);
390 i_assert(!conn->in_req_callback);
392 if (conn->to_idle == NULL) {
410 e_debug(conn->event,
414 conn->to_idle = timeout_add_to(conn->conn.ioloop, timeout,
415 http_client_connection_idle_timeout, conn);
416 array_append(&ppool->idle_conns, &conn, 1);
418 e_debug(conn->event, "Lost peer; already idle");
421 http_client_connection_detach_peer(conn);
424 void http_client_connection_check_idle(struct http_client_connection *conn)
427 struct http_client_peer_pool *ppool = conn->ppool;
432 peer = conn->peer;
434 i_assert(conn->to_idle != NULL);
438 if (conn->to_idle != NULL) {
446 if (conn->connected &&
447 array_is_created(&conn->request_wait_list) &&
448 array_count(&conn->request_wait_list) == 0 &&
449 !conn->in_req_callback &&
450 conn->incoming_payload == NULL &&
476 e_debug(conn->event,
480 conn->to_idle = timeout_add_to(conn->conn.ioloop, timeout,
481 http_client_connection_idle_timeout, conn);
483 array_append(&ppool->idle_conns, &conn, 1);
488 http_client_connection_stop_idle(struct http_client_connection *conn)
493 if (conn->to_idle != NULL)
494 timeout_remove(&conn->to_idle);
496 conn_arr = &conn->ppool->idle_conns;
498 if (*conn_idx == conn) {
505 void http_client_connection_claim_idle(struct http_client_connection *conn,
508 e_debug(conn->event, "Claimed as idle");
510 i_assert(peer->ppool == conn->ppool);
511 http_client_connection_stop_idle(conn);
513 if (conn->peer == NULL || conn->peer != peer) {
514 http_client_connection_detach_peer(conn);
516 conn->peer = peer;
517 conn->debug = peer->client->set.debug;
518 array_append(&peer->conns, &conn, 1);
523 http_client_connection_request_timeout(struct http_client_connection *conn)
525 conn->conn.input->stream_errno = ETIMEDOUT;
526 http_client_connection_abort_temp_error(&conn,
531 struct http_client_connection *conn)
533 struct http_client_peer *peer = conn->peer;
539 if (conn->pending_request != NULL)
542 i_assert(array_is_created(&conn->request_wait_list));
543 if (array_count(&conn->request_wait_list) > 0) {
545 requestp = array_idx(&conn->request_wait_list, 0);
551 else if (conn->to_requests != NULL)
552 timeout_reset(conn->to_requests);
554 conn->to_requests = timeout_add_to(
555 conn->conn.ioloop, timeout_msecs,
556 http_client_connection_request_timeout, conn);
561 struct http_client_connection *conn)
563 if (conn->to_requests != NULL)
564 timeout_reset(conn->to_requests);
568 struct http_client_connection *conn)
570 timeout_remove(&conn->to_requests);
574 http_client_connection_continue_timeout(struct http_client_connection *conn)
576 struct http_client_peer_shared *pshared = conn->ppool->peer;
581 i_assert(conn->pending_request == NULL);
583 timeout_remove(&conn->to_response);
586 e_debug(conn->event,
589 wait_reqs = array_get(&conn->request_wait_list, &wait_count);
597 int http_client_connection_next_request(struct http_client_connection *conn)
600 struct http_client_peer *peer = conn->peer;
601 struct http_client_peer_shared *pshared = conn->ppool->peer;
606 if ((ret=http_client_connection_check_ready(conn)) <= 0) {
608 e_debug(conn->event, "Not ready for next request");
614 pipelined = array_count(&conn->request_wait_list) > 0 ||
615 conn->pending_request != NULL;
622 http_client_connection_stop_idle(conn);
629 array_append(&conn->request_wait_list, &req, 1);
630 http_client_connection_ref_request(conn, req);
632 e_debug(conn->event, "Claimed request %s",
635 tmp_conn = conn;
642 conn->tunneling = TRUE;
656 i_assert(conn->to_response == NULL);
657 conn->to_response = timeout_add_to(conn->conn.ioloop,
659 http_client_connection_continue_timeout, conn);
667 struct http_client_connection *conn =
674 if (conn->connected_timestamp.tv_sec == 0) {
676 &conn->connect_start_timestamp);
682 &conn->connected_timestamp);
687 e_debug(conn->event, "%s", error);
688 http_client_connection_failure(conn, error);
691 if (conn->connect_failed) {
692 i_assert(!array_is_created(&conn->request_wait_list) ||
693 array_count(&conn->request_wait_list) == 0);
696 http_client_connection_lost(&conn,
704 http_client_connection_close(&conn);
707 static void http_client_payload_finished(struct http_client_connection *conn)
709 timeout_remove(&conn->to_input);
710 connection_input_resume(&conn->conn);
711 if (array_count(&conn->request_wait_list) > 0)
712 http_client_connection_start_request_timeout(conn);
716 http_client_payload_destroyed_timeout(struct http_client_connection *conn)
718 if (conn->close_indicated) {
719 http_client_connection_server_close(&conn);
722 http_client_connection_input(&conn->conn);
727 struct http_client_connection *conn = req->conn;
729 i_assert(conn != NULL);
730 i_assert(conn->pending_request == req);
731 i_assert(conn->incoming_payload != NULL);
732 i_assert(conn->conn.io == NULL);
734 e_debug(conn->event,
740 net_set_nonblock(conn->conn.fd_in, TRUE);
742 i_assert(req->response_offset < conn->conn.input->v_offset);
743 req->bytes_in = conn->conn.input->v_offset - req->response_offset;
746 if (http_client_connection_unref_request(conn, &conn->pending_request)) {
751 conn->incoming_payload = NULL;
758 if (!conn->disconnected) {
759 conn->to_input = timeout_add_short_to(
760 conn->conn.ioloop, 0,
761 http_client_payload_destroyed_timeout, conn);
765 if (http_client_connection_check_ready(conn) > 0)
766 http_client_peer_trigger_request_handler(conn->peer);
770 struct http_client_connection *conn, struct http_client_request *req)
774 i_assert(req->conn == conn);
775 if (conn->pending_request != req)
778 e_debug(conn->event, "Pending request destroyed prematurely");
780 payload = conn->incoming_payload;
790 payload = conn->incoming_payload;
806 struct http_client_connection *conn,
810 struct http_client_peer_shared *pshared = conn->ppool->peer;
814 i_assert(!conn->in_req_callback);
815 i_assert(conn->incoming_payload == NULL);
816 i_assert(conn->pending_request == NULL);
818 http_client_connection_ref(conn);
819 http_client_connection_ref_request(conn, req);
827 conn->incoming_payload = response->payload =
835 connection_input_halt(&conn->conn);
838 http_client_connection_stop_request_timeout(conn);
841 conn->in_req_callback = TRUE;
843 if (conn->disconnected) {
847 http_client_connection_unref_request(conn, &req);
848 http_client_connection_unref(&conn);
851 conn->in_req_callback = FALSE;
856 i_stream_remove_destroy_callback(conn->incoming_payload,
858 i_stream_unref(&conn->incoming_payload);
859 connection_input_resume(&conn->conn);
861 http_client_connection_unref_request(conn, &req);
862 return http_client_connection_unref(&conn);
871 conn->pending_request = req;
876 if (conn->to_input != NULL && conn->conn.input != NULL) {
878 http_client_payload_finished(conn);
882 http_client_connection_unref_request(conn, &req);
885 if (conn->incoming_payload == NULL && conn->conn.input != NULL) {
886 i_assert(conn->conn.io != NULL ||
888 return http_client_connection_unref(&conn);
890 http_client_connection_unref(&conn);
896 struct http_client_connection *conn =
898 struct http_client_peer *peer = conn->peer;
899 struct http_client_peer_shared *pshared = conn->ppool->peer;
908 i_assert(conn->incoming_payload == NULL);
912 if (conn->ssl_iostream != NULL &&
913 !ssl_iostream_is_handshaked(conn->ssl_iostream)) {
915 while ((ret=i_stream_read(conn->conn.input)) > 0 || ret == -2) {
916 if (ssl_iostream_is_handshaked(conn->ssl_iostream))
920 int stream_errno = conn->conn.input->stream_errno;
928 i_stream_get_name(conn->conn.input),
930 i_stream_get_error(conn->conn.input) : "EOF");
931 http_client_connection_failure(conn, error);
932 e_debug(conn->event, "%s", error);
933 http_client_connection_close(&conn);
937 if (!ssl_iostream_is_handshaked(conn->ssl_iostream)) {
944 http_client_connection_ready(conn);
947 if (conn->to_input != NULL) {
953 http_client_payload_finished(conn);
958 http_client_connection_reset_request_timeout(conn);
961 reqs = array_get(&conn->request_wait_list, &count);
974 if (conn->output_broken && (count == 0 ||
976 http_client_connection_server_close(&conn);
981 (conn->http_parser, payload_type, &response, &error)) > 0) {
987 e_debug(conn->event,
991 e_debug(conn->event,
995 http_client_connection_close(&conn);
1001 http_response_parser_get_last_offset(conn->http_parser);
1003 i_assert(req->response_offset < conn->conn.input->v_offset);
1004 req->bytes_in = conn->conn.input->v_offset - req->response_offset;
1007 timeout_remove(&conn->to_response);
1017 e_debug(conn->event,
1026 e_debug(conn->event,
1030 e_debug(conn->event,
1032 http_client_connection_close(&conn);
1040 e_debug(conn->event,
1048 e_debug(conn->event,
1051 o_stream_unset_flush_callback(conn->conn.output);
1052 conn->output_broken = early = TRUE;
1055 e_debug(conn->event,
1063 e_debug(conn->event, "Unlocked output");
1064 conn->output_locked = FALSE;
1068 array_delete(&conn->request_wait_list, 0, 1);
1071 if (!http_client_connection_unref_request(conn, &req_ref)) {
1076 conn->close_indicated = response.connection_close;
1088 http_client_connection_close(&conn);
1101 conn->output_locked = FALSE;
1129 conn->close_indicated = TRUE;
1136 (conn, req, &response))
1144 if (conn->close_indicated) {
1145 http_client_connection_server_close(&conn);
1150 reqs = array_get(&conn->request_wait_list, &count);
1164 if (conn->output_broken && (count == 0 ||
1166 http_client_connection_server_close(&conn);
1172 (conn->conn.input->eof || conn->conn.input->stream_errno != 0)) {
1173 int stream_errno = conn->conn.input->stream_errno;
1174 http_client_connection_lost(&conn,
1176 i_stream_get_name(conn->conn.input),
1178 i_stream_get_error(conn->conn.input) :
1184 http_client_connection_abort_error(&conn,
1196 http_client_connection_check_ready(conn) > 0)
1202 http_client_connection_continue_request(struct http_client_connection *conn)
1211 reqs = array_get(&conn->request_wait_list, &count);
1212 if (count == 0 || !conn->output_locked)
1216 pipelined = (count > 1 || conn->pending_request != NULL);
1219 e_debug(conn->event,
1222 http_client_connection_close(&conn);
1224 o_stream_unset_flush_callback(conn->conn.output);
1225 conn->output_broken = TRUE;
1233 o_stream_cork(conn->conn.output);
1235 tmp_conn = conn;
1241 if (conn->conn.output != NULL &&
1242 o_stream_uncork_flush(conn->conn.output) < 0) {
1243 http_client_connection_handle_output_error(conn);
1247 if (!conn->output_locked) {
1249 if (http_client_connection_check_ready(conn) > 0)
1250 http_client_peer_trigger_request_handler(conn->peer);
1255 int http_client_connection_output(struct http_client_connection *conn)
1257 struct ostream *output = conn->conn.output;
1261 http_client_connection_reset_request_timeout(conn);
1265 http_client_connection_handle_output_error(conn);
1269 i_assert(!conn->output_broken);
1271 if (conn->ssl_iostream != NULL &&
1272 !ssl_iostream_is_handshaked(conn->ssl_iostream))
1275 if (http_client_connection_continue_request(conn) < 0)
1284 struct http_client_connection *conn = *_conn;
1286 i_assert(conn->tunneling);
1290 tunnel->input = conn->conn.input;
1291 tunnel->output = conn->conn.output;
1292 tunnel->fd_in = conn->conn.fd_in;
1293 tunnel->fd_out = conn->conn.fd_out;
1296 conn->conn.input = NULL;
1297 conn->conn.output = NULL;
1298 conn->conn.fd_in = -1;
1299 conn->conn.fd_out = -1;
1300 conn->closing = TRUE;
1301 conn->connected = FALSE;
1302 connection_disconnect(&conn->conn);
1308 http_client_connection_ready(struct http_client_connection *conn)
1310 struct http_client_peer *peer = conn->peer;
1311 struct http_client_peer_pool *ppool = conn->ppool;
1317 e_debug(conn->event, "Ready for requests");
1320 conn->connected = TRUE;
1321 conn->last_ioloop = current_ioloop;
1322 timeout_remove(&conn->to_connect);
1327 if (*conn_idx == conn) {
1334 conn->connect_succeeded = TRUE;
1340 &conn->conn.input, &conn->conn.output);
1349 req = http_client_peer_claim_request(conn->peer, FALSE);
1353 conn->tunneling = TRUE;
1359 (void)http_client_connection_return_response(conn, req, &response);
1363 e_debug(conn->event,
1365 http_client_connection_close(&conn);
1370 conn->http_parser = http_response_parser_init
1371 (conn->conn.input, &set->response_hdr_limits, 0);
1372 o_stream_set_flush_callback(conn->conn.output,
1373 http_client_connection_output, conn);
1379 struct http_client_connection *conn = context;
1380 struct http_client_peer *peer = conn->peer;
1381 struct http_client_peer_shared *pshared = conn->ppool->peer;
1385 if (ssl_iostream_check_cert_validity(conn->ssl_iostream, host, &error) == 0)
1386 e_debug(conn->event, "SSL handshake successful");
1388 e_debug(conn->event, "SSL handshake successful, "
1398 http_client_connection_ssl_init(struct http_client_connection *conn,
1401 struct http_client_peer *peer = conn->peer;
1402 struct http_client_peer_pool *ppool = conn->ppool;
1416 e_debug(conn->event, "Starting SSL handshake");
1418 connection_input_halt(&conn->conn);
1421 &conn->conn.input, &conn->conn.output,
1422 &conn->ssl_iostream, &error) < 0) {
1425 conn->conn.name, error);
1428 connection_input_resume(&conn->conn);
1429 ssl_iostream_set_handshake_callback(conn->ssl_iostream,
1430 http_client_connection_ssl_handshaked, conn);
1431 if (ssl_iostream_handshake(conn->ssl_iostream) < 0) {
1433 conn->conn.name, ssl_iostream_get_last_error(conn->ssl_iostream));
1437 if (ssl_iostream_is_handshaked(conn->ssl_iostream)) {
1438 http_client_connection_ready(conn);
1442 o_stream_set_flush_callback(conn->conn.output,
1443 http_client_connection_output, conn);
1451 struct http_client_connection *conn =
1453 struct http_client_peer *peer = conn->peer;
1454 struct http_client_peer_shared *pshared = conn->ppool->peer;
1459 http_client_connection_failure(conn, t_strdup_printf(
1462 conn->connected_timestamp = ioloop_timeval;
1463 e_debug(conn->event, "Connected");
1480 if (http_client_connection_ssl_init(conn, &error) < 0) {
1481 e_debug(conn->event, "%s", error);
1482 http_client_connection_failure(conn, error);
1483 http_client_connection_close(&conn);
1487 http_client_connection_ready(conn);
1512 http_client_connection_delayed_connect_error(struct http_client_connection *conn)
1514 timeout_remove(&conn->to_input);
1515 errno = conn->connect_errno;
1516 http_client_connection_connected(&conn->conn, FALSE);
1517 http_client_connection_close(&conn);
1520 static void http_client_connect_timeout(struct http_client_connection *conn)
1522 conn->conn.disconnect_reason = CONNECTION_DISCONNECT_CONNECT_TIMEOUT;
1523 http_client_connection_destroy(&conn->conn);
1527 http_client_connection_connect(struct http_client_connection *conn,
1530 struct http_client_context *cctx = conn->ppool->peer->cctx;
1532 conn->connect_start_timestamp = ioloop_timeval;
1533 if (connection_client_connect(&conn->conn) < 0) {
1534 conn->connect_errno = errno;
1535 e_debug(conn->event, "Connect failed: %m");
1536 conn->to_input = timeout_add_short_to(conn->conn.ioloop, 0,
1537 http_client_connection_delayed_connect_error, conn);
1544 conn->to_connect = timeout_add_to(
1546 http_client_connect_timeout, conn);
1551 http_client_connect_tunnel_timeout(struct http_client_connection *conn)
1553 struct http_client_peer_shared *pshared = conn->ppool->peer;
1558 &conn->connect_start_timestamp);
1564 e_debug(conn->event, "%s", error);
1565 http_client_connection_failure(conn, error);
1566 http_client_connection_close(&conn);
1571 struct http_client_connection *conn)
1573 struct http_client_peer_shared *pshared = conn->ppool->peer;
1577 struct http_client_request *req = conn->connect_request;
1579 conn->connect_request = NULL;
1582 http_client_connection_failure(conn, t_strdup_printf(
1590 connection_init_from_streams(cctx->conn_list, &conn->conn,
1592 connection_switch_ioloop_to(&conn->conn, cctx->ioloop);
1595 conn->connect_initialized = TRUE;
1599 http_client_connection_connect_tunnel(struct http_client_connection *conn,
1603 struct http_client_context *cctx = conn->ppool->peer->cctx;
1604 struct http_client *client = conn->peer->client;
1606 conn->connect_start_timestamp = ioloop_timeval;
1608 conn->connect_request = http_client_request_connect_ip
1609 (client, ip, port, http_client_connection_tunnel_response, conn);
1610 http_client_request_set_urgent(conn->connect_request);
1611 http_client_request_submit(conn->connect_request);
1616 conn->to_connect = timeout_add_to(
1618 http_client_connect_tunnel_timeout, conn);
1630 struct http_client_connection *conn;
1658 conn = i_new(struct http_client_connection, 1);
1659 conn->refcount = 1;
1660 conn->id = id++;
1661 conn->ppool = ppool;
1662 conn->peer = peer;
1663 conn->debug = client->set.debug;
1665 i_array_init(&conn->request_wait_list, 16);
1666 conn->io_wait_timer = io_wait_timer_add_to(cctx->ioloop);
1668 conn->label = i_strdup_printf("%s [%d]",
1669 http_client_peer_shared_label(pshared), conn->id);
1670 conn->event = event_create(peer->client->event);
1671 event_set_append_log_prefix(conn->event,
1672 t_strdup_printf("conn %s: ", conn->label));
1677 (conn, &addr->a.tcp.ip, addr->a.tcp.port, timeout_msecs);
1680 connection_init_client_unix(cctx->conn_list, &conn->conn,
1682 connection_switch_ioloop_to(&conn->conn, cctx->ioloop);
1683 conn->connect_initialized = TRUE;
1684 http_client_connection_connect(conn, timeout_msecs);
1687 connection_init_client_ip(cctx->conn_list, &conn->conn,
1689 connection_switch_ioloop_to(&conn->conn, cctx->ioloop);
1690 conn->connect_initialized = TRUE;
1691 http_client_connection_connect(conn, timeout_msecs);
1694 array_append(&ppool->pending_conns, &conn, 1);
1695 array_append(&ppool->conns, &conn, 1);
1696 array_append(&peer->conns, &conn, 1);
1700 e_debug(conn->event,
1703 (conn->to_input == NULL ? "" : " [broken]"));
1704 return conn;
1707 void http_client_connection_ref(struct http_client_connection *conn)
1709 i_assert(conn->refcount > 0);
1710 conn->refcount++;
1714 http_client_connection_disconnect(struct http_client_connection *conn)
1716 struct http_client_peer_pool *ppool = conn->ppool;
1720 if (conn->disconnected)
1722 conn->disconnected = TRUE;
1724 e_debug(conn->event, "Connection disconnect");
1726 conn->closing = TRUE;
1727 conn->connected = FALSE;
1729 if (conn->connect_request != NULL)
1730 http_client_request_abort(&conn->connect_request);
1732 if (conn->incoming_payload != NULL) {
1734 i_stream_remove_destroy_callback(conn->incoming_payload,
1736 conn->incoming_payload = NULL;
1739 http_client_connection_abort_any_requests(conn);
1741 if (conn->http_parser != NULL)
1742 http_response_parser_deinit(&conn->http_parser);
1744 if (conn->connect_initialized)
1745 connection_disconnect(&conn->conn);
1747 io_remove(&conn->io_req_payload);
1748 timeout_remove(&conn->to_requests);
1749 timeout_remove(&conn->to_connect);
1750 timeout_remove(&conn->to_input);
1751 timeout_remove(&conn->to_response);
1756 if (*conn_idx == conn) {
1763 if (*conn_idx == conn) {
1769 http_client_connection_detach_peer(conn);
1771 http_client_connection_stop_idle(conn); // FIXME: needed?
1776 struct http_client_connection *conn = *_conn;
1777 struct http_client_peer_pool *ppool = conn->ppool;
1779 i_assert(conn->refcount > 0);
1783 if (--conn->refcount > 0)
1786 e_debug(conn->event, "Connection destroy");
1788 http_client_connection_disconnect(conn);
1790 i_assert(conn->io_req_payload == NULL);
1791 i_assert(conn->to_requests == NULL);
1792 i_assert(conn->to_connect == NULL);
1793 i_assert(conn->to_input == NULL);
1794 i_assert(conn->to_idle == NULL);
1795 i_assert(conn->to_response == NULL);
1797 if (array_is_created(&conn->request_wait_list))
1798 array_free(&conn->request_wait_list);
1800 if (conn->ssl_iostream != NULL)
1801 ssl_iostream_unref(&conn->ssl_iostream);
1802 if (conn->connect_initialized)
1803 connection_deinit(&conn->conn);
1804 io_wait_timer_remove(&conn->io_wait_timer);
1806 event_unref(&conn->event);
1807 i_free(conn->label);
1808 i_free(conn);
1816 struct http_client_connection *conn = *_conn;
1818 e_debug(conn->event, "Connection close");
1820 http_client_connection_disconnect(conn);
1825 void http_client_connection_switch_ioloop(struct http_client_connection *conn)
1827 struct http_client_peer_shared *pshared = conn->ppool->peer;
1831 if (conn->connect_initialized)
1832 connection_switch_ioloop_to(&conn->conn, ioloop);
1833 if (conn->io_req_payload != NULL) {
1834 conn->io_req_payload =
1835 io_loop_move_io_to(ioloop, &conn->io_req_payload);
1837 if (conn->to_requests != NULL) {
1838 conn->to_requests =
1839 io_loop_move_timeout_to(ioloop, &conn->to_requests);
1841 if (conn->to_connect != NULL) {
1842 conn->to_connect =
1843 io_loop_move_timeout_to(ioloop, &conn->to_connect);
1845 if (conn->to_input != NULL) {
1846 conn->to_input =
1847 io_loop_move_timeout_to(ioloop, &conn->to_input);
1849 if (conn->to_idle != NULL) {
1850 conn->to_idle =
1851 io_loop_move_timeout_to(ioloop, &conn->to_idle);
1853 if (conn->to_response != NULL) {
1854 conn->to_response =
1855 io_loop_move_timeout_to(ioloop, &conn->to_response);
1857 if (conn->incoming_payload != NULL)
1858 i_stream_switch_ioloop_to(conn->incoming_payload, ioloop);
1859 conn->io_wait_timer =
1860 io_wait_timer_move_to(&conn->io_wait_timer, ioloop);