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:
Daniel Stenberg 2005-01-29 22:31:06 +00:00
parent 91f483c591
commit 8dbaf534c8
4 changed files with 52 additions and 29 deletions

11
CHANGES
View File

@ -7,6 +7,17 @@
Changelog
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
bad assumptions.

View File

@ -506,19 +506,24 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
Curl_done(&easy->easy_conn, easy->result);
}
/* after the transfer is done, go 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 */
Curl_posttransfer(easy->easy_handle);
/* When we follow redirects, must to go back to the CONNECT state */
if(easy->easy_conn->newurl) {
char *newurl = easy->easy_conn->newurl;
easy->easy_conn->newurl = NULL;
if(easy->easy_conn->newurl || retry) {
if(!retry) {
/* 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);
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) {
easy->state = CURLM_STATE_CONNECT;
result = CURLM_CALL_MULTI_PERFORM;
@ -529,6 +534,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
free(newurl);
}
else {
/* after the transfer is done, go DONE */
easy->state = CURLM_STATE_DONE;
result = CURLM_CALL_MULTI_PERFORM;
}

View File

@ -2060,7 +2060,32 @@ Curl_connect_host(struct SessionHandle *data,
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
@ -2106,31 +2131,12 @@ CURLcode Curl_perform(struct SessionHandle *data)
if(res == CURLE_OK && !data->set.source_url) {
res = Transfer(conn); /* now fetch that URL please */
if(res == CURLE_OK) {
retry = Curl_retry_request(conn, &newurl);
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(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
if(!retry)
/*
* We must duplicate the new URL here as the connection data
* may be free()ed in the Curl_done() function.
* We must duplicate the new URL here as the connection data may
* be free()ed in the Curl_done() function.
*/
newurl = conn->newurl?strdup(conn->newurl):NULL;
}

View File

@ -36,7 +36,7 @@ void Curl_single_fdset(struct connectdata *conn,
CURLcode Curl_readwrite_init(struct connectdata *conn);
CURLcode Curl_readrewind(struct connectdata *conn);
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 */
CURLcode
Curl_Transfer (struct connectdata *data,