}
}
+ conn->lost_prematurely = (conn->conn.input != NULL &&
+ conn->conn.input->v_offset == 0 &&
+ i_stream_get_data_size(conn->conn.input) == 0);
http_client_connection_abort_temp_error(_conn,
HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, error);
}
}
if (conn->connect_succeeded)
- http_client_peer_connection_lost(peer);
+ http_client_peer_connection_lost(peer, conn->lost_prematurely);
}
bool http_client_connection_unref(struct http_client_connection **_conn)
}
}
-void http_client_peer_connection_lost(struct http_client_peer *peer)
+void http_client_peer_connection_lost(struct http_client_peer *peer,
+ bool premature)
{
unsigned int num_pending, num_urgent;
num_pending = http_client_peer_requests_pending(peer, &num_urgent);
http_client_peer_debug(peer,
- "Lost a connection (%u queues linked, %u connections left, "
+ "Lost a connection%s (%u queues linked, %u connections left, "
"%u requests pending, %u requests urgent)",
+ (premature ? " prematurely" : ""),
array_count(&peer->queues), array_count(&peer->conns),
num_pending, num_urgent);
+ /* update backoff timer if the connection was lost prematurely.
+ this prevents reconnecting immediately to a server that is
+ misbehaving by disconnecting before sending a response.
+ */
+ if (premature) {
+ peer->last_failure = ioloop_timeval;
+ http_client_peer_increase_backoff_timer(peer);
+ }
+
if (peer->handling_requests) {
/* we got here from the request handler loop */
http_client_peer_debug(peer,
bool connect_initialized:1; /* connection was initialized */
bool connect_succeeded:1; /* connection succeeded including SSL */
bool connect_failed:1; /* connection failed */
+ bool lost_prematurely:1; /* lost connection before receiving any data */
bool closing:1;
bool disconnected:1;
bool close_indicated:1;
void http_client_peer_connection_success(struct http_client_peer *peer);
void http_client_peer_connection_failure(struct http_client_peer *peer,
const char *reason);
-void http_client_peer_connection_lost(struct http_client_peer *peer);
+void http_client_peer_connection_lost(struct http_client_peer *peer,
+ bool premature);
bool http_client_peer_is_connected(struct http_client_peer *peer);
unsigned int
http_client_peer_idle_connections(struct http_client_peer *peer);