Newer
Older
/* This was formerly done in transfer.c, but we better do it here */
if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
/* This was a re-use of a connection and we got a write error in the
* DO-phase. Then we DISCONNECT this connection and have another attempt
* to CONNECT and then DO again! The retry cannot possibly find another
* connection to re-use, since we only keep one possible connection for
* each. */
infof(data, "Re-used connection seems dead, get a new one\n");
conn->bits.close = TRUE; /* enforce close of this connection */
Daniel Stenberg
committed
result = Curl_done(&conn, result, FALSE); /* we are so done with this */
Daniel Stenberg
committed
/* conn may no longer be a good pointer */
Daniel Stenberg
committed
/*
* According to bug report #1330310. We need to check for
* CURLE_SEND_ERROR here as well. I figure this could happen when the
* request failed on a FTP connection and thus Curl_done() itself tried
* to use the connection (again). Slight Lack of feedback in the report,
* but I don't think this extra check can do much harm.
*/
if((CURLE_OK == result) || (CURLE_SEND_ERROR == result)) {
Daniel Stenberg
committed
bool async;
bool protocol_done = TRUE;
/* Now, redo the connect and get a new connection */
result = Curl_connect(data, connp, &async, &protocol_done);
Daniel Stenberg
committed
if(CURLE_OK == result) {
/* We have connected or sent away a name resolve query fine */
conn = *connp; /* setup conn to again point to something nice */
Daniel Stenberg
committed
if(async) {
/* Now, if async is TRUE here, we need to wait for the name
to resolve */
result = Curl_wait_for_resolv(conn, NULL);
if(result)
return result;
Daniel Stenberg
committed
/* Resolved, continue with the connection */
result = Curl_async_resolved(conn, &protocol_done);
Daniel Stenberg
committed
if(result)
return result;
}
/* ... finally back to actually retry the DO phase */
Patrick Monnerat
committed
result = conn->handler->do_it(conn, done);
Daniel Stenberg
committed
}
Daniel Stenberg
committed
if((result == CURLE_OK) && *done)
/* do_complete must be called after the protocol-specific DO function */
Daniel Stenberg
committed
do_complete(conn);
CURLcode Curl_do_more(struct connectdata *conn)
{
CURLcode result=CURLE_OK;
Patrick Monnerat
committed
if(conn->handler->do_more)
result = conn->handler->do_more(conn);
if(result == CURLE_OK)
/* do_complete must be called after the protocol-specific DO function */
do_complete(conn);
return result;
}
/* Called on connect, and if there's already a protocol-specific struct
allocated for a different connection, this frees it that it can be setup
properly later on. */
void Curl_reset_reqproto(struct connectdata *conn)
{
struct SessionHandle *data = conn->data;
Daniel Stenberg
committed
if(data->state.proto.generic && data->state.current_conn != conn) {
free(data->state.proto.generic);
data->state.proto.generic = NULL;
Daniel Stenberg
committed
data->state.current_conn = conn;