1
1
// Licensed to the .NET Foundation under one or more agreements.
2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
4
+ using System . Globalization ;
5
+ using System . Text ;
6
+ using System . Text . Unicode ;
4
7
using Microsoft . AspNetCore . Http ;
5
8
using Microsoft . AspNetCore . Http . Features ;
6
9
using Microsoft . AspNetCore . OutputCaching . Memory ;
@@ -150,7 +153,7 @@ public void ContentIsNotModified_NotConditionalRequest_False()
150
153
}
151
154
152
155
[ Fact ]
153
- public void ContentIsNotModified_IfModifiedSince_FallsbackToDateHeader ( )
156
+ public void ContentIsNotModified_IfModifiedSince_FallsBackToDateHeader ( )
154
157
{
155
158
var utcNow = DateTimeOffset . UtcNow ;
156
159
var sink = new TestSink ( ) ;
@@ -329,7 +332,7 @@ public void ContentIsNotModified_IfNoneMatch_MatchesAtLeastOneValue_True()
329
332
}
330
333
331
334
[ Fact ]
332
- public void StartResponsegAsync_IfAllowResponseCaptureIsTrue_SetsResponseTime ( )
335
+ public void StartResponseAsync_IfAllowResponseCaptureIsTrue_SetsResponseTime ( )
333
336
{
334
337
var clock = new TestClock
335
338
{
@@ -798,10 +801,8 @@ public async Task Locking_PreventsConcurrentRequests()
798
801
// Wait for the second request to start before processing the first one
799
802
task2Executing . Wait ( ) ;
800
803
801
- // Simluate some delay to allow for the second request to run while this one is pending
804
+ // Simulate some delay to allow for the second request to run while this one is pending
802
805
await Task . Delay ( 500 ) ;
803
-
804
- c . Response . Write ( "Hello" + responseCounter ) ;
805
806
} ) ;
806
807
807
808
var context1 = TestUtils . CreateTestContext ( ) ;
@@ -826,35 +827,96 @@ public async Task Locking_PreventsConcurrentRequests()
826
827
Assert . Equal ( 1 , responseCounter ) ;
827
828
}
828
829
830
+ [ Fact ]
831
+ public async Task Locking_IgnoresNonCacheableResponses ( )
832
+ {
833
+ var responseCounter = 0 ;
834
+
835
+ var blocker1 = new TaskCompletionSource < bool > ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
836
+ var blocker2 = new TaskCompletionSource < bool > ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
837
+
838
+ var memoryStream1 = new MemoryStream ( ) ;
839
+ var memoryStream2 = new MemoryStream ( ) ;
840
+
841
+ var options = new OutputCacheOptions ( ) ;
842
+ options . AddBasePolicy ( build => build . Cache ( ) ) ;
843
+
844
+ var middleware = TestUtils . CreateTestMiddleware ( options : options , next : async c =>
845
+ {
846
+ responseCounter ++ ;
847
+
848
+ if ( responseCounter == 1 )
849
+ {
850
+ blocker1 . SetResult ( true ) ;
851
+ }
852
+
853
+ c . Response . Cookies . Append ( "a" , "b" ) ;
854
+ c . Response . Write ( "Hello" + responseCounter ) ;
855
+
856
+ await blocker2 . Task ;
857
+ } ) ;
858
+
859
+ var context1 = TestUtils . CreateTestContext ( ) ;
860
+ context1 . HttpContext . Request . Method = "GET" ;
861
+ context1 . HttpContext . Request . Path = "/" ;
862
+ context1 . HttpContext . Response . Body = memoryStream1 ;
863
+
864
+ var context2 = TestUtils . CreateTestContext ( ) ;
865
+ context2 . HttpContext . Request . Method = "GET" ;
866
+ context2 . HttpContext . Request . Path = "/" ;
867
+ context2 . HttpContext . Response . Body = memoryStream2 ;
868
+
869
+ var task1 = Task . Run ( ( ) => middleware . Invoke ( context1 . HttpContext ) ) ;
870
+
871
+ // Wait for context1 to be processed
872
+ await blocker1 . Task ;
873
+
874
+ // Start context2
875
+ var task2 = Task . Run ( ( ) => middleware . Invoke ( context2 . HttpContext ) ) ;
876
+
877
+ // Wait for it to be blocked by the locking feature
878
+ await Task . Delay ( 500 ) ;
879
+
880
+ // Unblock context1
881
+ blocker2 . SetResult ( true ) ;
882
+
883
+ await Task . WhenAll ( task1 , task2 ) ;
884
+
885
+ Assert . Equal ( 2 , responseCounter ) ;
886
+
887
+ // Ensure that even though two requests were processed, no result was returned from cache
888
+ Assert . Equal ( "Hello1" , Encoding . UTF8 . GetString ( memoryStream1 . ToArray ( ) ) ) ;
889
+ Assert . Equal ( "Hello2" , Encoding . UTF8 . GetString ( memoryStream2 . ToArray ( ) ) ) ;
890
+ }
891
+
829
892
[ Fact ]
830
893
public async Task Locking_ExecuteAllRequestsWhenDisabled ( )
831
894
{
832
895
var responseCounter = 0 ;
833
896
834
- var task1Executing = new ManualResetEventSlim ( false ) ;
835
- var task2Executing = new ManualResetEventSlim ( false ) ;
897
+ var blocker1 = new TaskCompletionSource < bool > ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
898
+ var blocker2 = new TaskCompletionSource < bool > ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
836
899
837
900
var options = new OutputCacheOptions ( ) ;
838
901
options . AddBasePolicy ( build => build . Cache ( ) . SetLocking ( false ) ) ;
839
902
840
- var middleware = TestUtils . CreateTestMiddleware ( options : options , next : c =>
903
+ var middleware = TestUtils . CreateTestMiddleware ( options : options , next : async c =>
841
904
{
842
905
responseCounter ++ ;
843
906
844
907
switch ( responseCounter )
845
908
{
846
909
case 1 :
847
- task1Executing . Set ( ) ;
848
- task2Executing . Wait ( ) ;
910
+ blocker1 . SetResult ( true ) ;
911
+ await blocker2 . Task ;
849
912
break ;
850
913
case 2 :
851
- task1Executing . Wait ( ) ;
852
- task2Executing . Set ( ) ;
914
+ await blocker1 . Task ;
915
+ blocker2 . SetResult ( true ) ;
853
916
break ;
854
917
}
855
918
856
919
c . Response . Write ( "Hello" + responseCounter ) ;
857
- return Task . CompletedTask ;
858
920
} ) ;
859
921
860
922
var context1 = TestUtils . CreateTestContext ( ) ;
0 commit comments