4
4
using System ;
5
5
using System . Collections . Generic ;
6
6
using System . Diagnostics ;
7
- using System . Diagnostics . CodeAnalysis ;
8
7
using System . IO ;
9
- using System . Net ;
10
8
using System . Runtime . InteropServices ;
11
9
using System . Threading ;
12
10
using System . Threading . Tasks ;
@@ -135,7 +133,7 @@ public void MarkDelegated()
135
133
if ( ! RequestContext . DisconnectToken . IsCancellationRequested )
136
134
{
137
135
// This is logged rather than thrown because it is too late for an exception to be visible in user code.
138
- Logger . LogError ( LoggerEventIds . FewerBytesThanExpected , "ResponseStream::Dispose; Fewer bytes were written than were specified in the Content-Length." ) ;
136
+ Log . FewerBytesThanExpected ( Logger ) ;
139
137
}
140
138
_requestContext . Abort ( ) ;
141
139
return ;
@@ -180,14 +178,14 @@ public void MarkDelegated()
180
178
if ( ThrowWriteExceptions )
181
179
{
182
180
var exception = new IOException ( string . Empty , new HttpSysException ( ( int ) statusCode ) ) ;
183
- Logger . LogError ( LoggerEventIds . WriteError , exception , "Flush" ) ;
181
+ Log . WriteError ( Logger , exception ) ;
184
182
Abort ( ) ;
185
183
throw exception ;
186
184
}
187
185
else
188
186
{
189
187
// Abort the request but do not close the stream, let future writes complete silently
190
- Logger . LogDebug ( LoggerEventIds . WriteErrorIgnored , $ "Flush; Ignored write exception: { statusCode } " ) ;
188
+ Log . WriteErrorIgnored ( Logger , statusCode ) ;
191
189
Abort ( dispose : false ) ;
192
190
}
193
191
}
@@ -350,7 +348,7 @@ private unsafe Task FlushInternalAsync(ArraySegment<byte> data, CancellationToke
350
348
}
351
349
catch ( Exception e )
352
350
{
353
- Logger . LogError ( LoggerEventIds . ErrorWhenFlushAsync , e , "FlushAsync" ) ;
351
+ Log . ErrorWhenFlushAsync ( Logger , e ) ;
354
352
asyncResult . Dispose ( ) ;
355
353
Abort ( ) ;
356
354
throw ;
@@ -360,21 +358,21 @@ private unsafe Task FlushInternalAsync(ArraySegment<byte> data, CancellationToke
360
358
{
361
359
if ( cancellationToken . IsCancellationRequested )
362
360
{
363
- Logger . LogDebug ( LoggerEventIds . WriteFlushCancelled , $ "FlushAsync; Write cancelled with error code: { statusCode } " ) ;
361
+ Log . WriteFlushCancelled ( Logger , statusCode ) ;
364
362
asyncResult . Cancel ( ThrowWriteExceptions ) ;
365
363
}
366
364
else if ( ThrowWriteExceptions )
367
365
{
368
366
asyncResult . Dispose ( ) ;
369
367
Exception exception = new IOException ( string . Empty , new HttpSysException ( ( int ) statusCode ) ) ;
370
- Logger . LogError ( LoggerEventIds . ErrorWhenFlushAsync , exception , "FlushAsync" ) ;
368
+ Log . ErrorWhenFlushAsync ( Logger , exception ) ;
371
369
Abort ( ) ;
372
370
throw exception ;
373
371
}
374
372
else
375
373
{
376
374
// Abort the request but do not close the stream, let future writes complete silently
377
- Logger . LogDebug ( LoggerEventIds . WriteErrorIgnored , $ "FlushAsync; Ignored write exception: { statusCode } " ) ;
375
+ Log . WriteErrorIgnored ( Logger , statusCode ) ;
378
376
asyncResult . FailSilently ( ) ;
379
377
}
380
378
}
@@ -488,6 +486,8 @@ private HttpApiTypes.HTTP_FLAGS ComputeLeftToWrite(long writeCount, bool endOfRe
488
486
489
487
public override void Write ( byte [ ] buffer , int offset , int count )
490
488
{
489
+ ValidateBufferArguments ( buffer , offset , count ) ;
490
+
491
491
if ( ! RequestContext . AllowSynchronousIO )
492
492
{
493
493
throw new InvalidOperationException ( "Synchronous IO APIs are disabled, see AllowSynchronousIO." ) ;
@@ -522,7 +522,7 @@ private void CheckWriteCount(long? count)
522
522
523
523
public override IAsyncResult BeginWrite ( byte [ ] buffer , int offset , int count , AsyncCallback callback , object state )
524
524
{
525
- return WriteAsync ( buffer , offset , count ) . ToIAsyncResult ( callback , state ) ;
525
+ return TaskToApm . Begin ( WriteAsync ( buffer , offset , count ) , callback , state ) ;
526
526
}
527
527
528
528
public override void EndWrite ( IAsyncResult asyncResult )
@@ -531,11 +531,14 @@ public override void EndWrite(IAsyncResult asyncResult)
531
531
{
532
532
throw new ArgumentNullException ( nameof ( asyncResult ) ) ;
533
533
}
534
- ( ( Task ) asyncResult ) . GetAwaiter ( ) . GetResult ( ) ;
534
+
535
+ TaskToApm . End ( asyncResult ) ;
535
536
}
536
537
537
538
public override Task WriteAsync ( byte [ ] buffer , int offset , int count , CancellationToken cancellationToken )
538
539
{
540
+ ValidateBufferArguments ( buffer , offset , count ) ;
541
+
539
542
// Validates for null and bounds. Allows count == 0.
540
543
// TODO: Verbose log parameters
541
544
var data = new ArraySegment < byte > ( buffer , offset , count ) ;
@@ -644,7 +647,7 @@ internal unsafe Task SendFileAsyncCore(string fileName, long offset, long? count
644
647
}
645
648
catch ( Exception e )
646
649
{
647
- Logger . LogError ( LoggerEventIds . FileSendAsyncError , e , "SendFileAsync" ) ;
650
+ Log . FileSendAsyncError ( Logger , e ) ;
648
651
asyncResult . Dispose ( ) ;
649
652
Abort ( ) ;
650
653
throw ;
@@ -654,21 +657,21 @@ internal unsafe Task SendFileAsyncCore(string fileName, long offset, long? count
654
657
{
655
658
if ( cancellationToken . IsCancellationRequested )
656
659
{
657
- Logger . LogDebug ( LoggerEventIds . FileSendAsyncCancelled , $ "SendFileAsync; Write cancelled with error code: { statusCode } " ) ;
660
+ Log . FileSendAsyncCancelled ( Logger , statusCode ) ;
658
661
asyncResult . Cancel ( ThrowWriteExceptions ) ;
659
662
}
660
663
else if ( ThrowWriteExceptions )
661
664
{
662
665
asyncResult . Dispose ( ) ;
663
666
var exception = new IOException ( string . Empty , new HttpSysException ( ( int ) statusCode ) ) ;
664
- Logger . LogError ( LoggerEventIds . FileSendAsyncError , exception , "SendFileAsync" ) ;
667
+ Log . FileSendAsyncError ( Logger , exception ) ;
665
668
Abort ( ) ;
666
669
throw exception ;
667
670
}
668
671
else
669
672
{
670
- // Abort the request but do not close the stream, let future writes complete silently
671
- Logger . LogDebug ( LoggerEventIds . FileSendAsyncErrorIgnored , $ "SendFileAsync; Ignored write exception: { statusCode } " ) ;
673
+ // Abort the request but do not close the stream, let future writes complete
674
+ Log . FileSendAsyncErrorIgnored ( Logger , statusCode ) ;
672
675
asyncResult . FailSilently ( ) ;
673
676
}
674
677
}
@@ -715,8 +718,6 @@ internal void SwitchToOpaqueMode()
715
718
716
719
// The final Content-Length async write can only be Canceled by CancelIoEx.
717
720
// Sync can only be Canceled by CancelSynchronousIo, but we don't attempt this right now.
718
- [ SuppressMessage ( "Microsoft.Usage" , "CA1806:DoNotIgnoreMethodResults" , Justification =
719
- "It is safe to ignore the return value on a cancel operation because the connection is being closed" ) ]
720
721
internal unsafe void CancelLastWrite ( )
721
722
{
722
723
ResponseStreamAsyncResult asyncState = _lastWrite ;
@@ -733,5 +734,72 @@ private void CheckDisposed()
733
734
throw new ObjectDisposedException ( GetType ( ) . FullName ) ;
734
735
}
735
736
}
737
+
738
+ private static class Log
739
+ {
740
+ private static readonly Action < ILogger , Exception > _fewerBytesThanExpected =
741
+ LoggerMessage . Define ( LogLevel . Error , LoggerEventIds . FewerBytesThanExpected , "ResponseStream::Dispose; Fewer bytes were written than were specified in the Content-Length." ) ;
742
+
743
+ private static readonly Action < ILogger , Exception > _writeError =
744
+ LoggerMessage . Define ( LogLevel . Error , LoggerEventIds . WriteError , "Flush" ) ;
745
+
746
+ private static readonly Action < ILogger , uint , Exception > _writeErrorIgnored =
747
+ LoggerMessage . Define < uint > ( LogLevel . Debug , LoggerEventIds . WriteErrorIgnored , "Flush; Ignored write exception: {StatusCode}" ) ;
748
+
749
+ private static readonly Action < ILogger , Exception > _errorWhenFlushAsync =
750
+ LoggerMessage . Define ( LogLevel . Debug , LoggerEventIds . ErrorWhenFlushAsync , "FlushAsync" ) ;
751
+
752
+ private static readonly Action < ILogger , uint , Exception > _writeFlushCancelled =
753
+ LoggerMessage . Define < uint > ( LogLevel . Debug , LoggerEventIds . WriteFlushCancelled , "FlushAsync; Write cancelled with error code: {StatusCode}" ) ;
754
+
755
+ private static readonly Action < ILogger , Exception > _fileSendAsyncError =
756
+ LoggerMessage . Define ( LogLevel . Error , LoggerEventIds . FileSendAsyncError , "SendFileAsync" ) ;
757
+
758
+ private static readonly Action < ILogger , uint , Exception > _fileSendAsyncCancelled =
759
+ LoggerMessage . Define < uint > ( LogLevel . Debug , LoggerEventIds . FileSendAsyncCancelled , "SendFileAsync; Write cancelled with error code: {StatusCode}" ) ;
760
+
761
+ private static readonly Action < ILogger , uint , Exception > _fileSendAsyncErrorIgnored =
762
+ LoggerMessage . Define < uint > ( LogLevel . Debug , LoggerEventIds . FileSendAsyncErrorIgnored , "SendFileAsync; Ignored write exception: {StatusCode}" ) ;
763
+
764
+ public static void FewerBytesThanExpected ( ILogger logger )
765
+ {
766
+ _fewerBytesThanExpected ( logger , null ) ;
767
+ }
768
+
769
+ public static void WriteError ( ILogger logger , IOException exception )
770
+ {
771
+ _writeError ( logger , exception ) ;
772
+ }
773
+
774
+ public static void WriteErrorIgnored ( ILogger logger , uint statusCode )
775
+ {
776
+ _writeErrorIgnored ( logger , statusCode , null ) ;
777
+ }
778
+
779
+ public static void ErrorWhenFlushAsync ( ILogger logger , Exception exception )
780
+ {
781
+ _errorWhenFlushAsync ( logger , exception ) ;
782
+ }
783
+
784
+ public static void WriteFlushCancelled ( ILogger logger , uint statusCode )
785
+ {
786
+ _writeFlushCancelled ( logger , statusCode , null ) ;
787
+ }
788
+
789
+ public static void FileSendAsyncError ( ILogger logger , Exception exception )
790
+ {
791
+ _fileSendAsyncError ( logger , exception ) ;
792
+ }
793
+
794
+ public static void FileSendAsyncCancelled ( ILogger logger , uint statusCode )
795
+ {
796
+ _fileSendAsyncCancelled ( logger , statusCode , null ) ;
797
+ }
798
+
799
+ public static void FileSendAsyncErrorIgnored ( ILogger logger , uint statusCode )
800
+ {
801
+ _fileSendAsyncErrorIgnored ( logger , statusCode , null ) ;
802
+ }
803
+ }
736
804
}
737
805
}
0 commit comments