WebConnectionStream.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. //
  2. // System.Net.WebConnectionStream
  3. //
  4. // Authors:
  5. // Gonzalo Paniagua Javier ([email protected])
  6. // Martin Baulig <[email protected]>
  7. //
  8. // (C) 2003 Ximian, Inc (http://www.ximian.com)
  9. // (C) 2004 Novell, Inc (http://www.novell.com)
  10. // Copyright (c) 2017 Xamarin Inc. (http://www.xamarin.com)
  11. //
  12. //
  13. // Permission is hereby granted, free of charge, to any person obtaining
  14. // a copy of this software and associated documentation files (the
  15. // "Software"), to deal in the Software without restriction, including
  16. // without limitation the rights to use, copy, modify, merge, publish,
  17. // distribute, sublicense, and/or sell copies of the Software, and to
  18. // permit persons to whom the Software is furnished to do so, subject to
  19. // the following conditions:
  20. //
  21. // The above copyright notice and this permission notice shall be
  22. // included in all copies or substantial portions of the Software.
  23. //
  24. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  28. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  29. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  30. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  31. //
  32. using System.IO;
  33. using System.Text;
  34. using System.Threading;
  35. using System.Threading.Tasks;
  36. using System.Runtime.ExceptionServices;
  37. using System.Net.Sockets;
  38. namespace System.Net
  39. {
  40. abstract class WebConnectionStream : Stream
  41. {
  42. protected bool closed;
  43. bool disposed;
  44. object locker = new object ();
  45. int read_timeout;
  46. int write_timeout;
  47. internal bool IgnoreIOErrors;
  48. protected WebConnectionStream (WebConnection cnc, WebOperation operation, Stream stream)
  49. {
  50. Connection = cnc;
  51. Operation = operation;
  52. Request = operation.Request;
  53. InnerStream = stream;
  54. read_timeout = Request.ReadWriteTimeout;
  55. write_timeout = read_timeout;
  56. }
  57. internal HttpWebRequest Request {
  58. get;
  59. }
  60. internal WebConnection Connection {
  61. get;
  62. }
  63. internal WebOperation Operation {
  64. get;
  65. }
  66. internal ServicePoint ServicePoint => Connection.ServicePoint;
  67. internal Stream InnerStream {
  68. get;
  69. }
  70. public override bool CanTimeout {
  71. get { return true; }
  72. }
  73. public override int ReadTimeout {
  74. get {
  75. return read_timeout;
  76. }
  77. set {
  78. if (value < -1)
  79. throw new ArgumentOutOfRangeException ("value");
  80. read_timeout = value;
  81. }
  82. }
  83. public override int WriteTimeout {
  84. get {
  85. return write_timeout;
  86. }
  87. set {
  88. if (value < -1)
  89. throw new ArgumentOutOfRangeException ("value");
  90. write_timeout = value;
  91. }
  92. }
  93. protected Exception GetException (Exception e)
  94. {
  95. e = HttpWebRequest.FlattenException (e);
  96. if (e is WebException)
  97. return e;
  98. if (Operation.Aborted || e is OperationCanceledException || e is ObjectDisposedException)
  99. return HttpWebRequest.CreateRequestAbortedException ();
  100. return e;
  101. }
  102. public override int Read (byte[] buffer, int offset, int size)
  103. {
  104. if (!CanRead)
  105. throw new NotSupportedException (SR.net_writeonlystream);
  106. Operation.ThrowIfClosedOrDisposed ();
  107. if (buffer == null)
  108. throw new ArgumentNullException (nameof (buffer));
  109. int length = buffer.Length;
  110. if (offset < 0 || length < offset)
  111. throw new ArgumentOutOfRangeException (nameof (offset));
  112. if (size < 0 || (length - offset) < size)
  113. throw new ArgumentOutOfRangeException (nameof (size));
  114. try {
  115. return ReadAsync (buffer, offset, size, CancellationToken.None).Result;
  116. } catch (Exception e) {
  117. throw GetException (e);
  118. }
  119. }
  120. public override IAsyncResult BeginRead (byte[] buffer, int offset, int size,
  121. AsyncCallback cb, object state)
  122. {
  123. if (!CanRead)
  124. throw new NotSupportedException (SR.net_writeonlystream);
  125. Operation.ThrowIfClosedOrDisposed ();
  126. if (buffer == null)
  127. throw new ArgumentNullException (nameof (buffer));
  128. int length = buffer.Length;
  129. if (offset < 0 || length < offset)
  130. throw new ArgumentOutOfRangeException (nameof (offset));
  131. if (size < 0 || (length - offset) < size)
  132. throw new ArgumentOutOfRangeException (nameof (size));
  133. var task = ReadAsync (buffer, offset, size, CancellationToken.None);
  134. return TaskToApm.Begin (task, cb, state);
  135. }
  136. public override int EndRead (IAsyncResult r)
  137. {
  138. if (r == null)
  139. throw new ArgumentNullException (nameof (r));
  140. try {
  141. return TaskToApm.End<int> (r);
  142. } catch (Exception e) {
  143. throw GetException (e);
  144. }
  145. }
  146. public override IAsyncResult BeginWrite (byte[] buffer, int offset, int size,
  147. AsyncCallback cb, object state)
  148. {
  149. if (!CanWrite)
  150. throw new NotSupportedException (SR.net_readonlystream);
  151. Operation.ThrowIfClosedOrDisposed ();
  152. if (buffer == null)
  153. throw new ArgumentNullException (nameof (buffer));
  154. int length = buffer.Length;
  155. if (offset < 0 || length < offset)
  156. throw new ArgumentOutOfRangeException (nameof (offset));
  157. if (size < 0 || (length - offset) < size)
  158. throw new ArgumentOutOfRangeException (nameof (size));
  159. var task = WriteAsync (buffer, offset, size, CancellationToken.None);
  160. return TaskToApm.Begin (task, cb, state);
  161. }
  162. public override void EndWrite (IAsyncResult r)
  163. {
  164. if (r == null)
  165. throw new ArgumentNullException (nameof (r));
  166. try {
  167. TaskToApm.End (r);
  168. } catch (Exception e) {
  169. throw GetException (e);
  170. }
  171. }
  172. public override void Write (byte[] buffer, int offset, int size)
  173. {
  174. if (!CanWrite)
  175. throw new NotSupportedException (SR.net_readonlystream);
  176. Operation.ThrowIfClosedOrDisposed ();
  177. if (buffer == null)
  178. throw new ArgumentNullException (nameof (buffer));
  179. int length = buffer.Length;
  180. if (offset < 0 || length < offset)
  181. throw new ArgumentOutOfRangeException (nameof (offset));
  182. if (size < 0 || (length - offset) < size)
  183. throw new ArgumentOutOfRangeException (nameof (size));
  184. try {
  185. WriteAsync (buffer, offset, size).Wait ();
  186. } catch (Exception e) {
  187. throw GetException (e);
  188. }
  189. }
  190. public override void Flush ()
  191. {
  192. }
  193. internal void InternalClose ()
  194. {
  195. disposed = true;
  196. }
  197. protected abstract void Close_internal (ref bool disposed);
  198. public override void Close ()
  199. {
  200. Close_internal (ref disposed);
  201. }
  202. public override long Seek (long a, SeekOrigin b)
  203. {
  204. throw new NotSupportedException ();
  205. }
  206. public override void SetLength (long a)
  207. {
  208. throw new NotSupportedException ();
  209. }
  210. public override bool CanSeek {
  211. get {
  212. return false;
  213. }
  214. }
  215. public override long Position {
  216. get { throw new NotSupportedException (); }
  217. set { throw new NotSupportedException (); }
  218. }
  219. }
  220. }