Rick Strahl's Weblog
Rick Strahl's FoxPro and Web Connection Weblog
White Papers | Products | Message Board | News |

wwFtp and WinInet Problems with IE 11


8 comments
November 25, 2013 •

In the last few weeks I've gotten a few notes from various customers that wwFtp has started to break for them after upgrading to IE 11. It appears there's been a new bug introduced with IE 11 that causes failures on certain types of connections.

There's more info on this in this StackOverflow question:

http://stackoverflow.com/questions/19683291/wininet-from-ie-11-randomly-returns-error-12003-for-most-ftp-functions

Specifically it points at some reproducible problems.

So far all the problems I've heard reported are related to file uploads rather than downloads. And for uploads there are a few workaround available.

Setting the Scenario

So I set up a simple test to upload some files to my own FTP server and sure enough I can see the problem occurring with this code:

CLEAR
DO wwftp
DO wwutils
 
LOCAL o as wwFtp
o=create("wwFTP")

? o.FTPConnect("www.west-wind.com","ricks",GetSystemPassword())
? o.FTPSendFileEx("c:\temp\geocrumbs.jpg","geocrumbs.jpg")
? o.FTPSendFileEx("c:\temp\iefullscreen.png","iefullscreen.png")
? o.FTPSendFileEx("c:\temp\iemetrononfullscreen.png","iemetrononfullscreen.png")
? o.cErrorMsg
o.FTPClose()
 
RETURN

Here I'm using FtpSendFileEx() to upload multiple files on a single connection and when I run this the third FTPSendFileEx call ends up failing with a 12003 error (extended error) with an error message basically echoing back the transfer command.

200 Type set to I
226 Transfer OK

Oddly this looks like the transfer worked even though the error message shows, but examing the target folder on the server reveals that the file was not actually sent or at least not written over there.

So what can we do?

Disable lPassiveFtp

wwFtp by default uses Passive FTP as it's more flexible for going through firewalls and proxied HTTP connections. By default lPassiveFtp is .T. and so passive FTP is used. Passive FTP basically creates a connection does it's transfer and drops the connection and automatically reestablishes as needed. In the process the FTP connection might actually jump ports.

By setting:

o.lPassiveFtp = .F.

wwFtp uses Active connections which stay alive for the duration of the connection made and stays fixed on a single port.

Using Active Connections I had no problems with uploading many files.

