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.util.connector.transport.http;
20  
21  import java.net.InetAddress;
22  import java.net.UnknownHostException;
23  import java.nio.charset.Charset;
24  import java.util.Collections;
25  import java.util.HashSet;
26  import java.util.Map;
27  import java.util.Optional;
28  import java.util.Set;
29  
30  import org.eclipse.aether.ConfigurationProperties;
31  import org.eclipse.aether.RepositorySystemSession;
32  import org.eclipse.aether.repository.RemoteRepository;
33  import org.eclipse.aether.util.ConfigUtils;
34  
35  /**
36   * A utility class to read HTTP transport related configuration. It implements all HTTP transport related configurations from
37   * {@link ConfigurationProperties} and transport implementations are free to use those that are supported by themselves.
38   *
39   * @see ConfigurationProperties
40   * @see RepositorySystemSession#getConfigProperties()
41   * @since 2.0.15
42   */
43  public final class HttpTransporterUtils {
44      private HttpTransporterUtils() {}
45  
46      /**
47       * Getter for {@link ConfigurationProperties#USER_AGENT}.
48       */
49      public static String getUserAgent(RepositorySystemSession session, RemoteRepository repository) {
50          return ConfigUtils.getString(
51                  session,
52                  ConfigurationProperties.DEFAULT_USER_AGENT,
53                  ConfigurationProperties.USER_AGENT,
54                  "aether.connector.userAgent");
55      }
56  
57      /**
58       * Getter for {@link ConfigurationProperties#HTTPS_SECURITY_MODE}.
59       */
60      public static String getHttpsSecurityMode(RepositorySystemSession session, RemoteRepository repository) {
61          String result = ConfigUtils.getString(
62                  session,
63                  ConfigurationProperties.HTTPS_SECURITY_MODE_DEFAULT,
64                  ConfigurationProperties.HTTPS_SECURITY_MODE + "." + repository.getId(),
65                  ConfigurationProperties.HTTPS_SECURITY_MODE);
66          if (!ConfigurationProperties.HTTPS_SECURITY_MODE_DEFAULT.equals(result)
67                  && !ConfigurationProperties.HTTPS_SECURITY_MODE_INSECURE.equals(result)) {
68              throw new IllegalArgumentException("Unsupported '" + result + "' HTTPS security mode.");
69          }
70          return result;
71      }
72  
73      /**
74       * Getter for {@link ConfigurationProperties#HTTP_CONNECTION_MAX_TTL}.
75       */
76      public static int getHttpConnectionMaxTtlSeconds(RepositorySystemSession session, RemoteRepository repository) {
77          int result = ConfigUtils.getInteger(
78                  session,
79                  ConfigurationProperties.DEFAULT_HTTP_CONNECTION_MAX_TTL,
80                  ConfigurationProperties.HTTP_CONNECTION_MAX_TTL + "." + repository.getId(),
81                  ConfigurationProperties.HTTP_CONNECTION_MAX_TTL);
82          if (result < 0) {
83              throw new IllegalArgumentException(ConfigurationProperties.HTTP_CONNECTION_MAX_TTL + " value must be >= 0");
84          }
85          return result;
86      }
87  
88      /**
89       * Getter for {@link ConfigurationProperties#HTTP_MAX_CONNECTIONS_PER_ROUTE}.
90       */
91      public static int getHttpMaxConnectionsPerRoute(RepositorySystemSession session, RemoteRepository repository) {
92          int result = ConfigUtils.getInteger(
93                  session,
94                  ConfigurationProperties.DEFAULT_HTTP_MAX_CONNECTIONS_PER_ROUTE,
95                  ConfigurationProperties.HTTP_MAX_CONNECTIONS_PER_ROUTE + "." + repository.getId(),
96                  ConfigurationProperties.HTTP_MAX_CONNECTIONS_PER_ROUTE);
97          if (result < 1) {
98              throw new IllegalArgumentException(
99                      ConfigurationProperties.HTTP_MAX_CONNECTIONS_PER_ROUTE + " value must be > 0");
100         }
101         return result;
102     }
103 
104     /**
105      * Getter for {@link ConfigurationProperties#HTTP_HEADERS}.
106      */
107     @SuppressWarnings("unchecked")
108     public static Map<String, String> getHttpHeaders(RepositorySystemSession session, RemoteRepository repository) {
109         return (Map<String, String>) ConfigUtils.getMap(
110                 session,
111                 Collections.emptyMap(),
112                 ConfigurationProperties.HTTP_HEADERS + "." + repository.getId(),
113                 ConfigurationProperties.HTTP_HEADERS);
114     }
115 
116     /**
117      * Getter for {@link ConfigurationProperties#HTTP_PREEMPTIVE_AUTH}.
118      */
119     public static boolean isHttpPreemptiveAuth(RepositorySystemSession session, RemoteRepository repository) {
120         return ConfigUtils.getBoolean(
121                 session,
122                 ConfigurationProperties.DEFAULT_HTTP_PREEMPTIVE_AUTH,
123                 ConfigurationProperties.HTTP_PREEMPTIVE_AUTH + "." + repository.getId(),
124                 ConfigurationProperties.HTTP_PREEMPTIVE_AUTH);
125     }
126 
127     /**
128      * Getter for {@link ConfigurationProperties#HTTP_PREEMPTIVE_PUT_AUTH}.
129      */
130     public static boolean isHttpPreemptivePutAuth(RepositorySystemSession session, RemoteRepository repository) {
131         return ConfigUtils.getBoolean(
132                 session,
133                 ConfigurationProperties.DEFAULT_HTTP_PREEMPTIVE_PUT_AUTH,
134                 ConfigurationProperties.HTTP_PREEMPTIVE_PUT_AUTH + "." + repository.getId(),
135                 ConfigurationProperties.HTTP_PREEMPTIVE_PUT_AUTH);
136     }
137 
138     /**
139      * Getter for {@link ConfigurationProperties#HTTP_SUPPORT_WEBDAV}.
140      */
141     public static boolean isHttpSupportWebDav(RepositorySystemSession session, RemoteRepository repository) {
142         return ConfigUtils.getBoolean(
143                 session,
144                 ConfigurationProperties.DEFAULT_HTTP_SUPPORT_WEBDAV,
145                 ConfigurationProperties.HTTP_SUPPORT_WEBDAV + "." + repository.getId(),
146                 ConfigurationProperties.HTTP_SUPPORT_WEBDAV);
147     }
148 
149     /**
150      * Getter for {@link ConfigurationProperties#HTTP_CREDENTIAL_ENCODING}.
151      */
152     public static Charset getHttpCredentialsEncoding(RepositorySystemSession session, RemoteRepository repository) {
153         return Charset.forName(ConfigUtils.getString(
154                 session,
155                 ConfigurationProperties.DEFAULT_HTTP_CREDENTIAL_ENCODING,
156                 ConfigurationProperties.HTTP_CREDENTIAL_ENCODING + "." + repository.getId(),
157                 ConfigurationProperties.HTTP_CREDENTIAL_ENCODING));
158     }
159 
160     /**
161      * Getter for {@link ConfigurationProperties#CONNECT_TIMEOUT}.
162      */
163     public static int getHttpConnectTimeout(RepositorySystemSession session, RemoteRepository repository) {
164         return ConfigUtils.getInteger(
165                 session,
166                 ConfigurationProperties.DEFAULT_CONNECT_TIMEOUT,
167                 ConfigurationProperties.CONNECT_TIMEOUT + "." + repository.getId(),
168                 ConfigurationProperties.CONNECT_TIMEOUT);
169     }
170 
171     /**
172      * Getter for {@link ConfigurationProperties#REQUEST_TIMEOUT}.
173      */
174     public static int getHttpRequestTimeout(RepositorySystemSession session, RemoteRepository repository) {
175         return ConfigUtils.getInteger(
176                 session,
177                 ConfigurationProperties.DEFAULT_REQUEST_TIMEOUT,
178                 ConfigurationProperties.REQUEST_TIMEOUT + "." + repository.getId(),
179                 ConfigurationProperties.REQUEST_TIMEOUT);
180     }
181 
182     /**
183      * Getter for {@link ConfigurationProperties#HTTP_RETRY_HANDLER_COUNT}.
184      */
185     public static int getHttpRetryHandlerCount(RepositorySystemSession session, RemoteRepository repository) {
186         int result = ConfigUtils.getInteger(
187                 session,
188                 ConfigurationProperties.DEFAULT_HTTP_RETRY_HANDLER_COUNT,
189                 ConfigurationProperties.HTTP_RETRY_HANDLER_COUNT + "." + repository.getId(),
190                 ConfigurationProperties.HTTP_RETRY_HANDLER_COUNT);
191         if (result < 0) {
192             throw new IllegalArgumentException(
193                     ConfigurationProperties.HTTP_RETRY_HANDLER_COUNT + " value must be >= 0");
194         }
195         return result;
196     }
197 
198     /**
199      * Getter for {@link ConfigurationProperties#HTTP_RETRY_HANDLER_INTERVAL}.
200      */
201     public static long getHttpRetryHandlerInterval(RepositorySystemSession session, RemoteRepository repository) {
202         long result = ConfigUtils.getLong(
203                 session,
204                 ConfigurationProperties.DEFAULT_HTTP_RETRY_HANDLER_INTERVAL,
205                 ConfigurationProperties.HTTP_RETRY_HANDLER_INTERVAL + "." + repository.getId(),
206                 ConfigurationProperties.HTTP_RETRY_HANDLER_INTERVAL);
207         if (result < 0) {
208             throw new IllegalArgumentException(
209                     ConfigurationProperties.HTTP_RETRY_HANDLER_INTERVAL + " value must be >= 0");
210         }
211         return result;
212     }
213 
214     /**
215      * Getter for {@link ConfigurationProperties#HTTP_RETRY_HANDLER_INTERVAL_MAX}.
216      */
217     public static long getHttpRetryHandlerIntervalMax(RepositorySystemSession session, RemoteRepository repository) {
218         long result = ConfigUtils.getLong(
219                 session,
220                 ConfigurationProperties.DEFAULT_HTTP_RETRY_HANDLER_INTERVAL_MAX,
221                 ConfigurationProperties.HTTP_RETRY_HANDLER_INTERVAL_MAX + "." + repository.getId(),
222                 ConfigurationProperties.HTTP_RETRY_HANDLER_INTERVAL_MAX);
223         if (result < 0) {
224             throw new IllegalArgumentException(
225                     ConfigurationProperties.HTTP_RETRY_HANDLER_INTERVAL_MAX + " value must be >= 0");
226         }
227         return result;
228     }
229 
230     /**
231      * Getter for {@link ConfigurationProperties#HTTP_EXPECT_CONTINUE}.
232      */
233     public static Optional<Boolean> getHttpExpectContinue(
234             RepositorySystemSession session, RemoteRepository repository) {
235         String expectContinue = ConfigUtils.getString(
236                 session,
237                 null,
238                 ConfigurationProperties.HTTP_EXPECT_CONTINUE + "." + repository.getId(),
239                 ConfigurationProperties.HTTP_EXPECT_CONTINUE);
240         if (expectContinue != null) {
241             return Optional.of(Boolean.parseBoolean(expectContinue));
242         }
243         return Optional.empty();
244     }
245 
246     /**
247      * Getter for {@link ConfigurationProperties#HTTP_REUSE_CONNECTIONS}.
248      */
249     public static boolean isHttpReuseConnections(RepositorySystemSession session, RemoteRepository repository) {
250         return ConfigUtils.getBoolean(
251                 session,
252                 ConfigurationProperties.DEFAULT_HTTP_REUSE_CONNECTIONS,
253                 ConfigurationProperties.HTTP_REUSE_CONNECTIONS + "." + repository.getId(),
254                 ConfigurationProperties.HTTP_REUSE_CONNECTIONS);
255     }
256 
257     /**
258      * Getter for {@link ConfigurationProperties#HTTP_RETRY_HANDLER_SERVICE_UNAVAILABLE}.
259      */
260     public static Set<Integer> getHttpServiceUnavailableCodes(
261             RepositorySystemSession session, RemoteRepository repository) {
262         String stringValue = ConfigUtils.getString(
263                 session,
264                 ConfigurationProperties.DEFAULT_HTTP_RETRY_HANDLER_SERVICE_UNAVAILABLE,
265                 ConfigurationProperties.HTTP_RETRY_HANDLER_SERVICE_UNAVAILABLE + "." + repository.getId(),
266                 ConfigurationProperties.HTTP_RETRY_HANDLER_SERVICE_UNAVAILABLE);
267         Set<Integer> result = new HashSet<>();
268         try {
269             for (String code : ConfigUtils.parseCommaSeparatedUniqueNames(stringValue)) {
270                 result.add(Integer.parseInt(code));
271             }
272         } catch (NumberFormatException e) {
273             throw new IllegalArgumentException(
274                     "Illegal HTTP codes for " + ConfigurationProperties.HTTP_RETRY_HANDLER_SERVICE_UNAVAILABLE
275                             + " (list of integers): " + stringValue);
276         }
277         return result;
278     }
279 
280     /**
281      * Getter for {@link ConfigurationProperties#HTTP_LOCAL_ADDRESS}.
282      */
283     public static Optional<InetAddress> getHttpLocalAddress(
284             RepositorySystemSession session, RemoteRepository repository) {
285         String bindAddress = ConfigUtils.getString(
286                 session,
287                 null,
288                 ConfigurationProperties.HTTP_LOCAL_ADDRESS + "." + repository.getId(),
289                 ConfigurationProperties.HTTP_LOCAL_ADDRESS);
290         if (bindAddress != null) {
291             try {
292                 return Optional.of(InetAddress.getByName(bindAddress));
293             } catch (UnknownHostException uhe) {
294                 throw new IllegalArgumentException(
295                         "Given bind address (" + bindAddress + ") cannot be resolved for remote repository "
296                                 + repository,
297                         uhe);
298             }
299         }
300         return Optional.empty();
301     }
302 }