来自IE 11的wininet随机返回大多数FTP功能的错误12003

时间:2013-10-30 13:15:17

标签: ftp wininet internet-explorer-11

我们有一段代码可以在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版本以摆脱这些错误?

2 个答案:

答案 0 :(得分:6)

不幸的是, 代码中没有问题。

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

<强>详情

基础问题似乎是任何FTP交互,其中WinInet依赖于特定的服务器响应。它将在第一次在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的其他网站。)

答案 1 :(得分:0)

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