php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #25239 FTP functions won't retrieve more than ~8k from Serv-U FTP server
Submitted: 2003-08-25 13:44 UTC Modified: 2003-08-25 17:28 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: mhumphrey at designvision dot com Assigned:
Status: Closed Package: FTP related
PHP Version: 4.3.2 OS: Win32
Private report: No CVE-ID:
 [2003-08-25 13:44 UTC] mhumphrey at designvision dot com
Description:
------------
FTP functions won't retrieve more than ~8k from Serv-U FTP server ver 4.1 ( www.rhinosoft.com ). Anything over that gets truncated and a QUIT appears in the server log in mid-transfer.

I'm using PHP 4.3.2 on Win32 with Apache 2.0.46

I don't know if this is PHP or Serv-U that's off spec here...all i know is they don't seem to like each other.


Reproduce code:
---------------
Just use any FTP function and try to pull a >8k text file down from a Serv-U server.  Seems to effect every FTP capable function i've tried: fread(), readfile(), file_get_contents(), etc...

Expected result:
----------------
A string of the same size as the file on the FTP server.

Actual result:
--------------
Your returned data will be truncated at around the 8k point.

Here's what Serv-U's log has to say, notice the QUIT that seems to come up in mid-transfer, possibly a clue?:

[2] Mon 25Aug03 13:31:01 - (000012) RETR /entertainment.xml
[3] Mon 25Aug03 13:31:01 - (000012) Sending file c:\apache2\htdocs\momo\entertainment.xml
[7] Mon 25Aug03 13:31:01 - Sock ID=32 accept(504,0x010F9F74,0x010F9F9C) --> 464 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=32 ioctlsocket(464,FIONBIO,0x010F9F88) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=32 WSAAsyncSelect(464,65580,1024,FD_READ FD_WRITE FD_CLOSE) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=31 WSAAsyncSelect(504,65580,0,<<NONE>>) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=31 setsockopt(504,SOL_SOCKET,SO_LINGER,0x010F9F30,4) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=31 shutdown(504,0) --> -1 (WSAENOTCONN)
[7] Mon 25Aug03 13:31:01 - Sock ID=31 shutdown(504,1) --> -1 (WSAENOTCONN)
[7] Mon 25Aug03 13:31:01 - Sock ID=31 closesocket(504) --> 0 (OK)
[6] Mon 25Aug03 13:31:01 - (000012) 150 Opening BINARY mode data connection for entertainment.xml (21289 bytes).
[7] Mon 25Aug03 13:31:01 - Sock ID=32 setsockopt(464,SOL_SOCKET,SO_OOBINLINE,0x010FA860,4) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=32 setsockopt(464,SOL_SOCKET,SO_KEEPALIVE,0x010FA850,4) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=32 setsockopt(464,IPPROTO_TCP,TCP_NODELAY,0x010FA840,4) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=32 setsockopt(464,SOL_SOCKET,SO_SNDBUF,0x010FA834,4) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=32 setsockopt(464,SOL_SOCKET,SO_RCVBUF,0x010FA824,4) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=30 RB_READ Stat=OK
[7] Mon 25Aug03 13:31:01 - Sock ID=30 recv(440,0x016CDC78,2048,0) --> -1 (WSAEWOULDBLOCK)
[7] Mon 25Aug03 13:31:01 - Sock ID=30 WSAGetLastError() --> WSAEWOULDBLOCK
[7] Mon 25Aug03 13:31:01 - Sock ID=32 FD_WRITE Stat=OK
[7] Mon 25Aug03 13:31:01 - Sock ID=32 send(464,0x016A0209,4096,0) --> 4096 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=32 send(464,0x016A1209,4096,0) --> 4096 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=32 send(464,0x016A2209,4096,0) --> -1 (WSAEWOULDBLOCK)
[7] Mon 25Aug03 13:31:01 - Sock ID=32 WSAGetLastError() --> WSAEWOULDBLOCK
[7] Mon 25Aug03 13:31:01 - Sock ID=30 RB_WRITE Stat=OK
[7] Mon 25Aug03 13:31:01 - Sock ID=30 send(440,0x016C93C4,78,0) --> 78 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=32 RB_WRITE Stat=OK
[7] Mon 25Aug03 13:31:01 - Sock ID=32 send(464,0x016A2209,4096,0) --> -1 (WSAEWOULDBLOCK)
[7] Mon 25Aug03 13:31:01 - Sock ID=32 WSAGetLastError() --> WSAEWOULDBLOCK
[7] Mon 25Aug03 13:31:01 - Sock ID=30 FD_READ Stat=OK
[7] Mon 25Aug03 13:31:01 - Sock ID=30 recv(440,0x016CDC78,2048,0) --> 6 (OK)
[2] Mon 25Aug03 13:31:01 - (000012) QUIT
[6] Mon 25Aug03 13:31:01 - (000012) 221 Goodbye!
[7] Mon 25Aug03 13:31:01 - Sock ID=32 WSAAsyncSelect(464,65580,0,<<NONE>>) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=32 setsockopt(464,SOL_SOCKET,SO_LINGER,0x010FB378,4) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=32 shutdown(464,0) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=32 shutdown(464,1) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=32 closesocket(464) --> 0 (OK)
[3] Mon 25Aug03 13:31:01 - (000012) Error sending file c:\apache2\htdocs\momo\entertainment.xml, aborting (107 Kb/sec - 8192 bytes, reason unknown)
[6] Mon 25Aug03 13:31:01 - (000012) 426 Data connection closed, file transfer entertainment.xml aborted.
[7] Mon 25Aug03 13:31:01 - Sock ID=30 RB_READ Stat=OK
[7] Mon 25Aug03 13:31:01 - Sock ID=30 recv(440,0x016CDC78,2048,0) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=30 RB_WRITE Stat=OK
[5] Mon 25Aug03 13:31:01 - (000012) Closing connection for user MOMO (00:00:02 connected)
[7] Mon 25Aug03 13:31:01 - Sock ID=30 WSAAsyncSelect(440,65580,0,<<NONE>>) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=30 setsockopt(440,SOL_SOCKET,SO_LINGER,0x010FEA1C,4) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=30 shutdown(440,0) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=30 shutdown(440,1) --> 0 (OK)
[7] Mon 25Aug03 13:31:01 - Sock ID=30 closesocket(440) --> 0 (OK)


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-08-25 15:37 UTC] pollita@php.net
#1) Could you try the same transfer using the ftp extension?  (i.e.: ftp_connect(), ftp_login(), etc...)

