cURL / Mailing Lists / curl-library / Single Mail

curl-library

FTP CURLOPT_POSTQUOTE with CURLOPT_NOBODY bug ?

From: Philippe Vaucher <pvaucher_at_infomaniak.ch>
Date: Tue, 24 Jan 2006 01:54:17 +0100

Hello,

I found a rather strange bug with libcurl in a multithreaded
environnement doing FTP commands with CURLOPT_POSTQUOTE
and CURLOPT_NOBODY together, when two threads connect to the
same FTP server.

Sometimes libcurl gives me a weird CURLE_TOO_MANY_REDIRECTS (47)
for an FTP "DELE" command. And sometimes not.

If I set CURLOPT_MAXREDIRS to -1 (which the docs says it is supposed to
already be)
then libcurl tries to delete the file twice and it ends in a
CURLE_FTP_QUOTE_ERROR (21).

I did set CURLOPT_NOBODY and I think I did everything fine.
If I remove CURLOPT_NOBODY it works without the error above
but then I have an FTP "LIST" occuring and this slows down
my app a lot.

I posted some debug logs of what happens to show the problem :

- log_ok.log shows what is correct and should happen.
- log_error.log shows at the end the max_redirs problem.

I built a small testcase, it requires boost (www.boost.org) for the
threading.
Just edit informations with your own server at the start of main.cpp,
compile & run
and look at the 123123123.log etc files to see what happend.

I tried for the testcase to mimic the closest possible the real application
that's why I do some recursive FTP LIST before.

I'm using libcurl 7.15.1

I'd appreciate any ideas / quick fix :)
Thank you in advance.

Philippe

