diff --git a/lib/ftp.c b/lib/ftp.c index e28236da01..04c0ad7baa 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -3657,7 +3657,11 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) return result; result = ftp_statemach(data, ftpc, &complete); - *completep = (int)complete; + /* ftp_nb_type() might have skipped sending `TYPE A|I` when not + * deemed necessary and directly sent `STORE name`. If this was + * then complete, but we are still waiting on the data connection, + * the transfer has not been initiated yet. */ + *completep = (int)(ftpc->wait_data_conn ? 0 : complete); } else { /* download */ diff --git a/tests/http/test_30_vsftpd.py b/tests/http/test_30_vsftpd.py index 79fe335066..9c8138cf45 100644 --- a/tests/http/test_30_vsftpd.py +++ b/tests/http/test_30_vsftpd.py @@ -185,7 +185,7 @@ class TestVsFTPD: r.check_stats(count=count, http_status=226) self.check_downloads(curl, srcfile, count) - def test_30_09_active_upload(self, env: Env, vsftpd: VsFTPD): + def test_30_09_active_up_file(self, env: Env, vsftpd: VsFTPD): docname = 'upload-1k' curl = CurlClient(env=env) srcfile = os.path.join(env.gen_dir, docname) @@ -199,6 +199,20 @@ class TestVsFTPD: r.check_stats(count=count, http_status=226) self.check_upload(env, vsftpd, docname=docname) + def test_30_10_active_up_ascii(self, env: Env, vsftpd: VsFTPD): + docname = 'upload-1k' + curl = CurlClient(env=env) + srcfile = os.path.join(env.gen_dir, docname) + dstfile = os.path.join(vsftpd.docs_dir, docname) + self._rmf(dstfile) + count = 1 + url = f'ftp://{env.ftp_domain}:{vsftpd.port}/' + r = curl.ftp_upload(urls=[url], fupload=f'{srcfile}', with_stats=True, extra_args=[ + '--ftp-port', '127.0.0.1', '--use-ascii' + ]) + r.check_stats(count=count, http_status=226) + self.check_upload(env, vsftpd, docname=docname, binary=False) + def check_downloads(self, client, srcfile: str, count: int, complete: bool = True): for i in range(count): @@ -212,7 +226,7 @@ class TestVsFTPD: n=1)) assert False, f'download {dfile} differs:\n{diff}' - def check_upload(self, env, vsftpd: VsFTPD, docname): + def check_upload(self, env, vsftpd: VsFTPD, docname, binary=True): srcfile = os.path.join(env.gen_dir, docname) dstfile = os.path.join(vsftpd.docs_dir, docname) assert os.path.exists(srcfile) @@ -223,4 +237,4 @@ class TestVsFTPD: fromfile=srcfile, tofile=dstfile, n=1)) - assert False, f'upload {dstfile} differs:\n{diff}' + assert not binary and len(diff) == 0, f'upload {dstfile} differs:\n{diff}'