Je viens de tester cela sur un de nos serveurs dev et même il y a une encéphalopathie des cervidés émis par le FtpWebRequest .NET:
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)
Ce fut sans même préciser «/» dans le uri lors de la création de l'objet FtpWebRequest .
Si vous déboguez ou parcourez le code source, une classe appelée 'FtpControlStream' entre en jeu. Voir la pile d'appels:
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#
Il y a une méthode nommée BuildCommandsList() qui est invoquée. BuildCommandsList() construit une liste de commandes à envoyer au serveur FTP. Cette méthode a l'extrait de code suivant:
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));
}
Lors de la première connexion au m_PreviousServerPath du serveur est toujours nulle, la valeur de newServerPath est «/» et est calculée par une fonction nommée GetPathAndFileName() (invoqué quelques lignes antérieures à ce bloc de code). GetPathAndFileName() calcule newServerPath en tant que "/" si aucun chemin n'est fourni ou si "/" est explicitement ajouté à la fin de l'uri 'ftp: // ....'. Par conséquent, cela finit par entraîner l'ajout de la commande CWD au pipeline de commandes, car null! = "/".
En résumé, vous ne pouvez pas remplacer ce comportement car il est gravé dans la source.