@@ -1998,5 +1998,90 @@ await ExpectAsync(Http2FrameType.HEADERS,
1998
1998
await WaitForConnectionErrorAsync < HPackEncodingException > ( ignoreNonGoAwayFrames : false , expectedLastStreamId : 1 , Http2ErrorCode . INTERNAL_ERROR ,
1999
1999
CoreStrings . HPackErrorNotEnoughBuffer ) ;
2000
2000
}
2001
+
2002
+ [ Fact ]
2003
+ public async Task WriteAsync_PreCancelledCancellationToken_DoesNotAbort ( )
2004
+ {
2005
+ var headers = new [ ]
2006
+ {
2007
+ new KeyValuePair < string , string > ( HeaderNames . Method , "GET" ) ,
2008
+ new KeyValuePair < string , string > ( HeaderNames . Path , "/" ) ,
2009
+ new KeyValuePair < string , string > ( HeaderNames . Scheme , "http" ) ,
2010
+ } ;
2011
+ await InitializeConnectionAsync ( async context =>
2012
+ {
2013
+ // The cancellation is checked at the start of WriteAsync and no application state is changed.
2014
+ await Assert . ThrowsAsync < OperationCanceledException > ( ( ) => context . Response . WriteAsync ( "hello," , new CancellationToken ( true ) ) ) ;
2015
+ Assert . False ( context . Response . HasStarted ) ;
2016
+ } ) ;
2017
+
2018
+ await StartStreamAsync ( 1 , headers , endStream : true ) ;
2019
+
2020
+ var headersFrame = await ExpectAsync ( Http2FrameType . HEADERS ,
2021
+ withLength : 55 ,
2022
+ withFlags : ( byte ) Http2HeadersFrameFlags . END_HEADERS ,
2023
+ withStreamId : 1 ) ;
2024
+ await ExpectAsync ( Http2FrameType . DATA ,
2025
+ withLength : 0 ,
2026
+ withFlags : ( byte ) Http2DataFrameFlags . END_STREAM ,
2027
+ withStreamId : 1 ) ;
2028
+
2029
+ await StopConnectionAsync ( expectedLastStreamId : 1 , ignoreNonGoAwayFrames : false ) ;
2030
+
2031
+ _hpackDecoder . Decode ( headersFrame . PayloadSequence , endHeaders : false , handler : this ) ;
2032
+
2033
+ Assert . Equal ( 3 , _decodedHeaders . Count ) ;
2034
+ Assert . Contains ( "date" , _decodedHeaders . Keys , StringComparer . OrdinalIgnoreCase ) ;
2035
+ Assert . Equal ( "200" , _decodedHeaders [ HeaderNames . Status ] ) ;
2036
+ Assert . Equal ( "0" , _decodedHeaders [ HeaderNames . ContentLength ] ) ;
2037
+ }
2038
+
2039
+ [ Fact ]
2040
+ public async Task WriteAsync_CancellationTokenTriggeredDueToFlowControl_SendRST ( )
2041
+ {
2042
+ var cts = new CancellationTokenSource ( ) ;
2043
+ var writeStarted = new TaskCompletionSource < int > ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
2044
+ var headers = new [ ]
2045
+ {
2046
+ new KeyValuePair < string , string > ( HeaderNames . Method , "GET" ) ,
2047
+ new KeyValuePair < string , string > ( HeaderNames . Path , "/" ) ,
2048
+ new KeyValuePair < string , string > ( HeaderNames . Scheme , "http" ) ,
2049
+ } ;
2050
+ await InitializeConnectionAsync ( async context =>
2051
+ {
2052
+ await context . Response . Body . FlushAsync ( ) ; // https://github.com/aspnet/KestrelHttpServer/issues/3031
2053
+ var writeTask = context . Response . WriteAsync ( "hello," , cts . Token ) ;
2054
+ writeStarted . SetResult ( 0 ) ;
2055
+ await Assert . ThrowsAsync < OperationCanceledException > ( ( ) => writeTask ) ;
2056
+ } ) ;
2057
+
2058
+ _clientSettings . InitialWindowSize = 0 ;
2059
+ await SendSettingsAsync ( ) ;
2060
+ await ExpectAsync ( Http2FrameType . SETTINGS ,
2061
+ withLength : 0 ,
2062
+ withFlags : ( byte ) Http2SettingsFrameFlags . ACK ,
2063
+ withStreamId : 0 ) ;
2064
+
2065
+ await StartStreamAsync ( 1 , headers , endStream : true ) ;
2066
+
2067
+ var headersFrame = await ExpectAsync ( Http2FrameType . HEADERS ,
2068
+ withLength : 37 ,
2069
+ withFlags : ( byte ) Http2HeadersFrameFlags . END_HEADERS ,
2070
+ withStreamId : 1 ) ;
2071
+
2072
+ await writeStarted . Task ;
2073
+
2074
+ cts . Cancel ( ) ;
2075
+
2076
+ await WaitForStreamErrorAsync ( 1 , Http2ErrorCode . INTERNAL_ERROR , null ) ;
2077
+
2078
+ await StopConnectionAsync ( expectedLastStreamId : 1 , ignoreNonGoAwayFrames : false ) ;
2079
+
2080
+ _hpackDecoder . Decode ( headersFrame . PayloadSequence , endHeaders : false , handler : this ) ;
2081
+
2082
+ Assert . Equal ( 2 , _decodedHeaders . Count ) ;
2083
+ Assert . Contains ( "date" , _decodedHeaders . Keys , StringComparer . OrdinalIgnoreCase ) ;
2084
+ Assert . Equal ( "200" , _decodedHeaders [ HeaderNames . Status ] ) ;
2085
+ }
2001
2086
}
2002
2087
}
0 commit comments