01:37:21| -------- [CALL] ftp_list(ftp://user:pass@server.com/dir2/) --------

01:37:21| [info] About to connect() to server.com port 21
01:37:21| [info] Trying 84.16.81.31... 01:37:21| [info] connected
01:37:21| [info] Connected to server.com (84.16.81.31) port 21
01:37:21| << recv: 220 ProFTPD 1.2.10 Server (ProFTPD) [84.16.81.31]
01:37:21| >> send: USER user
01:37:21| << recv: 331 Password required for use.
01:37:21| >> send: PASS pass
01:37:21| << recv: 230 User user logged in.
01:37:21| >> send: PWD
01:37:21| << recv: 257 "/web" is current directory.
01:37:21| [info] Entry path is '/web'
01:37:21| >> send: CWD dir2
01:37:21| << recv: 250 CWD command successful
01:37:21| >> send: EPSV
01:37:21| [info] Connect data stream passively
01:37:21| << recv: 229 Entering Extended Passive Mode (|||35943|)
01:37:21| [info] Trying 84.16.81.31... 01:37:21| [info] connected
01:37:21| [info] Connecting to 84.16.81.31 (84.16.81.31) port 35943
01:37:21| >> send: TYPE A
01:37:21| << recv: 200 Type set to A
01:37:21| >> send: LIST
01:37:21| << recv: 150 Opening ASCII mode data connection for file list
01:37:21| << recv data (skip log)
01:37:21| [info] Remembering we are in dir dir2/
01:37:21| << recv: 226 Transfer complete.
01:37:21| [info] Connection #0 to host server.com left intact

01:37:21| -------- [CALL] ftp_list(ftp://user:pass@server.com/dir2/include/) --------

01:37:21| [info] Re-using existing connection! (#0) with host server.com
01:37:21| [info] Connected to server.com (84.16.81.31) port 21
01:37:21| >> send: CWD /web
01:37:21| << recv: 250 CWD command successful
01:37:21| >> send: CWD dir2
01:37:21| << recv: 250 CWD command successful
01:37:21| >> send: CWD include
01:37:21| << recv: 250 CWD command successful
01:37:21| >> send: EPSV
01:37:21| [info] Connect data stream passively
01:37:21| << recv: 229 Entering Extended Passive Mode (|||35944|)
01:37:21| [info] Trying 84.16.81.31... 01:37:21| [info] connected
01:37:21| [info] Connecting to 84.16.81.31 (84.16.81.31) port 35944
01:37:21| >> send: TYPE A
01:37:21| << recv: 200 Type set to A
01:37:21| >> send: LIST
01:37:21| << recv: 150 Opening ASCII mode data connection for file list
01:37:21| << recv data (skip log)
01:37:21| [info] Remembering we are in dir dir2/include/
01:37:21| << recv: 226 Transfer complete.
01:37:21| [info] Connection #0 to host server.com left intact

01:37:21| -------- [CALL] ftp_list(ftp://user:pass@server.com/dir2/include/domit/) --------

01:37:21| [info] Re-using existing connection! (#0) with host server.com
01:37:21| [info] Connected to server.com (84.16.81.31) port 21
01:37:21| >> send: CWD /web
01:37:21| << recv: 250 CWD command successful
01:37:21| >> send: CWD dir2
01:37:21| << recv: 250 CWD command successful
01:37:21| >> send: CWD include
01:37:21| << recv: 250 CWD command successful
01:37:21| >> send: CWD domit
01:37:21| << recv: 250 CWD command successful
01:37:21| >> send: EPSV
01:37:21| [info] Connect data stream passively
01:37:21| << recv: 229 Entering Extended Passive Mode (|||35945|)
01:37:21| [info] Trying 84.16.81.31... 01:37:21| [info] connected
01:37:21| [info] Connecting to 84.16.81.31 (84.16.81.31) port 35945
01:37:21| >> send: TYPE A
01:37:21| << recv: 200 Type set to A
01:37:21| >> send: LIST
01:37:21| << recv: 150 Opening ASCII mode data connection for file list
01:37:21| << recv data (skip log)
01:37:21| [info] Remembering we are in dir dir2/include/domit/
01:37:21| << recv: 226 Transfer complete.
01:37:21| [info] Connection #0 to host server.com left intact

01:37:21| -------- [CALL] ftp_list(ftp://user:pass@server.com/dir2/pics/) --------

01:37:21| [info] Re-using existing connection! (#0) with host server.com
01:37:21| [info] Connected to server.com (84.16.81.31) port 21
01:37:21| >> send: CWD /web
01:37:21| << recv: 250 CWD command successful
01:37:21| >> send: CWD dir2
01:37:21| << recv: 250 CWD command successful
01:37:21| >> send: CWD pics
01:37:21| << recv: 250 CWD command successful

01:37:21| >> send: EPSV
01:37:21| [info] Connect data stream passively
01:37:21| << recv: 229 Entering Extended Passive Mode (|||35946|)
01:37:21| [info] Trying 84.16.81.31... 01:37:21| [info] connected
01:37:21| [info] Connecting to 84.16.81.31 (84.16.81.31) port 35946
01:37:21| >> send: TYPE A
01:37:21| << recv: 200 Type set to A
01:37:21| >> send: LIST
01:37:21| << recv: 150 Opening ASCII mode data connection for file list
01:37:21| << recv data (skip log)
01:37:21| [info] Remembering we are in dir dir2/pics/
01:37:21| << recv: 226 Transfer complete.
01:37:21| [info] Connection #0 to host server.com left intact

01:37:21| -------- [CALL] ftp_list(ftp://user:pass@server.com/dir2/xml/) --------

01:37:21| [info] Re-using existing connection! (#0) with host server.com
01:37:21| [info] Connected to server.com (84.16.81.31) port 21
01:37:21| >> send: CWD /web
01:37:21| << recv: 250 CWD command successful
01:37:21| >> send: CWD dir2
01:37:21| << recv: 250 CWD command successful
01:37:21| >> send: CWD xml
01:37:21| << recv: 250 CWD command successful
01:37:21| >> send: EPSV
01:37:21| [info] Connect data stream passively
01:37:21| << recv: 229 Entering Extended Passive Mode (|||35947|)
01:37:21| [info] Trying 84.16.81.31... 01:37:21| [info] connected
01:37:21| [info] Connecting to 84.16.81.31 (84.16.81.31) port 35947
01:37:21| >> send: TYPE A
01:37:21| << recv: 200 Type set to A
01:37:21| >> send: LIST
01:37:21| << recv: 150 Opening ASCII mode data connection for file list
01:37:21| << recv data (skip log)
01:37:21| [info] Remembering we are in dir dir2/xml/
01:37:21| << recv: 226 Transfer complete.
01:37:21| [info] Connection #0 to host server.com left intact

01:37:21| -------- [CALL] ftp_cmd(ftp://user:pass@server.com/dir2/, DELE a.txt) --------

01:37:21| [info] Re-using existing connection! (#0) with host server.com
01:37:21| [info] Connected to server.com (84.16.81.31) port 21
01:37:21| >> send: CWD /web
01:37:21| << recv: 250 CWD command successful
01:37:21| >> send: CWD dir2
01:37:21| << recv: 250 CWD command successful
01:37:21| [info] Remembering we are in dir dir2/
01:37:21| >> send: DELE a.txt
01:37:21| << recv: 250 DELE command successful
01:37:21| [info] Connection #0 to host server.com left intact
01:37:21| >> send: QUIT
01:37:21| << recv: 221 Goodbye.
01:37:21| [info] Closing connection #0

01:37:21| -------- [CALL] ftp_list(ftp://user:pass@server.com/dir1/) --------

01:37:21| [info] About to connect() to server.com port 21
01:37:21| [info] Trying 84.16.81.31... 01:37:21| [info] connected
01:37:21| [info] Connected to server.com (84.16.81.31) port 21
01:37:21| << recv: 220 ProFTPD 1.2.10 Server (ProFTPD) [84.16.81.31]
01:37:21| >> send: USER user
01:37:21| << recv: 331 Password required for user.
01:37:21| >> send: PASS pass
01:37:21| << recv: 230 User user logged in.
01:37:21| >> send: PWD
01:37:21| << recv: 257 "/web" is current directory.
01:37:21| [info] Entry path is '/web'
01:37:21| >> send: CWD dir1
01:37:21| << recv: 250 CWD command successful
01:37:21| >> send: EPSV
01:37:21| [info] Connect data stream passively
01:37:21| << recv: 229 Entering Extended Passive Mode (|||35942|)
01:37:21| [info] Trying 84.16.81.31... 01:37:21| [info] connected
01:37:21| [info] Connecting to 84.16.81.31 (84.16.81.31) port 35942
01:37:21| >> send: TYPE A
01:37:21| << recv: 200 Type set to A
01:37:21| >> send: LIST
01:37:21| << recv: 150 Opening ASCII mode data connection for file list
01:37:21| << recv data (skip log)
01:37:21| [info] Remembering we are in dir tmp8/
01:37:21| << recv: 226 Transfer complete.
01:37:21| [info] Connection #0 to host server.com left intact

01:37:21| -------- [CALL] ftp_cmd(ftp://user:pass@server.com/dir1/, DELE b.txt) --------

01:37:21| [info] Re-using existing connection! (#0) with host server.com
01:37:21| [info] Connected to server.com (84.16.81.31) port 21
01:37:21| [info] Request has same path as previous transfer
01:37:21| [info] Connection died, retrying a fresh connect
01:37:21| [info] Remembering we are in dir tmp8/
01:37:21| >> send: DELE b.txt
01:37:21| << recv: 250 DELE command successful
01:37:21| >> send: QUIT
01:37:21| << recv: 221 Goodbye.
01:37:21| [info] Closing connection #0
01:37:21| [info] Maximum (0) redirects followed
01:37:21| [info] number of redirects hit maximum amount

Received on 2006-01-24