55using System . Buffers ;
66using System . Collections . Generic ;
77using System . Diagnostics ;
8+ using System . IO ;
89using System . Linq ;
910using System . Security . Claims ;
1011using System . Text ;
@@ -452,6 +453,191 @@ public async Task HandshakeSuccessSendsResponseWithoutError()
452453 }
453454 }
454455
456+ [ Fact ]
457+ public async Task HubMessageOverTheMaxMessageSizeThrows ( )
458+ {
459+ var payload = Encoding . UTF8 . GetBytes ( "{\" type\" :1, \" invocationId\" :\" 1\" , \" target\" : \" Echo\" , \" arguments\" :[\" hello\" ]}\u001e " ) ;
460+ var maximumMessageSize = payload . Length - 10 ;
461+ InvalidDataException exception = null ;
462+
463+ bool ExpectedErrors ( WriteContext writeContext )
464+ {
465+ if ( writeContext . LoggerName == "Microsoft.AspNetCore.SignalR.HubConnectionHandler" && ( writeContext . Exception is InvalidDataException ide ) )
466+ {
467+ exception = ide ;
468+ return true ;
469+ }
470+ return false ;
471+ }
472+
473+ using ( StartVerifiableLog ( ExpectedErrors ) )
474+ {
475+ var connectionHandler = HubConnectionHandlerTestUtils . GetHubConnectionHandler ( typeof ( HubT ) , LoggerFactory ,
476+ services => services . AddSignalR ( ) . AddHubOptions < HubT > ( o => o . MaximumReceiveMessageSize = maximumMessageSize ) ) ;
477+
478+ using ( var client = new TestClient ( ) )
479+ {
480+ var connectionHandlerTask = await client . ConnectAsync ( connectionHandler ) ;
481+
482+ await client . Connection . Application . Output . WriteAsync ( payload ) ;
483+
484+ client . Dispose ( ) ;
485+
486+ await connectionHandlerTask . OrTimeout ( ) ;
487+ }
488+ }
489+
490+ Assert . NotNull ( exception ) ;
491+ Assert . Equal ( exception . Message , $ "The maximum message size of { maximumMessageSize } B was exceeded. The message size can be configured in AddHubOptions.") ;
492+ }
493+
494+ [ Fact ]
495+ public async Task ChunkedHubMessageOverTheMaxMessageSizeThrows ( )
496+ {
497+ var payload = Encoding . UTF8 . GetBytes ( "{\" type\" :1, \" invocationId\" :\" 1\" , \" target\" : \" Echo\" , \" arguments\" :[\" hello\" ]}\u001e " ) ;
498+ var maximumMessageSize = payload . Length - 10 ;
499+ InvalidDataException exception = null ;
500+
501+ bool ExpectedErrors ( WriteContext writeContext )
502+ {
503+ if ( writeContext . LoggerName == "Microsoft.AspNetCore.SignalR.HubConnectionHandler" && ( writeContext . Exception is InvalidDataException ide ) )
504+ {
505+ exception = ide ;
506+ return true ;
507+ }
508+ return false ;
509+ }
510+
511+ using ( StartVerifiableLog ( ExpectedErrors ) )
512+ {
513+ var connectionHandler = HubConnectionHandlerTestUtils . GetHubConnectionHandler ( typeof ( HubT ) , LoggerFactory ,
514+ services => services . AddSignalR ( ) . AddHubOptions < HubT > ( o => o . MaximumReceiveMessageSize = maximumMessageSize ) ) ;
515+
516+ using ( var client = new TestClient ( ) )
517+ {
518+ var connectionHandlerTask = await client . ConnectAsync ( connectionHandler ) ;
519+
520+ await client . Connection . Application . Output . WriteAsync ( payload . AsMemory ( 0 , payload . Length / 2 ) ) ;
521+ await client . Connection . Application . Output . WriteAsync ( payload . AsMemory ( payload . Length / 2 ) ) ;
522+
523+ client . Dispose ( ) ;
524+
525+ await connectionHandlerTask . OrTimeout ( ) ;
526+ }
527+ }
528+
529+ Assert . NotNull ( exception ) ;
530+ Assert . Equal ( exception . Message , $ "The maximum message size of { maximumMessageSize } B was exceeded. The message size can be configured in AddHubOptions.") ;
531+ }
532+
533+ [ Fact ]
534+ public async Task ManyHubMessagesOneOverTheMaxMessageSizeThrows ( )
535+ {
536+ var payload1 = Encoding . UTF8 . GetBytes ( "{\" type\" :1, \" invocationId\" :\" 1\" , \" target\" : \" Echo\" , \" arguments\" :[\" one\" ]}\u001e " ) ;
537+ var payload2 = Encoding . UTF8 . GetBytes ( "{\" type\" :1, \" invocationId\" :\" 2\" , \" target\" : \" Echo\" , \" arguments\" :[\" two\" ]}\u001e " ) ;
538+ var payload3 = Encoding . UTF8 . GetBytes ( "{\" type\" :1, \" invocationId\" :\" 3\" , \" target\" : \" Echo\" , \" arguments\" :[\" three\" ]}\u001e " ) ;
539+
540+ // Between the first and the second payload so we'll end up slicing with some remaining in the slice for
541+ // the next message
542+ var maximumMessageSize = payload1 . Length + 1 ;
543+ InvalidDataException exception = null ;
544+
545+ bool ExpectedErrors ( WriteContext writeContext )
546+ {
547+ if ( writeContext . LoggerName == "Microsoft.AspNetCore.SignalR.HubConnectionHandler" && ( writeContext . Exception is InvalidDataException ide ) )
548+ {
549+ exception = ide ;
550+ return true ;
551+ }
552+ return false ;
553+ }
554+
555+ using ( StartVerifiableLog ( ExpectedErrors ) )
556+ {
557+ var connectionHandler = HubConnectionHandlerTestUtils . GetHubConnectionHandler ( typeof ( HubT ) , LoggerFactory ,
558+ services => services . AddSignalR ( ) . AddHubOptions < HubT > ( o => o . MaximumReceiveMessageSize = maximumMessageSize ) ) ;
559+
560+ using ( var client = new TestClient ( ) )
561+ {
562+ var connectionHandlerTask = await client . ConnectAsync ( connectionHandler ) ;
563+
564+ client . Connection . Application . Output . Write ( payload1 ) ;
565+ client . Connection . Application . Output . Write ( payload2 ) ;
566+ client . Connection . Application . Output . Write ( payload3 ) ;
567+ await client . Connection . Application . Output . FlushAsync ( ) ;
568+
569+ // 2 invocations should be processed
570+ var completionMessage = await client . ReadAsync ( ) . OrTimeout ( ) as CompletionMessage ;
571+ Assert . NotNull ( completionMessage ) ;
572+ Assert . Equal ( "1" , completionMessage . InvocationId ) ;
573+ Assert . Equal ( "one" , completionMessage . Result ) ;
574+
575+ completionMessage = await client . ReadAsync ( ) . OrTimeout ( ) as CompletionMessage ;
576+ Assert . NotNull ( completionMessage ) ;
577+ Assert . Equal ( "2" , completionMessage . InvocationId ) ;
578+ Assert . Equal ( "two" , completionMessage . Result ) ;
579+
580+ // We never receive the 3rd message since it was over the maximum message size
581+ CloseMessage closeMessage = await client . ReadAsync ( ) . OrTimeout ( ) as CloseMessage ;
582+ Assert . NotNull ( closeMessage ) ;
583+
584+ client . Dispose ( ) ;
585+
586+ await connectionHandlerTask . OrTimeout ( ) ;
587+ }
588+ }
589+
590+ Assert . NotNull ( exception ) ;
591+ Assert . Equal ( exception . Message , $ "The maximum message size of { maximumMessageSize } B was exceeded. The message size can be configured in AddHubOptions.") ;
592+ }
593+
594+ [ Fact ]
595+ public async Task ManyHubMessagesUnderTheMessageSizeButConfiguredWithMax ( )
596+ {
597+ var payload1 = Encoding . UTF8 . GetBytes ( "{\" type\" :1, \" invocationId\" :\" 1\" , \" target\" : \" Echo\" , \" arguments\" :[\" one\" ]}\u001e " ) ;
598+ var payload2 = Encoding . UTF8 . GetBytes ( "{\" type\" :1, \" invocationId\" :\" 2\" , \" target\" : \" Echo\" , \" arguments\" :[\" two\" ]}\u001e " ) ;
599+ var payload3 = Encoding . UTF8 . GetBytes ( "{\" type\" :1, \" invocationId\" :\" 3\" , \" target\" : \" Echo\" , \" arguments\" :[\" three\" ]}\u001e " ) ;
600+
601+ // Bigger than all 3 messages
602+ var maximumMessageSize = payload3 . Length + 10 ;
603+
604+ using ( StartVerifiableLog ( ) )
605+ {
606+ var connectionHandler = HubConnectionHandlerTestUtils . GetHubConnectionHandler ( typeof ( HubT ) , LoggerFactory ,
607+ services => services . AddSignalR ( ) . AddHubOptions < HubT > ( o => o . MaximumReceiveMessageSize = maximumMessageSize ) ) ;
608+
609+ using ( var client = new TestClient ( ) )
610+ {
611+ var connectionHandlerTask = await client . ConnectAsync ( connectionHandler ) ;
612+
613+ client . Connection . Application . Output . Write ( payload1 ) ;
614+ client . Connection . Application . Output . Write ( payload2 ) ;
615+ client . Connection . Application . Output . Write ( payload3 ) ;
616+ await client . Connection . Application . Output . FlushAsync ( ) ;
617+
618+ // 2 invocations should be processed
619+ var completionMessage = await client . ReadAsync ( ) . OrTimeout ( ) as CompletionMessage ;
620+ Assert . NotNull ( completionMessage ) ;
621+ Assert . Equal ( "1" , completionMessage . InvocationId ) ;
622+ Assert . Equal ( "one" , completionMessage . Result ) ;
623+
624+ completionMessage = await client . ReadAsync ( ) . OrTimeout ( ) as CompletionMessage ;
625+ Assert . NotNull ( completionMessage ) ;
626+ Assert . Equal ( "2" , completionMessage . InvocationId ) ;
627+ Assert . Equal ( "two" , completionMessage . Result ) ;
628+
629+ completionMessage = await client . ReadAsync ( ) . OrTimeout ( ) as CompletionMessage ;
630+ Assert . NotNull ( completionMessage ) ;
631+ Assert . Equal ( "3" , completionMessage . InvocationId ) ;
632+ Assert . Equal ( "three" , completionMessage . Result ) ;
633+
634+ client . Dispose ( ) ;
635+
636+ await connectionHandlerTask . OrTimeout ( ) ;
637+ }
638+ }
639+ }
640+
455641 [ Fact ]
456642 public async Task HandshakeFailureFromIncompatibleProtocolVersionSendsResponseWithError ( )
457643 {
@@ -2789,7 +2975,7 @@ public async Task UploadManyStreams()
27892975
27902976 foreach ( string id in ids )
27912977 {
2792- await client . BeginUploadStreamAsync ( "invocation_" + id , nameof ( MethodHub . StreamingConcat ) , new [ ] { id } , Array . Empty < object > ( ) ) ;
2978+ await client . BeginUploadStreamAsync ( "invocation_" + id , nameof ( MethodHub . StreamingConcat ) , new [ ] { id } , Array . Empty < object > ( ) ) ;
27932979 }
27942980
27952981 var words = new [ ] { "zygapophyses" , "qwerty" , "abcd" } ;
@@ -2868,7 +3054,7 @@ public async Task UploadStreamItemInvalidTypeAutoCasts()
28683054 }
28693055 }
28703056 }
2871-
3057+
28723058 [ Fact ]
28733059 public async Task ServerReportsProtocolMinorVersion ( )
28743060 {
@@ -2881,7 +3067,7 @@ public async Task ServerReportsProtocolMinorVersion()
28813067 testProtocol . Setup ( m => m . TransferFormat ) . Returns ( TransferFormat . Binary ) ;
28823068
28833069 var connectionHandler = HubConnectionHandlerTestUtils . GetHubConnectionHandler ( typeof ( HubT ) ,
2884- ( services ) => services . AddSingleton < IHubProtocol > ( testProtocol . Object ) , LoggerFactory ) ;
3070+ LoggerFactory , ( services ) => services . AddSingleton < IHubProtocol > ( testProtocol . Object ) ) ;
28853071
28863072 using ( var client = new TestClient ( protocol : testProtocol . Object ) )
28873073 {
0 commit comments