Я только что проверил это на одном из наших серверов разработки, и действительно. CWD выпущен .NET FtpWebRequest:
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
<strong>testuser, 257 "/" is current directory.
testuser, CWD /
testuser, change directory '/' -> 'D:\testfolder' --> Access allowed.
testuser, 250 CWD command successful. "/" is current directory.</strong>
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)
Это было даже без указания '/' в URI при создании объекта FtpWebRequest.
Если вы отлаживаете или просматриваете исходный код, в игру вступает класс с именем 'FtpControlStream'. Смотрите стек вызовов:
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#
Есть метод с именем BuildCommandsList (), который вызывается. BuildCommandsList () создает список команд для отправки на FTP-сервер. Этот метод имеет следующий фрагмент кода:
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 всегда равно нулю, значение newServerPath равно "/" и вычисляется функцией с именем GetPathAndFileName () (вызывается за несколько строк до этого блока кода). GetPathAndFileName () вычисляет newServerPath как "/", если путь не указан или если "/" явно прикреплено в конце строки 'ftp: // ....'.
Так что это, конечно, в конечном итоге приводит к добавлению команды CWD в конвейер команд, потому что null! = "/".
В двух словах, к сожалению, вы не можете переопределить это поведение, потому что оно записано в источнике.