#2) Is there a public Serv-U FTP server available to test against which you can point me towards?  (The only ones I've ever come across were installed by script kiddies on unprotected windows boxes -- Not that I'm blaming the software mind you)
 [2003-08-25 15:55 UTC] mhumphrey at designvision dot com
#1) ftp_connect(), ftp_login(), ftp_get() worked as expected...file was full 22 k.  Seems to only be the functions that read into a string or the ob.  So that's good to know for coding a workaround.

#2) I'm the (35 year old) script kiddie who installed Serv-U on two seperate "unprotected" Win2k systems (well, i'm only a SK when i'm using PHP, the rest of the time i'm a C++adult ;) You can download a free 30 day trial of Serv-U at http://www.serv-u.com/customer/record.asp?prod=su  I'll also give you an account on the Serv-U at our office that you may test with, i'll send that login info by email.  Thanks for the quick reply!
 [2003-08-25 16:06 UTC] pollita@php.net
@php.net mail isn't working right at the moment, but I've found an anonymous ftp server running Serv-U and verified it from linux, however it does indeed appear to be limited only to Serv-U servers (other daemons interact fine).

 [2003-08-25 16:11 UTC] mhumphrey at designvision dot com
Ah OK great.  Yes, like i said it's only with Serv-U FTP, but that still doesn't tell us who's bug it is.

Might want to mention it to them...it's a pretty popular product.  Cheap license, effective, and easy to configure.

I'll use the ftp_get() workaround for now.  Thanks again!
 [2003-08-25 16:37 UTC] pollita@php.net
I'm inclined to blame PHP for this.  The root cause seems to be that the PHP streams layer is setting the EOF flag if there's no data ready and waiting on the socket.  Meanwhile, Serv-U is waiting for clear output buffers to continue sending data.

Serv-U's behavior isn't, strictly speaking, bad.  PHP needs to learn how to handle this situation properly.

I'll need to consult with the streams author to find a suitable fix.
 [2003-08-25 17:28 UTC] pollita@php.net
Seems I was right to blame PHP, but wrong in my initial diagnosis.

PHP optimistically closes the control connection once the data connection is established.  For most FTPds this works fine, however Serv-U obeys RFC959 section 2.3 which states:

-----------------------------------------------
The protocol requires that the control connections be open while data transfer is in progress.  It is the responsibility of the user to request the closing of the control connections when finished using the FTP service, while it is the server who takes the action.  The server may abort data transfer if the control connections are closed without command.
-----------------------------------------------

The fix will show up in the next snapshot and ver 4.3.4 or 5.0.0 (whichever comes first).
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sat Apr 19 22:02:16 2014 UTC