using System; using System.Collections.Generic; using System.IO; using System.Net.Cache; using System.Net.Security; using System.Net.Sockets; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading; namespace System.Net { /// Implements a File Transfer Protocol (FTP) client. // Token: 0x02000222 RID: 546 public sealed class FtpWebRequest : WebRequest { // Token: 0x060012A7 RID: 4775 RVA: 0x00038490 File Offset: 0x00036690 internal FtpWebRequest(global::System.Uri uri) { this.requestUri = uri; this.proxy = GlobalProxySelection.Select; } // Token: 0x060012A9 RID: 4777 RVA: 0x0003859C File Offset: 0x0003679C private static Exception GetMustImplement() { return new NotImplementedException(); } /// Gets the certificates used for establishing an encrypted connection to the FTP server. /// An object that contains the client certificates. // Token: 0x1700060F RID: 1551 // (get) Token: 0x060012AA RID: 4778 RVA: 0x000385A4 File Offset: 0x000367A4 // (set) Token: 0x060012AB RID: 4779 RVA: 0x000385AC File Offset: 0x000367AC [global::System.MonoTODO] public global::System.Security.Cryptography.X509Certificates.X509CertificateCollection ClientCertificates { get { throw FtpWebRequest.GetMustImplement(); } set { throw FtpWebRequest.GetMustImplement(); } } /// Gets or sets the name of the connection group that contains the service point used to send the current request. /// A value that contains a connection group name. /// A new value was specified for this property for a request that is already in progress. // Token: 0x17000610 RID: 1552 // (get) Token: 0x060012AC RID: 4780 RVA: 0x000385B4 File Offset: 0x000367B4 // (set) Token: 0x060012AD RID: 4781 RVA: 0x000385BC File Offset: 0x000367BC [global::System.MonoTODO] public override string ConnectionGroupName { get { throw FtpWebRequest.GetMustImplement(); } set { throw FtpWebRequest.GetMustImplement(); } } /// Always throws a . /// Always throws a . /// Content type information is not supported for FTP. // Token: 0x17000611 RID: 1553 // (get) Token: 0x060012AE RID: 4782 RVA: 0x000385C4 File Offset: 0x000367C4 // (set) Token: 0x060012AF RID: 4783 RVA: 0x000385CC File Offset: 0x000367CC public override string ContentType { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } /// Gets or sets a value that is ignored by the class. /// An value that should be ignored. // Token: 0x17000612 RID: 1554 // (get) Token: 0x060012B0 RID: 4784 RVA: 0x000385D4 File Offset: 0x000367D4 // (set) Token: 0x060012B1 RID: 4785 RVA: 0x000385D8 File Offset: 0x000367D8 public override long ContentLength { get { return 0L; } set { } } /// Gets or sets a byte offset into the file being downloaded by this request. /// An instance that specifies the file offset, in bytes. The default value is zero. /// A new value was specified for this property for a request that is already in progress. /// The value specified for this property is less than zero. // Token: 0x17000613 RID: 1555 // (get) Token: 0x060012B2 RID: 4786 RVA: 0x000385DC File Offset: 0x000367DC // (set) Token: 0x060012B3 RID: 4787 RVA: 0x000385E4 File Offset: 0x000367E4 public long ContentOffset { get { return this.offset; } set { this.CheckRequestStarted(); if (value < 0L) { throw new ArgumentOutOfRangeException(); } this.offset = value; } } /// Gets or sets the credentials used to communicate with the FTP server. /// An instance; otherwise, null if the property has not been set. /// The value specified for a set operation is null. /// An of a type other than was specified for a set operation. /// A new value was specified for this property for a request that is already in progress. /// /// /// // Token: 0x17000614 RID: 1556 // (get) Token: 0x060012B4 RID: 4788 RVA: 0x00038604 File Offset: 0x00036804 // (set) Token: 0x060012B5 RID: 4789 RVA: 0x0003860C File Offset: 0x0003680C public override ICredentials Credentials { get { return this.credentials; } set { this.CheckRequestStarted(); if (value == null) { throw new ArgumentNullException(); } if (!(value is NetworkCredential)) { throw new ArgumentException(); } this.credentials = value as NetworkCredential; } } /// Defines the default cache policy for all FTP requests. /// A that defines the cache policy for FTP requests. /// The caller tried to set this property to null. // Token: 0x17000615 RID: 1557 // (get) Token: 0x060012B6 RID: 4790 RVA: 0x00038640 File Offset: 0x00036840 // (set) Token: 0x060012B7 RID: 4791 RVA: 0x00038648 File Offset: 0x00036848 [global::System.MonoTODO] public new static global::System.Net.Cache.RequestCachePolicy DefaultCachePolicy { get { throw FtpWebRequest.GetMustImplement(); } set { throw FtpWebRequest.GetMustImplement(); } } /// Gets or sets a that specifies that an SSL connection should be used. /// true if control and data transmissions are encrypted; otherwise, false. The default value is false. /// The connection to the FTP server has already been established. // Token: 0x17000616 RID: 1558 // (get) Token: 0x060012B8 RID: 4792 RVA: 0x00038650 File Offset: 0x00036850 // (set) Token: 0x060012B9 RID: 4793 RVA: 0x00038658 File Offset: 0x00036858 public bool EnableSsl { get { return this.enableSsl; } set { this.CheckRequestStarted(); this.enableSsl = value; } } /// Gets an empty object. /// An empty object. /// /// /// /// /// /// // Token: 0x17000617 RID: 1559 // (get) Token: 0x060012BA RID: 4794 RVA: 0x00038668 File Offset: 0x00036868 // (set) Token: 0x060012BB RID: 4795 RVA: 0x00038670 File Offset: 0x00036870 [global::System.MonoTODO] public override WebHeaderCollection Headers { get { throw FtpWebRequest.GetMustImplement(); } set { throw FtpWebRequest.GetMustImplement(); } } /// Gets or sets a value that specifies whether the control connection to the FTP server is closed after the request completes. /// true if the connection to the server should not be destroyed; otherwise, false. The default value is true. /// A new value was specified for this property for a request that is already in progress. // Token: 0x17000618 RID: 1560 // (get) Token: 0x060012BC RID: 4796 RVA: 0x00038678 File Offset: 0x00036878 // (set) Token: 0x060012BD RID: 4797 RVA: 0x00038680 File Offset: 0x00036880 [global::System.MonoTODO("We don't support KeepAlive = true")] public bool KeepAlive { get { return this.keepAlive; } set { this.CheckRequestStarted(); } } /// Gets or sets the command to send to the FTP server. /// A value that contains the FTP command to send to the server. The default value is . /// A new value was specified for this property for a request that is already in progress. /// The method is invalid.- or -The method is not supported.- or -Multiple methods were specified. // Token: 0x17000619 RID: 1561 // (get) Token: 0x060012BE RID: 4798 RVA: 0x00038688 File Offset: 0x00036888 // (set) Token: 0x060012BF RID: 4799 RVA: 0x00038690 File Offset: 0x00036890 public override string Method { get { return this.method; } set { this.CheckRequestStarted(); if (value == null) { throw new ArgumentNullException("Method string cannot be null"); } if (value.Length == 0 || Array.BinarySearch(FtpWebRequest.supportedCommands, value) < 0) { throw new ArgumentException("Method not supported", "value"); } this.method = value; } } /// Always throws a . /// Always throws a . /// Preauthentication is not supported for FTP. // Token: 0x1700061A RID: 1562 // (get) Token: 0x060012C0 RID: 4800 RVA: 0x000386E8 File Offset: 0x000368E8 // (set) Token: 0x060012C1 RID: 4801 RVA: 0x000386F0 File Offset: 0x000368F0 public override bool PreAuthenticate { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } } /// Gets or sets the proxy used to communicate with the FTP server. /// An instance responsible for communicating with the FTP server. /// This property cannot be set to null. /// A new value was specified for this property for a request that is already in progress. /// /// /// // Token: 0x1700061B RID: 1563 // (get) Token: 0x060012C2 RID: 4802 RVA: 0x000386F8 File Offset: 0x000368F8 // (set) Token: 0x060012C3 RID: 4803 RVA: 0x00038700 File Offset: 0x00036900 public override IWebProxy Proxy { get { return this.proxy; } set { this.CheckRequestStarted(); if (value == null) { throw new ArgumentNullException(); } this.proxy = value; } } /// Gets or sets a time-out when reading from or writing to a stream. /// The number of milliseconds before the reading or writing times out. The default value is 300,000 milliseconds (5 minutes). /// The request has already been sent. /// The value specified for a set operation is less than or equal to zero and is not equal to . // Token: 0x1700061C RID: 1564 // (get) Token: 0x060012C4 RID: 4804 RVA: 0x0003871C File Offset: 0x0003691C // (set) Token: 0x060012C5 RID: 4805 RVA: 0x00038724 File Offset: 0x00036924 public int ReadWriteTimeout { get { return this.rwTimeout; } set { this.CheckRequestStarted(); if (value < -1) { throw new ArgumentOutOfRangeException(); } this.rwTimeout = value; } } /// Gets or sets the new name of a file being renamed. /// The new name of the file being renamed. // Token: 0x1700061D RID: 1565 // (get) Token: 0x060012C6 RID: 4806 RVA: 0x00038740 File Offset: 0x00036940 // (set) Token: 0x060012C7 RID: 4807 RVA: 0x00038748 File Offset: 0x00036948 public string RenameTo { get { return this.renameTo; } set { this.CheckRequestStarted(); if (value == null || value.Length == 0) { throw new ArgumentException("RenameTo value can't be null or empty", "RenameTo"); } this.renameTo = value; } } /// Gets the URI requested by this instance. /// A instance that identifies a resource that is accessed using the File Transfer Protocol. // Token: 0x1700061E RID: 1566 // (get) Token: 0x060012C8 RID: 4808 RVA: 0x00038784 File Offset: 0x00036984 public override global::System.Uri RequestUri { get { return this.requestUri; } } /// Gets the object used to connect to the FTP server. /// A object that can be used to customize connection behavior. /// /// /// /// // Token: 0x1700061F RID: 1567 // (get) Token: 0x060012C9 RID: 4809 RVA: 0x0003878C File Offset: 0x0003698C public ServicePoint ServicePoint { get { return this.GetServicePoint(); } } /// Gets or sets the behavior of a client application's data transfer process. /// false if the client application's data transfer process listens for a connection on the data port; otherwise, true if the client should initiate a connection on the data port. The default value is true. /// A new value was specified for this property for a request that is already in progress. // Token: 0x17000620 RID: 1568 // (get) Token: 0x060012CA RID: 4810 RVA: 0x00038794 File Offset: 0x00036994 // (set) Token: 0x060012CB RID: 4811 RVA: 0x0003879C File Offset: 0x0003699C public bool UsePassive { get { return this.usePassive; } set { this.CheckRequestStarted(); this.usePassive = value; } } /// Always throws a . /// Always throws a . /// Default credentials are not supported for FTP. // Token: 0x17000621 RID: 1569 // (get) Token: 0x060012CC RID: 4812 RVA: 0x000387AC File Offset: 0x000369AC // (set) Token: 0x060012CD RID: 4813 RVA: 0x000387B4 File Offset: 0x000369B4 [global::System.MonoTODO] public override bool UseDefaultCredentials { get { throw FtpWebRequest.GetMustImplement(); } set { throw FtpWebRequest.GetMustImplement(); } } /// Gets or sets a value that specifies the data type for file transfers. /// true to indicate to the server that the data to be transferred is binary; false to indicate that the data is text. The default value is true. /// A new value was specified for this property for a request that is already in progress. // Token: 0x17000622 RID: 1570 // (get) Token: 0x060012CE RID: 4814 RVA: 0x000387BC File Offset: 0x000369BC // (set) Token: 0x060012CF RID: 4815 RVA: 0x000387C4 File Offset: 0x000369C4 public bool UseBinary { get { return this.binary; } set { this.CheckRequestStarted(); this.binary = value; } } /// Gets or sets the number of milliseconds to wait for a request. /// An value that contains the number of milliseconds to wait before a request times out. The default value is . /// The value specified is less than zero and is not . /// A new value was specified for this property for a request that is already in progress. // Token: 0x17000623 RID: 1571 // (get) Token: 0x060012D0 RID: 4816 RVA: 0x000387D4 File Offset: 0x000369D4 // (set) Token: 0x060012D1 RID: 4817 RVA: 0x000387DC File Offset: 0x000369DC public override int Timeout { get { return this.timeout; } set { this.CheckRequestStarted(); if (value < -1) { throw new ArgumentOutOfRangeException(); } this.timeout = value; } } // Token: 0x17000624 RID: 1572 // (get) Token: 0x060012D2 RID: 4818 RVA: 0x000387F8 File Offset: 0x000369F8 private string DataType { get { return (!this.binary) ? "A" : "I"; } } // Token: 0x17000625 RID: 1573 // (get) Token: 0x060012D3 RID: 4819 RVA: 0x00038814 File Offset: 0x00036A14 // (set) Token: 0x060012D4 RID: 4820 RVA: 0x00038864 File Offset: 0x00036A64 private FtpWebRequest.RequestState State { get { object obj = this.locker; FtpWebRequest.RequestState requestState; lock (obj) { requestState = this.requestState; } return requestState; } set { object obj = this.locker; lock (obj) { this.CheckIfAborted(); this.CheckFinalState(); this.requestState = value; } } } /// Terminates an asynchronous FTP operation. /// /// /// /// /// /// // Token: 0x060012D5 RID: 4821 RVA: 0x000388BC File Offset: 0x00036ABC public override void Abort() { object obj = this.locker; lock (obj) { if (this.State == FtpWebRequest.RequestState.TransferInProgress) { this.SendCommand(false, "ABOR", new string[0]); } if (!this.InFinalState()) { this.State = FtpWebRequest.RequestState.Aborted; this.ftpResponse = new FtpWebResponse(this, this.requestUri, this.method, FtpStatusCode.FileActionAborted, "Aborted by request"); } } } /// Begins sending a request and receiving a response from an FTP server asynchronously. /// An instance that indicates the status of the operation. /// An delegate that references the method to invoke when the operation is complete. /// A user-defined object that contains information about the operation. This object is passed to the delegate when the operation completes. /// /// or has already been called for this instance. /// /// /// /// /// /// /// /// // Token: 0x060012D6 RID: 4822 RVA: 0x00038954 File Offset: 0x00036B54 public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state) { if (this.asyncResult != null && !this.asyncResult.IsCompleted) { throw new InvalidOperationException("Cannot re-call BeginGetRequestStream/BeginGetResponse while a previous call is still in progress"); } this.CheckIfAborted(); this.asyncResult = new FtpAsyncResult(callback, state); object obj = this.locker; lock (obj) { if (this.InFinalState()) { this.asyncResult.SetCompleted(true, this.ftpResponse); } else { if (this.State == FtpWebRequest.RequestState.Before) { this.State = FtpWebRequest.RequestState.Scheduled; } Thread thread = new Thread(new ThreadStart(this.ProcessRequest)); thread.Start(); } } return this.asyncResult; } /// Ends a pending asynchronous operation started with . /// A reference that contains an instance. This object contains the FTP server's response to the request. /// The that was returned when the operation started. /// /// is null. /// /// was not obtained by calling . /// This method was already called for the operation identified by . /// /// /// /// /// /// // Token: 0x060012D7 RID: 4823 RVA: 0x00038A24 File Offset: 0x00036C24 public override WebResponse EndGetResponse(IAsyncResult asyncResult) { if (asyncResult == null) { throw new ArgumentNullException("AsyncResult cannot be null!"); } if (!(asyncResult is FtpAsyncResult) || asyncResult != this.asyncResult) { throw new ArgumentException("AsyncResult is from another request!"); } FtpAsyncResult ftpAsyncResult = (FtpAsyncResult)asyncResult; if (!ftpAsyncResult.WaitUntilComplete(this.timeout, false)) { this.Abort(); throw new WebException("Transfer timed out.", WebExceptionStatus.Timeout); } this.CheckIfAborted(); asyncResult = null; if (ftpAsyncResult.GotException) { throw ftpAsyncResult.Exception; } return ftpAsyncResult.Response; } /// Returns the FTP server response. /// A reference that contains an instance. This object contains the FTP server's response to the request. /// /// or has already been called for this instance.- or -An HTTP proxy is enabled, and you attempted to use an FTP command other than , , or . /// /// is set to true, but the server does not support this feature. /// /// /// /// /// /// /// /// // Token: 0x060012D8 RID: 4824 RVA: 0x00038AB4 File Offset: 0x00036CB4 public override WebResponse GetResponse() { IAsyncResult asyncResult = this.BeginGetResponse(null, null); return this.EndGetResponse(asyncResult); } /// Begins asynchronously opening a request's content stream for writing. /// An instance that indicates the status of the operation. /// An delegate that references the method to invoke when the operation is complete. /// A user-defined object that contains information about the operation. This object is passed to the delegate when the operation completes. /// A previous call to this method or has not yet completed. /// A connection to the FTP server could not be established. /// The property is not set to . /// /// /// /// /// /// /// /// // Token: 0x060012D9 RID: 4825 RVA: 0x00038AD4 File Offset: 0x00036CD4 public override IAsyncResult BeginGetRequestStream(AsyncCallback callback, object state) { if (this.method != "STOR" && this.method != "STOU" && this.method != "APPE") { throw new ProtocolViolationException(); } object obj = this.locker; lock (obj) { this.CheckIfAborted(); if (this.State != FtpWebRequest.RequestState.Before) { throw new InvalidOperationException("Cannot re-call BeginGetRequestStream/BeginGetResponse while a previous call is still in progress"); } this.State = FtpWebRequest.RequestState.Scheduled; } this.asyncResult = new FtpAsyncResult(callback, state); Thread thread = new Thread(new ThreadStart(this.ProcessRequest)); thread.Start(); return this.asyncResult; } /// Ends a pending asynchronous operation started with . /// A writable instance associated with this instance. /// The object that was returned when the operation started. /// /// is null. /// /// was not obtained by calling . /// This method was already called for the operation identified by . /// /// /// /// /// /// // Token: 0x060012DA RID: 4826 RVA: 0x00038BAC File Offset: 0x00036DAC public override Stream EndGetRequestStream(IAsyncResult asyncResult) { if (asyncResult == null) { throw new ArgumentNullException("asyncResult"); } if (!(asyncResult is FtpAsyncResult)) { throw new ArgumentException("asyncResult"); } if (this.State == FtpWebRequest.RequestState.Aborted) { throw new WebException("Request aborted", WebExceptionStatus.RequestCanceled); } if (asyncResult != this.asyncResult) { throw new ArgumentException("AsyncResult is from another request!"); } FtpAsyncResult ftpAsyncResult = (FtpAsyncResult)asyncResult; if (!ftpAsyncResult.WaitUntilComplete(this.timeout, false)) { this.Abort(); throw new WebException("Request timed out"); } if (ftpAsyncResult.GotException) { throw ftpAsyncResult.Exception; } return ftpAsyncResult.Stream; } /// Retrieves the stream used to upload data to an FTP server. /// A writable instance used to store data to be sent to the server by the current request. /// /// has been called and has not completed. - or -An HTTP proxy is enabled, and you attempted to use an FTP command other than , , or . /// A connection to the FTP server could not be established. /// The property is not set to or . /// /// /// /// /// /// /// /// // Token: 0x060012DB RID: 4827 RVA: 0x00038C54 File Offset: 0x00036E54 public override Stream GetRequestStream() { IAsyncResult asyncResult = this.BeginGetRequestStream(null, null); return this.EndGetRequestStream(asyncResult); } // Token: 0x060012DC RID: 4828 RVA: 0x00038C74 File Offset: 0x00036E74 private ServicePoint GetServicePoint() { if (this.servicePoint == null) { this.servicePoint = ServicePointManager.FindServicePoint(this.requestUri, this.proxy); } return this.servicePoint; } // Token: 0x060012DD RID: 4829 RVA: 0x00038CAC File Offset: 0x00036EAC private void ResolveHost() { this.CheckIfAborted(); this.hostEntry = this.GetServicePoint().HostEntry; if (this.hostEntry == null) { this.ftpResponse.UpdateStatus(new FtpStatus(FtpStatusCode.ActionAbortedLocalProcessingError, "Cannot resolve server name")); throw new WebException("The remote server name could not be resolved: " + this.requestUri, null, WebExceptionStatus.NameResolutionFailure, this.ftpResponse); } } // Token: 0x060012DE RID: 4830 RVA: 0x00038D14 File Offset: 0x00036F14 private void ProcessRequest() { if (this.State == FtpWebRequest.RequestState.Scheduled) { this.ftpResponse = new FtpWebResponse(this, this.requestUri, this.method, this.keepAlive); try { this.ProcessMethod(); this.asyncResult.SetCompleted(false, this.ftpResponse); } catch (Exception ex) { this.State = FtpWebRequest.RequestState.Error; this.SetCompleteWithError(ex); } } else { if (this.InProgress()) { FtpStatus responseStatus = this.GetResponseStatus(); this.ftpResponse.UpdateStatus(responseStatus); if (this.ftpResponse.IsFinal()) { this.State = FtpWebRequest.RequestState.Finished; } } this.asyncResult.SetCompleted(false, this.ftpResponse); } } // Token: 0x060012DF RID: 4831 RVA: 0x00038DE4 File Offset: 0x00036FE4 private void SetType() { if (this.binary) { FtpStatus ftpStatus = this.SendCommand("TYPE", new string[] { this.DataType }); if (ftpStatus.StatusCode < FtpStatusCode.CommandOK || ftpStatus.StatusCode >= (FtpStatusCode)300) { throw this.CreateExceptionFromResponse(ftpStatus); } } } // Token: 0x060012E0 RID: 4832 RVA: 0x00038E40 File Offset: 0x00037040 private string GetRemoteFolderPath(global::System.Uri uri) { string text = global::System.Uri.UnescapeDataString(uri.LocalPath); string text2; if (this.initial_path == null || this.initial_path == "/") { text2 = text; } else { if (text[0] == '/') { text = text.Substring(1); } global::System.Uri uri2 = new global::System.Uri("ftp://dummy-host" + this.initial_path); text2 = new global::System.Uri(uri2, text).LocalPath; } int num = text2.LastIndexOf('/'); if (num == -1) { return null; } return text2.Substring(0, num + 1); } // Token: 0x060012E1 RID: 4833 RVA: 0x00038ED8 File Offset: 0x000370D8 private void CWDAndSetFileName(global::System.Uri uri) { string remoteFolderPath = this.GetRemoteFolderPath(uri); if (remoteFolderPath != null) { FtpStatus ftpStatus = this.SendCommand("CWD", new string[] { remoteFolderPath }); if (ftpStatus.StatusCode < FtpStatusCode.CommandOK || ftpStatus.StatusCode >= (FtpStatusCode)300) { throw this.CreateExceptionFromResponse(ftpStatus); } int num = uri.LocalPath.LastIndexOf('/'); if (num >= 0) { this.file_name = global::System.Uri.UnescapeDataString(uri.LocalPath.Substring(num + 1)); } } } // Token: 0x060012E2 RID: 4834 RVA: 0x00038F60 File Offset: 0x00037160 private void ProcessMethod() { this.State = FtpWebRequest.RequestState.Connecting; this.ResolveHost(); this.OpenControlConnection(); this.CWDAndSetFileName(this.requestUri); this.SetType(); string text = this.method; if (text != null) { if (FtpWebRequest.<>f__switch$map5 == null) { FtpWebRequest.<>f__switch$map5 = new Dictionary(12) { { "RETR", 0 }, { "NLST", 0 }, { "LIST", 0 }, { "APPE", 1 }, { "STOR", 1 }, { "STOU", 1 }, { "SIZE", 2 }, { "MDTM", 2 }, { "PWD", 2 }, { "MKD", 2 }, { "RENAME", 2 }, { "DELE", 2 } }; } int num; if (FtpWebRequest.<>f__switch$map5.TryGetValue(text, out num)) { switch (num) { case 0: this.DownloadData(); break; case 1: this.UploadData(); break; case 2: this.ProcessSimpleMethod(); break; default: goto IL_124; } this.CheckIfAborted(); return; } } IL_124: throw new Exception(string.Format("Support for command {0} not implemented yet", this.method)); } // Token: 0x060012E3 RID: 4835 RVA: 0x000390B0 File Offset: 0x000372B0 private void CloseControlConnection() { if (this.controlStream != null) { this.SendCommand("QUIT", new string[0]); this.controlStream.Close(); this.controlStream = null; } } // Token: 0x060012E4 RID: 4836 RVA: 0x000390E4 File Offset: 0x000372E4 internal void CloseDataConnection() { if (this.origDataStream != null) { this.origDataStream.Close(); this.origDataStream = null; } } // Token: 0x060012E5 RID: 4837 RVA: 0x00039104 File Offset: 0x00037304 private void CloseConnection() { this.CloseControlConnection(); this.CloseDataConnection(); } // Token: 0x060012E6 RID: 4838 RVA: 0x00039114 File Offset: 0x00037314 private void ProcessSimpleMethod() { this.State = FtpWebRequest.RequestState.TransferInProgress; if (this.method == "PWD") { this.method = "PWD"; } if (this.method == "RENAME") { this.method = "RNFR"; } FtpStatus ftpStatus = this.SendCommand(this.method, new string[] { this.file_name }); this.ftpResponse.Stream = Stream.Null; string statusDescription = ftpStatus.StatusDescription; string text = this.method; switch (text) { case "SIZE": { if (ftpStatus.StatusCode != FtpStatusCode.FileStatus) { throw this.CreateExceptionFromResponse(ftpStatus); } int num2 = 4; int num3 = 0; while (num2 < statusDescription.Length && char.IsDigit(statusDescription[num2])) { num2++; num3++; } if (num3 == 0) { throw new WebException("Bad format for server response in " + this.method); } long num4; if (!long.TryParse(statusDescription.Substring(4, num3), out num4)) { throw new WebException("Bad format for server response in " + this.method); } this.ftpResponse.contentLength = num4; break; } case "MDTM": if (ftpStatus.StatusCode != FtpStatusCode.FileStatus) { throw this.CreateExceptionFromResponse(ftpStatus); } this.ftpResponse.LastModified = DateTime.ParseExact(statusDescription.Substring(4), "yyyyMMddHHmmss", null); break; case "MKD": if (ftpStatus.StatusCode != FtpStatusCode.PathnameCreated) { throw this.CreateExceptionFromResponse(ftpStatus); } break; case "CWD": this.method = "PWD"; if (ftpStatus.StatusCode != FtpStatusCode.FileActionOK) { throw this.CreateExceptionFromResponse(ftpStatus); } ftpStatus = this.SendCommand(this.method, new string[0]); if (ftpStatus.StatusCode != FtpStatusCode.PathnameCreated) { throw this.CreateExceptionFromResponse(ftpStatus); } break; case "RNFR": this.method = "RENAME"; if (ftpStatus.StatusCode != FtpStatusCode.FileCommandPending) { throw this.CreateExceptionFromResponse(ftpStatus); } ftpStatus = this.SendCommand("RNTO", new string[] { (this.renameTo == null) ? string.Empty : this.renameTo }); if (ftpStatus.StatusCode != FtpStatusCode.FileActionOK) { throw this.CreateExceptionFromResponse(ftpStatus); } break; case "DELE": if (ftpStatus.StatusCode != FtpStatusCode.FileActionOK) { throw this.CreateExceptionFromResponse(ftpStatus); } break; } this.State = FtpWebRequest.RequestState.Finished; } // Token: 0x060012E7 RID: 4839 RVA: 0x00039424 File Offset: 0x00037624 private void UploadData() { this.State = FtpWebRequest.RequestState.OpeningData; this.OpenDataConnection(); this.State = FtpWebRequest.RequestState.TransferInProgress; this.requestStream = new FtpDataStream(this, this.dataStream, false); this.asyncResult.Stream = this.requestStream; } // Token: 0x060012E8 RID: 4840 RVA: 0x0003946C File Offset: 0x0003766C private void DownloadData() { this.State = FtpWebRequest.RequestState.OpeningData; this.OpenDataConnection(); this.State = FtpWebRequest.RequestState.TransferInProgress; this.ftpResponse.Stream = new FtpDataStream(this, this.dataStream, true); } // Token: 0x060012E9 RID: 4841 RVA: 0x000394A8 File Offset: 0x000376A8 private void CheckRequestStarted() { if (this.State != FtpWebRequest.RequestState.Before) { throw new InvalidOperationException("There is a request currently in progress"); } } // Token: 0x060012EA RID: 4842 RVA: 0x000394C0 File Offset: 0x000376C0 private void OpenControlConnection() { Exception ex = null; global::System.Net.Sockets.Socket socket = null; foreach (IPAddress ipaddress in this.hostEntry.AddressList) { socket = new global::System.Net.Sockets.Socket(ipaddress.AddressFamily, global::System.Net.Sockets.SocketType.Stream, global::System.Net.Sockets.ProtocolType.Tcp); IPEndPoint ipendPoint = new IPEndPoint(ipaddress, this.requestUri.Port); if (!this.ServicePoint.CallEndPointDelegate(socket, ipendPoint)) { socket.Close(); socket = null; } else { try { socket.Connect(ipendPoint); this.localEndPoint = (IPEndPoint)socket.LocalEndPoint; break; } catch (global::System.Net.Sockets.SocketException ex2) { ex = ex2; socket.Close(); socket = null; } } } if (socket == null) { throw new WebException("Unable to connect to remote server", ex, WebExceptionStatus.UnknownError, this.ftpResponse); } this.controlStream = new global::System.Net.Sockets.NetworkStream(socket); this.controlReader = new StreamReader(this.controlStream, Encoding.ASCII); this.State = FtpWebRequest.RequestState.Authenticating; this.Authenticate(); FtpStatus ftpStatus = this.SendCommand("OPTS", new string[] { "utf8", "on" }); ftpStatus = this.SendCommand("PWD", new string[0]); this.initial_path = FtpWebRequest.GetInitialPath(ftpStatus); } // Token: 0x060012EB RID: 4843 RVA: 0x00039618 File Offset: 0x00037818 private static string GetInitialPath(FtpStatus status) { int statusCode = (int)status.StatusCode; if (statusCode < 200 || statusCode > 300 || status.StatusDescription.Length <= 4) { throw new WebException("Error getting current directory: " + status.StatusDescription, null, WebExceptionStatus.UnknownError, null); } string text = status.StatusDescription.Substring(4); if (text[0] == '"') { int num = text.IndexOf('"', 1); if (num == -1) { throw new WebException("Error getting current directory: PWD -> " + status.StatusDescription, null, WebExceptionStatus.UnknownError, null); } text = text.Substring(1, num - 1); } if (!text.EndsWith("/")) { text += "/"; } return text; } // Token: 0x060012EC RID: 4844 RVA: 0x000396DC File Offset: 0x000378DC private global::System.Net.Sockets.Socket SetupPassiveConnection(string statusDescription) { if (statusDescription.Length < 4) { throw new WebException("Cannot open passive data connection"); } int num = 3; while (num < statusDescription.Length && !char.IsDigit(statusDescription[num])) { num++; } if (num >= statusDescription.Length) { throw new WebException("Cannot open passive data connection"); } string[] array = statusDescription.Substring(num).Split(new char[] { ',' }, 6); if (array.Length != 6) { throw new WebException("Cannot open passive data connection"); } int num2 = array[5].Length - 1; while (num2 >= 0 && !char.IsDigit(array[5][num2])) { num2--; } if (num2 < 0) { throw new WebException("Cannot open passive data connection"); } array[5] = array[5].Substring(0, num2 + 1); IPAddress ipaddress; try { ipaddress = IPAddress.Parse(string.Join(".", array, 0, 4)); } catch (FormatException) { throw new WebException("Cannot open passive data connection"); } int num3; int num4; if (!int.TryParse(array[4], out num3) || !int.TryParse(array[5], out num4)) { throw new WebException("Cannot open passive data connection"); } int num5 = (num3 << 8) + num4; if (num5 < 0 || num5 > 65535) { throw new WebException("Cannot open passive data connection"); } IPEndPoint ipendPoint = new IPEndPoint(ipaddress, num5); global::System.Net.Sockets.Socket socket = new global::System.Net.Sockets.Socket(ipendPoint.AddressFamily, global::System.Net.Sockets.SocketType.Stream, global::System.Net.Sockets.ProtocolType.Tcp); try { socket.Connect(ipendPoint); } catch (global::System.Net.Sockets.SocketException) { socket.Close(); throw new WebException("Cannot open passive data connection"); } return socket; } // Token: 0x060012ED RID: 4845 RVA: 0x000398B0 File Offset: 0x00037AB0 private Exception CreateExceptionFromResponse(FtpStatus status) { FtpWebResponse ftpWebResponse = new FtpWebResponse(this, this.requestUri, this.method, status); return new WebException("Server returned an error: " + status.StatusDescription, null, WebExceptionStatus.ProtocolError, ftpWebResponse); } // Token: 0x060012EE RID: 4846 RVA: 0x000398EC File Offset: 0x00037AEC internal void SetTransferCompleted() { if (this.InFinalState()) { return; } this.State = FtpWebRequest.RequestState.Finished; FtpStatus responseStatus = this.GetResponseStatus(); this.ftpResponse.UpdateStatus(responseStatus); if (!this.keepAlive) { this.CloseConnection(); } } // Token: 0x060012EF RID: 4847 RVA: 0x00039930 File Offset: 0x00037B30 internal void OperationCompleted() { if (!this.keepAlive) { this.CloseConnection(); } } // Token: 0x060012F0 RID: 4848 RVA: 0x00039944 File Offset: 0x00037B44 private void SetCompleteWithError(Exception exc) { if (this.asyncResult != null) { this.asyncResult.SetCompleted(false, exc); } } // Token: 0x060012F1 RID: 4849 RVA: 0x00039960 File Offset: 0x00037B60 private global::System.Net.Sockets.Socket InitDataConnection() { if (this.usePassive) { FtpStatus ftpStatus = this.SendCommand("PASV", new string[0]); if (ftpStatus.StatusCode != FtpStatusCode.EnteringPassive) { throw this.CreateExceptionFromResponse(ftpStatus); } return this.SetupPassiveConnection(ftpStatus.StatusDescription); } else { global::System.Net.Sockets.Socket socket = new global::System.Net.Sockets.Socket(global::System.Net.Sockets.AddressFamily.InterNetwork, global::System.Net.Sockets.SocketType.Stream, global::System.Net.Sockets.ProtocolType.Tcp); try { socket.Bind(new IPEndPoint(this.localEndPoint.Address, 0)); socket.Listen(1); } catch (global::System.Net.Sockets.SocketException ex) { socket.Close(); throw new WebException("Couldn't open listening socket on client", ex); } IPEndPoint ipendPoint = (IPEndPoint)socket.LocalEndPoint; string text = ipendPoint.Address.ToString().Replace('.', ','); int num = ipendPoint.Port >> 8; int num2 = ipendPoint.Port % 256; string text2 = string.Concat(new object[] { text, ",", num, ",", num2 }); FtpStatus ftpStatus = this.SendCommand("PORT", new string[] { text2 }); if (ftpStatus.StatusCode != FtpStatusCode.CommandOK) { socket.Close(); throw this.CreateExceptionFromResponse(ftpStatus); } return socket; } } // Token: 0x060012F2 RID: 4850 RVA: 0x00039AB8 File Offset: 0x00037CB8 private void OpenDataConnection() { global::System.Net.Sockets.Socket socket = this.InitDataConnection(); FtpStatus ftpStatus; if (this.offset > 0L) { ftpStatus = this.SendCommand("REST", new string[] { this.offset.ToString() }); if (ftpStatus.StatusCode != FtpStatusCode.FileCommandPending) { throw this.CreateExceptionFromResponse(ftpStatus); } } if (this.method != "NLST" && this.method != "LIST" && this.method != "STOU") { ftpStatus = this.SendCommand(this.method, new string[] { this.file_name }); } else { ftpStatus = this.SendCommand(this.method, new string[0]); } if (ftpStatus.StatusCode != FtpStatusCode.OpeningData && ftpStatus.StatusCode != FtpStatusCode.DataAlreadyOpen) { throw this.CreateExceptionFromResponse(ftpStatus); } if (this.usePassive) { this.origDataStream = new global::System.Net.Sockets.NetworkStream(socket, true); this.dataStream = this.origDataStream; if (this.EnableSsl) { this.ChangeToSSLSocket(ref this.dataStream); } } else { global::System.Net.Sockets.Socket socket2 = null; try { socket2 = socket.Accept(); } catch (global::System.Net.Sockets.SocketException) { socket.Close(); if (socket2 != null) { socket2.Close(); } throw new ProtocolViolationException("Server commited a protocol violation."); } socket.Close(); this.origDataStream = new global::System.Net.Sockets.NetworkStream(socket, true); this.dataStream = this.origDataStream; if (this.EnableSsl) { this.ChangeToSSLSocket(ref this.dataStream); } } this.ftpResponse.UpdateStatus(ftpStatus); } // Token: 0x060012F3 RID: 4851 RVA: 0x00039C7C File Offset: 0x00037E7C private void Authenticate() { string text = null; string text2 = null; string text3 = null; if (this.credentials != null) { text = this.credentials.UserName; text2 = this.credentials.Password; text3 = this.credentials.Domain; } if (text == null) { text = "anonymous"; } if (text2 == null) { text2 = "@anonymous"; } if (!string.IsNullOrEmpty(text3)) { text = text3 + '\\' + text; } FtpStatus ftpStatus = this.GetResponseStatus(); this.ftpResponse.BannerMessage = ftpStatus.StatusDescription; if (this.EnableSsl) { this.InitiateSecureConnection(ref this.controlStream); this.controlReader = new StreamReader(this.controlStream, Encoding.ASCII); ftpStatus = this.SendCommand("PBSZ", new string[] { "0" }); int num = (int)ftpStatus.StatusCode; if (num < 200 || num >= 300) { throw this.CreateExceptionFromResponse(ftpStatus); } ftpStatus = this.SendCommand("PROT", new string[] { "P" }); num = (int)ftpStatus.StatusCode; if (num < 200 || num >= 300) { throw this.CreateExceptionFromResponse(ftpStatus); } ftpStatus = new FtpStatus(FtpStatusCode.SendUserCommand, string.Empty); } if (ftpStatus.StatusCode != FtpStatusCode.SendUserCommand) { throw this.CreateExceptionFromResponse(ftpStatus); } ftpStatus = this.SendCommand("USER", new string[] { text }); FtpStatusCode statusCode = ftpStatus.StatusCode; if (statusCode != FtpStatusCode.LoggedInProceed) { if (statusCode != FtpStatusCode.SendPasswordCommand) { throw this.CreateExceptionFromResponse(ftpStatus); } ftpStatus = this.SendCommand("PASS", new string[] { text2 }); if (ftpStatus.StatusCode != FtpStatusCode.LoggedInProceed) { throw this.CreateExceptionFromResponse(ftpStatus); } } this.ftpResponse.WelcomeMessage = ftpStatus.StatusDescription; this.ftpResponse.UpdateStatus(ftpStatus); } // Token: 0x060012F4 RID: 4852 RVA: 0x00039E7C File Offset: 0x0003807C private FtpStatus SendCommand(string command, params string[] parameters) { return this.SendCommand(true, command, parameters); } // Token: 0x060012F5 RID: 4853 RVA: 0x00039E88 File Offset: 0x00038088 private FtpStatus SendCommand(bool waitResponse, string command, params string[] parameters) { string text = command; if (parameters.Length > 0) { text = text + " " + string.Join(" ", parameters); } text += "\r\n"; byte[] bytes = Encoding.ASCII.GetBytes(text); try { this.controlStream.Write(bytes, 0, bytes.Length); } catch (IOException) { return new FtpStatus(FtpStatusCode.ServiceNotAvailable, "Write failed"); } if (!waitResponse) { return null; } FtpStatus responseStatus = this.GetResponseStatus(); if (this.ftpResponse != null) { this.ftpResponse.UpdateStatus(responseStatus); } return responseStatus; } // Token: 0x060012F6 RID: 4854 RVA: 0x00039F44 File Offset: 0x00038144 internal static FtpStatus ServiceNotAvailable() { return new FtpStatus(FtpStatusCode.ServiceNotAvailable, global::Locale.GetText("Invalid response from server")); } // Token: 0x060012F7 RID: 4855 RVA: 0x00039F5C File Offset: 0x0003815C internal FtpStatus GetResponseStatus() { string text = null; try { text = this.controlReader.ReadLine(); } catch (IOException) { } if (text == null || text.Length < 3) { return FtpWebRequest.ServiceNotAvailable(); } int num; if (!int.TryParse(text.Substring(0, 3), out num)) { return FtpWebRequest.ServiceNotAvailable(); } if (text.Length > 3 && text[3] == '-') { string text2 = null; string text3 = num.ToString() + ' '; for (;;) { text2 = null; try { text2 = this.controlReader.ReadLine(); } catch (IOException) { } if (text2 == null) { break; } text = text + Environment.NewLine + text2; if (text2.StartsWith(text3, StringComparison.Ordinal)) { goto Block_8; } } return FtpWebRequest.ServiceNotAvailable(); Block_8:; } return new FtpStatus((FtpStatusCode)num, text); } // Token: 0x060012F8 RID: 4856 RVA: 0x0003A070 File Offset: 0x00038270 private void InitiateSecureConnection(ref Stream stream) { FtpStatus ftpStatus = this.SendCommand("AUTH", new string[] { "TLS" }); if (ftpStatus.StatusCode != FtpStatusCode.ServerWantsSecureSession) { throw this.CreateExceptionFromResponse(ftpStatus); } this.ChangeToSSLSocket(ref stream); } // Token: 0x060012F9 RID: 4857 RVA: 0x0003A0B8 File Offset: 0x000382B8 internal bool ChangeToSSLSocket(ref Stream stream) { global::System.Net.Security.SslStream sslStream = new global::System.Net.Security.SslStream(stream, true, this.callback, null); sslStream.AuthenticateAsClient(this.requestUri.Host, null, global::System.Security.Authentication.SslProtocols.Default, false); stream = sslStream; return true; } // Token: 0x060012FA RID: 4858 RVA: 0x0003A0F4 File Offset: 0x000382F4 private bool InFinalState() { return this.State == FtpWebRequest.RequestState.Aborted || this.State == FtpWebRequest.RequestState.Error || this.State == FtpWebRequest.RequestState.Finished; } // Token: 0x060012FB RID: 4859 RVA: 0x0003A128 File Offset: 0x00038328 private bool InProgress() { return this.State != FtpWebRequest.RequestState.Before && !this.InFinalState(); } // Token: 0x060012FC RID: 4860 RVA: 0x0003A144 File Offset: 0x00038344 internal void CheckIfAborted() { if (this.State == FtpWebRequest.RequestState.Aborted) { throw new WebException("Request aborted", WebExceptionStatus.RequestCanceled); } } // Token: 0x060012FD RID: 4861 RVA: 0x0003A160 File Offset: 0x00038360 private void CheckFinalState() { if (this.InFinalState()) { throw new InvalidOperationException("Cannot change final state"); } } // Token: 0x04001008 RID: 4104 private const string ChangeDir = "CWD"; // Token: 0x04001009 RID: 4105 private const string UserCommand = "USER"; // Token: 0x0400100A RID: 4106 private const string PasswordCommand = "PASS"; // Token: 0x0400100B RID: 4107 private const string TypeCommand = "TYPE"; // Token: 0x0400100C RID: 4108 private const string PassiveCommand = "PASV"; // Token: 0x0400100D RID: 4109 private const string PortCommand = "PORT"; // Token: 0x0400100E RID: 4110 private const string AbortCommand = "ABOR"; // Token: 0x0400100F RID: 4111 private const string AuthCommand = "AUTH"; // Token: 0x04001010 RID: 4112 private const string RestCommand = "REST"; // Token: 0x04001011 RID: 4113 private const string RenameFromCommand = "RNFR"; // Token: 0x04001012 RID: 4114 private const string RenameToCommand = "RNTO"; // Token: 0x04001013 RID: 4115 private const string QuitCommand = "QUIT"; // Token: 0x04001014 RID: 4116 private const string EOL = "\r\n"; // Token: 0x04001015 RID: 4117 private global::System.Uri requestUri; // Token: 0x04001016 RID: 4118 private string file_name; // Token: 0x04001017 RID: 4119 private ServicePoint servicePoint; // Token: 0x04001018 RID: 4120 private Stream origDataStream; // Token: 0x04001019 RID: 4121 private Stream dataStream; // Token: 0x0400101A RID: 4122 private Stream controlStream; // Token: 0x0400101B RID: 4123 private StreamReader controlReader; // Token: 0x0400101C RID: 4124 private NetworkCredential credentials; // Token: 0x0400101D RID: 4125 private IPHostEntry hostEntry; // Token: 0x0400101E RID: 4126 private IPEndPoint localEndPoint; // Token: 0x0400101F RID: 4127 private IWebProxy proxy; // Token: 0x04001020 RID: 4128 private int timeout = 100000; // Token: 0x04001021 RID: 4129 private int rwTimeout = 300000; // Token: 0x04001022 RID: 4130 private long offset; // Token: 0x04001023 RID: 4131 private bool binary = true; // Token: 0x04001024 RID: 4132 private bool enableSsl; // Token: 0x04001025 RID: 4133 private bool usePassive = true; // Token: 0x04001026 RID: 4134 private bool keepAlive; // Token: 0x04001027 RID: 4135 private string method = "RETR"; // Token: 0x04001028 RID: 4136 private string renameTo; // Token: 0x04001029 RID: 4137 private object locker = new object(); // Token: 0x0400102A RID: 4138 private FtpWebRequest.RequestState requestState; // Token: 0x0400102B RID: 4139 private FtpAsyncResult asyncResult; // Token: 0x0400102C RID: 4140 private FtpWebResponse ftpResponse; // Token: 0x0400102D RID: 4141 private Stream requestStream; // Token: 0x0400102E RID: 4142 private string initial_path; // Token: 0x0400102F RID: 4143 private static readonly string[] supportedCommands = new string[] { "APPE", "DELE", "LIST", "MDTM", "MKD", "NLST", "PWD", "RENAME", "RETR", "RMD", "SIZE", "STOR", "STOU" }; // Token: 0x04001030 RID: 4144 private global::System.Net.Security.RemoteCertificateValidationCallback callback = delegate(object sender, X509Certificate certificate, global::System.Security.Cryptography.X509Certificates.X509Chain chain, global::System.Net.Security.SslPolicyErrors sslPolicyErrors) { if (ServicePointManager.ServerCertificateValidationCallback != null) { return ServicePointManager.ServerCertificateValidationCallback(sender, certificate, chain, sslPolicyErrors); } if (sslPolicyErrors != global::System.Net.Security.SslPolicyErrors.None) { throw new InvalidOperationException("SSL authentication error: " + sslPolicyErrors); } return true; }; // Token: 0x02000223 RID: 547 private enum RequestState { // Token: 0x04001035 RID: 4149 Before, // Token: 0x04001036 RID: 4150 Scheduled, // Token: 0x04001037 RID: 4151 Connecting, // Token: 0x04001038 RID: 4152 Authenticating, // Token: 0x04001039 RID: 4153 OpeningData, // Token: 0x0400103A RID: 4154 TransferInProgress, // Token: 0x0400103B RID: 4155 Finished, // Token: 0x0400103C RID: 4156 Aborted, // Token: 0x0400103D RID: 4157 Error } } }