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 }