private static void GetPathInfo(GetPathOption pathOption, Uri uri, out string path, out string directory, out string filename) { path = uri.GetComponents(UriComponents.Path, UriFormat.Unescaped); int num = path.LastIndexOf('/'); if (((pathOption == GetPathOption.AssumeFilename) && (num != -1)) && (num == (path.Length - 1))) { path = path.Substring(0, path.Length - 1); num = path.LastIndexOf('/'); } if (pathOption == GetPathOption.AssumeNoFilename) { directory = path; filename = string.Empty; } else { directory = path.Substring(0, num + 1); filename = path.Substring(num + 1, path.Length - (num + 1)); } if ((directory.Length > 1) && (directory[directory.Length - 1] == '/')) { directory = directory.Substring(0, directory.Length - 1); } }
/// <summary> /// <para>Gets the path component of the Uri</para> /// </summary> private static void GetPathInfo(GetPathOption pathOption, Uri uri, out string path, out string directory, out string filename) { path = uri.GetComponents(UriComponents.Path, UriFormat.Unescaped); int index = path.LastIndexOf('/'); if (pathOption == GetPathOption.AssumeFilename && index != -1 && index == path.Length - 1) { // Remove last '/' and continue normal processing path = path.Substring(0, path.Length - 1); index = path.LastIndexOf('/'); } // split path into directory and filename if (pathOption == GetPathOption.AssumeNoFilename) { directory = path; filename = string.Empty; } else { directory = path.Substring(0, index + 1); filename = path.Substring(index + 1, path.Length - (index + 1)); } // strip off trailing '/' on directory if present if (directory.Length > 1 && directory[directory.Length - 1] == '/') { directory = directory.Substring(0, directory.Length - 1); } }
/// <summary> /// <para>Creates an array of commands, that will be sent to the server</para> /// </summary> protected override PipelineEntry[] BuildCommandsList(WebRequest req) { bool resetLoggedInState = false; FtpWebRequest request = (FtpWebRequest)req; if (NetEventSource.IsEnabled) { NetEventSource.Info(this); } _responseUri = request.RequestUri; ArrayList commandList = new ArrayList(); if (request.EnableSsl && !UsingSecureStream) { commandList.Add(new PipelineEntry(FormatFtpCommand("AUTH", "TLS"))); // According to RFC we need to re-authorize with USER/PASS after we re-authenticate. resetLoggedInState = true; } if (resetLoggedInState) { _loginDirectory = null; _establishedServerDirectory = null; _requestedServerDirectory = null; _currentTypeSetting = string.Empty; if (_loginState == FtpLoginState.LoggedIn) { _loginState = FtpLoginState.LoggedInButNeedsRelogin; } } if (_loginState != FtpLoginState.LoggedIn) { Credentials = request.Credentials.GetCredential(request.RequestUri, "basic"); _welcomeMessage = new StringBuilder(); _exitMessage = new StringBuilder(); string domainUserName = string.Empty; string password = string.Empty; if (Credentials != null) { domainUserName = Credentials.UserName; string domain = Credentials.Domain; if (!string.IsNullOrEmpty(domain)) { domainUserName = domain + "\\" + domainUserName; } password = Credentials.Password; } if (domainUserName.Length == 0 && password.Length == 0) { domainUserName = "******"; password = "******"; } commandList.Add(new PipelineEntry(FormatFtpCommand("USER", domainUserName))); commandList.Add(new PipelineEntry(FormatFtpCommand("PASS", password), PipelineEntryFlags.DontLogParameter)); // If SSL, always configure data channel encryption after authentication to maximum RFC compatibility. The RFC allows for // PBSZ/PROT commands to come either before or after the USER/PASS, but some servers require USER/PASS immediately after // the AUTH TLS command. if (request.EnableSsl && !UsingSecureStream) { commandList.Add(new PipelineEntry(FormatFtpCommand("PBSZ", "0"))); commandList.Add(new PipelineEntry(FormatFtpCommand("PROT", "P"))); } commandList.Add(new PipelineEntry(FormatFtpCommand("OPTS", "utf8 on"))); commandList.Add(new PipelineEntry(FormatFtpCommand("PWD", null))); } GetPathOption getPathOption = GetPathOption.Normal; if (request.MethodInfo.HasFlag(FtpMethodFlags.DoesNotTakeParameter)) { getPathOption = GetPathOption.AssumeNoFilename; } else if (request.MethodInfo.HasFlag(FtpMethodFlags.ParameterIsDirectory)) { getPathOption = GetPathOption.AssumeFilename; } string requestPath; string requestDirectory; string requestFilename; GetPathInfo(getPathOption, request.RequestUri, out requestPath, out requestDirectory, out requestFilename); if (requestFilename.Length == 0 && request.MethodInfo.HasFlag(FtpMethodFlags.TakesParameter)) { throw new WebException(SR.net_ftp_invalid_uri); } // We optimize for having the current working directory staying at the login directory. This ensure that // our relative paths work right and reduces unnecessary CWD commands. // Usually, we don't change the working directory except for some FTP commands. If necessary, // we need to reset our working directory back to the login directory. if (_establishedServerDirectory != null && _loginDirectory != null && _establishedServerDirectory != _loginDirectory) { commandList.Add(new PipelineEntry(FormatFtpCommand("CWD", _loginDirectory), PipelineEntryFlags.UserCommand)); _requestedServerDirectory = _loginDirectory; } // For most commands, we don't need to navigate to the directory since we pass in the full // path as part of the FTP protocol command. However, some commands require it. if (request.MethodInfo.HasFlag(FtpMethodFlags.MustChangeWorkingDirectoryToPath) && requestDirectory.Length > 0) { commandList.Add(new PipelineEntry(FormatFtpCommand("CWD", requestDirectory), PipelineEntryFlags.UserCommand)); _requestedServerDirectory = requestDirectory; } if (!request.MethodInfo.IsCommandOnly) { string requestedTypeSetting = request.UseBinary ? "I" : "A"; if (_currentTypeSetting != requestedTypeSetting) { commandList.Add(new PipelineEntry(FormatFtpCommand("TYPE", requestedTypeSetting))); _currentTypeSetting = requestedTypeSetting; } if (request.UsePassive) { string passiveCommand = (ServerAddress.AddressFamily == AddressFamily.InterNetwork) ? "PASV" : "EPSV"; commandList.Add(new PipelineEntry(FormatFtpCommand(passiveCommand, null), PipelineEntryFlags.CreateDataConnection)); } else { string portCommand = (ServerAddress.AddressFamily == AddressFamily.InterNetwork) ? "PORT" : "EPRT"; CreateFtpListenerSocket(request); commandList.Add(new PipelineEntry(FormatFtpCommand(portCommand, GetPortCommandLine(request)))); } if (request.ContentOffset > 0) { // REST command must always be the last sent before the main file command is sent. commandList.Add(new PipelineEntry(FormatFtpCommand("REST", request.ContentOffset.ToString(CultureInfo.InvariantCulture)))); } } PipelineEntryFlags flags = PipelineEntryFlags.UserCommand; if (!request.MethodInfo.IsCommandOnly) { flags |= PipelineEntryFlags.GiveDataStream; if (!request.UsePassive) { flags |= PipelineEntryFlags.CreateDataConnection; } } if (request.MethodInfo.Operation == FtpOperation.Rename) { string baseDir = (requestDirectory == string.Empty) ? string.Empty : requestDirectory + "/"; commandList.Add(new PipelineEntry(FormatFtpCommand("RNFR", baseDir + requestFilename), flags)); string renameTo; if (!string.IsNullOrEmpty(request.RenameTo) && request.RenameTo.StartsWith("/", StringComparison.OrdinalIgnoreCase)) { renameTo = request.RenameTo; // Absolute path } else { renameTo = baseDir + request.RenameTo; // Relative path } commandList.Add(new PipelineEntry(FormatFtpCommand("RNTO", renameTo), flags)); } else if (request.MethodInfo.HasFlag(FtpMethodFlags.DoesNotTakeParameter)) { commandList.Add(new PipelineEntry(FormatFtpCommand(request.Method, string.Empty), flags)); } else if (request.MethodInfo.HasFlag(FtpMethodFlags.MustChangeWorkingDirectoryToPath)) { commandList.Add(new PipelineEntry(FormatFtpCommand(request.Method, requestFilename), flags)); } else { commandList.Add(new PipelineEntry(FormatFtpCommand(request.Method, requestPath), flags)); } commandList.Add(new PipelineEntry(FormatFtpCommand("QUIT", null))); return((PipelineEntry[])commandList.ToArray(typeof(PipelineEntry))); }
/// <summary> /// <para>Gets the path component of the Uri</para> /// </summary> private static void GetPathInfo(GetPathOption pathOption, Uri uri, out string path, out string directory, out string filename) { path = uri.GetComponents(UriComponents.Path, UriFormat.Unescaped); int index = path.LastIndexOf('/'); if (pathOption == GetPathOption.AssumeFilename && index != -1 && index == path.Length - 1) { // Remove last '/' and continue normal processing path = path.Substring(0, path.Length - 1); index = path.LastIndexOf('/'); } // split path into directory and filename if (pathOption == GetPathOption.AssumeNoFilename) { directory = path; filename = string.Empty; } else { directory = path.Substring(0, index + 1); filename = path.Substring(index + 1, path.Length - (index + 1)); } // strip off trailing '/' on directory if present if (directory.Length > 1 && directory[directory.Length - 1] == '/') directory = directory.Substring(0, directory.Length - 1); }
protected override CommandStream.PipelineEntry[] BuildCommandsList(WebRequest req) { string str3; string str4; string str5; bool flag = false; FtpWebRequest request = (FtpWebRequest)req; this.m_ResponseUri = request.RequestUri; ArrayList list = new ArrayList(); if (request.EnableSsl && !base.UsingSecureStream) { list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("AUTH", "TLS"))); flag = true; } if (flag) { this.m_LoginDirectory = null; this.m_EstablishedServerDirectory = null; this.m_RequestedServerDirectory = null; this.m_CurrentTypeSetting = string.Empty; if (this.m_LoginState == FtpLoginState.LoggedIn) { this.m_LoginState = FtpLoginState.LoggedInButNeedsRelogin; } } if (this.m_LoginState != FtpLoginState.LoggedIn) { this.Credentials = request.Credentials.GetCredential(request.RequestUri, "basic"); this.m_WelcomeMessage = new StringBuilder(); this.m_ExitMessage = new StringBuilder(); string parameter = string.Empty; string password = string.Empty; if (this.Credentials != null) { parameter = this.Credentials.InternalGetDomainUserName(); password = this.Credentials.InternalGetPassword(); } if ((parameter.Length == 0) && (password.Length == 0)) { parameter = "anonymous"; password = "******"; } list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("USER", parameter))); list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("PASS", password), CommandStream.PipelineEntryFlags.DontLogParameter)); if (request.EnableSsl && !base.UsingSecureStream) { list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("PBSZ", "0"))); list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("PROT", "P"))); } list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("OPTS", "utf8 on"))); list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("PWD", null))); } GetPathOption normal = GetPathOption.Normal; if (request.MethodInfo.HasFlag(FtpMethodFlags.DoesNotTakeParameter)) { normal = GetPathOption.AssumeNoFilename; } else if (request.MethodInfo.HasFlag(FtpMethodFlags.ParameterIsDirectory)) { normal = GetPathOption.AssumeFilename; } GetPathInfo(normal, request.RequestUri, out str3, out str4, out str5); if ((str5.Length == 0) && request.MethodInfo.HasFlag(FtpMethodFlags.TakesParameter)) { throw new WebException(SR.GetString("net_ftp_invalid_uri")); } if (((this.m_EstablishedServerDirectory != null) && (this.m_LoginDirectory != null)) && (this.m_EstablishedServerDirectory != this.m_LoginDirectory)) { list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("CWD", this.m_LoginDirectory), CommandStream.PipelineEntryFlags.UserCommand)); this.m_RequestedServerDirectory = this.m_LoginDirectory; } if (request.MethodInfo.HasFlag(FtpMethodFlags.MustChangeWorkingDirectoryToPath) && (str4.Length > 0)) { list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("CWD", str4), CommandStream.PipelineEntryFlags.UserCommand)); this.m_RequestedServerDirectory = str4; } if (((request.CacheProtocol != null) && (request.CacheProtocol.ProtocolStatus == CacheValidationStatus.DoNotTakeFromCache)) && (request.MethodInfo.Operation == FtpOperation.DownloadFile)) { list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("MDTM", str3))); } if (!request.MethodInfo.IsCommandOnly) { if ((request.CacheProtocol == null) || (request.CacheProtocol.ProtocolStatus != CacheValidationStatus.Continue)) { string str6 = request.UseBinary ? "I" : "A"; if (this.m_CurrentTypeSetting != str6) { list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("TYPE", str6))); this.m_CurrentTypeSetting = str6; } if (request.UsePassive) { string command = (base.ServerAddress.AddressFamily == AddressFamily.InterNetwork) ? "PASV" : "EPSV"; list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand(command, null), CommandStream.PipelineEntryFlags.CreateDataConnection)); } else { string str8 = (base.ServerAddress.AddressFamily == AddressFamily.InterNetwork) ? "PORT" : "EPRT"; this.CreateFtpListenerSocket(request); list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand(str8, this.GetPortCommandLine(request)))); } if ((request.CacheProtocol != null) && (request.CacheProtocol.ProtocolStatus == CacheValidationStatus.CombineCachedAndServerResponse)) { if (request.CacheProtocol.Validator.CacheEntry.StreamSize > 0L) { list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("REST", request.CacheProtocol.Validator.CacheEntry.StreamSize.ToString(CultureInfo.InvariantCulture)))); } } else if (request.ContentOffset > 0L) { list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("REST", request.ContentOffset.ToString(CultureInfo.InvariantCulture)))); } } else { list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("SIZE", str3))); list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("MDTM", str3))); } } if ((request.CacheProtocol == null) || (request.CacheProtocol.ProtocolStatus != CacheValidationStatus.Continue)) { CommandStream.PipelineEntryFlags userCommand = CommandStream.PipelineEntryFlags.UserCommand; if (!request.MethodInfo.IsCommandOnly) { userCommand |= CommandStream.PipelineEntryFlags.GiveDataStream; if (!request.UsePassive) { userCommand |= CommandStream.PipelineEntryFlags.CreateDataConnection; } } if (request.MethodInfo.Operation == FtpOperation.Rename) { list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("RNFR", str4 + "/" + str5), userCommand)); list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("RNTO", str4 + "/" + request.RenameTo), userCommand)); } else if (request.MethodInfo.HasFlag(FtpMethodFlags.DoesNotTakeParameter)) { list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand(request.Method, string.Empty), userCommand)); } else if (request.MethodInfo.HasFlag(FtpMethodFlags.MustChangeWorkingDirectoryToPath)) { list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand(request.Method, str5), userCommand)); } else { list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand(request.Method, str3), userCommand)); } if (!request.KeepAlive) { list.Add(new CommandStream.PipelineEntry(this.FormatFtpCommand("QUIT", null))); } } return((CommandStream.PipelineEntry[])list.ToArray(typeof(CommandStream.PipelineEntry))); }
/// <summary> /// <para>Gets the path componet of the Uri</para> /// </summary> private static void GetPathAndFilename(GetPathOption pathOption, Uri uri, ref string path, ref string filename, ref bool isRoot) { string tempPath = uri.GetParts( UriComponents.Path|UriComponents.KeepDelimiter, UriFormat.Unescaped); isRoot = false; if (tempPath.StartsWith("//")) { isRoot = true; tempPath = tempPath.Substring(1, tempPath.Length-1); } int index = tempPath.LastIndexOf('/'); switch (pathOption) { case GetPathOption.AssumeFilename: if (index != -1 && index == tempPath.Length-1) { // Remove last '/' and continue normal processing tempPath = tempPath.Substring(0, tempPath.Length-1); index = tempPath.LastIndexOf('/'); } path = tempPath.Substring(0, index+1); filename = tempPath.Substring(index+1, tempPath.Length-(index+1)); break; case GetPathOption.AssumeNoFilename: path = tempPath; filename = ""; break; case GetPathOption.Normal: default: path = tempPath.Substring(0, index+1); filename = tempPath.Substring(index+1, tempPath.Length-(index+1)); break; } if (path.Length == 0) path = "/"; }