Unfortunately, active connections do not always work and can be flaky with connection drop offs, but it entirely depends on the environment. In general I recommend using Passive as the default but in light of the current bug, using Active at least should be tried (and you should always expose that setting as an option in your application settings so you can easily switch modes.

Connect and disconnect for each Transfer

Another option for sending files is to simply not reuse connections and send files by opening, sending and closing the connection. Doing this is reliable but it'll add a little overhead especially if you're sending lots of files.

So this works too:

LOCAL o as wwFtp
o=create("wwFTP")
o.lPassiveFtp = .T.
 
? o.FTPConnect("www.west-wind.com","ricks",GetSystemPassword())
? o.FTPSendFileEx("c:\temp\geocrumbs.jpg","geocrumbs.jpg")
o.FTPClose()
? o.FTPConnect("www.west-wind.com","ricks",GetSystemPassword())
? o.FTPSendFileEx("c:\temp\iefullscreen.png","iefullscreen.png")
o.FTPClose()
? o.FTPConnect("www.west-wind.com","ricks",GetSystemPassword())
? o.FTPSendFileEx("c:\temp\iemetrononfullscreen.png","iemetrononfullscreen.png")
o.FTPClose()

Use FtpSendFileEx2

Some time ago I quietly added an wwFtp::FtpSendFileEx2() function to wwFtp. The original FtpSendEx() method is a very low level function that makes a bunch of internal API calls from within Visual FoxPro. It also adds some additional features like giving you the ability to get notified of chunks of data being sent.

Even prior to this IE 11 issue, I've found that on occasion when sending large numbers of files, FtpSendFileEx() would occasionally stall for no apparent reason. It was rare but enough of a problem to consider alternatives. The alternative was to build another routine - FtpSendFileEx2(), which provides the same functionality but calls one of the higher level WinInet functions (FtpPutFile()) which is basically a single command. It turns out that using FtpPutFile() under the hood is a lot more reliable than the various API streaming functions.

FptSendFileEx2() is parameter compatible with FtpSendFile() but - it doesn't support the update even calls the OnFtpBufferUpdate() to provide progress information as the file is sent off a single API call into WinInet.

LOCAL o as wwFtp
o=create("wwFTP")
 
? o.FTPConnect("www.west-wind.com","ricks",GetSystemPassword())
? o.FTPSendFileEx2("c:\temp\geocrumbs.jpg","geocrumbs.jpg")
? o.FTPSendFileEx2("c:\temp\iefullscreen.png","iefullscreen.png")
? o.FTPSendFileEx2("c:\temp\iemetrononfullscreen.png","iemetrononfullscreen.png")

o.FTPClose()

and that works reliably too.

I use FtpSendFileEx2() in Help Builder to upload HTML help files to a Web site, and that can be 1000s of files in a session - and it works without problems, so this is what I would recommend you use for uploading files in bulk.

What to use?

If you're uploading a bunch of smallish files a use FtpSendFileEx2() - you won't need progress info on a per file basis, but you can certainly handle intra file upload info. If you upload just one or two larger files and you need the OnFtpUpdate() API to provide progress info, use FtpSendFileEx() but just make sure you reconnect for each file upload.

Switching active/passive mode is just a quick fix that might help get you out of a bind, but as a long term solution I'd still recommend you use Passive mode as it's much more reliable.

Hopefully this will be a temporary issue that Microsoft addresses soon - this is turning out to be a major headache for some of my customers who've been calling in frantically asking to see if there's a solution to this problem. It sucks when an application that's been running for 10 years mysteriously breaks after a silly browser update.

Posted in:

Feedback for this Weblog Entry


re: wwFtp and WinInet Problems with IE 11



Bernie Murciano
December 04, 2013

Hi Rick:

I tried the ftpsendfileex2 and is not working for me, consistently it fails when sending more than 3 files. Errors starting to occur when windows was updated a few days ago. Do you have any other recommendations

re: wwFtp and WinInet Problems with IE 11



Gilles LAJOT-SARTHOU
December 05, 2013

Hello Rick,

The problem with IE11 is also for wwHTTP, not only for wwFTP.

I resolve it, by removing the IE11 update.

Best regards

re: wwFtp and WinInet Problems with IE 11



ScottM
December 05, 2013

I am using libCurl. If anyone need help with vfp and libcurl, let me know at scott (at) nemrc (dot) com.

re: wwFtp and WinInet Problems with IE 11



Rick Strahl
December 06, 2013

@Lajot - I don't think there are any issues with HTTP. I have HTTP functionality in many Fox applications using wwHttp and it works just fine.

Make sure you have a recent version of wwHttp and you have the appropriate connection flags set.

+++ Rick ---

re: wwFtp and WinInet Problems with IE 11



Bernie Murciano
December 06, 2013

Rick ,can you comment on my original message.

ftpsendfileex2 doesn't fix it. Do you have other alternatives while waiting on Microsoft

re: wwFtp and WinInet Problems with IE 11



Fernando Suárez García
December 16, 2013

For testing I have done, just by disconnecting and reconnecting solves the problema. It's appears as then only efective workarround.

re: wwFtp and WinInet Problems with IE 11



Larry Newtwon
December 19, 2013

Yeah, after spending last night and this morning testing it, I came to the same conclusion. After 3/4 files, the next one would hang and put a small 4K piece of garbage on the FTP site. This is what happens when we use software that is based on Microsoft. I didn't make that mistake with my email package. In any event, the fix was 10 seconds of cutting and pasting the ftpconnect command to the bottom of the loop and executing it everytime I send a file.

re: wwFtp and WinInet Problems with IE 11



Dominik Feckter
January 29, 2014

After Upload the first Artikle-Image i get the ErrorNo 12003, with Errortext. "226 Transfer OK".

FTP-Protokoll after the first Connection: (000005)29.01.2014 10:46:53 - (not logged in) (192.168.2.25)> Connected, sending welcome message... (000005)29.01.2014 10:46:53 - (not logged in) (192.168.2.25)> 220-FileZilla Server version 0.9.41 beta (000005)29.01.2014 10:46:53 - (not logged in) (192.168.2.25)> 220-written by Tim Kosse (Tim.Kosse@gmx.de) (000005)29.01.2014 10:46:53 - (not logged in) (192.168.2.25)> 220 Please visit http://sourceforge.net/projects/filezilla/ (000005)29.01.2014 10:46:53 - (not logged in) (192.168.2.25)> USER test1 (000005)29.01.2014 10:46:53 - (not logged in) (192.168.2.25)> 331 Password required for test1 (000005)29.01.2014 10:46:53 - (not logged in) (192.168.2.25)> PASS **** (000005)29.01.2014 10:46:53 - test1 (192.168.2.25)> 230 Logged on (000005)29.01.2014 10:46:53 - test1 (192.168.2.25)> TYPE A (000005)29.01.2014 10:46:53 - test1 (192.168.2.25)> 200 Type set to A (000005)29.01.2014 10:46:53 - test1 (192.168.2.25)> PASV (000005)29.01.2014 10:46:53 - test1 (192.168.2.25)> 227 Entering Passive Mode (192,168,2,26,223,241) (000005)29.01.2014 10:46:53 - test1 (192.168.2.25)> LIST (000005)29.01.2014 10:46:53 - test1 (192.168.2.25)> 150 Connection accepted (000005)29.01.2014 10:46:53 - test1 (192.168.2.25)> 226 Transfer OK (000005)29.01.2014 10:46:53 - test1 (192.168.2.25)> TYPE A (000005)29.01.2014 10:46:53 - test1 (192.168.2.25)> 200 Type set to A (000005)29.01.2014 10:46:53 - test1 (192.168.2.25)> PASV (000005)29.01.2014 10:46:53 - test1 (192.168.2.25)> 227 Entering Passive Mode (192,168,2,26,223,242) (000005)29.01.2014 10:46:53 - test1 (192.168.2.25)> LIST (000005)29.01.2014 10:46:53 - test1 (192.168.2.25)> 150 Connection accepted

"150 Connection accepted"

The solution for me is to open the FTP-Connection 2 Times before Uploading, then it works.

After the Second Connection the FTP has the Status:

"150 Opening data channel for file transfer."

THISFORM.lConnected=.F.

LOCAL cUrl m.cUrl=thisform.curl

THIS.oFtp.lPassiveFTP=.T. THISFORM.nFtperror=THIS.oFtp.FtpConnect(ALLTRIM(m.cUrl), ALLTRIM(THISFORM.cBenutzer),ALLTRIM(THISFORM.cPassword)) IF THISFORM.nFtperror<>0 THIS.oFtp.lPassiveFTP=.F. THIS.writelog(THISFORM.cpath+"Artikel\FTP_Upload.log",DTOC(DATE())+" "+TIME()+"Verbindungsfehler "+ALLTRIM(STR(Thisform.nFtpError,10,0))) THISFORM.nFtperror=THIS.oFtp.FtpConnect(THISFORM.cUrl, ALLTRIM(THISFORM.cBenutzer),ALLTRIM(THISFORM.cPassword))

ENDIF IF THIS.nFtperror=0 THISFORM.lConnected=.T. RETURN 0 ENDIF RETURN 1

 
© Rick Strahl, West Wind Technologies, 2003 - 2024