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);
            }
        }
示例#2
0
        /// <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);
            }
        }
示例#3
0
        /// <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)));
        }
示例#4
0
        /// <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 = "/";
        }
 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);
     }
 }