Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
HttpRequestStream.cs
Go to the documentation of this file.
1using System.IO;
6
7namespace System.Net;
8
9internal sealed class HttpRequestStream : Stream
10{
12 {
14
16
17 internal unsafe void* _pPinnedBuffer;
18
19 internal uint _dataAlreadyRead;
20
21 private unsafe static readonly IOCompletionCallback s_IOCallback = Callback;
22
23 internal HttpRequestStreamAsyncResult(object asyncObject, object userState, AsyncCallback callback)
24 : base(asyncObject, userState, callback)
25 {
26 }
27
28 internal HttpRequestStreamAsyncResult(object asyncObject, object userState, AsyncCallback callback, uint dataAlreadyRead)
29 : base(asyncObject, userState, callback)
30 {
31 _dataAlreadyRead = dataAlreadyRead;
32 }
33
34 internal unsafe HttpRequestStreamAsyncResult(ThreadPoolBoundHandle boundHandle, object asyncObject, object userState, AsyncCallback callback, byte[] buffer, int offset, uint size, uint dataAlreadyRead)
35 : base(asyncObject, userState, callback)
36 {
37 _dataAlreadyRead = dataAlreadyRead;
38 _boundHandle = boundHandle;
41 }
42
43 internal void IOCompleted(uint errorCode, uint numBytes)
44 {
45 IOCompleted(this, errorCode, numBytes);
46 }
47
48 private unsafe static void IOCompleted(HttpRequestStreamAsyncResult asyncResult, uint errorCode, uint numBytes)
49 {
50 if (System.Net.NetEventSource.Log.IsEnabled())
51 {
52 System.Net.NetEventSource.Info(null, $"asyncResult: {asyncResult} errorCode:0x {errorCode:x8} numBytes: {numBytes}", "IOCompleted");
53 }
54 object obj = null;
55 try
56 {
57 if (errorCode != 0 && errorCode != 38)
58 {
59 asyncResult.ErrorCode = (int)errorCode;
60 obj = new HttpListenerException((int)errorCode);
61 }
62 else
63 {
64 obj = numBytes;
65 if (System.Net.NetEventSource.Log.IsEnabled())
66 {
67 System.Net.NetEventSource.DumpBuffer(asyncResult, (IntPtr)asyncResult._pPinnedBuffer, (int)numBytes, "IOCompleted");
68 }
69 }
70 if (System.Net.NetEventSource.Log.IsEnabled())
71 {
72 System.Net.NetEventSource.Info(null, $"asyncResult: {asyncResult} calling Complete()", "IOCompleted");
73 }
74 }
75 catch (Exception ex)
76 {
77 obj = ex;
78 }
79 asyncResult.InvokeCallback(obj);
80 }
81
82 private unsafe static void Callback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
83 {
85 if (System.Net.NetEventSource.Log.IsEnabled())
86 {
87 System.Net.NetEventSource.Info(null, $"asyncResult: {httpRequestStreamAsyncResult} errorCode:0x {errorCode:x8} numBytes: {numBytes} nativeOverlapped:0x{(IntPtr)nativeOverlapped:x8}", "Callback");
88 }
89 IOCompleted(httpRequestStreamAsyncResult, errorCode, numBytes);
90 }
91
92 protected unsafe override void Cleanup()
93 {
94 base.Cleanup();
95 if (_pOverlapped != null)
96 {
98 }
99 }
100 }
101
102 private bool _closed;
103
105
106 private uint _dataChunkOffset;
107
108 private int _dataChunkIndex;
109
110 private bool _inOpaqueMode;
111
112 public override bool CanSeek => false;
113
114 public override bool CanWrite => false;
115
116 public override bool CanRead => true;
117
118 public override long Length
119 {
120 get
121 {
123 }
124 }
125
126 public override long Position
127 {
128 get
129 {
131 }
132 set
133 {
135 }
136 }
137
138 internal bool Closed => _closed;
139
141
143
144 public override int Read(byte[] buffer, int offset, int count)
145 {
146 if (System.Net.NetEventSource.Log.IsEnabled())
147 {
148 System.Net.NetEventSource.Info(this, "buffer.Length:" + buffer.Length + " count:" + count + " offset:" + offset, "Read");
149 }
151 if (count == 0 || _closed)
152 {
153 return 0;
154 }
155 return ReadCore(buffer, offset, count);
156 }
157
158 public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
159 {
160 if (System.Net.NetEventSource.Log.IsEnabled())
161 {
162 System.Net.NetEventSource.Info(this, "buffer.Length:" + buffer.Length + " count:" + count + " offset:" + offset, "BeginRead");
163 }
165 return BeginReadCore(buffer, offset, count, callback, state);
166 }
167
168 public override void Flush()
169 {
170 }
171
173 {
174 return Task.CompletedTask;
175 }
176
177 public override long Seek(long offset, SeekOrigin origin)
178 {
180 }
181
182 public override void SetLength(long value)
183 {
185 }
186
187 public override void Write(byte[] buffer, int offset, int count)
188 {
190 }
191
192 public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
193 {
195 }
196
197 public override void EndWrite(IAsyncResult asyncResult)
198 {
200 }
201
202 protected override void Dispose(bool disposing)
203 {
204 if (System.Net.NetEventSource.Log.IsEnabled())
205 {
206 System.Net.NetEventSource.Info(this, "_closed:" + _closed, "Dispose");
207 }
208 _closed = true;
209 base.Dispose(disposing);
210 }
211
213 {
214 if (System.Net.NetEventSource.Log.IsEnabled())
215 {
216 System.Net.NetEventSource.Info(this, $"httpContextt:{httpContext}", ".ctor");
217 }
218 _httpContext = httpContext;
219 }
220
221 private unsafe int ReadCore(byte[] buffer, int offset, int size)
222 {
223 uint num = 0u;
224 if (_dataChunkIndex != -1)
225 {
227 }
228 if (_dataChunkIndex == -1 && num < size)
229 {
230 if (System.Net.NetEventSource.Log.IsEnabled())
231 {
232 System.Net.NetEventSource.Info(this, "size:" + size + " offset:" + offset, "ReadCore");
233 }
234 uint num2 = 0u;
235 uint bytesReturned = 0u;
236 offset += (int)num;
237 size -= (int)num;
238 if (size > 131072)
239 {
240 size = 131072;
241 }
242 fixed (byte* ptr = buffer)
243 {
244 if (System.Net.NetEventSource.Log.IsEnabled())
245 {
246 System.Net.NetEventSource.Info(this, "Calling Interop.HttpApi.HttpReceiveRequestEntityBody", "ReadCore");
247 }
248 uint flags = 0u;
249 if (!_inOpaqueMode)
250 {
251 flags = 1u;
252 }
253 num2 = global::Interop.HttpApi.HttpReceiveRequestEntityBody(_httpContext.RequestQueueHandle, _httpContext.RequestId, flags, ptr + offset, (uint)size, out bytesReturned, null);
254 num += bytesReturned;
255 if (System.Net.NetEventSource.Log.IsEnabled())
256 {
257 System.Net.NetEventSource.Info(this, "Call to Interop.HttpApi.HttpReceiveRequestEntityBody returned:" + num2 + " dataRead:" + num, "ReadCore");
258 }
259 }
260 if (num2 != 0 && num2 != 38)
261 {
262 Exception ex = new HttpListenerException((int)num2);
263 if (System.Net.NetEventSource.Log.IsEnabled())
264 {
265 System.Net.NetEventSource.Error(this, ex.ToString(), "ReadCore");
266 }
267 throw ex;
268 }
269 UpdateAfterRead(num2, num);
270 }
271 if (System.Net.NetEventSource.Log.IsEnabled())
272 {
273 System.Net.NetEventSource.DumpBuffer(this, buffer, offset, (int)num, "ReadCore");
274 System.Net.NetEventSource.Info(this, "returning dataRead:" + num, "ReadCore");
275 }
276 return (int)num;
277 }
278
279 private void UpdateAfterRead(uint statusCode, uint dataRead)
280 {
281 if (System.Net.NetEventSource.Log.IsEnabled())
282 {
283 System.Net.NetEventSource.Info(this, "statusCode:" + statusCode + " _closed:" + _closed, "UpdateAfterRead");
284 }
285 if (statusCode == 38 || dataRead == 0)
286 {
287 Close();
288 }
289 if (System.Net.NetEventSource.Log.IsEnabled())
290 {
291 System.Net.NetEventSource.Info(this, "statusCode:" + statusCode + " _closed:" + _closed, "UpdateAfterRead");
292 }
293 }
294
295 public unsafe IAsyncResult BeginReadCore(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
296 {
297 if (size == 0 || _closed)
298 {
299 HttpRequestStreamAsyncResult httpRequestStreamAsyncResult = new HttpRequestStreamAsyncResult(this, state, callback);
300 httpRequestStreamAsyncResult.InvokeCallback(0u);
301 return httpRequestStreamAsyncResult;
302 }
303 HttpRequestStreamAsyncResult httpRequestStreamAsyncResult2 = null;
304 uint num = 0u;
305 if (_dataChunkIndex != -1)
306 {
308 if (_dataChunkIndex != -1 && num == size)
309 {
310 httpRequestStreamAsyncResult2 = new HttpRequestStreamAsyncResult(_httpContext.RequestQueueBoundHandle, this, state, callback, buffer, offset, (uint)size, 0u);
311 httpRequestStreamAsyncResult2.InvokeCallback(num);
312 }
313 }
314 if (_dataChunkIndex == -1 && num < size)
315 {
316 if (System.Net.NetEventSource.Log.IsEnabled())
317 {
318 System.Net.NetEventSource.Info(this, "size:" + size + " offset:" + offset, "BeginReadCore");
319 }
320 uint num2 = 0u;
321 offset += (int)num;
322 size -= (int)num;
323 if (size > 131072)
324 {
325 size = 131072;
326 }
327 httpRequestStreamAsyncResult2 = new HttpRequestStreamAsyncResult(_httpContext.RequestQueueBoundHandle, this, state, callback, buffer, offset, (uint)size, num);
328 uint bytesReturned;
329 try
330 {
331 fixed (byte* ptr = buffer)
332 {
333 if (System.Net.NetEventSource.Log.IsEnabled())
334 {
335 System.Net.NetEventSource.Info(this, "Calling Interop.HttpApi.HttpReceiveRequestEntityBody", "BeginReadCore");
336 }
337 uint flags = 0u;
338 if (!_inOpaqueMode)
339 {
340 flags = 1u;
341 }
342 num2 = global::Interop.HttpApi.HttpReceiveRequestEntityBody(_httpContext.RequestQueueHandle, _httpContext.RequestId, flags, httpRequestStreamAsyncResult2._pPinnedBuffer, (uint)size, out bytesReturned, httpRequestStreamAsyncResult2._pOverlapped);
343 if (System.Net.NetEventSource.Log.IsEnabled())
344 {
345 System.Net.NetEventSource.Info(this, "Call to Interop.HttpApi.HttpReceiveRequestEntityBody returned:" + num2 + " dataRead:" + num, "BeginReadCore");
346 }
347 }
348 }
349 catch (Exception ex)
350 {
351 if (System.Net.NetEventSource.Log.IsEnabled())
352 {
353 System.Net.NetEventSource.Error(this, ex.ToString(), "BeginReadCore");
354 }
355 httpRequestStreamAsyncResult2.InternalCleanup();
356 throw;
357 }
358 if (num2 != 0 && num2 != 997)
359 {
360 httpRequestStreamAsyncResult2.InternalCleanup();
361 if (num2 != 38)
362 {
363 Exception ex2 = new HttpListenerException((int)num2);
364 if (System.Net.NetEventSource.Log.IsEnabled())
365 {
366 System.Net.NetEventSource.Error(this, ex2.ToString(), "BeginReadCore");
367 }
368 httpRequestStreamAsyncResult2.InternalCleanup();
369 throw ex2;
370 }
371 httpRequestStreamAsyncResult2 = new HttpRequestStreamAsyncResult(this, state, callback, num);
372 httpRequestStreamAsyncResult2.InvokeCallback(0u);
373 }
374 else if (num2 == 0 && HttpListener.SkipIOCPCallbackOnSuccess)
375 {
376 httpRequestStreamAsyncResult2.IOCompleted(num2, bytesReturned);
377 }
378 }
379 return httpRequestStreamAsyncResult2;
380 }
381
382 public override int EndRead(IAsyncResult asyncResult)
383 {
384 if (System.Net.NetEventSource.Log.IsEnabled())
385 {
386 System.Net.NetEventSource.Info(this, $"asyncResult: {asyncResult}", "EndRead");
387 }
388 if (asyncResult == null)
389 {
390 throw new ArgumentNullException("asyncResult");
391 }
392 if (!(asyncResult is HttpRequestStreamAsyncResult httpRequestStreamAsyncResult) || httpRequestStreamAsyncResult.AsyncObject != this)
393 {
394 throw new ArgumentException(System.SR.net_io_invalidasyncresult, "asyncResult");
395 }
396 if (httpRequestStreamAsyncResult.EndCalled)
397 {
399 }
400 httpRequestStreamAsyncResult.EndCalled = true;
401 object obj = httpRequestStreamAsyncResult.InternalWaitForCompletion();
402 if (obj is Exception ex)
403 {
404 if (System.Net.NetEventSource.Log.IsEnabled())
405 {
406 System.Net.NetEventSource.Info(this, "Rethrowing exception:" + ex, "EndRead");
407 System.Net.NetEventSource.Error(this, ex.ToString(), "EndRead");
408 }
410 }
411 uint num = (uint)obj;
412 UpdateAfterRead((uint)httpRequestStreamAsyncResult.ErrorCode, num);
413 if (System.Net.NetEventSource.Log.IsEnabled())
414 {
415 System.Net.NetEventSource.Info(this, $"returnValue:{obj}", "EndRead");
416 }
417 return (int)(num + httpRequestStreamAsyncResult._dataAlreadyRead);
418 }
419
420 internal void SwitchToOpaqueMode()
421 {
422 if (System.Net.NetEventSource.Log.IsEnabled())
423 {
424 System.Net.NetEventSource.Info(this, null, "SwitchToOpaqueMode");
425 }
426 _inOpaqueMode = true;
427 }
428
429 internal uint GetChunks(byte[] buffer, int offset, int size)
430 {
431 return global::Interop.HttpApi.GetChunks(_httpContext.Request.RequestBuffer, _httpContext.Request.OriginalBlobAddress, ref _dataChunkIndex, ref _dataChunkOffset, buffer, offset, size);
432 }
433}
override string ToString()
Definition Exception.cs:384
static void ValidateBufferArguments(byte[] buffer, int offset, int count)
Definition Stream.cs:1044
virtual void Close()
Definition Stream.cs:644
ThreadPoolBoundHandle RequestQueueBoundHandle
static readonly bool SkipIOCPCallbackOnSuccess
static unsafe void IOCompleted(HttpRequestStreamAsyncResult asyncResult, uint errorCode, uint numBytes)
HttpRequestStreamAsyncResult(object asyncObject, object userState, AsyncCallback callback)
HttpRequestStreamAsyncResult(object asyncObject, object userState, AsyncCallback callback, uint dataAlreadyRead)
static unsafe readonly IOCompletionCallback s_IOCallback
unsafe HttpRequestStreamAsyncResult(ThreadPoolBoundHandle boundHandle, object asyncObject, object userState, AsyncCallback callback, byte[] buffer, int offset, uint size, uint dataAlreadyRead)
static unsafe void Callback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped)
override void SetLength(long value)
override int Read(byte[] buffer, int offset, int count)
override int EndRead(IAsyncResult asyncResult)
override void Dispose(bool disposing)
readonly HttpListenerContext _httpContext
HttpRequestStream(HttpListenerContext httpContext)
override void EndWrite(IAsyncResult asyncResult)
override long Seek(long offset, SeekOrigin origin)
override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
uint GetChunks(byte[] buffer, int offset, int size)
override Task FlushAsync(CancellationToken cancellationToken)
void UpdateAfterRead(uint statusCode, uint dataRead)
override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
override void Write(byte[] buffer, int offset, int count)
unsafe int ReadCore(byte[] buffer, int offset, int size)
HttpListenerContext InternalHttpContext
unsafe IAsyncResult BeginReadCore(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
void InvokeCallback(object result)
static readonly System.Net.NetEventSource Log
static void Info(object thisOrContextObject, FormattableString formattableString=null, [CallerMemberName] string memberName=null)
static void Error(object thisOrContextObject, FormattableString formattableString, [CallerMemberName] string memberName=null)
static void DumpBuffer(object thisOrContextObject, byte[] buffer, int offset, int count, [CallerMemberName] string memberName=null)
static unsafe IntPtr UnsafeAddrOfPinnedArrayElement(Array arr, int index)
Definition Marshal.cs:775
static string net_readonlystream
Definition SR.cs:152
static string net_io_invalidendcall
Definition SR.cs:22
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string net_io_invalidasyncresult
Definition SR.cs:20
static string net_noseek
Definition SR.cs:114
Definition SR.cs:7
static Task CompletedTask
Definition Task.cs:1120
unsafe void FreeNativeOverlapped(NativeOverlapped *overlapped)
unsafe NativeOverlapped * AllocateNativeOverlapped(IOCompletionCallback callback, object? state, object? pinData)
static unsafe? object GetNativeOverlappedState(NativeOverlapped *overlapped)
unsafe delegate void IOCompletionCallback(uint errorCode, uint numBytes, NativeOverlapped *pOVERLAP)