Acabo de probar esto en uno de nuestros servidores dev y de hecho hay una caquexia crónica emitido por el .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
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)
Este fue sin siquiera especificar '/' en el URI al crear el objeto FtpWebRequest .
Si depura o explora el código fuente, entra en juego una clase llamada 'FtpControlStream'. Ver la pila de llamadas:
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#
Hay un método llamado BuildCommandsList() que se invoca. BuildCommandsList() crea una lista de comandos para enviar al servidor FTP. Este método tiene el siguiente fragmento de código:
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));
}
Tras la primera conexión a la m_PreviousServerPath servidor siempre es nulo, el valor de newServerPath es "/" y se calcula mediante una función llamada GetPathAndFileName() (invocado unos pocos líneas antes de este bloque de código). GetPathAndFileName() calcula newServerPath como "/" si no se proporciona ninguna ruta o si "/" está explícitamente añadido al final de la URL 'ftp: // ....'.
Por lo tanto, esto hace que, por supuesto, el comando CWD se agregue a la canalización de comandos porque null! = "/".
En pocas palabras, desafortunadamente no puede anular este comportamiento porque está grabado en la fuente.