diff options
| author | Daniel Stenberg <daniel@haxx.se> | 2005-01-11 14:00:45 +0000 | 
|---|---|---|
| committer | Daniel Stenberg <daniel@haxx.se> | 2005-01-11 14:00:45 +0000 | 
| commit | 29102befa66e009c668d6a51cc41051a273d4703 (patch) | |
| tree | dca83edda366c442b09a414fa9d0dacbb711f840 /lib | |
| parent | 9d1145598abf9fddae2e88cca9e114c12a1b7d9d (diff) | |
Cyrill Osterwalder posted a detailed analysis about a bug that occurs when
using a custom Host: header and curl fails to send a request on a re-used
persistent connection and thus creates a new connection and resends it. It
then sent two Host: headers. Cyrill's analysis was posted here:
http://curl.haxx.se/mail/archive-2005-01/0022.html
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/multi.c | 4 | ||||
| -rw-r--r-- | lib/transfer.c | 17 | ||||
| -rw-r--r-- | lib/transfer.h | 2 | 
3 files changed, 15 insertions, 8 deletions
| diff --git a/lib/multi.c b/lib/multi.c index 2822b16a4..6d037f098 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -342,7 +342,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)            gotourl = strdup(easy->easy_handle->change.url);            if(gotourl) {              easy->easy_handle->change.url_changed = FALSE; -            easy->result = Curl_follow(easy->easy_handle, gotourl); +            easy->result = Curl_follow(easy->easy_handle, gotourl, FALSE);              if(CURLE_OK == easy->result)                easy->state = CURLM_STATE_CONNECT;              else @@ -518,7 +518,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)              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); +              easy->result = Curl_follow(easy->easy_handle, newurl, FALSE);              if(CURLE_OK == easy->result) {                easy->state = CURLM_STATE_CONNECT;                result = CURLM_CALL_MULTI_PERFORM; diff --git a/lib/transfer.c b/lib/transfer.c index f297654c9..7a15d3f3d 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -1742,9 +1742,11 @@ static void strcpy_url(char *output, char *url)   * as given by the remote server and set up the new URL to request.   */  CURLcode Curl_follow(struct SessionHandle *data, -                     char *newurl) /* this 'newurl' is the Location: string, +                     char *newurl, /* this 'newurl' is the Location: string,                                        and it must be malloc()ed before passed                                        here */ +                     bool retry) /* set TRUE if this is a request retry as +                                    opposed to a real redirect following */  {    /* Location: redirect */    char prot[16]; /* URL protocol string storage */ @@ -1758,8 +1760,9 @@ CURLcode Curl_follow(struct SessionHandle *data,      return CURLE_TOO_MANY_REDIRECTS;    } -  /* mark the next request as a followed location: */ -  data->state.this_is_a_follow = TRUE; +  if(!retry) +    /* mark the next request as a followed location: */ +    data->state.this_is_a_follow = TRUE;    data->set.followlocation++; /* count location-followers */ @@ -2063,7 +2066,7 @@ Curl_connect_host(struct SessionHandle *data,        res = Curl_done(conn, res);        if(CURLE_OK == res) {          char *gotourl = strdup(data->change.url); -        res = Curl_follow(data, gotourl); +        res = Curl_follow(data, gotourl, FALSE);          if(res)            free(gotourl);        } @@ -2086,6 +2089,7 @@ CURLcode Curl_perform(struct SessionHandle *data)    CURLcode res2;    struct connectdata *conn=NULL;    char *newurl = NULL; /* possibly a new URL to follow to! */ +  bool retry = FALSE;    data->state.used_interface = Curl_if_easy; @@ -2119,6 +2123,8 @@ CURLcode Curl_perform(struct SessionHandle *data)          res = Transfer(conn); /* now fetch that URL please */          if(res == CURLE_OK) { +          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 @@ -2135,6 +2141,7 @@ CURLcode Curl_perform(struct SessionHandle *data)                                          prevent i.e HTTP transfers to return                                          error just because nothing has been                                          transfered! */ +            retry = TRUE;            }            else              /* @@ -2174,7 +2181,7 @@ CURLcode Curl_perform(struct SessionHandle *data)         */        if((res == CURLE_OK) && newurl) { -        res = Curl_follow(data, newurl); +        res = Curl_follow(data, newurl, retry);          if(CURLE_OK == res) {            newurl = NULL;            continue; diff --git a/lib/transfer.h b/lib/transfer.h index 78a3e046b..86301d60a 100644 --- a/lib/transfer.h +++ b/lib/transfer.h @@ -26,7 +26,7 @@ CURLcode Curl_perform(struct SessionHandle *data);  CURLcode Curl_pretransfer(struct SessionHandle *data);  CURLcode Curl_pretransfersec(struct connectdata *conn);  CURLcode Curl_posttransfer(struct SessionHandle *data); -CURLcode Curl_follow(struct SessionHandle *data, char *newurl); +CURLcode Curl_follow(struct SessionHandle *data, char *newurl, bool retry);  CURLcode Curl_readwrite(struct connectdata *conn, bool *done);  void Curl_single_fdset(struct connectdata *conn,                         fd_set *read_fd_set, | 
