@@ -432,6 +432,88 @@ public void ConfigureEndpointDevelopmentCertificateGetsIgnoredIfPfxFileDoesNotEx
432432 }
433433 }
434434
435+ [ Fact ]
436+ public void ConfigureEndpoint_ThrowsWhen_HttpsConfigIsDeclaredInNonHttpsEndpoints ( )
437+ {
438+ var serverOptions = CreateServerOptions ( ) ;
439+
440+ var config = new ConfigurationBuilder ( ) . AddInMemoryCollection ( new [ ]
441+ {
442+ new KeyValuePair < string , string > ( "Endpoints:End1:Url" , "http://*:5001" ) ,
443+ // We shouldn't need to specify a real cert, because KestrelConfigurationLoader should check whether the endpoint requires a cert before trying to load it.
444+ new KeyValuePair < string , string > ( "Endpoints:End1:Certificate:Path" , "fakecert.pfx" ) ,
445+ } ) . Build ( ) ;
446+
447+ var ex = Assert . Throws < InvalidOperationException > ( ( ) => serverOptions . Configure ( config ) . Load ( ) ) ;
448+ Assert . Equal ( CoreStrings . FormatEndpointHasUnusedHttpsConfig ( "End1" , "Certificate" ) , ex . Message ) ;
449+
450+ config = new ConfigurationBuilder ( ) . AddInMemoryCollection ( new [ ]
451+ {
452+ new KeyValuePair < string , string > ( "Endpoints:End1:Url" , "http://*:5001" ) ,
453+ new KeyValuePair < string , string > ( "Endpoints:End1:Certificate:Subject" , "example.org" ) ,
454+ } ) . Build ( ) ;
455+
456+ ex = Assert . Throws < InvalidOperationException > ( ( ) => serverOptions . Configure ( config ) . Load ( ) ) ;
457+ Assert . Equal ( CoreStrings . FormatEndpointHasUnusedHttpsConfig ( "End1" , "Certificate" ) , ex . Message ) ;
458+
459+ config = new ConfigurationBuilder ( ) . AddInMemoryCollection ( new [ ]
460+ {
461+ new KeyValuePair < string , string > ( "Endpoints:End1:Url" , "http://*:5001" ) ,
462+ new KeyValuePair < string , string > ( "Endpoints:End1:ClientCertificateMode" , ClientCertificateMode . RequireCertificate . ToString ( ) ) ,
463+ } ) . Build ( ) ;
464+
465+ ex = Assert . Throws < InvalidOperationException > ( ( ) => serverOptions . Configure ( config ) . Load ( ) ) ;
466+ Assert . Equal ( CoreStrings . FormatEndpointHasUnusedHttpsConfig ( "End1" , "ClientCertificateMode" ) , ex . Message ) ;
467+
468+ config = new ConfigurationBuilder ( ) . AddInMemoryCollection ( new [ ]
469+ {
470+ new KeyValuePair < string , string > ( "Endpoints:End1:Url" , "http://*:5001" ) ,
471+ new KeyValuePair < string , string > ( "Endpoints:End1:SslProtocols:0" , SslProtocols . Tls13 . ToString ( ) ) ,
472+ } ) . Build ( ) ;
473+
474+ ex = Assert . Throws < InvalidOperationException > ( ( ) => serverOptions . Configure ( config ) . Load ( ) ) ;
475+ Assert . Equal ( CoreStrings . FormatEndpointHasUnusedHttpsConfig ( "End1" , "SslProtocols" ) , ex . Message ) ;
476+
477+ config = new ConfigurationBuilder ( ) . AddInMemoryCollection ( new [ ]
478+ {
479+ new KeyValuePair < string , string > ( "Endpoints:End1:Url" , "http://*:5001" ) ,
480+ new KeyValuePair < string , string > ( "Endpoints:End1:Sni:Protocols" , HttpProtocols . Http1 . ToString ( ) ) ,
481+ } ) . Build ( ) ;
482+
483+ ex = Assert . Throws < InvalidOperationException > ( ( ) => serverOptions . Configure ( config ) . Load ( ) ) ;
484+ Assert . Equal ( CoreStrings . FormatEndpointHasUnusedHttpsConfig ( "End1" , "Sni" ) , ex . Message ) ;
485+ }
486+
487+ [ Fact ]
488+ public void ConfigureEndpoint_DoesNotThrowWhen_HttpsConfigIsDeclaredInEndpointDefaults ( )
489+ {
490+ var serverOptions = CreateServerOptions ( ) ;
491+
492+ var config = new ConfigurationBuilder ( ) . AddInMemoryCollection ( new [ ]
493+ {
494+ new KeyValuePair < string , string > ( "Endpoints:End1:Url" , "http://*:5001" ) ,
495+ new KeyValuePair < string , string > ( "EndpointDefaults:ClientCertificateMode" , ClientCertificateMode . RequireCertificate . ToString ( ) ) ,
496+ } ) . Build ( ) ;
497+
498+ var ( _, endpointsToStart ) = serverOptions . Configure ( config ) . Reload ( ) ;
499+ var end1 = Assert . Single ( endpointsToStart ) ;
500+ Assert . NotNull ( end1 ? . EndpointConfig ) ;
501+ Assert . Null ( end1 . EndpointConfig . ClientCertificateMode ) ;
502+
503+ serverOptions = CreateServerOptions ( ) ;
504+
505+ config = new ConfigurationBuilder ( ) . AddInMemoryCollection ( new [ ]
506+ {
507+ new KeyValuePair < string , string > ( "Endpoints:End1:Url" , "http://*:5001" ) ,
508+ new KeyValuePair < string , string > ( "EndpointDefaults:SslProtocols:0" , SslProtocols . Tls13 . ToString ( ) ) ,
509+ } ) . Build ( ) ;
510+
511+ ( _ , endpointsToStart ) = serverOptions . Configure ( config ) . Reload ( ) ;
512+ end1 = Assert . Single ( endpointsToStart ) ;
513+ Assert . NotNull ( end1 ? . EndpointConfig ) ;
514+ Assert . Null ( end1 . EndpointConfig . SslProtocols ) ;
515+ }
516+
435517 [ ConditionalTheory ]
436518 [ InlineData ( "http1" , HttpProtocols . Http1 ) ]
437519 // [InlineData("http2", HttpProtocols.Http2)] // Not supported due to missing ALPN support. https://github.com/dotnet/corefx/issues/33016
@@ -746,6 +828,36 @@ public void EndpointConfigureSection_CanSetClientCertificateMode()
746828 Assert . True ( ran2 ) ;
747829 }
748830
831+
832+ [ Fact ]
833+ public void EndpointConfigureSection_CanConfigureSni ( )
834+ {
835+ var serverOptions = CreateServerOptions ( ) ;
836+ var certPath = Path . Combine ( "shared" , "TestCertificates" , "https-ecdsa.pem" ) ;
837+ var keyPath = Path . Combine ( "shared" , "TestCertificates" , "https-ecdsa.key" ) ;
838+
839+ var config = new ConfigurationBuilder ( ) . AddInMemoryCollection ( new [ ]
840+ {
841+ new KeyValuePair < string , string > ( "Endpoints:End1:Url" , "https://*:5001" ) ,
842+ new KeyValuePair < string , string > ( "Endpoints:End1:Sni:*.example.org:Protocols" , HttpProtocols . None . ToString ( ) ) ,
843+ new KeyValuePair < string , string > ( "Endpoints:End1:Sni:*.example.org:SslProtocols:0" , SslProtocols . Tls13 . ToString ( ) ) ,
844+ new KeyValuePair < string , string > ( "Endpoints:End1:Sni:*.example.org:ClientCertificateMode" , ClientCertificateMode . RequireCertificate . ToString ( ) ) ,
845+ new KeyValuePair < string , string > ( "Endpoints:End1:Sni:*.example.org:Certificate:Path" , certPath ) ,
846+ new KeyValuePair < string , string > ( "Endpoints:End1:Sni:*.example.org:Certificate:KeyPath" , keyPath ) ,
847+ } ) . Build ( ) ;
848+
849+ var ( _, endpointsToStart ) = serverOptions . Configure ( config ) . Reload ( ) ;
850+ var end1 = Assert . Single ( endpointsToStart ) ;
851+ var ( name , sniConfig ) = Assert . Single ( end1 ? . EndpointConfig ? . Sni ) ;
852+
853+ Assert . Equal ( "*.example.org" , name ) ;
854+ Assert . Equal ( HttpProtocols . None , sniConfig . Protocols ) ;
855+ Assert . Equal ( SslProtocols . Tls13 , sniConfig . SslProtocols ) ;
856+ Assert . Equal ( ClientCertificateMode . RequireCertificate , sniConfig . ClientCertificateMode ) ;
857+ Assert . Equal ( certPath , sniConfig . Certificate . Path ) ;
858+ Assert . Equal ( keyPath , sniConfig . Certificate . KeyPath ) ;
859+ }
860+
749861 [ Fact ]
750862 public void EndpointConfigureSection_CanOverrideClientCertificateModeFromConfigureHttpsDefaults ( )
751863 {
0 commit comments