connect_init() (lib/http_proxy.c) swaps out the protocol state while
working on the proxy connection, this is then restored by
Curl_connect_done() after the connection completes.
ftp_do_more() extracted the protocol state pointer to a local variable
at the start of the function then calls Curl_proxy_connect(). If the proxy
connection completes, Curl_proxy_connect() will call Curl_connect_done()
(via Curl_proxyCONNECT()), which restores data->req.p to point to the ftp
protocol state instead of the http proxy protocol state, but the local
variable in ftp_do_more still pointed to the old value.
Ultimately this meant that the state worked on by ftp_do_more() was the
http proxy state not the ftp state initialised by ftp_connect(), but
subsequent calls to any ftp_ function would use the original state.
For my use-case, the visible consequence was that ftp->downloadsize was
never set and so downloaded data was never returned to the application.
This commit updates the ftp protocol state pointer in ftp_do_more() after
Curl_proxy_connect() returns, ensuring that the correct state pointer is
used.
Fixes #8737
Closes #9043
bool connected = FALSE;
bool complete = FALSE;
- /* the ftp struct is inited in ftp_connect() */
- struct FTP *ftp = data->req.p.ftp;
+ /* the ftp struct is inited in ftp_connect(). If we are connecting to an HTTP
+ * proxy then the state will not be valid until after that connection is
+ * complete */
+ struct FTP *ftp = NULL;
/* if the second connection isn't done yet, wait for it */
if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
return result;
#endif
+ /* Curl_proxy_connect might have moved the protocol state */
+ ftp = data->req.p.ftp;
+
if(ftpc->state) {
/* already in a state so skip the initial commands.
They are only done to kickstart the do_more state */