@@ -531,18 +531,89 @@ private void StartListener()
531
531
return ;
532
532
}
533
533
534
+ CallbackRoutes selectedRoute = null ;
535
+ bool selectedRouteHasAuth = false ;
536
+ string multipleCallback = null ;
537
+ bool hasAuthRoutes = false ;
538
+ string basicAuthNoCred = null ;
539
+ bool authFailed = false ;
540
+
534
541
// Variables used only within the "for". They are here for performance reasons
535
542
bool mustAuthenticate ;
536
543
bool isAuthOk ;
537
- CallbackRoutes selectedRoute = null ;
538
- string multipleCallback = null ;
539
544
540
545
foreach ( CallbackRoutes route in _callbackRoutes )
541
546
{
542
547
if ( ! IsRouteMatch ( route , context . Request . HttpMethod , context . Request . RawUrl ) )
543
548
{
544
549
continue ;
545
550
}
551
+
552
+ // Check auth first
553
+ mustAuthenticate = route . Authentication != null && route . Authentication . AuthenticationType != AuthenticationType . None ;
554
+ if ( mustAuthenticate )
555
+ {
556
+ hasAuthRoutes = true ;
557
+ if ( route . Authentication . AuthenticationType == AuthenticationType . Basic )
558
+ {
559
+ var credReq = context . Request . Credentials ;
560
+ if ( credReq is null )
561
+ {
562
+ if ( basicAuthNoCred is null )
563
+ {
564
+ basicAuthNoCred = route . Route ;
565
+ }
566
+
567
+ continue ;
568
+ }
569
+
570
+ var credSite = route . Authentication . Credentials ?? Credential ;
571
+
572
+ isAuthOk = credSite != null
573
+ && ( credSite . UserName == credReq . UserName )
574
+ && ( credSite . Password == credReq . Password ) ;
575
+ }
576
+ else if ( route . Authentication . AuthenticationType == AuthenticationType . ApiKey )
577
+ {
578
+ var apikeyReq = GetApiKeyFromHeaders ( context . Request . Headers ) ;
579
+ if ( apikeyReq is null )
580
+ {
581
+ continue ;
582
+ }
583
+
584
+ var apikeySite = route . Authentication . ApiKey ?? ApiKey ;
585
+
586
+ isAuthOk = apikeyReq == apikeySite ;
587
+ }
588
+ else
589
+ {
590
+ isAuthOk = false ;
591
+ }
592
+
593
+ if ( isAuthOk )
594
+ {
595
+ // This route can be used and has precedence over non-authenticated routes
596
+ if ( ! selectedRouteHasAuth )
597
+ {
598
+ selectedRoute = null ;
599
+ multipleCallback = null ;
600
+ }
601
+
602
+ selectedRouteHasAuth = true ;
603
+ }
604
+ else
605
+ {
606
+ authFailed = true ;
607
+ continue ;
608
+ }
609
+ }
610
+ else if ( selectedRouteHasAuth || authFailed )
611
+ {
612
+ // The selected route has authentication and/or a route exists with failed authentication.
613
+ // Those have precedence over non-authenticated routes
614
+ continue ;
615
+ }
616
+
546
617
if ( selectedRoute is null )
547
618
{
548
619
selectedRoute = route ;
@@ -554,17 +625,21 @@ private void StartListener()
554
625
}
555
626
}
556
627
557
- if ( multipleCallback is not null )
558
- {
559
- multipleCallback += "." ;
560
- context . Response . StatusCode = ( int ) HttpStatusCode . InternalServerError ;
561
- OutPutStream ( context . Response , multipleCallback ) ;
562
628
563
- HandleContextResponse ( context ) ;
564
- }
565
- else if ( selectedRoute is null )
629
+ if ( selectedRoute is null )
566
630
{
567
- if ( CommandReceived != null )
631
+ if ( hasAuthRoutes )
632
+ {
633
+ if ( ! authFailed && basicAuthNoCred is not null )
634
+ {
635
+ context . Response . Headers . Add ( "WWW-Authenticate" ,
636
+ $ "Basic realm=\" Access to { basicAuthNoCred } \" ") ;
637
+ }
638
+
639
+ context . Response . StatusCode = ( int ) HttpStatusCode . Unauthorized ;
640
+ context . Response . ContentLength64 = 0 ;
641
+ }
642
+ else if ( CommandReceived != null )
568
643
{
569
644
// Starting a new thread to be able to handle a new request in parallel
570
645
CommandReceived . Invoke ( this , new WebServerEventArgs ( context ) ) ;
@@ -574,55 +649,19 @@ private void StartListener()
574
649
context . Response . StatusCode = ( int ) HttpStatusCode . NotFound ;
575
650
context . Response . ContentLength64 = 0 ;
576
651
}
577
-
578
- HandleContextResponse ( context ) ;
652
+ }
653
+ else if ( multipleCallback is not null )
654
+ {
655
+ multipleCallback += "." ;
656
+ context . Response . StatusCode = ( int ) HttpStatusCode . InternalServerError ;
657
+ OutPutStream ( context . Response , multipleCallback ) ;
579
658
}
580
659
else
581
660
{
582
- // Check auth first
583
- mustAuthenticate = selectedRoute . Authentication != null && selectedRoute . Authentication . AuthenticationType != AuthenticationType . None ;
584
- isAuthOk = ! mustAuthenticate ;
585
-
586
- if ( mustAuthenticate )
587
- {
588
- if ( selectedRoute . Authentication . AuthenticationType == AuthenticationType . Basic )
589
- {
590
- var credSite = selectedRoute . Authentication . Credentials ?? Credential ;
591
- var credReq = context . Request . Credentials ;
592
-
593
- isAuthOk = credReq != null && credSite != null
594
- && ( credSite . UserName == credReq . UserName )
595
- && ( credSite . Password == credReq . Password ) ;
596
- }
597
- else if ( selectedRoute . Authentication . AuthenticationType == AuthenticationType . ApiKey )
598
- {
599
- var apikeySite = selectedRoute . Authentication . ApiKey ?? ApiKey ;
600
- var apikeyReq = GetApiKeyFromHeaders ( context . Request . Headers ) ;
601
-
602
- isAuthOk = apikeyReq != null
603
- && apikeyReq == apikeySite ;
604
- }
605
- }
606
-
607
- if ( ! isAuthOk )
608
- {
609
- if ( selectedRoute . Authentication != null &&
610
- selectedRoute . Authentication . AuthenticationType == AuthenticationType . Basic )
611
- {
612
- context . Response . Headers . Add ( "WWW-Authenticate" ,
613
- $ "Basic realm=\" Access to { selectedRoute . Route } \" ") ;
614
- }
615
-
616
- context . Response . StatusCode = ( int ) HttpStatusCode . Unauthorized ;
617
- context . Response . ContentLength64 = 0 ;
618
-
619
- HandleContextResponse ( context ) ;
620
- return ;
621
- }
622
-
623
661
InvokeRoute ( selectedRoute , context ) ;
624
- HandleContextResponse ( context ) ;
625
662
}
663
+
664
+ HandleContextResponse ( context ) ;
626
665
} ) . Start ( ) ;
627
666
628
667
}
0 commit comments