mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
Using the multi interface, and doing a requsted a re-used connection that
gets closed just after the request has been sent failed and did not re-issue a request on a fresh reconnect like the easy interface did. Now it does! (define CURL_MULTIEASY, run test case 160)
This commit is contained in:
parent
91f483c591
commit
8dbaf534c8
11
CHANGES
11
CHANGES
@ -7,6 +7,17 @@
|
|||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
Daniel (29 January 2005)
|
Daniel (29 January 2005)
|
||||||
|
- Using the multi interface, and doing a requsted a re-used connection that
|
||||||
|
gets closed just after the request has been sent failed and did not re-issue
|
||||||
|
a request on a fresh reconnect like the easy interface did. Now it does!
|
||||||
|
|
||||||
|
- Define CURL_MULTIEASY when building libcurl (lib/easy.c to be exact), to use
|
||||||
|
my new curl_easy_perform() that uses the multi interface to run the
|
||||||
|
request. It is a great testbed for the multi interface and I believe we
|
||||||
|
shall do it this way for real in the future when we have a successor to
|
||||||
|
curl_multi_fdset(). I've used this approach to detect and fix several of the
|
||||||
|
recent multi-interfaces issues.
|
||||||
|
|
||||||
- Adjusted the KNOWN_BUGS #17 fix a bit more since the FTP code also did some
|
- Adjusted the KNOWN_BUGS #17 fix a bit more since the FTP code also did some
|
||||||
bad assumptions.
|
bad assumptions.
|
||||||
|
|
||||||
|
16
lib/multi.c
16
lib/multi.c
@ -506,19 +506,24 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
Curl_done(&easy->easy_conn, easy->result);
|
Curl_done(&easy->easy_conn, easy->result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* after the transfer is done, go DONE */
|
|
||||||
else if(TRUE == done) {
|
else if(TRUE == done) {
|
||||||
|
char *newurl;
|
||||||
|
bool retry = Curl_retry_request(easy->easy_conn, &newurl);
|
||||||
|
|
||||||
/* call this even if the readwrite function returned error */
|
/* call this even if the readwrite function returned error */
|
||||||
Curl_posttransfer(easy->easy_handle);
|
Curl_posttransfer(easy->easy_handle);
|
||||||
|
|
||||||
/* When we follow redirects, must to go back to the CONNECT state */
|
/* When we follow redirects, must to go back to the CONNECT state */
|
||||||
if(easy->easy_conn->newurl) {
|
if(easy->easy_conn->newurl || retry) {
|
||||||
char *newurl = easy->easy_conn->newurl;
|
if(!retry) {
|
||||||
easy->easy_conn->newurl = NULL;
|
/* if the URL is a follow-location and not just a retried request
|
||||||
|
then figure out the URL here */
|
||||||
|
newurl = easy->easy_conn->newurl;
|
||||||
|
easy->easy_conn->newurl = NULL;
|
||||||
|
}
|
||||||
easy->result = Curl_done(&easy->easy_conn, CURLE_OK);
|
easy->result = Curl_done(&easy->easy_conn, CURLE_OK);
|
||||||
if(easy->result == CURLE_OK)
|
if(easy->result == CURLE_OK)
|
||||||
easy->result = Curl_follow(easy->easy_handle, newurl, FALSE);
|
easy->result = Curl_follow(easy->easy_handle, newurl, retry);
|
||||||
if(CURLE_OK == easy->result) {
|
if(CURLE_OK == easy->result) {
|
||||||
easy->state = CURLM_STATE_CONNECT;
|
easy->state = CURLM_STATE_CONNECT;
|
||||||
result = CURLM_CALL_MULTI_PERFORM;
|
result = CURLM_CALL_MULTI_PERFORM;
|
||||||
@ -529,6 +534,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
free(newurl);
|
free(newurl);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
/* after the transfer is done, go DONE */
|
||||||
easy->state = CURLM_STATE_DONE;
|
easy->state = CURLM_STATE_DONE;
|
||||||
result = CURLM_CALL_MULTI_PERFORM;
|
result = CURLM_CALL_MULTI_PERFORM;
|
||||||
}
|
}
|
||||||
|
@ -2060,7 +2060,32 @@ Curl_connect_host(struct SessionHandle *data,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns TRUE and sets '*url' if a request retry is wanted */
|
||||||
|
bool Curl_retry_request(struct connectdata *conn,
|
||||||
|
char **url)
|
||||||
|
{
|
||||||
|
bool retry = FALSE;
|
||||||
|
|
||||||
|
if((conn->keep.bytecount+conn->headerbytecount == 0) &&
|
||||||
|
conn->bits.reuse) {
|
||||||
|
/* We got no data and we attempted to re-use a connection. This might
|
||||||
|
happen if the connection was left alive when we were done using it
|
||||||
|
before, but that was closed when we wanted to read from it again. Bad
|
||||||
|
luck. Retry the same request on a fresh connect! */
|
||||||
|
infof(conn->data, "Connection died, retrying a fresh connect\n");
|
||||||
|
*url = strdup(conn->data->change.url);
|
||||||
|
|
||||||
|
conn->bits.close = TRUE; /* close this connection */
|
||||||
|
conn->bits.retry = TRUE; /* mark this as a connection we're about
|
||||||
|
to retry. Marking it this way should
|
||||||
|
prevent i.e HTTP transfers to return
|
||||||
|
error just because nothing has been
|
||||||
|
transfered! */
|
||||||
|
retry = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retry;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_perform() is the internal high-level function that gets called by the
|
* Curl_perform() is the internal high-level function that gets called by the
|
||||||
@ -2106,31 +2131,12 @@ CURLcode Curl_perform(struct SessionHandle *data)
|
|||||||
if(res == CURLE_OK && !data->set.source_url) {
|
if(res == CURLE_OK && !data->set.source_url) {
|
||||||
res = Transfer(conn); /* now fetch that URL please */
|
res = Transfer(conn); /* now fetch that URL please */
|
||||||
if(res == CURLE_OK) {
|
if(res == CURLE_OK) {
|
||||||
|
retry = Curl_retry_request(conn, &newurl);
|
||||||
|
|
||||||
retry = FALSE;
|
if(!retry)
|
||||||
|
|
||||||
if((conn->keep.bytecount+conn->headerbytecount == 0) &&
|
|
||||||
conn->bits.reuse) {
|
|
||||||
/* We got no data and we attempted to re-use a connection. This
|
|
||||||
might happen if the connection was left alive when we were done
|
|
||||||
using it before, but that was closed when we wanted to read
|
|
||||||
from it again. Bad luck. Retry the same request on a fresh
|
|
||||||
connect! */
|
|
||||||
infof(data, "Connection died, retrying a fresh connect\n");
|
|
||||||
newurl = strdup(conn->data->change.url);
|
|
||||||
|
|
||||||
conn->bits.close = TRUE; /* close this connection */
|
|
||||||
conn->bits.retry = TRUE; /* mark this as a connection we're about
|
|
||||||
to retry. Marking it this way should
|
|
||||||
prevent i.e HTTP transfers to return
|
|
||||||
error just because nothing has been
|
|
||||||
transfered! */
|
|
||||||
retry = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/*
|
/*
|
||||||
* We must duplicate the new URL here as the connection data
|
* We must duplicate the new URL here as the connection data may
|
||||||
* may be free()ed in the Curl_done() function.
|
* be free()ed in the Curl_done() function.
|
||||||
*/
|
*/
|
||||||
newurl = conn->newurl?strdup(conn->newurl):NULL;
|
newurl = conn->newurl?strdup(conn->newurl):NULL;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ void Curl_single_fdset(struct connectdata *conn,
|
|||||||
CURLcode Curl_readwrite_init(struct connectdata *conn);
|
CURLcode Curl_readwrite_init(struct connectdata *conn);
|
||||||
CURLcode Curl_readrewind(struct connectdata *conn);
|
CURLcode Curl_readrewind(struct connectdata *conn);
|
||||||
CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
|
CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
|
||||||
|
bool Curl_retry_request(struct connectdata *conn, char **url);
|
||||||
/* This sets up a forthcoming transfer */
|
/* This sets up a forthcoming transfer */
|
||||||
CURLcode
|
CURLcode
|
||||||
Curl_Transfer (struct connectdata *data,
|
Curl_Transfer (struct connectdata *data,
|
||||||
|
Loading…
Reference in New Issue
Block a user