Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
HttpConnection.cs
Go to the documentation of this file.
5using System.IO;
10using System.Text;
13
14namespace System.Net.Http;
15
17{
19 {
28
29 private ulong _chunkBytesRemaining;
30
32
34
35 public override bool NeedsDrain => base.CanReadFromConnection;
36
38 : base(connection)
39 {
41 }
42
43 public override int Read(Span<byte> buffer)
44 {
45 if (_connection == null || buffer.Length == 0)
46 {
47 return 0;
48 }
50 if (num > 0)
51 {
52 return num;
53 }
54 int num2;
55 do
56 {
57 if (_connection == null)
58 {
59 return 0;
60 }
62 {
63 num = _connection.Read(buffer.Slice(0, (int)Math.Min((ulong)buffer.Length, _chunkBytesRemaining)));
64 if (num == 0)
65 {
67 }
68 _chunkBytesRemaining -= (ulong)num;
69 if (_chunkBytesRemaining == 0L)
70 {
71 _state = ParsingState.ExpectChunkTerminator;
72 }
73 return num;
74 }
77 }
78 while (num2 <= 0);
79 return num2;
80 }
81
83 {
84 if (cancellationToken.IsCancellationRequested)
85 {
87 }
88 if (_connection == null || buffer.Length == 0)
89 {
90 return new ValueTask<int>(0);
91 }
93 if (num > 0)
94 {
95 return new ValueTask<int>(num);
96 }
97 if (_connection == null)
98 {
99 return new ValueTask<int>(0);
100 }
102 }
103
105 {
107 try
108 {
109 int num2;
110 do
111 {
112 if (_connection == null)
113 {
114 return 0;
115 }
117 {
118 int num = await _connection.ReadAsync(buffer.Slice(0, (int)Math.Min((ulong)buffer.Length, _chunkBytesRemaining))).ConfigureAwait(continueOnCapturedContext: false);
119 if (num == 0)
120 {
122 }
123 _chunkBytesRemaining -= (ulong)num;
124 if (_chunkBytesRemaining == 0L)
125 {
126 _state = ParsingState.ExpectChunkTerminator;
127 }
128 return num;
129 }
130 await _connection.FillAsync(async: true).ConfigureAwait(continueOnCapturedContext: false);
132 }
133 while (num2 <= 0);
134 return num2;
135 }
137 {
139 }
140 finally
141 {
142 ctr.Dispose();
143 }
144 }
145
147 {
149 if (!cancellationToken.IsCancellationRequested)
150 {
151 if (_connection != null)
152 {
154 }
155 return Task.CompletedTask;
156 }
158 }
159
161 {
163 try
164 {
165 while (true)
166 {
168 if (buffer.Length != 0)
169 {
170 await destination.WriteAsync(buffer, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
171 continue;
172 }
173 if (_connection == null)
174 {
175 break;
176 }
177 await _connection.FillAsync(async: true).ConfigureAwait(continueOnCapturedContext: false);
178 }
179 }
181 {
183 }
184 finally
185 {
186 ctr.Dispose();
187 }
188 }
189
191 {
192 int num = 0;
193 while (buffer.Length > 0)
194 {
196 if (readOnlyMemory.Length == 0)
197 {
198 break;
199 }
200 num += readOnlyMemory.Length;
202 buffer = buffer.Slice(readOnlyMemory.Length);
203 }
204 return num;
205 }
206
208 {
209 try
210 {
212 switch (_state)
213 {
214 case ParsingState.ExpectChunkHeader:
215 {
216 _connection._allowedReadLineBytes = 16384;
218 {
219 return default(ReadOnlyMemory<byte>);
220 }
221 if (!Utf8Parser.TryParse(line, out ulong value, out int bytesConsumed, 'X'))
222 {
224 }
226 if (bytesConsumed != line.Length)
227 {
229 }
230 if (value != 0)
231 {
232 _state = ParsingState.ExpectChunkData;
233 goto case ParsingState.ExpectChunkData;
234 }
235 _state = ParsingState.ConsumeTrailers;
236 goto case ParsingState.ConsumeTrailers;
237 }
238 case ParsingState.ExpectChunkData:
239 {
241 if (remainingBuffer.Length == 0)
242 {
243 return default(ReadOnlyMemory<byte>);
244 }
245 int num = Math.Min(maxBytesToRead, (int)Math.Min((ulong)remainingBuffer.Length, _chunkBytesRemaining));
247 _chunkBytesRemaining -= (ulong)num;
248 if (_chunkBytesRemaining == 0L)
249 {
250 _state = ParsingState.ExpectChunkTerminator;
251 }
252 return remainingBuffer.Slice(0, num);
253 }
254 case ParsingState.ExpectChunkTerminator:
255 _connection._allowedReadLineBytes = 16384;
257 {
258 return default(ReadOnlyMemory<byte>);
259 }
260 if (line.Length != 0)
261 {
263 }
264 _state = ParsingState.ExpectChunkHeader;
265 goto case ParsingState.ExpectChunkHeader;
266 case ParsingState.ConsumeTrailers:
267 while (true)
268 {
269 _connection._allowedReadLineBytes = 16384;
271 {
272 break;
273 }
274 if (line.IsEmpty)
275 {
276 cancellationRegistration.Dispose();
278 _state = ParsingState.Done;
280 _connection = null;
281 break;
282 }
283 if (!base.IsDisposed)
284 {
286 }
287 }
288 return default(ReadOnlyMemory<byte>);
289 default:
290 if (System.Net.NetEventSource.Log.IsEnabled())
291 {
292 System.Net.NetEventSource.Error(this, $"Unexpected state: {_state}", "ReadChunkFromConnectionBuffer");
293 }
294 return default(ReadOnlyMemory<byte>);
295 }
296 }
297 catch (Exception)
298 {
300 _connection = null;
301 throw;
302 }
303 }
304
306 {
307 for (int i = 0; i < lineAfterChunkSize.Length; i++)
308 {
309 switch (lineAfterChunkSize[i])
310 {
311 case 9:
312 case 32:
313 continue;
314 case 59:
315 return;
316 }
318 }
319 }
320
322 {
325 try
326 {
327 int drainedBytes = 0;
328 while (true)
329 {
331 while (ReadChunkFromConnectionBuffer(int.MaxValue, ctr).Length != 0)
332 {
333 }
334 if (_connection == null)
335 {
336 return true;
337 }
339 {
340 return false;
341 }
342 if (cts == null)
343 {
346 {
347 break;
348 }
350 {
351 cts = new CancellationTokenSource((int)maxResponseDrainTime.TotalMilliseconds);
352 ctr = cts.Token.Register(delegate(object s)
353 {
354 ((HttpConnection)s).Dispose();
355 }, _connection);
356 }
357 }
358 await _connection.FillAsync(async: true).ConfigureAwait(continueOnCapturedContext: false);
359 }
360 return false;
361 }
362 finally
363 {
364 ctr.Dispose();
365 cts?.Dispose();
366 }
367 }
368 }
369
371 {
372 private static readonly byte[] s_finalChunkBytes = new byte[5] { 48, 13, 10, 13, 10 };
373
375 : base(connection)
376 {
377 }
378
379 public override void Write(ReadOnlySpan<byte> buffer)
380 {
381 base.BytesWritten += buffer.Length;
383 if (buffer.Length == 0)
384 {
385 connectionOrThrow.Flush();
386 return;
387 }
388 connectionOrThrow.WriteHexInt32Async(buffer.Length, async: false).GetAwaiter().GetResult();
389 connectionOrThrow.WriteTwoBytesAsync(13, 10, async: false).GetAwaiter().GetResult();
391 connectionOrThrow.WriteTwoBytesAsync(13, 10, async: false).GetAwaiter().GetResult();
392 }
393
395 {
396 base.BytesWritten += buffer.Length;
398 return (buffer.Length == 0) ? connectionOrThrow.FlushAsync(async: true) : WriteChunkAsync(connectionOrThrow, buffer);
400 {
401 await connection.WriteHexInt32Async(buffer.Length, async: true).ConfigureAwait(continueOnCapturedContext: false);
402 await connection.WriteTwoBytesAsync(13, 10, async: true).ConfigureAwait(continueOnCapturedContext: false);
403 await connection.WriteAsync(buffer, async: true).ConfigureAwait(continueOnCapturedContext: false);
404 await connection.WriteTwoBytesAsync(13, 10, async: true).ConfigureAwait(continueOnCapturedContext: false);
405 }
406 }
407
408 public override Task FinishAsync(bool async)
409 {
411 _connection = null;
412 return connectionOrThrow.WriteBytesAsync(s_finalChunkBytes, async);
413 }
414 }
415
417 {
419 : base(connection)
420 {
421 }
422
423 public override int Read(Span<byte> buffer)
424 {
425 HttpConnection connection = _connection;
426 if (connection == null || buffer.Length == 0)
427 {
428 return 0;
429 }
430 int num = connection.Read(buffer);
431 if (num == 0)
432 {
433 _connection = null;
434 connection.Dispose();
435 }
436 return num;
437 }
438
440 {
442 HttpConnection connection = _connection;
443 if (connection == null || buffer.Length == 0)
444 {
445 return 0;
446 }
448 int num;
449 if (valueTask.IsCompletedSuccessfully)
450 {
451 num = valueTask.Result;
452 }
453 else
454 {
456 try
457 {
458 num = await valueTask.ConfigureAwait(continueOnCapturedContext: false);
459 }
461 {
463 }
464 finally
465 {
466 ctr.Dispose();
467 }
468 }
469 if (num == 0)
470 {
472 _connection = null;
473 connection.Dispose();
474 }
475 return num;
476 }
477
479 {
481 if (cancellationToken.IsCancellationRequested)
482 {
484 }
485 HttpConnection connection = _connection;
486 if (connection == null)
487 {
488 return Task.CompletedTask;
489 }
491 if (task.IsCompletedSuccessfully)
492 {
493 Finish(connection);
494 return Task.CompletedTask;
495 }
496 return CompleteCopyToAsync(task, connection, cancellationToken);
497 }
498
517
518 private void Finish(HttpConnection connection)
519 {
520 _connection = null;
521 connection.Dispose();
522 }
523 }
524
526 {
528
529 public override bool NeedsDrain => base.CanReadFromConnection;
530
532 : base(connection)
533 {
535 }
536
537 public override int Read(Span<byte> buffer)
538 {
539 if (_connection == null || buffer.Length == 0)
540 {
541 return 0;
542 }
543 if ((ulong)buffer.Length > _contentBytesRemaining)
544 {
545 buffer = buffer.Slice(0, (int)_contentBytesRemaining);
546 }
547 int num = _connection.Read(buffer);
548 if (num <= 0)
549 {
551 }
552 _contentBytesRemaining -= (ulong)num;
554 {
556 _connection = null;
557 }
558 return num;
559 }
560
562 {
564 if (_connection == null || buffer.Length == 0)
565 {
566 return 0;
567 }
568 if ((ulong)buffer.Length > _contentBytesRemaining)
569 {
570 buffer = buffer.Slice(0, (int)_contentBytesRemaining);
571 }
573 int num;
574 if (valueTask.IsCompletedSuccessfully)
575 {
576 num = valueTask.Result;
577 }
578 else
579 {
581 try
582 {
583 num = await valueTask.ConfigureAwait(continueOnCapturedContext: false);
584 }
586 {
588 }
589 finally
590 {
591 ctr.Dispose();
592 }
593 }
594 if (num <= 0)
595 {
598 }
599 _contentBytesRemaining -= (ulong)num;
601 {
603 _connection = null;
604 }
605 return num;
606 }
607
609 {
611 if (cancellationToken.IsCancellationRequested)
612 {
614 }
615 if (_connection == null)
616 {
617 return Task.CompletedTask;
618 }
620 if (task.IsCompletedSuccessfully)
621 {
622 Finish();
623 return Task.CompletedTask;
624 }
626 }
627
645
646 private void Finish()
647 {
650 _connection = null;
651 }
652
654 {
656 if (remainingBuffer.Length == 0)
657 {
658 return default(ReadOnlyMemory<byte>);
659 }
660 int num = Math.Min(maxBytesToRead, (int)Math.Min((ulong)remainingBuffer.Length, _contentBytesRemaining));
662 _contentBytesRemaining -= (ulong)num;
663 return remainingBuffer.Slice(0, num);
664 }
665
667 {
668 ReadFromConnectionBuffer(int.MaxValue);
670 {
671 Finish();
672 return true;
673 }
675 {
676 return false;
677 }
682 {
683 return false;
684 }
686 {
687 cts = new CancellationTokenSource((int)maxResponseDrainTime.TotalMilliseconds);
688 ctr = cts.Token.Register(delegate(object s)
689 {
690 ((HttpConnection)s).Dispose();
691 }, _connection);
692 }
693 try
694 {
695 do
696 {
697 await _connection.FillAsync(async: true).ConfigureAwait(continueOnCapturedContext: false);
698 ReadFromConnectionBuffer(int.MaxValue);
699 }
700 while (_contentBytesRemaining != 0L);
701 ctr.Dispose();
703 Finish();
704 return true;
705 }
706 finally
707 {
708 ctr.Dispose();
709 cts?.Dispose();
710 }
711 }
712 }
713
715 {
717 : base(connection)
718 {
719 }
720
721 public override void Write(ReadOnlySpan<byte> buffer)
722 {
723 base.BytesWritten += buffer.Length;
726 }
727
729 {
730 base.BytesWritten += buffer.Length;
732 return connectionOrThrow.WriteAsync(buffer, async: true);
733 }
734
735 public override Task FinishAsync(bool async)
736 {
737 _connection = null;
738 return Task.CompletedTask;
739 }
740 }
741
742 internal abstract class HttpContentReadStream : HttpContentStream
743 {
744 private int _disposed;
745
746 public sealed override bool CanRead => _disposed == 0;
747
748 public sealed override bool CanWrite => false;
749
750 public virtual bool NeedsDrain => false;
751
752 protected bool IsDisposed => _disposed == 1;
753
755 {
756 get
757 {
758 HttpConnection connection = _connection;
759 if (connection != null)
760 {
761 return connection._disposed != 1;
762 }
763 return false;
764 }
765 }
766
768 : base(connection)
769 {
770 }
771
772 public sealed override void Write(ReadOnlySpan<byte> buffer)
773 {
775 }
776
781
783 {
784 return new ValueTask<bool>(result: false);
785 }
786
787 protected override void Dispose(bool disposing)
788 {
789 if (Interlocked.Exchange(ref _disposed, 1) == 0)
790 {
791 if (disposing && NeedsDrain)
792 {
794 }
795 else
796 {
797 base.Dispose(disposing);
798 }
799 }
800 }
801
803 {
804 HttpConnection connection = _connection;
805 try
806 {
807 bool flag = await DrainAsync(connection._pool.Settings._maxResponseDrainSize).ConfigureAwait(continueOnCapturedContext: false);
808 if (System.Net.NetEventSource.Log.IsEnabled())
809 {
810 connection.Trace(flag ? "Connection drain succeeded" : $"Connection drain failed when MaxResponseDrainSize={connection._pool.Settings._maxResponseDrainSize} bytes or MaxResponseDrainTime=={connection._pool.Settings._maxResponseDrainTime} exceeded", "DrainOnDisposeAsync");
811 }
812 }
813 catch (Exception value)
814 {
815 if (System.Net.NetEventSource.Log.IsEnabled())
816 {
817 connection.Trace($"Connection drain failed due to exception: {value}", "DrainOnDisposeAsync");
818 }
819 }
820 base.Dispose(disposing: true);
821 }
822 }
823
825 {
826 public long BytesWritten { get; protected set; }
827
828 public sealed override bool CanRead => false;
829
830 public sealed override bool CanWrite => _connection != null;
831
833 : base(connection)
834 {
835 }
836
837 public sealed override void Flush()
838 {
840 }
841
842 public sealed override Task FlushAsync(CancellationToken ignored)
843 {
844 return _connection?.FlushAsync(async: true).AsTask();
845 }
846
847 public sealed override int Read(Span<byte> buffer)
848 {
849 throw new NotSupportedException();
850 }
851
856
858 {
859 throw new NotSupportedException();
860 }
861
862 public abstract Task FinishAsync(bool async);
863 }
864
866 {
867 public sealed override bool CanRead => _connection != null;
868
869 public sealed override bool CanWrite => _connection != null;
870
872 : base(connection)
873 {
874 if (System.Net.NetEventSource.Log.IsEnabled())
875 {
876 System.Net.NetEventSource.Info(this, null, ".ctor");
877 }
878 }
879
880 public override int Read(Span<byte> buffer)
881 {
882 HttpConnection connection = _connection;
883 if (connection == null || buffer.Length == 0)
884 {
885 return 0;
886 }
887 int num = connection.ReadBuffered(buffer);
888 if (num == 0)
889 {
890 _connection = null;
891 connection.Dispose();
892 }
893 return num;
894 }
895
897 {
899 HttpConnection connection = _connection;
900 if (connection == null || buffer.Length == 0)
901 {
902 return 0;
903 }
905 int num;
906 if (valueTask.IsCompletedSuccessfully)
907 {
908 num = valueTask.Result;
909 }
910 else
911 {
913 try
914 {
915 num = await valueTask.ConfigureAwait(continueOnCapturedContext: false);
916 }
918 {
920 }
921 finally
922 {
923 ctr.Dispose();
924 }
925 }
926 if (num == 0)
927 {
929 _connection = null;
930 connection.Dispose();
931 }
932 return num;
933 }
934
936 {
938 if (cancellationToken.IsCancellationRequested)
939 {
941 }
942 HttpConnection connection = _connection;
943 if (connection == null)
944 {
945 return Task.CompletedTask;
946 }
948 if (task.IsCompletedSuccessfully)
949 {
950 Finish(connection);
951 return Task.CompletedTask;
952 }
953 return CompleteCopyToAsync(task, connection, cancellationToken);
954 }
955
974
975 private void Finish(HttpConnection connection)
976 {
977 connection.Dispose();
978 _connection = null;
979 }
980
981 public override void Write(ReadOnlySpan<byte> buffer)
982 {
983 HttpConnection connection = _connection;
984 if (connection == null)
985 {
987 }
988 if (buffer.Length != 0)
989 {
990 connection.WriteWithoutBuffering(buffer);
991 }
992 }
993
995 {
996 if (cancellationToken.IsCancellationRequested)
997 {
999 }
1000 HttpConnection connection = _connection;
1001 if (connection == null)
1002 {
1004 }
1005 if (buffer.Length == 0)
1006 {
1007 return default(ValueTask);
1008 }
1010 if (!valueTask.IsCompleted)
1011 {
1013 }
1014 return valueTask;
1015 }
1016
1017 public override void Flush()
1018 {
1019 _connection?.Flush();
1020 }
1021
1023 {
1024 if (cancellationToken.IsCancellationRequested)
1025 {
1027 }
1028 HttpConnection connection = _connection;
1029 if (connection == null)
1030 {
1031 return Task.CompletedTask;
1032 }
1033 ValueTask task = connection.FlushAsync(async: true);
1034 if (!task.IsCompleted)
1035 {
1037 }
1038 return task.AsTask();
1039 }
1040
1057 }
1058
1059 private static readonly byte[] s_contentLength0NewlineAsciiBytes = Encoding.ASCII.GetBytes("Content-Length: 0\r\n");
1060
1061 private static readonly byte[] s_spaceHttp10NewlineAsciiBytes = Encoding.ASCII.GetBytes(" HTTP/1.0\r\n");
1062
1063 private static readonly byte[] s_spaceHttp11NewlineAsciiBytes = Encoding.ASCII.GetBytes(" HTTP/1.1\r\n");
1064
1065 private static readonly byte[] s_httpSchemeAndDelimiter = Encoding.ASCII.GetBytes(Uri.UriSchemeHttp + Uri.SchemeDelimiter);
1066
1067 private static readonly byte[] s_http1DotBytes = Encoding.ASCII.GetBytes("HTTP/1.");
1068
1069 private static readonly ulong s_http10Bytes = BitConverter.ToUInt64(Encoding.ASCII.GetBytes("HTTP/1.0"));
1070
1071 private static readonly ulong s_http11Bytes = BitConverter.ToUInt64(Encoding.ASCII.GetBytes("HTTP/1.1"));
1072
1073 private readonly HttpConnectionPool _pool;
1074
1075 private readonly Socket _socket;
1076
1077 private readonly Stream _stream;
1078
1080
1082
1084
1085 private readonly byte[] _writeBuffer;
1086
1087 private int _writeOffset;
1088
1090
1091 private string[] _headerValues = Array.Empty<string>();
1092
1094
1096
1097 private byte[] _readBuffer;
1098
1099 private int _readOffset;
1100
1101 private int _readLength;
1102
1104
1105 private bool _inUse;
1106
1107 private bool _detachedFromPool;
1108
1109 private bool _canRetry;
1110
1112
1113 private bool _connectionClose;
1114
1115 private int _disposed;
1116
1118
1120
1121 private int ReadBufferSize => _readBuffer.Length;
1122
1124
1126 {
1127 _pool = pool;
1128 _stream = stream;
1129 _socket = socket;
1131 _writeBuffer = new byte[4096];
1132 _readBuffer = new byte[4096];
1135 if (HttpTelemetry.Log.IsEnabled())
1136 {
1137 HttpTelemetry.Log.Http11ConnectionEstablished();
1138 _disposed = 2;
1139 }
1140 if (System.Net.NetEventSource.Log.IsEnabled())
1141 {
1143 }
1144 }
1145
1147 {
1148 Dispose(disposing: false);
1149 }
1150
1151 public override void Dispose()
1152 {
1153 Dispose(disposing: true);
1154 }
1155
1156 private void Dispose(bool disposing)
1157 {
1158 int num = Interlocked.Exchange(ref _disposed, 1);
1159 if (num == 1)
1160 {
1161 return;
1162 }
1163 if (System.Net.NetEventSource.Log.IsEnabled())
1164 {
1165 Trace("Connection closing.", "Dispose");
1166 }
1167 if (HttpTelemetry.Log.IsEnabled() && num == 2)
1168 {
1169 HttpTelemetry.Log.Http11ConnectionClosed();
1170 }
1171 if (!_detachedFromPool)
1172 {
1174 }
1175 if (disposing)
1176 {
1177 GC.SuppressFinalize(this);
1178 _stream.Dispose();
1180 if (valueTask.HasValue)
1181 {
1182 HttpConnectionBase.IgnoreExceptions(valueTask.GetValueOrDefault());
1183 }
1184 }
1185 }
1186
1187 public bool PrepareForReuse(bool async)
1188 {
1190 if (readAheadTask.HasValue)
1191 {
1192 return !_readAheadTask.Value.IsCompleted;
1193 }
1194 if (!async && _socket != null)
1195 {
1196 try
1197 {
1198 return !_socket.Poll(0, SelectMode.SelectRead);
1199 }
1201 {
1202 return false;
1203 }
1204 }
1205 try
1206 {
1208 return !_readAheadTask.Value.IsCompleted;
1209 }
1210 catch (Exception value)
1211 {
1212 if (System.Net.NetEventSource.Log.IsEnabled())
1213 {
1214 Trace($"Error performing read ahead: {value}", "PrepareForReuse");
1215 }
1216 return false;
1217 }
1218 }
1219
1234
1236 {
1238 {
1240 _readAheadTask = null;
1242 return readAheadTask;
1243 }
1244 return null;
1245 }
1246
1247 public override long GetIdleTicks(long nowTicks)
1248 {
1250 }
1251
1256
1258 {
1259 if (headers.HeaderStore != null)
1260 {
1262 {
1263 if (header.Key.KnownHeader == null)
1264 {
1267 }
1268 else
1269 {
1270 await WriteBytesAsync(header.Key.KnownHeader.AsciiBytesWithColonSpace, async).ConfigureAwait(continueOnCapturedContext: false);
1271 }
1273 if (headerValuesCount > 0)
1274 {
1277 if (cookiesFromContainer != null && header.Key.KnownHeader == KnownHeaders.Cookie)
1278 {
1281 cookiesFromContainer = null;
1282 }
1283 if (headerValuesCount > 1)
1284 {
1285 HttpHeaderParser parser = header.Key.Parser;
1286 string separator = ", ";
1287 if (parser != null && parser.SupportsMultipleValues)
1288 {
1289 separator = parser.Separator;
1290 }
1291 for (int i = 1; i < headerValuesCount; i++)
1292 {
1295 }
1296 }
1297 }
1299 }
1300 }
1301 if (cookiesFromContainer != null)
1302 {
1308 }
1309 }
1310
1338
1340 {
1342 {
1344 return Task.CompletedTask;
1345 }
1346 return WriteAsciiStringAsync(value.ToString(), async);
1347 }
1348
1358
1360 {
1365 _canRetry = false;
1367 if (System.Net.NetEventSource.Log.IsEnabled())
1368 {
1369 Trace($"Sending request: {request}", "SendAsyncCore");
1370 }
1372 Unsafe.SkipInit(out HttpResponseMessage result);
1373 try
1374 {
1375 if (HttpTelemetry.Log.IsEnabled())
1376 {
1377 HttpTelemetry.Log.RequestHeadersStart();
1378 }
1381 if ((object)normalizedMethod == HttpMethod.Connect)
1382 {
1383 if (!request.HasHeaders || request.Headers.Host == null)
1384 {
1386 }
1388 }
1389 else
1390 {
1391 if (Kind == HttpConnectionKind.Proxy)
1392 {
1394 if (request.RequestUri.HostNameType != UriHostNameType.IPv6)
1395 {
1397 }
1398 else
1399 {
1403 }
1404 if (!request.RequestUri.IsDefaultPort)
1405 {
1408 }
1409 }
1411 }
1412 bool flag = request.Version.Minor == 0 && request.Version.Major == 1;
1414 string cookiesFromContainer = null;
1416 {
1418 if (cookiesFromContainer == "")
1419 {
1420 cookiesFromContainer = null;
1421 }
1422 }
1423 if (!request.HasHeaders || request.Headers.Host == null)
1424 {
1425 await WriteHostHeaderAsync(request.RequestUri, async).ConfigureAwait(continueOnCapturedContext: false);
1426 }
1427 if (request.HasHeaders || cookiesFromContainer != null)
1428 {
1430 }
1431 if (request.Content != null)
1432 {
1433 await WriteHeadersAsync(request.Content.Headers, null, async).ConfigureAwait(continueOnCapturedContext: false);
1434 }
1435 else if (normalizedMethod.MustHaveRequestBody)
1436 {
1438 }
1440 if (HttpTelemetry.Log.IsEnabled())
1441 {
1442 HttpTelemetry.Log.RequestHeadersStop();
1443 }
1444 if (request.Content == null)
1445 {
1447 }
1448 else
1449 {
1450 bool flag2 = request.HasHeaders && request.Headers.ExpectContinue == true;
1451 if (System.Net.NetEventSource.Log.IsEnabled())
1452 {
1453 Trace($"Request content is not null, start processing it. hasExpectContinueHeader = {flag2}", "SendAsyncCore");
1454 }
1455 if (!flag2)
1456 {
1458 }
1459 else
1460 {
1463 Timer expect100Timer = new Timer(delegate(object s)
1464 {
1465 ((TaskCompletionSource<bool>)s).TrySetResult(result: true);
1468 }
1469 }
1470 _allowedReadLineBytes = (int)Math.Min(2147483647L, (long)_pool.Settings._maxResponseHeadersLength * 1024L);
1472 if (!valueTask.HasValue)
1473 {
1474 await InitialFillAsync(async).ConfigureAwait(continueOnCapturedContext: false);
1475 }
1476 else
1477 {
1478 ValueTask<int> valueOrDefault = valueTask.GetValueOrDefault();
1479 int num;
1480 if (valueOrDefault.IsCompleted)
1481 {
1482 num = valueOrDefault.Result;
1483 }
1484 else
1485 {
1486 if (!async)
1487 {
1488 Trace("Pre-emptive read completed asynchronously for a synchronous request.", "SendAsyncCore");
1489 }
1490 num = await valueOrDefault.ConfigureAwait(continueOnCapturedContext: false);
1491 }
1492 if (System.Net.NetEventSource.Log.IsEnabled())
1493 {
1494 Trace($"Received {num} bytes.", "SendAsyncCore");
1495 }
1496 _readOffset = 0;
1497 _readLength = num;
1498 }
1499 if (_readLength == 0)
1500 {
1502 {
1503 _canRetry = true;
1504 }
1506 }
1508 {
1509 RequestMessage = request,
1510 Content = new HttpConnectionResponseContent()
1511 };
1513 if (HttpTelemetry.Log.IsEnabled())
1514 {
1515 HttpTelemetry.Log.ResponseHeadersStart();
1516 }
1517 while ((uint)(response.StatusCode - 100) <= 99u)
1518 {
1519 if (allowExpect100ToContinue != null && response.StatusCode == HttpStatusCode.Continue)
1520 {
1521 allowExpect100ToContinue.TrySetResult(result: true);
1523 }
1524 else if (response.StatusCode == HttpStatusCode.SwitchingProtocols)
1525 {
1526 break;
1527 }
1528 if (System.Net.NetEventSource.Log.IsEnabled())
1529 {
1530 Trace($"Current {response.StatusCode} response is an interim response or not expected, need to read for a final response.", "SendAsyncCore");
1531 }
1533 {
1534 }
1536 }
1537 while (true)
1538 {
1540 if (IsLineEmpty(line))
1541 {
1542 break;
1543 }
1544 ParseHeaderNameValue(this, line.Span, response, isFromTrailer: false);
1545 }
1546 if (HttpTelemetry.Log.IsEnabled())
1547 {
1548 HttpTelemetry.Log.ResponseHeadersStop();
1549 }
1550 if (allowExpect100ToContinue != null)
1551 {
1552 if (response.StatusCode >= HttpStatusCode.MultipleChoices && request.Content != null && (!request.Content.Headers.ContentLength.HasValue || request.Content.Headers.ContentLength.GetValueOrDefault() > 1024) && !AuthenticationHelper.IsSessionAuthenticationChallenge(response))
1553 {
1554 allowExpect100ToContinue.TrySetResult(result: false);
1555 if (!allowExpect100ToContinue.Task.Result)
1556 {
1557 _connectionClose = true;
1558 }
1559 }
1560 else
1561 {
1562 allowExpect100ToContinue.TrySetResult(result: true);
1563 }
1564 }
1565 if (response.Headers.ConnectionClose.GetValueOrDefault())
1566 {
1567 _connectionClose = true;
1568 }
1569 if (sendRequestContentTask != null)
1570 {
1573 await task.ConfigureAwait(continueOnCapturedContext: false);
1574 }
1575 if (System.Net.NetEventSource.Log.IsEnabled())
1576 {
1577 Trace("Request is fully sent.", "SendAsyncCore");
1578 }
1579 cancellationRegistration.Dispose();
1581 Stream stream;
1582 if ((object)normalizedMethod == HttpMethod.Head || response.StatusCode == HttpStatusCode.NoContent || response.StatusCode == HttpStatusCode.NotModified)
1583 {
1586 }
1587 else if ((object)normalizedMethod == HttpMethod.Connect && response.StatusCode == HttpStatusCode.OK)
1588 {
1589 stream = new RawConnectionStream(this);
1590 _connectionClose = true;
1592 _detachedFromPool = true;
1593 }
1594 else if (response.StatusCode == HttpStatusCode.SwitchingProtocols)
1595 {
1596 stream = new RawConnectionStream(this);
1597 _connectionClose = true;
1599 _detachedFromPool = true;
1600 }
1601 else if (!response.Content.Headers.ContentLength.HasValue)
1602 {
1603 stream = ((response.Headers.TransferEncodingChunked != true) ? ((HttpContentReadStream)new ConnectionCloseReadStream(this)) : ((HttpContentReadStream)new ChunkedEncodingReadStream(this, response)));
1604 }
1605 else
1606 {
1607 long valueOrDefault2 = response.Content.Headers.ContentLength.GetValueOrDefault();
1608 if (valueOrDefault2 <= 0)
1609 {
1612 }
1613 else
1614 {
1616 }
1617 }
1618 ((HttpConnectionResponseContent)response.Content).SetStream(stream);
1619 if (System.Net.NetEventSource.Log.IsEnabled())
1620 {
1621 Trace($"Received response: {response}", "SendAsyncCore");
1622 }
1624 {
1626 }
1627 result = response;
1628 return result;
1629 }
1630 catch (Exception ex)
1631 {
1632 Exception error = ex;
1633 cancellationRegistration.Dispose();
1634 allowExpect100ToContinue?.TrySetResult(result: false);
1635 if (System.Net.NetEventSource.Log.IsEnabled())
1636 {
1637 Trace($"Error sending request: {error}", "SendAsyncCore");
1638 }
1639 if (sendRequestContentTask != null && !sendRequestContentTask.IsCompletedSuccessfully)
1640 {
1641 if (Volatile.Read(ref _disposed) == 1)
1642 {
1644 try
1645 {
1647 }
1649 {
1650 throw mappedException;
1651 }
1652 }
1654 }
1655 Dispose();
1657 {
1658 throw mappedException2;
1659 }
1660 if (!(ex is Exception source))
1661 {
1662 throw ex;
1663 }
1665 }
1666 return result;
1667 }
1668
1673
1694
1696 {
1697 return (request.HasHeaders && request.Headers.TransferEncodingChunked == true) ? ((HttpContentWriteStream)new ChunkedEncodingWriteStream(this)) : ((HttpContentWriteStream)new ContentLengthWriteStream(this));
1698 }
1699
1701 {
1702 return cancellationToken.Register(delegate(object s)
1703 {
1705 if (weakReference.TryGetTarget(out var target))
1706 {
1707 if (System.Net.NetEventSource.Log.IsEnabled())
1708 {
1709 target.Trace("Cancellation requested. Disposing of the connection.", "RegisterCancellation");
1710 }
1711 target.Dispose();
1712 }
1713 }, _weakThisRef);
1714 }
1715
1717 {
1718 return line.Length == 0;
1719 }
1720
1722 {
1724 if (HttpTelemetry.Log.IsEnabled())
1725 {
1726 HttpTelemetry.Log.RequestContentStart();
1727 }
1728 if (async)
1729 {
1730 await request.Content.CopyToAsync(stream, _transportContext, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
1731 }
1732 else
1733 {
1735 }
1736 await stream.FinishAsync(async).ConfigureAwait(continueOnCapturedContext: false);
1738 if (HttpTelemetry.Log.IsEnabled())
1739 {
1740 HttpTelemetry.Log.RequestContentStop(stream.BytesWritten);
1741 }
1742 if (System.Net.NetEventSource.Log.IsEnabled())
1743 {
1744 Trace("Finished sending request content.", "SendRequestContentAsync");
1745 }
1746 }
1747
1749 {
1750 bool flag = await allowExpect100ToContinueTask.ConfigureAwait(continueOnCapturedContext: false);
1751 expect100Timer.Dispose();
1752 if (flag)
1753 {
1754 if (System.Net.NetEventSource.Log.IsEnabled())
1755 {
1756 Trace("Sending request content for Expect: 100-continue.", "SendRequestContentWithExpect100ContinueAsync");
1757 }
1758 try
1759 {
1761 return;
1762 }
1763 catch
1764 {
1765 Dispose();
1766 throw;
1767 }
1768 }
1769 if (System.Net.NetEventSource.Log.IsEnabled())
1770 {
1771 Trace("Canceling request content for Expect: 100-continue.", "SendRequestContentWithExpect100ContinueAsync");
1772 }
1773 }
1774
1776 {
1777 if (line.Length < 12 || line[8] != 32)
1778 {
1780 }
1781 ulong num = BitConverter.ToUInt64(line);
1782 if (num == s_http11Bytes)
1783 {
1784 response.SetVersionWithoutValidation(HttpVersion.Version11);
1785 }
1786 else if (num == s_http10Bytes)
1787 {
1788 response.SetVersionWithoutValidation(HttpVersion.Version10);
1789 }
1790 else
1791 {
1792 byte b = line[7];
1793 if (!HttpConnectionBase.IsDigit(b) || !line.Slice(0, 7).SequenceEqual(s_http1DotBytes))
1794 {
1796 }
1797 response.SetVersionWithoutValidation(new Version(1, b - 48));
1798 }
1799 byte b2 = line[9];
1800 byte b3 = line[10];
1801 byte b4 = line[11];
1803 {
1805 }
1806 response.SetStatusCodeWithoutValidation((HttpStatusCode)(100 * (b2 - 48) + 10 * (b3 - 48) + (b4 - 48)));
1807 if (line.Length == 12)
1808 {
1809 response.SetReasonPhraseWithoutValidation(string.Empty);
1810 return;
1811 }
1812 if (line[12] == 32)
1813 {
1815 string text = HttpStatusDescription.Get(response.StatusCode);
1816 if (text != null && EqualsOrdinal(text, readOnlySpan))
1817 {
1818 response.SetReasonPhraseWithoutValidation(text);
1819 return;
1820 }
1821 try
1822 {
1823 response.ReasonPhrase = HttpRuleParser.DefaultHttpEncoding.GetString(readOnlySpan);
1824 return;
1825 }
1826 catch (FormatException inner)
1827 {
1829 }
1830 }
1832 }
1833
1835 {
1836 int i = 0;
1837 while (line[i] != 58 && line[i] != 32)
1838 {
1839 i++;
1840 if (i == line.Length)
1841 {
1843 }
1844 }
1845 if (i == 0)
1846 {
1848 }
1849 if (!HeaderDescriptor.TryGet(line.Slice(0, i), out var descriptor))
1850 {
1852 }
1853 if (isFromTrailer && descriptor.KnownHeader != null && (descriptor.KnownHeader.HeaderType & HttpHeaderType.NonTrailing) == HttpHeaderType.NonTrailing)
1854 {
1855 if (System.Net.NetEventSource.Log.IsEnabled())
1856 {
1857 connection.Trace("Stripping forbidden " + descriptor.Name + " from trailer headers.", "ParseHeaderNameValue");
1858 }
1859 return;
1860 }
1861 while (line[i] == 32)
1862 {
1863 i++;
1864 if (i == line.Length)
1865 {
1867 }
1868 }
1869 if (line[i++] != 58)
1870 {
1872 }
1873 for (; i < line.Length && (line[i] == 32 || line[i] == 9); i++)
1874 {
1875 }
1876 Encoding valueEncoding = connection._pool.Settings._responseHeaderEncodingSelector?.Invoke(descriptor.Name, response.RequestMessage);
1878 if (isFromTrailer)
1879 {
1880 string headerValue = descriptor.GetHeaderValue(readOnlySpan, valueEncoding);
1881 response.TrailingHeaders.TryAddWithoutValidation(((descriptor.HeaderType & HttpHeaderType.Request) == HttpHeaderType.Request) ? descriptor.AsCustomHeader() : descriptor, headerValue);
1882 }
1883 else if ((descriptor.HeaderType & HttpHeaderType.Content) == HttpHeaderType.Content)
1884 {
1885 string headerValue2 = descriptor.GetHeaderValue(readOnlySpan, valueEncoding);
1886 response.Content.Headers.TryAddWithoutValidation(descriptor, headerValue2);
1887 }
1888 else
1889 {
1891 response.Headers.TryAddWithoutValidation(((descriptor.HeaderType & HttpHeaderType.Request) == HttpHeaderType.Request) ? descriptor.AsCustomHeader() : descriptor, responseHeaderValueWithCaching);
1892 }
1893 }
1894
1896 {
1898 _writeOffset += source.Length;
1899 }
1900
1902 {
1904 _writeOffset += source.Length;
1905 }
1906
1908 {
1909 int num = _writeBuffer.Length - _writeOffset;
1910 if (source.Length <= num)
1911 {
1913 return;
1914 }
1915 if (_writeOffset != 0)
1916 {
1917 WriteToBuffer(source.Slice(0, num));
1918 source = source.Slice(num);
1919 Flush();
1920 }
1921 if (source.Length >= _writeBuffer.Length)
1922 {
1924 }
1925 else
1926 {
1928 }
1929 }
1930
1932 {
1933 int num = _writeBuffer.Length - _writeOffset;
1934 if (source.Length <= num)
1935 {
1937 return;
1938 }
1939 if (_writeOffset != 0)
1940 {
1941 WriteToBuffer(source.Slice(0, num));
1942 source = source.Slice(num);
1944 }
1945 if (source.Length >= _writeBuffer.Length)
1946 {
1948 }
1949 else
1950 {
1952 }
1953 }
1954
1956 {
1957 if (_writeOffset != 0)
1958 {
1959 int num = _writeBuffer.Length - _writeOffset;
1960 if (source.Length <= num)
1961 {
1963 Flush();
1964 return;
1965 }
1966 Flush();
1967 }
1969 }
1970
1972 {
1973 if (_writeOffset == 0)
1974 {
1976 }
1977 int num = _writeBuffer.Length - _writeOffset;
1978 if (source.Length <= num)
1979 {
1981 return FlushAsync(async);
1982 }
1984 }
1985
1991
1992 private Task WriteByteAsync(byte b, bool async)
1993 {
1994 if (_writeOffset < _writeBuffer.Length)
1995 {
1997 return Task.CompletedTask;
1998 }
1999 return WriteByteSlowAsync(b, async);
2000 }
2001
2008
2009 private Task WriteTwoBytesAsync(byte b1, byte b2, bool async)
2010 {
2011 if (_writeOffset <= _writeBuffer.Length - 2)
2012 {
2013 byte[] writeBuffer = _writeBuffer;
2014 writeBuffer[_writeOffset++] = b1;
2015 writeBuffer[_writeOffset++] = b2;
2016 return Task.CompletedTask;
2017 }
2019 }
2020
2026
2027 private Task WriteBytesAsync(byte[] bytes, bool async)
2028 {
2029 if (_writeOffset <= _writeBuffer.Length - bytes.Length)
2030 {
2032 _writeOffset += bytes.Length;
2033 return Task.CompletedTask;
2034 }
2035 return WriteBytesSlowAsync(bytes, bytes.Length, async);
2036 }
2037
2038 private async Task WriteBytesSlowAsync(byte[] bytes, int length, bool async)
2039 {
2040 int offset = 0;
2041 while (true)
2042 {
2043 int val = length - offset;
2044 int num = Math.Min(val, _writeBuffer.Length - _writeOffset);
2046 _writeOffset += num;
2047 offset += num;
2048 if (offset != length)
2049 {
2050 if (_writeOffset == _writeBuffer.Length)
2051 {
2053 _writeOffset = 0;
2054 }
2055 continue;
2056 }
2057 break;
2058 }
2059 }
2060
2061 private Task WriteStringAsync(string s, bool async)
2062 {
2064 if (s.Length <= _writeBuffer.Length - writeOffset)
2065 {
2066 byte[] writeBuffer = _writeBuffer;
2067 foreach (char c in s)
2068 {
2069 if ((c & 0xFF80u) != 0)
2070 {
2072 }
2073 writeBuffer[writeOffset++] = (byte)c;
2074 }
2076 return Task.CompletedTask;
2077 }
2078 return WriteStringAsyncSlow(s, async);
2079 }
2080
2081 private Task WriteStringAsync(string s, bool async, Encoding encoding)
2082 {
2083 if (encoding == null)
2084 {
2085 return WriteStringAsync(s, async);
2086 }
2087 if (encoding.GetMaxByteCount(s.Length) <= _writeBuffer.Length - _writeOffset)
2088 {
2089 _writeOffset += encoding.GetBytes(s, _writeBuffer.AsSpan(_writeOffset));
2090 return Task.CompletedTask;
2091 }
2092 return WriteStringWithEncodingAsyncSlow(s, async, encoding);
2093 }
2094
2096 {
2097 int minimumLength = ((s.Length <= 512) ? encoding.GetMaxByteCount(s.Length) : encoding.GetByteCount(s));
2098 byte[] rentedBuffer = ArrayPool<byte>.Shared.Rent(minimumLength);
2099 try
2100 {
2101 int bytes = encoding.GetBytes(s, rentedBuffer);
2103 }
2104 finally
2105 {
2106 ArrayPool<byte>.Shared.Return(rentedBuffer);
2107 }
2108 }
2109
2110 private Task WriteAsciiStringAsync(string s, bool async)
2111 {
2113 if (s.Length <= _writeBuffer.Length - writeOffset)
2114 {
2115 byte[] writeBuffer = _writeBuffer;
2116 foreach (char c in s)
2117 {
2118 writeBuffer[writeOffset++] = (byte)c;
2119 }
2121 return Task.CompletedTask;
2122 }
2123 return WriteStringAsyncSlow(s, async);
2124 }
2125
2126 private async Task WriteStringAsyncSlow(string s, bool async)
2127 {
2128 foreach (char c in s)
2129 {
2130 if ((c & 0xFF80u) != 0)
2131 {
2133 }
2135 }
2136 }
2137
2138 private void Flush()
2139 {
2140 if (_writeOffset > 0)
2141 {
2143 _writeOffset = 0;
2144 }
2145 }
2146
2148 {
2149 if (_writeOffset > 0)
2150 {
2152 _writeOffset = 0;
2153 return result;
2154 }
2155 return default(ValueTask);
2156 }
2157
2159 {
2160 if (System.Net.NetEventSource.Log.IsEnabled())
2161 {
2162 Trace($"Writing {source.Length} bytes.", "WriteToStream");
2163 }
2165 }
2166
2168 {
2169 if (System.Net.NetEventSource.Log.IsEnabled())
2170 {
2171 Trace($"Writing {source.Length} bytes.", "WriteToStreamAsync");
2172 }
2173 if (async)
2174 {
2175 return _stream.WriteAsync(source);
2176 }
2177 _stream.Write(source.Span);
2178 return default(ValueTask);
2179 }
2180
2182 {
2184 int num = span.IndexOf<byte>(10);
2185 if (num < 0)
2186 {
2187 if (_allowedReadLineBytes < span.Length)
2188 {
2190 }
2191 line = default(ReadOnlySpan<byte>);
2192 return false;
2193 }
2194 int num2 = num + 1;
2195 _readOffset += num2;
2198 line = span.Slice(0, (num > 0 && span[num - 1] == 13) ? (num - 1) : num);
2199 return true;
2200 }
2201
2203 {
2204 int previouslyScannedBytes = 0;
2205 int num;
2206 int num2;
2207 int readOffset;
2208 int num3;
2209 while (true)
2210 {
2212 num2 = Array.IndexOf(_readBuffer, (byte)10, num, _readLength - num);
2213 if (num2 >= 0)
2214 {
2216 num3 = num2 - readOffset;
2217 if (num2 > 0 && _readBuffer[num2 - 1] == 13)
2218 {
2219 num3--;
2220 }
2221 if (!foldedHeadersAllowed || num3 <= 0)
2222 {
2223 break;
2224 }
2225 if (num2 + 1 == _readLength)
2226 {
2227 int num4 = ((_readBuffer[num2 - 1] == 13) ? (num2 - 2) : (num2 - 1));
2229 _allowedReadLineBytes -= num4 - num;
2231 await FillAsync(async).ConfigureAwait(continueOnCapturedContext: false);
2232 continue;
2233 }
2234 char c = (char)_readBuffer[num2 + 1];
2235 if (c != ' ' && c != '\t')
2236 {
2237 break;
2238 }
2239 if (Array.IndexOf(_readBuffer, (byte)58, _readOffset, num2 - _readOffset) == -1)
2240 {
2242 }
2243 _readBuffer[num2] = 32;
2244 if (_readBuffer[num2 - 1] == 13)
2245 {
2246 _readBuffer[num2 - 1] = 32;
2247 }
2249 _allowedReadLineBytes -= num2 + 1 - num;
2251 }
2252 else
2253 {
2257 await FillAsync(async).ConfigureAwait(continueOnCapturedContext: false);
2258 }
2259 }
2260 _allowedReadLineBytes -= num2 + 1 - num;
2262 _readOffset = num2 + 1;
2264 }
2265
2273
2274 private void Fill()
2275 {
2276 FillAsync(async: false).GetAwaiter().GetResult();
2277 }
2278
2280 {
2281 _readOffset = 0;
2284 if (System.Net.NetEventSource.Log.IsEnabled())
2285 {
2286 Trace($"Received {_readLength} bytes.", "InitialFillAsync");
2287 }
2288 }
2289
2291 {
2292 int num = _readLength - _readOffset;
2293 if (num == 0)
2294 {
2295 _readOffset = (_readLength = 0);
2296 }
2297 else if (_readOffset > 0)
2298 {
2300 _readOffset = 0;
2301 _readLength = num;
2302 }
2303 else if (num == _readBuffer.Length)
2304 {
2305 byte[] array = new byte[_readBuffer.Length * 2];
2306 Buffer.BlockCopy(_readBuffer, 0, array, 0, num);
2308 _readOffset = 0;
2309 _readLength = num;
2310 }
2312 int num3 = num2;
2313 if (System.Net.NetEventSource.Log.IsEnabled())
2314 {
2315 Trace($"Received {num3} bytes.", "FillAsync");
2316 }
2317 if (num3 == 0)
2318 {
2320 }
2321 _readLength += num3;
2322 }
2323
2325 {
2327 _readOffset += buffer.Length;
2328 }
2329
2331 {
2332 int num = _readLength - _readOffset;
2333 if (num > 0)
2334 {
2335 if (destination.Length <= num)
2336 {
2338 return destination.Length;
2339 }
2340 ReadFromBuffer(destination.Slice(0, num));
2341 return num;
2342 }
2344 if (System.Net.NetEventSource.Log.IsEnabled())
2345 {
2346 Trace($"Received {num2} bytes.", "Read");
2347 }
2348 return num2;
2349 }
2350
2352 {
2353 int num = _readLength - _readOffset;
2354 if (num > 0)
2355 {
2356 if (destination.Length <= num)
2357 {
2359 return destination.Length;
2360 }
2361 ReadFromBuffer(destination.Span.Slice(0, num));
2362 return num;
2363 }
2365 if (System.Net.NetEventSource.Log.IsEnabled())
2366 {
2367 Trace($"Received {num2} bytes.", "ReadAsync");
2368 }
2369 return num2;
2370 }
2371
2373 {
2374 int num = _readLength - _readOffset;
2375 if (num > 0)
2376 {
2377 if (destination.Length <= num)
2378 {
2380 return destination.Length;
2381 }
2382 ReadFromBuffer(destination.Slice(0, num));
2383 return num;
2384 }
2385 _readOffset = (_readLength = 0);
2386 int num2 = _stream.Read(_readBuffer, 0, _readBuffer.Length);
2387 if (System.Net.NetEventSource.Log.IsEnabled())
2388 {
2389 Trace($"Received {num2} bytes.", "ReadBuffered");
2390 }
2391 _readLength = num2;
2392 int num3 = Math.Min(num2, destination.Length);
2393 _readBuffer.AsSpan(0, num3).CopyTo(destination);
2394 _readOffset = num3;
2395 return num3;
2396 }
2397
2399 {
2400 if (destination.Length < _readBuffer.Length)
2401 {
2403 }
2404 return ReadAsync(destination);
2405 }
2406
2408 {
2409 int num = _readLength - _readOffset;
2410 if (num > 0)
2411 {
2412 if (destination.Length <= num)
2413 {
2415 return destination.Length;
2416 }
2417 ReadFromBuffer(destination.Span.Slice(0, num));
2418 return num;
2419 }
2420 _readOffset = (_readLength = 0);
2421 int num2 = await _stream.ReadAsync(_readBuffer.AsMemory()).ConfigureAwait(continueOnCapturedContext: false);
2422 if (System.Net.NetEventSource.Log.IsEnabled())
2423 {
2424 Trace($"Received {num2} bytes.", "ReadBufferedAsyncCore");
2425 }
2426 _readLength = num2;
2427 int num3 = Math.Min(num2, destination.Length);
2428 _readBuffer.AsSpan(0, num3).CopyTo(destination.Span);
2429 _readOffset = num3;
2430 return num3;
2431 }
2432
2434 {
2435 if (System.Net.NetEventSource.Log.IsEnabled())
2436 {
2437 Trace($"Copying {count} bytes to stream.", "CopyFromBufferAsync");
2438 }
2439 int readOffset = _readOffset;
2440 _readOffset += count;
2441 if (async)
2442 {
2444 }
2446 return default(ValueTask);
2447 }
2448
2463
2478
2480 {
2482 if (remaining > 0)
2483 {
2484 if ((ulong)remaining > length)
2485 {
2486 remaining = (int)length;
2487 }
2489 length -= (ulong)remaining;
2490 if (length == 0L)
2491 {
2492 return;
2493 }
2494 }
2495 byte[] origReadBuffer = null;
2496 try
2497 {
2498 while (true)
2499 {
2500 await FillAsync(async).ConfigureAwait(continueOnCapturedContext: false);
2501 remaining = (((ulong)_readLength < length) ? _readLength : ((int)length));
2503 length -= (ulong)remaining;
2504 if (length == 0L)
2505 {
2506 break;
2507 }
2508 if (origReadBuffer != null)
2509 {
2510 continue;
2511 }
2512 byte[] readBuffer = _readBuffer;
2513 if (remaining == readBuffer.Length)
2514 {
2515 int num = (int)Math.Min((ulong)bufferSize, length);
2516 if (num > readBuffer.Length)
2517 {
2518 origReadBuffer = readBuffer;
2519 _readBuffer = ArrayPool<byte>.Shared.Rent(num);
2520 }
2521 }
2522 }
2523 }
2524 finally
2525 {
2526 if (origReadBuffer != null)
2527 {
2528 byte[] readBuffer2 = _readBuffer;
2530 ArrayPool<byte>.Shared.Return(readBuffer2);
2531 _readLength = ((_readOffset < _readLength) ? 1 : 0);
2532 _readOffset = 0;
2533 }
2534 }
2535 }
2536
2537 internal void Acquire()
2538 {
2539 _inUse = true;
2540 }
2541
2542 internal void Release()
2543 {
2544 _inUse = false;
2545 if (_currentRequest == null)
2546 {
2548 }
2549 }
2550
2551 internal void DetachFromPool()
2552 {
2553 _detachedFromPool = true;
2554 }
2555
2556 private void CompleteResponse()
2557 {
2558 _currentRequest = null;
2559 if (_readLength != _readOffset)
2560 {
2561 if (System.Net.NetEventSource.Log.IsEnabled())
2562 {
2563 Trace("Unexpected data on connection after response read.", "CompleteResponse");
2564 }
2565 _readOffset = (_readLength = 0);
2566 _connectionClose = true;
2567 }
2568 if (!_inUse)
2569 {
2571 }
2572 }
2573
2587
2589 {
2590 if (_connectionClose)
2591 {
2592 if (System.Net.NetEventSource.Log.IsEnabled())
2593 {
2594 Trace("Connection will not be reused.", "ReturnConnectionToPool");
2595 }
2596 Dispose();
2597 }
2598 else
2599 {
2602 }
2603 }
2604
2605 private static bool EqualsOrdinal(string left, ReadOnlySpan<byte> right)
2606 {
2607 if (left.Length != right.Length)
2608 {
2609 return false;
2610 }
2611 for (int i = 0; i < left.Length; i++)
2612 {
2613 if (left[i] != right[i])
2614 {
2615 return false;
2616 }
2617 }
2618 return true;
2619 }
2620
2621 public sealed override string ToString()
2622 {
2623 return $"{"HttpConnection"}({_pool})";
2624 }
2625
2626 public sealed override void Trace(string message, [CallerMemberName] string memberName = null)
2627 {
2628 System.Net.NetEventSource.Log.HandlerMessage(_pool?.GetHashCode() ?? 0, GetHashCode(), _currentRequest?.GetHashCode() ?? 0, memberName, message);
2629 }
2630}
int IList. IndexOf(object value)
Definition Array.cs:1228
static string ToString(byte[] value, int startIndex, int length)
static ulong ToUInt64(byte[] value, int startIndex)
static void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)
Definition Buffer.cs:102
static bool TryFormat(bool value, Span< byte > destination, out int bytesWritten, StandardFormat format=default(StandardFormat))
static bool TryParse(ReadOnlySpan< byte > source, out bool value, out int bytesConsumed, char standardFormat='\0')
void CopyTo(KeyValuePair< TKey, TValue >[] array, int index)
static long TickCount64
static void SuppressFinalize(object obj)
Definition GC.cs:202
Definition GC.cs:8
static CultureInfo InvariantCulture
static void ValidateCopyToArguments(Stream destination, int bufferSize)
Definition Stream.cs:1060
Task WriteAsync(byte[] buffer, int offset, int count)
Definition Stream.cs:914
int Read(byte[] buffer, int offset, int count)
void CopyTo(Stream destination)
Definition Stream.cs:540
void Dispose()
Definition Stream.cs:639
Task< int > ReadAsync(byte[] buffer, int offset, int count)
Definition Stream.cs:762
void Write(byte[] buffer, int offset, int count)
Task CopyToAsync(Stream destination)
Definition Stream.cs:571
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static string Get(HttpStatusCode code)
static readonly Version Version10
Definition HttpVersion.cs:7
static readonly Version Version11
Definition HttpVersion.cs:9
static bool IsSessionAuthenticationChallenge(HttpResponseMessage response)
static bool ShouldWrapInOperationCanceledException(Exception exception, CancellationToken cancellationToken)
static Exception CreateOperationCanceledException(Exception innerException, CancellationToken cancellationToken)
static void ThrowIfCancellationRequested(CancellationToken cancellationToken)
static void ProcessReceivedCookies(HttpResponseMessage response, CookieContainer cookieContainer)
static EmptyReadStream Instance
static int GetStoreValuesIntoStringArray(HeaderDescriptor descriptor, object sourceValues, [NotNull] ref string[] values)
static readonly KnownHeader Host
static readonly KnownHeader Cookie
string GetResponseHeaderValueWithCaching(HeaderDescriptor descriptor, ReadOnlySpan< byte > value, Encoding valueEncoding)
static void IgnoreExceptions(ValueTask< int > task)
void InvalidateHttp11Connection(HttpConnection connection, bool disposing=true)
void ReturnHttp11Connection(HttpConnection connection, bool isNewConnection=false)
HeaderEncodingSelector< HttpRequestMessage > _responseHeaderEncodingSelector
HeaderEncodingSelector< HttpRequestMessage > _requestHeaderEncodingSelector
ChunkedEncodingReadStream(HttpConnection connection, HttpResponseMessage response)
override ValueTask< int > ReadAsync(Memory< byte > buffer, CancellationToken cancellationToken)
async Task CopyToAsyncCore(Stream destination, CancellationToken cancellationToken)
int ReadChunksFromConnectionBuffer(Span< byte > buffer, CancellationTokenRegistration cancellationRegistration)
override async ValueTask< bool > DrainAsync(int maxDrainBytes)
static void ValidateChunkExtension(ReadOnlySpan< byte > lineAfterChunkSize)
override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
ReadOnlyMemory< byte > ReadChunkFromConnectionBuffer(int maxBytesToRead, CancellationTokenRegistration cancellationRegistration)
async ValueTask< int > ReadAsyncCore(Memory< byte > buffer, CancellationToken cancellationToken)
override void Write(ReadOnlySpan< byte > buffer)
override ValueTask WriteAsync(ReadOnlyMemory< byte > buffer, CancellationToken ignored)
override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
async Task CompleteCopyToAsync(Task copyTask, HttpConnection connection, CancellationToken cancellationToken)
override async ValueTask< int > ReadAsync(Memory< byte > buffer, CancellationToken cancellationToken)
ContentLengthReadStream(HttpConnection connection, ulong contentLength)
override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
override async ValueTask< int > ReadAsync(Memory< byte > buffer, CancellationToken cancellationToken)
override async ValueTask< bool > DrainAsync(int maxDrainBytes)
ReadOnlyMemory< byte > ReadFromConnectionBuffer(int maxBytesToRead)
async Task CompleteCopyToAsync(Task copyTask, CancellationToken cancellationToken)
override void Write(ReadOnlySpan< byte > buffer)
override ValueTask WriteAsync(ReadOnlyMemory< byte > buffer, CancellationToken ignored)
override void Write(ReadOnlySpan< byte > buffer)
virtual ValueTask< bool > DrainAsync(int maxDrainBytes)
override ValueTask WriteAsync(ReadOnlyMemory< byte > destination, CancellationToken cancellationToken)
override ValueTask< int > ReadAsync(Memory< byte > buffer, CancellationToken cancellationToken)
override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
override Task FlushAsync(CancellationToken ignored)
override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
async Task CompleteCopyToAsync(Task copyTask, HttpConnection connection, CancellationToken cancellationToken)
override void Write(ReadOnlySpan< byte > buffer)
override ValueTask WriteAsync(ReadOnlyMemory< byte > buffer, CancellationToken cancellationToken)
override Task FlushAsync(CancellationToken cancellationToken)
static async Task WaitWithConnectionCancellationAsync(ValueTask task, HttpConnection connection, CancellationToken cancellationToken)
override async ValueTask< int > ReadAsync(Memory< byte > buffer, CancellationToken cancellationToken)
readonly WeakReference< HttpConnection > _weakThisRef
HttpContentWriteStream CreateRequestContentStream(HttpRequestMessage request)
async Task< HttpResponseMessage > SendAsyncCore(HttpRequestMessage request, bool async, CancellationToken cancellationToken)
Task WriteTwoBytesAsync(byte b1, byte b2, bool async)
Task WriteBytesAsync(byte[] bytes, bool async)
static readonly byte[] s_http1DotBytes
static bool EqualsOrdinal(string left, ReadOnlySpan< byte > right)
Task WriteAsciiStringAsync(string s, bool async)
async ValueTask WriteAsync(ReadOnlyMemory< byte > source, bool async)
void Write(ReadOnlySpan< byte > source)
bool TryReadNextLine(out ReadOnlySpan< byte > line)
ValueTask WriteToStreamAsync(ReadOnlyMemory< byte > source, bool async)
async Task CopyToContentLengthAsync(Stream destination, bool async, ulong length, int bufferSize, CancellationToken cancellationToken)
int Read(Span< byte > destination)
async ValueTask DrainResponseAsync(HttpResponseMessage response, CancellationToken cancellationToken)
readonly TransportContext _transportContext
async ValueTask< ReadOnlyMemory< byte > > ReadNextResponseHeaderLineAsync(bool async, bool foldedHeadersAllowed=false)
bool MapSendException(Exception exception, CancellationToken cancellationToken, out Exception mappedException)
Task< HttpResponseMessage > SendAsync(HttpRequestMessage request, bool async, CancellationToken cancellationToken)
async ValueTask FillAsync(bool async)
void ReadFromBuffer(Span< byte > buffer)
async ValueTask< int > ReadAsync(Memory< byte > destination)
async Task CopyToUntilEofWithExistingBufferedDataAsync(Stream destination, bool async, int bufferSize, CancellationToken cancellationToken)
static readonly byte[] s_spaceHttp10NewlineAsciiBytes
void WriteToBuffer(ReadOnlyMemory< byte > source)
static readonly byte[] s_spaceHttp11NewlineAsciiBytes
async ValueTask SendRequestContentAsync(HttpRequestMessage request, HttpContentWriteStream stream, bool async, CancellationToken cancellationToken)
async ValueTask< int > ReadBufferedAsyncCore(Memory< byte > destination)
void WriteWithoutBuffering(ReadOnlySpan< byte > source)
async Task WriteStringWithEncodingAsyncSlow(string s, bool async, Encoding encoding)
static readonly ulong s_http10Bytes
HttpConnection(HttpConnectionPool pool, Socket socket, Stream stream, TransportContext transportContext)
ValueTask FlushAsync(bool async)
async ValueTask InitialFillAsync(bool async)
static readonly ulong s_http11Bytes
Task WriteStringAsync(string s, bool async)
async Task SendRequestContentWithExpect100ContinueAsync(HttpRequestMessage request, Task< bool > allowExpect100ToContinueTask, HttpContentWriteStream stream, Timer expect100Timer, bool async, CancellationToken cancellationToken)
Task WriteHexInt32Async(int value, bool async)
CancellationTokenRegistration RegisterCancellation(CancellationToken cancellationToken)
async ValueTask WriteHostHeaderAsync(Uri uri, bool async)
async Task WriteBytesSlowAsync(byte[] bytes, int length, bool async)
ValueTask< int > ReadBufferedAsync(Memory< byte > destination)
static void ParseHeaderNameValue(HttpConnection connection, ReadOnlySpan< byte > line, HttpResponseMessage response, bool isFromTrailer)
async Task WriteByteSlowAsync(byte b, bool async)
void WriteToStream(ReadOnlySpan< byte > source)
ReadOnlyMemory< byte > RemainingBuffer
ValueTask CopyFromBufferAsync(Stream destination, bool async, int count, CancellationToken cancellationToken)
int ReadBuffered(Span< byte > destination)
readonly HttpConnectionPool _pool
ValueTask WriteWithoutBufferingAsync(ReadOnlyMemory< byte > source, bool async)
Task WriteByteAsync(byte b, bool async)
static void ParseStatusLine(ReadOnlySpan< byte > line, HttpResponseMessage response)
void WriteToBuffer(ReadOnlySpan< byte > source)
async ValueTask WriteHeadersAsync(HttpHeaders headers, string cookiesFromContainer, bool async)
Task CopyToUntilEofAsync(Stream destination, bool async, int bufferSize, CancellationToken cancellationToken)
override void Trace(string message, [CallerMemberName] string memberName=null)
void ConsumeFromRemainingBuffer(int bytesToConsume)
override long GetIdleTicks(long nowTicks)
Task WriteStringAsync(string s, bool async, Encoding encoding)
Task WriteDecimalInt32Async(int value, bool async)
async Task WriteTwoBytesSlowAsync(byte b1, byte b2, bool async)
static readonly byte[] s_httpSchemeAndDelimiter
static bool IsLineEmpty(ReadOnlyMemory< byte > line)
async ValueTask FlushThenWriteWithoutBufferingAsync(ReadOnlyMemory< byte > source, bool async)
async Task WriteStringAsyncSlow(string s, bool async)
ValueTask< int >? ConsumeReadAheadTask()
static readonly byte[] s_contentLength0NewlineAsciiBytes
static HttpMethod Head
Definition HttpMethod.cs:43
static HttpMethod Normalize(HttpMethod method)
static HttpMethod Connect
Definition HttpMethod.cs:51
static Encoding DefaultHttpEncoding
static readonly HttpTelemetry Log
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)
bool Poll(int microSeconds, SelectMode mode)
Definition Socket.cs:2337
static ExceptionDispatchInfo Capture(Exception source)
static string net_http_invalid_response_premature_eof
Definition SR.cs:94
static string ObjectDisposed_StreamClosed
Definition SR.cs:20
static string net_http_invalid_response_header_line
Definition SR.cs:116
static string net_http_invalid_response_chunk_extension_invalid
Definition SR.cs:102
static string net_http_response_headers_exceeded_length
Definition SR.cs:124
static string net_http_content_readonly_stream
Definition SR.cs:44
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string net_http_invalid_response_status_reason
Definition SR.cs:110
static string net_http_invalid_response_status_code
Definition SR.cs:108
static string net_http_client_execution_error
Definition SR.cs:58
static string net_http_invalid_response_chunk_header_invalid
Definition SR.cs:100
static string net_http_invalid_response_status_line
Definition SR.cs:106
static string net_http_invalid_response_chunk_terminator_invalid
Definition SR.cs:104
static string net_http_request_no_host
Definition SR.cs:144
static string net_http_request_invalid_char_encoding
Definition SR.cs:132
static string net_http_invalid_response_premature_eof_bytecount
Definition SR.cs:98
static string net_http_invalid_response_header_folder
Definition SR.cs:114
static string net_http_authconnectionfailure
Definition SR.cs:158
static string net_http_invalid_response_header_name
Definition SR.cs:118
Definition SR.cs:7
static Encoding ASCII
Definition Encoding.cs:511
virtual byte[] GetBytes(char[] chars)
Definition Encoding.cs:781
int GetMaxByteCount(int charCount)
virtual int GetByteCount(char[] chars)
Definition Encoding.cs:713
static int CompareExchange(ref int location1, int value, int comparand)
static int Exchange(ref int location1, int value)
new ConfiguredTaskAwaitable< TResult > ConfigureAwait(bool continueOnCapturedContext)
Definition Task.cs:226
static Task FromCanceled(CancellationToken cancellationToken)
Definition Task.cs:3363
static Task CompletedTask
Definition Task.cs:1120
static readonly TimeSpan InfiniteTimeSpan
Definition Timeout.cs:5
static bool Read(ref bool location)
Definition Volatile.cs:67
static void Write(ref bool location, bool value)
Definition Volatile.cs:74
string IdnHost
Definition Uri.cs:537
bool IsDefaultPort
Definition Uri.cs:333
static readonly string SchemeDelimiter
Definition Uri.cs:187
UriHostNameType HostNameType
Definition Uri.cs:304
static readonly string UriSchemeHttp
Definition Uri.cs:165
int Port
Definition Uri.cs:453
static bool TryGet(string headerName, out HeaderDescriptor descriptor)
static ValueTask FromCanceled(CancellationToken cancellationToken)
Definition ValueTask.cs:180
ConfiguredValueTaskAwaitable ConfigureAwait(bool continueOnCapturedContext)
Definition ValueTask.cs:312
static ValueTask FromException(Exception exception)
Definition ValueTask.cs:190
static readonly TimeSpan Zero
Definition TimeSpan.cs:21