View Javadoc
1   /*
2    * The MIT License (MIT)
3    *
4    * Copyright (c) 2013-2026 The Coveralls Maven Plugin Project Contributors:
5    *     https://github.com/hazendaz/coveralls-maven-plugin/graphs/contributors
6    *
7    * Permission is hereby granted, free of charge, to any person obtaining a copy
8    * of this software and associated documentation files (the "Software"), to deal
9    * in the Software without restriction, including without limitation the rights
10   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11   * copies of the Software, and to permit persons to whom the Software is
12   * furnished to do so, subject to the following conditions:
13   *
14   * The above copyright notice and this permission notice shall be included in
15   * all copies or substantial portions of the Software.
16   *
17   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23   * THE SOFTWARE.
24   */
25  package org.eluder.coveralls.maven.plugin.httpclient;
26  
27  import java.net.Authenticator;
28  import java.net.InetSocketAddress;
29  import java.net.PasswordAuthentication;
30  import java.net.ProxySelector;
31  import java.net.http.HttpClient;
32  import java.time.Duration;
33  
34  import org.apache.commons.lang3.StringUtils;
35  import org.apache.maven.settings.Proxy;
36  import org.eluder.coveralls.maven.plugin.util.UrlUtils;
37  import org.eluder.coveralls.maven.plugin.util.Wildcards;
38  
39  /**
40   * A factory for creating HttpClient objects.
41   */
42  class HttpClientFactory {
43  
44      /** The Constant DEFAULT_CONNECTION_TIMEOUT. */
45      private static final Duration DEFAULT_CONNECTION_TIMEOUT = Duration.ofSeconds(10);
46  
47      /** The target url. */
48      private final String targetUrl;
49  
50      /** The hcb. */
51      private final HttpClient.Builder hcb = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1)
52              .followRedirects(HttpClient.Redirect.ALWAYS).connectTimeout(HttpClientFactory.DEFAULT_CONNECTION_TIMEOUT);
53  
54      /**
55       * Instantiates a new http client factory.
56       *
57       * @param targetUrl
58       *            the target url for the coveralls API
59       */
60      HttpClientFactory(final String targetUrl) {
61          this.targetUrl = targetUrl;
62      }
63  
64      /**
65       * Proxy.
66       *
67       * @param proxy
68       *            the proxy
69       *
70       * @return the http client factory
71       */
72      public HttpClientFactory proxy(final Proxy proxy) {
73          if (proxy != null && this.isProxied(this.targetUrl, proxy)) {
74              this.hcb.proxy(ProxySelector.of(new InetSocketAddress(proxy.getHost(), proxy.getPort())));
75  
76              if (StringUtils.isNotBlank(proxy.getUsername())) {
77                  final Authenticator authenticator = new Authenticator() {
78                      @Override
79                      protected PasswordAuthentication getPasswordAuthentication() {
80                          return new PasswordAuthentication(proxy.getUsername(), proxy.getPassword().toCharArray());
81                      }
82                  };
83                  this.hcb.authenticator(authenticator);
84              }
85          }
86          return this;
87      }
88  
89      /**
90       * Creates a new instance of HttpClient.
91       *
92       * @return a new instance of HttpClient
93       */
94      public HttpClient create() {
95          return this.hcb.build();
96      }
97  
98      /**
99       * Checks if is proxied.
100      *
101      * @param url
102      *            the url
103      * @param proxy
104      *            the proxy
105      *
106      * @return true, if is proxied
107      */
108     private boolean isProxied(final String url, final Proxy proxy) {
109         if (StringUtils.isNotBlank(proxy.getNonProxyHosts())) {
110             final var host = UrlUtils.create(url).getHost();
111             final var excludes = proxy.getNonProxyHosts().split("\\|", -1);
112             for (final String exclude : excludes) {
113                 if (exclude != null && !exclude.isBlank() && Wildcards.matches(host, exclude.trim())) {
114                     return false;
115                 }
116             }
117         }
118         return true;
119     }
120 }