Skip to content

Commit

Permalink
Added option to ignore invalid SSL certificates
Browse files Browse the repository at this point in the history
  • Loading branch information
Lenni0451 committed Mar 19, 2024
1 parent 4adcb11 commit e57c1b5
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import net.lenni0451.commons.httpclient.proxy.ProxyType;
import net.lenni0451.commons.httpclient.requests.HttpContentRequest;
import net.lenni0451.commons.httpclient.requests.HttpRequest;
import net.lenni0451.commons.httpclient.utils.IgnoringTrustManager;
import net.lenni0451.commons.httpclient.utils.URLWrapper;

import javax.annotation.Nonnull;
Expand Down Expand Up @@ -44,10 +45,11 @@ public HttpResponse execute(@Nonnull final HttpRequest request) throws IOExcepti
return new HttpResponse(new URLWrapper(response.uri()).toURL(), response.statusCode(), response.body(), response.headers().map());
}

private java.net.http.HttpClient buildClient(final HttpRequest request) {
private java.net.http.HttpClient buildClient(final HttpRequest request) throws IOException {
java.net.http.HttpClient.Builder builder = java.net.http.HttpClient.newBuilder();
CookieManager cookieManager = this.getCookieManager(request);
if (cookieManager != null) builder.cookieHandler(cookieManager);
if (this.isIgnoreInvalidSSL(request)) builder.sslContext(IgnoringTrustManager.makeIgnoringSSLContext());
builder.connectTimeout(Duration.ofMillis(this.client.getConnectTimeout()));
switch (request.getFollowRedirects()) {
case NOT_SET:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class HttpClient extends HeaderStore<HttpClient> implements HttpRequestBu
private int readTimeout = 10_000;
private RetryHandler retryHandler = new RetryHandler();
private ProxyHandler proxyHandler = new ProxyHandler();
private boolean ignoreInvalidSSL = false;

/**
* Create a new http client with the default executor.
Expand Down Expand Up @@ -178,6 +179,24 @@ public void setProxyHandler(@Nonnull final ProxyHandler proxyHandler) {
this.proxyHandler = proxyHandler;
}

/**
* @return Whether invalid SSL certificates should be ignored
*/
public boolean isIgnoreInvalidSSL() {
return this.ignoreInvalidSSL;
}

/**
* Set whether invalid SSL certificates should be ignored.
*
* @param ignoreInvalidSSL Whether invalid SSL certificates should be ignored
* @return This instance for chaining
*/
public HttpClient setIgnoreInvalidSSL(final boolean ignoreInvalidSSL) {
this.ignoreInvalidSSL = ignoreInvalidSSL;
return this;
}

/**
* Execute a request and pass the response to the response handler.<br>
* The return value of the response handler will be returned.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ protected final CookieManager getCookieManager(@Nonnull final HttpRequest reques
return request.isCookieManagerSet() ? request.getCookieManager() : this.client.getCookieManager();
}

protected final boolean isIgnoreInvalidSSL(@Nonnull final HttpRequest request) {
return request.isIgnoreInvalidSSLSet() ? request.getIgnoreInvalidSSL() : this.client.isIgnoreInvalidSSL();
}

protected final Map<String, List<String>> getHeaders(@Nonnull final HttpRequest request, @Nullable final CookieManager cookieManager) throws IOException {
Map<String, List<String>> headers = new HashMap<>();
if (request instanceof HttpContentRequest) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import net.lenni0451.commons.httpclient.requests.HttpContentRequest;
import net.lenni0451.commons.httpclient.requests.HttpRequest;
import net.lenni0451.commons.httpclient.utils.HttpRequestUtils;
import net.lenni0451.commons.httpclient.utils.IgnoringTrustManager;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.net.ssl.HttpsURLConnection;
import java.io.IOException;
import java.io.OutputStream;
import java.net.CookieManager;
Expand Down Expand Up @@ -38,6 +40,10 @@ private HttpURLConnection openConnection(final HttpRequest request, final Cookie
if (proxySelector != null) proxySelector.set();
URL url = request.getURL();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
if (this.isIgnoreInvalidSSL(request) && connection instanceof HttpsURLConnection) {
HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
httpsConnection.setSSLSocketFactory(IgnoringTrustManager.makeIgnoringSSLContext().getSocketFactory());
}
this.setupConnection(connection, cookieManager, request);
connection.connect();
return connection;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import net.lenni0451.commons.httpclient.HeaderStore;
import net.lenni0451.commons.httpclient.RetryHandler;
import net.lenni0451.commons.httpclient.utils.ResettableStorage;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
Expand All @@ -14,12 +15,9 @@ public class HttpRequest extends HeaderStore<HttpRequest> {
private final String method;
private final URL url;
private FollowRedirects followRedirects = FollowRedirects.NOT_SET;
@Nullable
private CookieManager cookieManager;
private boolean cookieManagerSet = false;
@Nonnull
private RetryHandler retryHandler = new RetryHandler();
private boolean retryHandlerSet = false;
private final ResettableStorage<CookieManager> cookieManager = new ResettableStorage<>();
private final ResettableStorage<RetryHandler> retryHandler = new ResettableStorage<>();
private final ResettableStorage<Boolean> ignoreInvalidSSL = new ResettableStorage<>();

public HttpRequest(final String method, final String url) throws MalformedURLException {
this(method, new URL(url));
Expand Down Expand Up @@ -76,7 +74,7 @@ public HttpRequest setFollowRedirects(@Nonnull final FollowRedirects followRedir
* @return If the cookie manager is set
*/
public boolean isCookieManagerSet() {
return this.cookieManagerSet;
return this.cookieManager.isSet();
}

/**
Expand All @@ -85,17 +83,17 @@ public boolean isCookieManagerSet() {
* @return This instance for chaining
*/
public HttpRequest unsetCookieManager() {
this.cookieManager = null;
this.cookieManagerSet = false;
this.cookieManager.unset();
return this;
}

/**
* @return The set cookie manager
* @throws IllegalStateException If the cookie manager is not set
*/
@Nullable
public CookieManager getCookieManager() {
return this.cookieManager;
return this.cookieManager.get();
}

/**
Expand All @@ -105,16 +103,15 @@ public CookieManager getCookieManager() {
* @return This instance for chaining
*/
public HttpRequest setCookieManager(@Nullable final CookieManager cookieManager) {
this.cookieManager = cookieManager;
this.cookieManagerSet = true;
this.cookieManager.set(cookieManager);
return this;
}

/**
* @return If the retry handler is set
*/
public boolean isRetryHandlerSet() {
return this.retryHandlerSet;
return this.retryHandler.isSet();
}

/**
Expand All @@ -123,17 +120,17 @@ public boolean isRetryHandlerSet() {
* @return This instance for chaining
*/
public HttpRequest unsetRetryHandler() {
this.retryHandler = new RetryHandler();
this.retryHandlerSet = false;
this.retryHandler.unset();
return this;
}

/**
* @return The set retry handler
* @throws IllegalStateException If the retry handler is not set
*/
@Nonnull
public RetryHandler getRetryHandler() {
return this.retryHandler;
return this.retryHandler.get();
}

/**
Expand All @@ -143,8 +140,43 @@ public RetryHandler getRetryHandler() {
* @return This instance for chaining
*/
public HttpRequest setRetryHandler(@Nonnull final RetryHandler retryHandler) {
this.retryHandler = retryHandler;
this.retryHandlerSet = true;
this.retryHandler.set(retryHandler);
return this;
}

/**
* @return If the ignore invalid SSL flag is set
*/
public boolean isIgnoreInvalidSSLSet() {
return this.ignoreInvalidSSL.isSet();
}

/**
* Unset the ignore invalid SSL flag.
*
* @return This instance for chaining
*/
public HttpRequest unsetIgnoreInvalidSSL() {
this.ignoreInvalidSSL.unset();
return this;
}

/**
* @return The set ignore invalid SSL flag
* @throws IllegalStateException If the ignore invalid SSL flag is not set
*/
public boolean getIgnoreInvalidSSL() {
return this.ignoreInvalidSSL.get();
}

/**
* Set the ignore invalid SSL flag to use for this request.
*
* @param ignoreInvalidSSL The ignore invalid SSL flag to use
* @return This instance for chaining
*/
public HttpRequest setIgnoreInvalidSSL(final boolean ignoreInvalidSSL) {
this.ignoreInvalidSSL.set(ignoreInvalidSSL);
return this;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package net.lenni0451.commons.httpclient.utils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509ExtendedTrustManager;
import java.io.IOException;
import java.net.Socket;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

public class IgnoringTrustManager extends X509ExtendedTrustManager {

public static SSLContext makeIgnoringSSLContext() throws IOException {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{new IgnoringTrustManager()}, new SecureRandom());
return sslContext;
} catch (Throwable t) {
throw new IOException("Failed to create ignoring SSL socket factory", t);
}
}


@Override
public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) {
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) {
}

@Override
public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) {
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) {
}

@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}

@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package net.lenni0451.commons.httpclient.utils;

public class ResettableStorage<T> {

private boolean set = false;
private T value;

public ResettableStorage() {
}

public ResettableStorage(final T defaultValue) {
this.set(defaultValue);
}

public boolean isSet() {
return this.set;
}

public void unset() {
this.set = false;
this.value = null;
}

public T get() {
if (!this.set) throw new IllegalStateException("Value is not set");
return this.value;
}

public void set(final T value) {
this.value = value;
this.set = true;
}

}

0 comments on commit e57c1b5

Please sign in to comment.