Loading CHANGES +2 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,8 @@ Changelog Yang Tse (10 April 2007) - Ravi Pratap provided some fixes for HTTP pipelining - configure script will ignore --enable-sspi option for non-native Windows. Daniel S (9 April 2007) Loading lib/ftp.c +2 −2 Original line number Diff line number Diff line Loading @@ -331,7 +331,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd, * line */ int i; conn->headerbytecount += gotbytes; data->reqdata.keep.headerbytecount += gotbytes; ftpc->nread_resp += gotbytes; for(i = 0; i < gotbytes; ptr++, i++) { Loading Loading @@ -564,7 +564,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */ * line */ int i; conn->headerbytecount += gotbytes; data->reqdata.keep.headerbytecount += gotbytes; *nreadp += gotbytes; for(i = 0; i < gotbytes; ptr++, i++) { Loading lib/http.c +2 −2 Original line number Diff line number Diff line Loading @@ -1630,8 +1630,8 @@ CURLcode Curl_http_done(struct connectdata *conn, if(!conn->bits.retry && ((http->readbytecount + conn->headerbytecount - conn->deductheadercount)) <= 0) { data->reqdata.keep.headerbytecount - data->reqdata.keep.deductheadercount)) <= 0) { /* If this connection isn't simply closed to be retried, AND nothing was read from the HTTP server (that counts), this can't be right so we return an error here */ Loading lib/multi.c +56 −17 Original line number Diff line number Diff line Loading @@ -207,7 +207,7 @@ void curl_multi_dump(CURLM *multi_handle); static void multistate(struct Curl_one_easy *easy, CURLMstate state) { #ifdef CURLDEBUG long index = -1; long index = -5000; #endif CURLMstate oldstate = easy->state; Loading Loading @@ -534,10 +534,12 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle, multi->num_alive--; if (easy->easy_handle->state.is_in_pipeline && easy->state > CURLM_STATE_DO) { easy->state > CURLM_STATE_DO && easy->state < CURLM_STATE_COMPLETED) { /* If the handle is in a pipeline and has finished sending off its request, we need to remember the fact that we want to remove this handle but do the actual removal at a later time */ request but not received its reponse yet, we need to remember the fact that we want to remove this handle but do the actual removal at a later time */ easy->easy_handle->state.cancelled = TRUE; return CURLM_OK; } Loading Loading @@ -603,7 +605,9 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle, /* and modify the connectindex since this handle can't point to the connection cache anymore */ if(easy->easy_conn) if(easy->easy_conn && (easy->easy_conn->send_pipe->size + easy->easy_conn->recv_pipe->size == 0)) easy->easy_conn->connectindex = -1; } Loading Loading @@ -648,6 +652,14 @@ bool Curl_multi_canPipeline(struct Curl_multi* multi) return multi->pipelining_enabled; } void Curl_multi_handlePipeBreak(struct SessionHandle *data) { struct Curl_one_easy *one_easy = data->set.one_easy; if (one_easy) one_easy->easy_conn = NULL; } static int waitconnect_getsock(struct connectdata *conn, curl_socket_t *sock, int numsocks) Loading Loading @@ -791,13 +803,17 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, struct Curl_transfer_keeper *k; do { bool disconnect_conn = FALSE; if(!GOOD_EASY_HANDLE(easy->easy_handle)) return CURLM_BAD_EASY_HANDLE; /* Handle the case when the pipe breaks, i.e., the connection we're using gets cleaned up and we're left with nothing. */ if (easy->easy_handle->state.pipe_broke) { infof(easy->easy_handle, "Pipe broke: handle 0x%x, url = %s\n", easy, easy->easy_handle->reqdata.path); if(easy->easy_handle->state.is_in_pipeline) { /* Head back to the CONNECT state */ multistate(easy, CURLM_STATE_CONNECT); Loading Loading @@ -920,7 +936,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* call again please so that we get the next socket setup */ result = CURLM_CALL_MULTI_PERFORM; if(protocol_connect) multistate(easy, CURLM_STATE_DO); multistate(easy, CURLM_STATE_WAITDO); else { #ifndef CURL_DISABLE_HTTP if (easy->easy_conn->bits.tunnel_connecting) Loading @@ -934,8 +950,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(CURLE_OK != easy->result) { /* failure detected */ Curl_disconnect(easy->easy_conn); /* disconnect properly */ easy->easy_conn = NULL; /* no more connection */ disconnect_conn = TRUE; break; } } Loading Loading @@ -964,8 +979,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(CURLE_OK != easy->result) { /* failure detected */ Curl_disconnect(easy->easy_conn); /* close the connection */ easy->easy_conn = NULL; /* no more connection */ /* Just break, the cleaning up is handled all in one place */ disconnect_conn = TRUE; break; } Loading Loading @@ -998,8 +1013,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* failure detected */ Curl_posttransfer(easy->easy_handle); Curl_done(&easy->easy_conn, easy->result, FALSE); Curl_disconnect(easy->easy_conn); /* close the connection */ easy->easy_conn = NULL; /* no more connection */ disconnect_conn = TRUE; } break; Loading Loading @@ -1065,8 +1079,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* failure detected */ Curl_posttransfer(easy->easy_handle); Curl_done(&easy->easy_conn, easy->result, FALSE); Curl_disconnect(easy->easy_conn); /* close the connection */ easy->easy_conn = NULL; /* no more connection */ disconnect_conn = TRUE; } } break; Loading Loading @@ -1098,8 +1111,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* failure detected */ Curl_posttransfer(easy->easy_handle); Curl_done(&easy->easy_conn, easy->result, FALSE); Curl_disconnect(easy->easy_conn); /* close the connection */ easy->easy_conn = NULL; /* no more connection */ disconnect_conn = TRUE; } break; Loading Loading @@ -1208,9 +1220,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(easy->result) { /* The transfer phase returned error, we mark the connection to get * closed to prevent being re-used. This is becasue we can't * closed to prevent being re-used. This is because we can't * possibly know if the connection is in a good shape or not now. */ easy->easy_conn->bits.close = TRUE; Curl_removeHandleFromPipeline(easy->easy_handle, easy->easy_conn->recv_pipe); if(CURL_SOCKET_BAD != easy->easy_conn->sock[SECONDARYSOCKET]) { /* if we failed anywhere, we must clean up the secondary socket if Loading Loading @@ -1292,10 +1306,17 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* This node should be delinked from the list now and we should post an information message that we are complete. */ /* Important: reset the conn pointer so that we don't point to memory that could be freed anytime */ easy->easy_conn = NULL; break; case CURLM_STATE_CANCELLED: /* Cancelled transfer, wait to be cleaned up */ /* Reset the conn pointer so we don't leave it dangling */ easy->easy_conn = NULL; break; default: Loading @@ -1308,6 +1329,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, * If an error was returned, and we aren't in completed state now, * then we go to completed and consider this transfer aborted. */ /* NOTE: no attempt to disconnect connections must be made in the case blocks above - cleanup happens only here */ easy->easy_handle->state.is_in_pipeline = FALSE; easy->easy_handle->state.pipe_broke = FALSE; Loading @@ -1315,7 +1340,21 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* if this has a connection, unsubscribe from the pipelines */ easy->easy_conn->writechannel_inuse = FALSE; easy->easy_conn->readchannel_inuse = FALSE; Curl_removeHandleFromPipeline(easy->easy_handle, easy->easy_conn->send_pipe); Curl_removeHandleFromPipeline(easy->easy_handle, easy->easy_conn->recv_pipe); } if (disconnect_conn) { Curl_disconnect(easy->easy_conn); /* disconnect properly */ /* This is where we make sure that the easy_conn pointer is reset. We don't have to do this in every case block above where a failure is detected */ easy->easy_conn = NULL; } multistate(easy, CURLM_STATE_COMPLETED); } } Loading lib/multiif.h +1 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ void Curl_expire(struct SessionHandle *data, long milli); void Curl_multi_rmeasy(void *multi, CURL *data); bool Curl_multi_canPipeline(struct Curl_multi* multi); void Curl_multi_handlePipeBreak(struct SessionHandle *data); /* the write bits start at bit 16 for the *getsock() bitmap */ #define GETSOCK_WRITEBITSTART 16 Loading Loading
CHANGES +2 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,8 @@ Changelog Yang Tse (10 April 2007) - Ravi Pratap provided some fixes for HTTP pipelining - configure script will ignore --enable-sspi option for non-native Windows. Daniel S (9 April 2007) Loading
lib/ftp.c +2 −2 Original line number Diff line number Diff line Loading @@ -331,7 +331,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd, * line */ int i; conn->headerbytecount += gotbytes; data->reqdata.keep.headerbytecount += gotbytes; ftpc->nread_resp += gotbytes; for(i = 0; i < gotbytes; ptr++, i++) { Loading Loading @@ -564,7 +564,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */ * line */ int i; conn->headerbytecount += gotbytes; data->reqdata.keep.headerbytecount += gotbytes; *nreadp += gotbytes; for(i = 0; i < gotbytes; ptr++, i++) { Loading
lib/http.c +2 −2 Original line number Diff line number Diff line Loading @@ -1630,8 +1630,8 @@ CURLcode Curl_http_done(struct connectdata *conn, if(!conn->bits.retry && ((http->readbytecount + conn->headerbytecount - conn->deductheadercount)) <= 0) { data->reqdata.keep.headerbytecount - data->reqdata.keep.deductheadercount)) <= 0) { /* If this connection isn't simply closed to be retried, AND nothing was read from the HTTP server (that counts), this can't be right so we return an error here */ Loading
lib/multi.c +56 −17 Original line number Diff line number Diff line Loading @@ -207,7 +207,7 @@ void curl_multi_dump(CURLM *multi_handle); static void multistate(struct Curl_one_easy *easy, CURLMstate state) { #ifdef CURLDEBUG long index = -1; long index = -5000; #endif CURLMstate oldstate = easy->state; Loading Loading @@ -534,10 +534,12 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle, multi->num_alive--; if (easy->easy_handle->state.is_in_pipeline && easy->state > CURLM_STATE_DO) { easy->state > CURLM_STATE_DO && easy->state < CURLM_STATE_COMPLETED) { /* If the handle is in a pipeline and has finished sending off its request, we need to remember the fact that we want to remove this handle but do the actual removal at a later time */ request but not received its reponse yet, we need to remember the fact that we want to remove this handle but do the actual removal at a later time */ easy->easy_handle->state.cancelled = TRUE; return CURLM_OK; } Loading Loading @@ -603,7 +605,9 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle, /* and modify the connectindex since this handle can't point to the connection cache anymore */ if(easy->easy_conn) if(easy->easy_conn && (easy->easy_conn->send_pipe->size + easy->easy_conn->recv_pipe->size == 0)) easy->easy_conn->connectindex = -1; } Loading Loading @@ -648,6 +652,14 @@ bool Curl_multi_canPipeline(struct Curl_multi* multi) return multi->pipelining_enabled; } void Curl_multi_handlePipeBreak(struct SessionHandle *data) { struct Curl_one_easy *one_easy = data->set.one_easy; if (one_easy) one_easy->easy_conn = NULL; } static int waitconnect_getsock(struct connectdata *conn, curl_socket_t *sock, int numsocks) Loading Loading @@ -791,13 +803,17 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, struct Curl_transfer_keeper *k; do { bool disconnect_conn = FALSE; if(!GOOD_EASY_HANDLE(easy->easy_handle)) return CURLM_BAD_EASY_HANDLE; /* Handle the case when the pipe breaks, i.e., the connection we're using gets cleaned up and we're left with nothing. */ if (easy->easy_handle->state.pipe_broke) { infof(easy->easy_handle, "Pipe broke: handle 0x%x, url = %s\n", easy, easy->easy_handle->reqdata.path); if(easy->easy_handle->state.is_in_pipeline) { /* Head back to the CONNECT state */ multistate(easy, CURLM_STATE_CONNECT); Loading Loading @@ -920,7 +936,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* call again please so that we get the next socket setup */ result = CURLM_CALL_MULTI_PERFORM; if(protocol_connect) multistate(easy, CURLM_STATE_DO); multistate(easy, CURLM_STATE_WAITDO); else { #ifndef CURL_DISABLE_HTTP if (easy->easy_conn->bits.tunnel_connecting) Loading @@ -934,8 +950,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(CURLE_OK != easy->result) { /* failure detected */ Curl_disconnect(easy->easy_conn); /* disconnect properly */ easy->easy_conn = NULL; /* no more connection */ disconnect_conn = TRUE; break; } } Loading Loading @@ -964,8 +979,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(CURLE_OK != easy->result) { /* failure detected */ Curl_disconnect(easy->easy_conn); /* close the connection */ easy->easy_conn = NULL; /* no more connection */ /* Just break, the cleaning up is handled all in one place */ disconnect_conn = TRUE; break; } Loading Loading @@ -998,8 +1013,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* failure detected */ Curl_posttransfer(easy->easy_handle); Curl_done(&easy->easy_conn, easy->result, FALSE); Curl_disconnect(easy->easy_conn); /* close the connection */ easy->easy_conn = NULL; /* no more connection */ disconnect_conn = TRUE; } break; Loading Loading @@ -1065,8 +1079,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* failure detected */ Curl_posttransfer(easy->easy_handle); Curl_done(&easy->easy_conn, easy->result, FALSE); Curl_disconnect(easy->easy_conn); /* close the connection */ easy->easy_conn = NULL; /* no more connection */ disconnect_conn = TRUE; } } break; Loading Loading @@ -1098,8 +1111,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* failure detected */ Curl_posttransfer(easy->easy_handle); Curl_done(&easy->easy_conn, easy->result, FALSE); Curl_disconnect(easy->easy_conn); /* close the connection */ easy->easy_conn = NULL; /* no more connection */ disconnect_conn = TRUE; } break; Loading Loading @@ -1208,9 +1220,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(easy->result) { /* The transfer phase returned error, we mark the connection to get * closed to prevent being re-used. This is becasue we can't * closed to prevent being re-used. This is because we can't * possibly know if the connection is in a good shape or not now. */ easy->easy_conn->bits.close = TRUE; Curl_removeHandleFromPipeline(easy->easy_handle, easy->easy_conn->recv_pipe); if(CURL_SOCKET_BAD != easy->easy_conn->sock[SECONDARYSOCKET]) { /* if we failed anywhere, we must clean up the secondary socket if Loading Loading @@ -1292,10 +1306,17 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* This node should be delinked from the list now and we should post an information message that we are complete. */ /* Important: reset the conn pointer so that we don't point to memory that could be freed anytime */ easy->easy_conn = NULL; break; case CURLM_STATE_CANCELLED: /* Cancelled transfer, wait to be cleaned up */ /* Reset the conn pointer so we don't leave it dangling */ easy->easy_conn = NULL; break; default: Loading @@ -1308,6 +1329,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, * If an error was returned, and we aren't in completed state now, * then we go to completed and consider this transfer aborted. */ /* NOTE: no attempt to disconnect connections must be made in the case blocks above - cleanup happens only here */ easy->easy_handle->state.is_in_pipeline = FALSE; easy->easy_handle->state.pipe_broke = FALSE; Loading @@ -1315,7 +1340,21 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* if this has a connection, unsubscribe from the pipelines */ easy->easy_conn->writechannel_inuse = FALSE; easy->easy_conn->readchannel_inuse = FALSE; Curl_removeHandleFromPipeline(easy->easy_handle, easy->easy_conn->send_pipe); Curl_removeHandleFromPipeline(easy->easy_handle, easy->easy_conn->recv_pipe); } if (disconnect_conn) { Curl_disconnect(easy->easy_conn); /* disconnect properly */ /* This is where we make sure that the easy_conn pointer is reset. We don't have to do this in every case block above where a failure is detected */ easy->easy_conn = NULL; } multistate(easy, CURLM_STATE_COMPLETED); } } Loading
lib/multiif.h +1 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ void Curl_expire(struct SessionHandle *data, long milli); void Curl_multi_rmeasy(void *multi, CURL *data); bool Curl_multi_canPipeline(struct Curl_multi* multi); void Curl_multi_handlePipeBreak(struct SessionHandle *data); /* the write bits start at bit 16 for the *getsock() bitmap */ #define GETSOCK_WRITEBITSTART 16 Loading