对于大多数 FTP 函数,IE 11 中的 wininet 随机返回错误 12003

Posted

技术标签:

【中文标题】对于大多数 FTP 函数,IE 11 中的 wininet 随机返回错误 12003【英文标题】:wininet from IE 11 randomly returns error 12003 for most FTP functions 【发布时间】:2013-10-30 13:15:16 【问题描述】:

我们有一段代码可以在 ftp 服务器上上传/下载和列出文件。它使用 WinInet 来处理 FTP 命令。它已经工作了好几年了。但是,在 Windows 8.1 和带有 IE 11 的 Windows 7 中,相同的代码有时会返回错误 12003。ftp 服务器日志中没有错误。

简单函数用于检查 FTP 响应是否有错误

bool IsLastErrorReallyAnError()

 int err = GetLastError();

 bool isError = true;

 if (err == ERROR_INTERNET_EXTENDED_ERROR)
 
     isError = false;
     DWORD error, size = 0;
    ::InternetGetLastResponseInfo(&error, NULL, &size);
    std::vector<wchar_t> response(size+1);
    ::InternetGetLastResponseInfo(&error, &response[0], &size);

    utils::trace("Backup", "Checking FTP respose", &response[0]);

    std::vector<std::wstring> lines;
    boost::split(lines, std::wstring(&response[0]), boost::is_any_of(L"\n"));

    for (auto it = lines.cbegin(); it != lines.cend(); ++it)
    
        // If some response starts with 5хх then it is real error
        if (boost::starts_with(*it,L"5"))
        
            utils::trace("Backup", "Real FTP error", &((*it)[0]));
            isError = true;
            break;
        
    

    if (!isError)
    
        utils::trace("Backup", "Checking FTP respose ", L"false error!");
    
 

 return isError;

在我们的程序日志中,我们得到

05:56:43.680    0x21c   ERR CFtpFileSystem  CFtpFileSystem::TryOpenBinaryFile: FtpOpenFileW error 12003
05:56:43.680    0x21c   INF Backup  Checking FTP respose: 226 Transfer OK
200 Type set to I

05:56:43.680    0x21c   INF Backup  Checking FTP respose : false error!

在 FTP 服务器日志中(它有不同的时区):

(000445)30.10.2013 16:56:23 - (not logged in) (10.16.83.3)> Connected, sending welcome message...
(000445)30.10.2013 16:56:23 - (not logged in) (10.16.83.3)> 220-FileZilla Server version 0.9.41 beta
(000445)30.10.2013 16:56:23 - (not logged in) (10.16.83.3)> 220-written by Tim Kosse (Tim.Kosse@gmx.de)
(000445)30.10.2013 16:56:23 - (not logged in) (10.16.83.3)> 220 Please visit http://sourceforge.net/projects/filezilla/
(000445)30.10.2013 16:56:29 - (not logged in) (10.16.83.3)> USER test
(000445)30.10.2013 16:56:29 - (not logged in) (10.16.83.3)> 331 Password required for test
(000445)30.10.2013 16:56:35 - (not logged in) (10.16.83.3)> PASS ****
(000445)30.10.2013 16:56:35 - test (10.16.83.3)> 230 Logged on
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> TYPE I
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> 200 Type set to I
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> PASV
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> 227 Entering Passive Mode (10,16,82,191,238,169)
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> STOR /srv-test/0f0c04cc-c323-4bb6-a814-696fbbd695c3/527101B9/ab42ed5a-7df0-4421-a03c-d9f75891dcbf
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> 150 Connection accepted
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> 226 Transfer OK
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> TYPE I
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> 200 Type set to I
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> PASV
(000445)30.10.2013 16:56:43 - test (10.16.83.3)> 227 Entering Passive Mode (10,16,82,191,238,170)
(000445)30.10.2013 16:56:56 - test (10.16.83.3)> disconnected.

任何想法如何调整 IE11 附带的 wininet 版本以消除此类错误?

【问题讨论】:

【参考方案1】:

很遗憾,您的代码中没有问题。

这是为数不多的情况之一,您实际上在刚刚发布的 IE 11 中包含的更新的 WinInet 中遇到了一个全新但主要的问题。它将破坏大多数使用 Microsoft 的 Win 7/8 FTP 类的 FTP 应用程序升级的用户。 我建议您将自己添加到此错误报告中: https://connect.microsoft.com/IE/feedback/details/808279/ftpopenfile-and-internetwritefile-broken-changed-in-ie11 希望能给微软灌输一些紧迫感。

详情

根本问题似乎是 WinInet 依赖于特定服务器响应的任何 FTP 交互。它将在 FTP 会话中第一次工作,但在那之后,WinInet 总是落后于一个响应 - 因此永远不会看到它需要处理后续请求的正确响应代码。

示例

PASV 模式 STOR 需要 WinInet 解析开放数据端口的服务器响应。如果使用 FtpOpenFile(),第二次上传将失败(尽管 FtpPutFile 似乎可以工作,并且可能是 PORT 模式)。

相关问题

除了第一个 FtpRename 失败之外,还有其他报告 - 因为在 RNFR 片段之后,WinInet 在发送 RNTO 片段之前等待特定响应。当 WinInet 落后时,它永远不会看到 PREVIOUS 服务器响应代码,也永远不会看到它正在等待的必要服务器响应代码(尽管跟踪确认服务器确实发送了它)。

如何复制

这可以通过在每次 FTP API 调用后使用 InternetGetLastResponseInfo() 来观察。在使用 FtpOpenFile() 或第一次重命名首次 PASV 上传后,所有后续 FTP API 调用都将显示服务器对 PRECEDING FTP API 调用的响应。

(PS:我以为我昨天已经指出了这个错误 - 当问题出现时,每个人都试图“修复”他们自己的代码毫无意义。但不知何故,信息会在第二天消失。希望人们能找到关于其他使用 Google 的网站。)

【讨论】:

【参考方案2】:

我通过动态加载我在 SxS 文件夹中找到的旧版本 DLL 解决了这个问题。

【讨论】:

以上是关于对于大多数 FTP 函数,IE 11 中的 wininet 随机返回错误 12003的主要内容,如果未能解决你的问题,请参考以下文章

win7系统如何卸载自带的IE11,安装IE8?

在win2008 R2 服务器中搭建好了ftp服务器,通过IE访问,提示输入用户名和密码

IE 11 错误 - 访问被拒绝 - XMLHttpRequest

Windows7系统如果安装&升级IE11浏览器

如何解决swiper3无法在ie9中运行的bug

win7旗舰版 无法卸载掉IE11,每次卸载都有这个问题,求解