@@ -544,7 +544,7 @@ public interface Builder extends SdkHttpClient.Builder<Apache5HttpClient.Builder
544544 }
545545
546546 private static final class DefaultBuilder implements Builder {
547- private static final String [] REQUIRED_TCP_KEEPALIVE_PERMISSIONS = {
547+ private static final String [] REQUIRED_TCP_SOCKET_OPTION_PERMISSIONS = {
548548 "setOption.TCP_KEEPIDLE" ,
549549 "setOption.TCP_KEEPINTERVAL" ,
550550 "setOption.TCP_KEEPCOUNT"
@@ -751,7 +751,7 @@ public void setAuthSchemeProviderRegistry(Registry<AuthSchemeFactory> authScheme
751751 public SdkHttpClient buildWithDefaults (AttributeMap serviceDefaults ) {
752752 AttributeMap resolvedOptions = standardOptions .build ().merge (serviceDefaults ).merge (
753753 SdkHttpConfigurationOption .GLOBAL_HTTP_DEFAULTS );
754- checkTcpKeepAlivePermissions ();
754+ checkTcpSocketOptionPermissions ();
755755 return new Apache5HttpClient (this , resolvedOptions );
756756 }
757757
@@ -760,28 +760,46 @@ public SdkHttpClient buildWithDefaults(AttributeMap serviceDefaults) {
760760 * that Apache HC5 requires for its default TCP keepalive socket options.
761761 * No-op when no SecurityManager is installed (including Java 24+).
762762 */
763- private static void checkTcpKeepAlivePermissions () {
763+ private static void checkTcpSocketOptionPermissions () {
764764 SecurityManager sm = System .getSecurityManager ();
765765 if (sm == null ) {
766766 return ;
767767 }
768768
769769 try {
770770 Class <?> permClass = ClassLoaderHelper .loadClass ("jdk.net.NetworkPermission" , Apache5HttpClient .class );
771- for (String permName : REQUIRED_TCP_KEEPALIVE_PERMISSIONS ) {
771+ for (String permName : REQUIRED_TCP_SOCKET_OPTION_PERMISSIONS ) {
772772 java .security .Permission perm =
773773 (java .security .Permission ) permClass .getConstructor (String .class ).newInstance (permName );
774774 sm .checkPermission (perm );
775775 }
776776 } catch (SecurityException e ) {
777- throw new IllegalStateException (
778- "Apache5HttpClient requires jdk.net.NetworkPermission for \" "
779- + String .join ("\" , \" " , REQUIRED_TCP_KEEPALIVE_PERMISSIONS )
780- + "\" when a SecurityManager is active." , e );
777+ if (isTcpSocketOptionPermissionDenied (e )) {
778+ throw new IllegalStateException (
779+ "Apache5HttpClient requires jdk.net.NetworkPermission for \" "
780+ + String .join ("\" , \" " , REQUIRED_TCP_SOCKET_OPTION_PERMISSIONS )
781+ + "\" when a SecurityManager is active." , e );
782+ }
783+ log .warn (() -> "SecurityManager denied a non-TCP socket option permission during "
784+ + "verification: " + e .getMessage (), e );
781785 } catch (Exception e ) {
782- log .warn (() -> "Unable to verify TCP keepalive permissions : " + e .getMessage (), e );
786+ log .warn (() -> "Could not verify jdk.net.NetworkPermission for TCP socket options : " + e .getMessage (), e );
783787 }
784788 }
789+
790+ private static boolean isTcpSocketOptionPermissionDenied (SecurityException e ) {
791+ String message = e .getMessage ();
792+ if (message == null ) {
793+ return false ;
794+ }
795+ for (String perm : REQUIRED_TCP_SOCKET_OPTION_PERMISSIONS ) {
796+ if (message .contains (perm )) {
797+ return true ;
798+ }
799+ }
800+ return false ;
801+ }
802+
785803 }
786804
787805 private static class ApacheConnectionManagerFactory {
0 commit comments