2626import com .yahoo .athenz .common .server .log .jetty .JettyConnectionLoggerFactory ;
2727import com .yahoo .athenz .common .server .util .ConfigProperties ;
2828import com .yahoo .athenz .common .server .util .config .providers .ConfigProviderFile ;
29+ import com .yahoo .athenz .container .config .PortConfig ;
30+ import com .yahoo .athenz .container .config .PortUriConfiguration ;
31+ import com .yahoo .athenz .container .config .PortUriConfigurationManager ;
2932import com .yahoo .athenz .container .filter .HealthCheckFilter ;
3033import jakarta .servlet .DispatcherType ;
3134import org .eclipse .jetty .deploy .DeploymentManager ;
@@ -68,14 +71,15 @@ public class AthenzJettyContainer {
6871
6972 static final String ATHENZ_DEFAULT_EXCLUDED_PROTOCOLS = "SSLv2,SSLv3" ;
7073
71- private Server server = null ;
74+ Server server = null ;
7275 private String banner = null ;
7376 private Handler .Sequence handlers = null ;
7477 private PrivateKeyStore privateKeyStore ;
7578 private final boolean decodeAmbiguousUris ;
7679 private final AthenzConnectionListener connectionListener = new AthenzConnectionListener ();
7780 private final JettyConnectionLoggerFactory jettyConnectionLoggerFactory = new JettyConnectionLoggerFactory ();
78-
81+
82+
7983 public AthenzJettyContainer () {
8084
8185 // check to see if we want to support ambiguous uris
@@ -290,6 +294,9 @@ void addServletHandlers(final String serverHostName) {
290294 servletCtxHandler .addFilter (filterHolder , checkUri .trim (), EnumSet .of (DispatcherType .REQUEST ));
291295 }
292296 }
297+
298+ // PortFilter is applied to all webapps (e.g. ZTS API) via webdefault.xml; no need to add it here.
299+
293300 contexts .addHandler (servletCtxHandler );
294301
295302 final String jettyHome = System .getProperty (AthenzConsts .ATHENZ_PROP_JETTY_HOME , getRootDir ());
@@ -441,7 +448,7 @@ SslContextFactory.Server createSSLContextObject(boolean needClientAuth) {
441448
442449 void addHTTPConnector (HttpConfiguration httpConfig , int httpPort , boolean proxyProtocol ,
443450 String listenHost , int idleTimeout ) {
444-
451+
445452 ServerConnector connector ;
446453 if (proxyProtocol ) {
447454 connector = new ServerConnector (server , new ProxyConnectionFactory (), new HttpConnectionFactory (httpConfig ));
@@ -525,12 +532,6 @@ public void addHTTPConnectors(HttpConfiguration httpConfig, int httpPort, int ht
525532 boolean proxyProtocol = Boolean .parseBoolean (
526533 System .getProperty (AthenzConsts .ATHENZ_PROP_PROXY_PROTOCOL , "false" ));
527534
528- // HTTP Connector
529-
530- if (httpPort > 0 ) {
531- addHTTPConnector (httpConfig , httpPort , proxyProtocol , listenHost , idleTimeout );
532- }
533-
534535 // check to see if we need to create our connection logger
535536 // for TLS connection failures
536537
@@ -545,27 +546,80 @@ public void addHTTPConnectors(HttpConfiguration httpConfig, int httpPort, int ht
545546 System .getProperty (AthenzConsts .ATHENZ_PROP_SNI_REQUIRED , "false" ));
546547 boolean sniHostCheck = Boolean .parseBoolean (
547548 System .getProperty (AthenzConsts .ATHENZ_PROP_SNI_HOSTCHECK , "true" ));
549+
550+ // Use port-uri.json for connectors if configured; otherwise use properties
551+ PortUriConfigurationManager configManager = PortUriConfigurationManager .getInstance ();
552+
553+ if (configManager .isPortListConfigured ()) {
554+ LOG .info ("Creating HTTP/HTTPS connectors based on port-uri.json configuration" );
555+ addConnectorsFromPortConfig (configManager .getConfiguration (), httpConfig ,
556+ proxyProtocol , listenHost , idleTimeout , sniRequired , sniHostCheck , connectionLogger );
557+ } else {
558+ LOG .info ("Creating HTTP/HTTPS connectors based on properties configuration" );
559+ addConnectorsFromProperties (httpConfig , httpPort , httpsPort , oidcPort , statusPort ,
560+ proxyProtocol , listenHost , idleTimeout , sniRequired , sniHostCheck , connectionLogger );
561+ }
562+ }
563+
564+ /**
565+ * Add HTTP/HTTPS connectors based on port-uri.json configuration
566+ */
567+ private void addConnectorsFromPortConfig (PortUriConfiguration config , HttpConfiguration httpConfig ,
568+ boolean proxyProtocol , String listenHost , int idleTimeout , boolean sniRequired ,
569+ boolean sniHostCheck , JettyConnectionLogger connectionLogger ) {
570+
571+ for (PortConfig portConfig : config .getPorts ()) {
572+ int port = portConfig .getPort ();
573+
574+ if (port <= 0 ) {
575+ continue ;
576+ }
577+
578+ // Determine if this port needs client authentication (mTLS)
579+ boolean needClientAuth = portConfig .isMtlsRequired ();
580+
581+ // Create HTTPS connector for this port
582+ HttpConfiguration httpsConfig = getHttpsConfig (httpConfig , port , sniRequired , sniHostCheck );
583+ addHTTPSConnector (httpsConfig , port , proxyProtocol , listenHost ,
584+ idleTimeout , needClientAuth , connectionLogger );
585+
586+ LOG .info ("Added connector for port {} (mTLS: {}, description: {})" ,
587+ port , needClientAuth , portConfig .getDescription ());
588+ }
589+ }
590+
591+ /**
592+ * Add HTTP/HTTPS connectors based on property configuration
593+ */
594+ private void addConnectorsFromProperties (HttpConfiguration httpConfig , int httpPort , int httpsPort ,
595+ int oidcPort , int statusPort , boolean proxyProtocol , String listenHost ,
596+ int idleTimeout , boolean sniRequired , boolean sniHostCheck ,
597+ JettyConnectionLogger connectionLogger ) {
598+
599+ // Default client auth setting from properties
548600 boolean needClientAuth = Boolean .parseBoolean (
549601 System .getProperty (AthenzConsts .ATHENZ_PROP_CLIENT_AUTH , "false" ));
550602
551- // HTTPS Connector
603+ // HTTP Connector
604+ if (httpPort > 0 ) {
605+ addHTTPConnector (httpConfig , httpPort , proxyProtocol , listenHost , idleTimeout );
606+ }
552607
608+ // HTTPS Connector
553609 if (httpsPort > 0 ) {
554610 HttpConfiguration httpsConfig = getHttpsConfig (httpConfig , httpsPort , sniRequired , sniHostCheck );
555611 addHTTPSConnector (httpsConfig , httpsPort , proxyProtocol , listenHost ,
556612 idleTimeout , needClientAuth , connectionLogger );
557613 }
558614
559615 // OIDC Connector - only if it's different from HTTPS
560-
561616 if (oidcPort > 0 && oidcPort != httpsPort ) {
562617 HttpConfiguration httpsConfig = getHttpsConfig (httpConfig , oidcPort , sniRequired , sniHostCheck );
563618 addHTTPSConnector (httpsConfig , oidcPort , proxyProtocol , listenHost ,
564619 idleTimeout , needClientAuth , connectionLogger );
565620 }
566621
567622 // Status Connector - only if it's different from HTTP/HTTPS
568-
569623 if (statusPort > 0 && statusPort != httpPort && statusPort != httpsPort ) {
570624 if (httpsPort > 0 ) {
571625 HttpConfiguration httpsConfig = getHttpsConfig (httpConfig , httpsPort , false , false );
@@ -612,9 +666,9 @@ public static AthenzJettyContainer createJettyContainer() {
612666 // for status port we'll use the protocol specified for the regular http
613667 // port. if both http and https are provided then https will be picked
614668 // it could also be either one of the values specified as well
615-
669+
616670 int statusPort = ConfigProperties .getPortNumber (AthenzConsts .ATHENZ_PROP_STATUS_PORT , 0 );
617-
671+
618672 String serverHostName = getServerHostName ();
619673
620674 AthenzJettyContainer container = new AthenzJettyContainer ();
@@ -626,6 +680,10 @@ public static AthenzJettyContainer createJettyContainer() {
626680 Integer .toString (AthenzConsts .ATHENZ_HTTP_MAX_THREADS )));
627681 container .createServer (maxThreads );
628682
683+ // Load port-uri.json configuration before creating connectors
684+ // This must be done before addHTTPConnectors() so the configuration is available
685+ loadPortUriConfiguration ();
686+
629687 HttpConfiguration httpConfig = container .newHttpConfiguration ();
630688 container .addHTTPConnectors (httpConfig , httpPort , httpsPort , oidcPort , statusPort );
631689
@@ -655,6 +713,21 @@ public static void initConfigManager() {
655713 CONFIG_MANAGER .addConfigSource (ConfigProviderFile .PROVIDER_DESCRIPTION_PREFIX + propFile );
656714 }
657715
716+ /**
717+ * Load port-uri.json configuration if available.
718+ * This must be called before creating HTTP/HTTPS connectors.
719+ */
720+ static void loadPortUriConfiguration () {
721+ // Configuration is automatically loaded by PortUriConfigurationManager singleton
722+ // upon first getInstance() call. Just trigger initialization and log the result.
723+ PortUriConfigurationManager configManager = PortUriConfigurationManager .getInstance ();
724+ if (configManager .isPortListConfigured ()) {
725+ LOG .info ("Port-uri configuration successfully loaded" );
726+ } else {
727+ LOG .info ("Port-uri configuration not available, will use properties for port configuration" );
728+ }
729+ }
730+
658731 public void run () {
659732 try {
660733 server .setDumpAfterStart (Boolean .parseBoolean (System .getProperty (AthenzConsts .ATHENZ_PROP_DUMP_AFTER_START , "false" )));
0 commit comments