FtpDataStream.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. using System;
  2. using System.Reflection;
  3. using System.Text.RegularExpressions;
  4. using System.Diagnostics;
  5. namespace System.Net.FtpClient {
  6. /// <summary>
  7. /// Base class for data stream connections
  8. /// </summary>
  9. public class FtpDataStream : FtpSocketStream {
  10. FtpReply m_commandStatus;
  11. /// <summary>
  12. /// Gets the status of the command that was used to open
  13. /// this data channel
  14. /// </summary>
  15. public FtpReply CommandStatus {
  16. get {
  17. return m_commandStatus;
  18. }
  19. set {
  20. m_commandStatus = value;
  21. }
  22. }
  23. FtpClient m_control = null;
  24. /// <summary>
  25. /// Gets or sets the control connection for this data stream. Setting
  26. /// the control connection causes the object to be clonded and a new
  27. /// connection is made to the server to carry out the task. This ensures
  28. /// that multiple streams can be opened simultainously.
  29. /// </summary>
  30. public FtpClient ControlConnection {
  31. get {
  32. return m_control;
  33. }
  34. set {
  35. m_control = value;
  36. }
  37. }
  38. long m_length = 0;
  39. /// <summary>
  40. /// Gets or sets the length of the stream. Only valid for file transfers
  41. /// and only valid on servers that support the Size command.
  42. /// </summary>
  43. public override long Length {
  44. get {
  45. return m_length;
  46. }
  47. }
  48. long m_position = 0;
  49. /// <summary>
  50. /// Gets or sets the position of the stream
  51. /// </summary>
  52. public override long Position {
  53. get {
  54. return m_position;
  55. }
  56. set {
  57. throw new InvalidOperationException("You cannot modify the position of a FtpDataStream. This property is updated as data is read or written to the stream.");
  58. }
  59. }
  60. /// <summary>
  61. /// Reads data off the stream
  62. /// </summary>
  63. /// <param name="buffer">The buffer to read into</param>
  64. /// <param name="offset">Where to start in the buffer</param>
  65. /// <param name="count">Number of bytes to read</param>
  66. /// <returns>The number of bytes read</returns>
  67. public override int Read(byte[] buffer, int offset, int count) {
  68. int read = base.Read(buffer, offset, count);
  69. m_position += read;
  70. return read;
  71. }
  72. /// <summary>
  73. /// Writes data to the stream
  74. /// </summary>
  75. /// <param name="buffer">The buffer to write to the stream</param>
  76. /// <param name="offset">Where to start in the buffer</param>
  77. /// <param name="count">The number of bytes to write to the buffer</param>
  78. public override void Write(byte[] buffer, int offset, int count) {
  79. base.Write(buffer, offset, count);
  80. m_position += count;
  81. }
  82. /// <summary>
  83. /// Sets the length of this stream
  84. /// </summary>
  85. /// <param name="value">Value to apply to the Length property</param>
  86. public override void SetLength(long value) {
  87. m_length = value;
  88. }
  89. /// <summary>
  90. /// Sets the position of the stream. Inteneded to be used
  91. /// internally by FtpControlConnection.
  92. /// </summary>
  93. /// <param name="pos">The position</param>
  94. public void SetPosition(long pos) {
  95. m_position = pos;
  96. }
  97. /// <summary>
  98. /// Disconnects (if necessary) and releases associated resources
  99. /// </summary>
  100. /// <param name="disposing">Disposing</param>
  101. protected override void Dispose(bool disposing) {
  102. if (disposing) {
  103. if (IsConnected)
  104. Close();
  105. m_control = null;
  106. }
  107. base.Dispose(disposing);
  108. }
  109. /// <summary>
  110. /// Closes the connection and reads the server's reply
  111. /// </summary>
  112. public new FtpReply Close() {
  113. base.Close();
  114. try {
  115. if (ControlConnection != null)
  116. return ControlConnection.CloseDataStream(this);
  117. }
  118. finally {
  119. m_commandStatus = new FtpReply();
  120. m_control = null;
  121. }
  122. return new FtpReply();
  123. }
  124. /// <summary>
  125. /// Creates a new data stream object
  126. /// </summary>
  127. /// <param name="conn">The control connection to be used for carrying out this operation</param>
  128. public FtpDataStream(FtpClient conn) {
  129. if (conn == null)
  130. throw new ArgumentException("The control connection cannot be null.");
  131. ControlConnection = conn;
  132. // always accept certficate no matter what because if code execution ever
  133. // gets here it means the certificate on the control connection object being
  134. // cloned was already accepted.
  135. ValidateCertificate += new FtpSocketStreamSslValidation(delegate(FtpSocketStream obj, FtpSslValidationEventArgs e) {
  136. e.Accept = true;
  137. });
  138. m_position = 0;
  139. }
  140. /// <summary>
  141. /// Finalizer
  142. /// </summary>
  143. ~FtpDataStream() {
  144. try {
  145. Dispose();
  146. }
  147. catch (Exception ex) {
  148. FtpTrace.WriteLine("[Finalizer] Caught and discarded an exception while disposing the FtpDataStream: {0}", ex.ToString());
  149. }
  150. }
  151. }
  152. }