View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.eclipse.aether.transport.apache;
20  
21  import javax.net.ssl.HostnameVerifier;
22  import javax.net.ssl.SSLContext;
23  
24  import java.util.Arrays;
25  import java.util.Objects;
26  
27  import org.eclipse.aether.RepositorySystemSession;
28  import org.eclipse.aether.repository.AuthenticationContext;
29  import org.eclipse.aether.util.ConfigUtils;
30  
31  /**
32   * Connection manager config: among other SSL-related configuration and cache key for connection pools (whose scheme
33   * registries are derived from this config).
34   */
35  final class ConnMgrConfig {
36  
37      /**
38       * Comma-separated list of <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#ciphersuites">Cipher Suites</a> which are enabled for HTTPS connections.
39       */
40      private static final String CIPHER_SUITES = "https.cipherSuites";
41  
42      /**
43       * Comma-separated list of <a href="https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#jssenames">Protocols</a> which are enabled for HTTPS connections.
44       */
45      private static final String PROTOCOLS = "https.protocols";
46  
47      final SSLContext context;
48  
49      final HostnameVerifier verifier;
50  
51      final String[] cipherSuites;
52  
53      final String[] protocols;
54  
55      final String httpsSecurityMode;
56  
57      final int connectionMaxTtlSeconds;
58  
59      final int maxConnectionsPerRoute;
60  
61      ConnMgrConfig(
62              RepositorySystemSession session,
63              AuthenticationContext authContext,
64              String httpsSecurityMode,
65              int connectionMaxTtlSeconds,
66              int maxConnectionsPerRoute) {
67          context = (authContext != null) ? authContext.get(AuthenticationContext.SSL_CONTEXT, SSLContext.class) : null;
68          verifier = (authContext != null)
69                  ? authContext.get(AuthenticationContext.SSL_HOSTNAME_VERIFIER, HostnameVerifier.class)
70                  : null;
71  
72          cipherSuites = split(getCipherSuites(session));
73          protocols = split(getProtocols(session));
74          this.httpsSecurityMode = httpsSecurityMode;
75          this.connectionMaxTtlSeconds = connectionMaxTtlSeconds;
76          this.maxConnectionsPerRoute = maxConnectionsPerRoute;
77      }
78  
79      private static String getCipherSuites(RepositorySystemSession session) {
80          String value = ConfigUtils.getString(
81                  session, null, ApacheTransporterConfigurationKeys.CONFIG_PROP_CIPHER_SUITES, CIPHER_SUITES);
82          if (value == null) {
83              value = System.getProperty(CIPHER_SUITES);
84          }
85          return value;
86      }
87  
88      private static String getProtocols(RepositorySystemSession session) {
89          String value = ConfigUtils.getString(
90                  session, null, ApacheTransporterConfigurationKeys.CONFIG_PROP_PROTOCOLS, PROTOCOLS);
91          if (value == null) {
92              value = System.getProperty(PROTOCOLS);
93          }
94          return value;
95      }
96  
97      private static String[] split(String value) {
98          if (value == null || value.isEmpty()) {
99              return null;
100         }
101         return value.split(",+");
102     }
103 
104     @Override
105     public boolean equals(Object obj) {
106         if (this == obj) {
107             return true;
108         }
109         if (obj == null || !getClass().equals(obj.getClass())) {
110             return false;
111         }
112         ConnMgrConfig that = (ConnMgrConfig) obj;
113         return Objects.equals(context, that.context)
114                 && Objects.equals(verifier, that.verifier)
115                 && Arrays.equals(cipherSuites, that.cipherSuites)
116                 && Arrays.equals(protocols, that.protocols)
117                 && Objects.equals(httpsSecurityMode, that.httpsSecurityMode)
118                 && connectionMaxTtlSeconds == that.connectionMaxTtlSeconds
119                 && maxConnectionsPerRoute == that.maxConnectionsPerRoute;
120     }
121 
122     @Override
123     public int hashCode() {
124         int hash = 17;
125         hash = hash * 31 + hash(context);
126         hash = hash * 31 + hash(verifier);
127         hash = hash * 31 + Arrays.hashCode(cipherSuites);
128         hash = hash * 31 + Arrays.hashCode(protocols);
129         hash = hash * 31 + hash(httpsSecurityMode);
130         hash = hash * 31 + hash(connectionMaxTtlSeconds);
131         hash = hash * 31 + hash(maxConnectionsPerRoute);
132         return hash;
133     }
134 
135     private static int hash(Object obj) {
136         return obj != null ? obj.hashCode() : 0;
137     }
138 }