禁用 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# - 使用散列密码验证用户的流程?

C# 如何创建一个类来存储来自文本框的字符串值

C# SQL命令获取某个元素出现在xml索引中的计数

c# - ASP.NET 5 MVC 6 : How to configure startup to send a html file when not on any mvc route

php - 就整体执行速度而言,哪个更快

python - 从 FTP 服务器上的 gz 文件检索数据,而不将其写入本地

python - 在 python 中通过数据库正确调用和使用 Linux find

c# - 如何从 "traditional"过渡到响应式(Reactive) MVVM

java - URLConnection FTP 列表文件

excel - 从 FTP 站点获取最新文件的批处理/宏代码