diff options
author | Daniel Stenberg <daniel@haxx.se> | 2013-08-05 23:49:53 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2013-08-06 09:57:59 +0200 |
commit | 7cc00d9a832c42a330888aa5c11a2abad1bd5ac0 (patch) | |
tree | 6a5cd7dd22df9292abd502fed6b5e25c72bcecbd /lib/multi.c | |
parent | 230e16dc033a05ad9b2ed8a499f74b69886e0865 (diff) |
FTP: when EPSV gets a 229 but fails to connect, retry with PASV
This is a regression as this logic used to work. It isn't clear when it
broke, but I'm assuming in 7.28.0 when we went all-multi internally.
This likely never worked with the multi interface. As the failed
connection is detected once the multi state has reached DO_MORE, the
Curl_do_more() function was now expanded somewhat so that the
ftp_do_more() function can request to go "back" to the previous state
when it makes another attempt - using PASV.
Added test case 1233 to verify this fix. It has the little issue that it
assumes no service is listening/accepting connections on port 1...
Reported-by: byte_bucket in the #curl IRC channel
Diffstat (limited to 'lib/multi.c')
-rw-r--r-- | lib/multi.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/lib/multi.c b/lib/multi.c index 774e80841..9653554f8 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -929,6 +929,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, struct SingleRequest *k; struct SessionHandle *data; long timeout_ms; + int control; if(!GOOD_EASY_HANDLE(easy)) return CURLM_BAD_EASY_HANDLE; @@ -1359,13 +1360,17 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* * When we are connected, DO MORE and then go DO_DONE */ - easy->result = Curl_do_more(easy->easy_conn, &dophase_done); + easy->result = Curl_do_more(easy->easy_conn, &control); /* No need to remove this handle from the send pipeline here since that is done in Curl_done() */ if(CURLE_OK == easy->result) { - if(dophase_done) { - multistate(easy, CURLM_STATE_DO_DONE); + if(control) { + /* if positive, advance to DO_DONE + if negative, go back to DOING */ + multistate(easy, control==1? + CURLM_STATE_DO_DONE: + CURLM_STATE_DOING); result = CURLM_CALL_MULTI_PERFORM; } else |