禁用 CD 的 C# FTP

标签 c# ftp

我正在尝试使以下代码正常工作:

  string url = String.Format(@"SOMEURL");
  string user = "SOMEUSER";
  string password = "SOMEPASSWORD";

  FtpWebRequest ftpclientRequest = (FtpWebRequest)WebRequest.Create(new Uri(url));
  ftpclientRequest.Method = WebRequestMethods.Ftp.ListDirectory;
  ftpclientRequest.UsePassive = true; 
  ftpclientRequest.Proxy = null;
  ftpclientRequest.Credentials = new NetworkCredential(user, password);
  FtpWebResponse response = ftpclientRequest.GetResponse() as FtpWebResponse;

这通常有效,但对于 1 个特定服务器,这会给出错误 500:无法识别语法。 Change Directory 命令在问题服务器上被禁用,站点管理员告诉我 .NET 默认情况下对所有 FTP 连接发出 Change Directory 命令。真的吗?有没有办法禁用它?
编辑:当我从命令行登录时,我在正确的目录中:
FTP>密码
257 “/”为当前目录

最佳答案

我刚刚在我们的一个开发服务器上对此进行了测试,确实有一个由 .NET FtpWebRequest 发出的 CWD:

new connection from 172.16.3.210 on 172.16.3.210:21 (Explicit SSL)
hostname resolved : devpc
sending welcome message.
220 Gene6 FTP Server v3.10.0 (Build 2) ready...
USER testuser
testuser, 331 Password required for testuser.
testuser, PASS ****
testuser, logged in as "testuser".
testuser, 230 User testuser logged in.
testuser, OPTS utf8 on
testuser, 501 Please CLNT first.
testuser, PWD
testuser, 257 "/" is current directory.
testuser, CWD /
testuser, change directory '/' -> 'D:\testfolder' --> Access allowed.
testuser, 250 CWD command successful. "/" is current directory.
testuser, TYPE I
testuser, 200 Type set to I.
testuser, PORT 172,16,3,210,4,127
testuser, 200 Port command successful.
testuser, NLST
testuser, 150 Opening data connection for directory list.
testuser, 226 Transfer ok.
testuser, 421 Connection closed, timed out.
testuser, disconnected. (00d00:05:01)

This was without even specifying '/' in the uri when creating the FtpWebRequest object.

If you debug or browse the source code, a class called 'FtpControlStream' comes into play. See call stack:

System.dll!System.Net.FtpControlStream.BuildCommandsList(System.Net.WebRequest req) Line 555    C#
System.dll!System.Net.CommandStream.SubmitRequest(System.Net.WebRequest request = 
    {System.Net.FtpWebRequest}, bool async = false, bool readInitalResponseOnConnect = true) Line 143   C#
System.dll!System.Net.FtpWebRequest.TimedSubmitRequestHelper(bool async) Line 1122 + 0x13 bytes C#
System.dll!System.Net.FtpWebRequest.SubmitRequest(bool async = false) Line 1042 + 0xc bytes C#
System.dll!System.Net.FtpWebRequest.GetResponse() Line 649  C#

There's a method named BuildCommandsList() which is invoked. BuildCommandsList() builds a list of commands to send to the FTP server. This method has the following snippet of code:

if (m_PreviousServerPath != newServerPath) { 
    if (!m_IsRootPath
        && m_LoginState == FtpLoginState.LoggedIn
        && m_LoginDirectory != null)
    { 
        newServerPath = m_LoginDirectory+newServerPath;
    } 
    m_NewServerPath = newServerPath; 

    commandList.Add(new PipelineEntry(FormatFtpCommand("CWD", newServerPath), PipelineEntryFlags.UserCommand)); 
}

在第一次连接到服务器时,m_PreviousServerPath 始终为 null,newServerPath 的值为“/”,并由名为 GetPathAndFileName() 的函数计算(在此代码块之前调用几行)。如果未提供路径或如果“/”明确附加在“ftp://....”uri 的末尾,则 GetPathAndFileName() 将 newServerPath 计算为“/”。

所以这当然最终会导致 CWD 命令被添加到命令管道中,因为 null != "/"。

简而言之,不幸的是你不能覆盖这个行为,因为它在源代码中被烧毁了。

关于禁用 CD 的 C# FTP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/201436/

相关文章:

c# - 将正则表达式转换为 htmlagilitypack

python - 在 Python 中从 FTP 服务器读取文件到 DataFrame

linux - SFTP 连接问题与密码

ftp - 在 Linux 中使用 FTP(唯一选项)通过单行命令同步目录中的文件

c# - 需要在c#中按键和值交叉2个字典

c# - 网页浏览器执行流程

c# - 在while循环中替代线程 sleep

C# - Windows ACL - 应用继承权限

Python和ftplib,无法登录?

python - Pandas 在 Python 3 中从安全的 FTP 服务器读取数据