Skip to content
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ build
target
.DS_Store
.savant/cache
/.classpath
/.project
/.settings/
104 changes: 55 additions & 49 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<groupId>io.fusionauth</groupId>
<artifactId>fusionauth-jwt</artifactId>
<version>6.0.0</version>
<version>7.0.0</version>
<packaging>jar</packaging>

<name>FusionAuth JWT</name>
Expand Down Expand Up @@ -60,54 +60,60 @@
</properties>

<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.15.4</version>
<type>jar</type>
<scope>compile</scope>
<optional>false</optional>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.4</version>
<type>jar</type>
<scope>compile</scope>
<optional>false</optional>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.15.4</version>
<type>jar</type>
<scope>compile</scope>
<optional>false</optional>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bc-fips</artifactId>
<version>2.1.2</version>
<type>jar</type>
<scope>test</scope>
<optional>false</optional>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.9.0</version>
<type>jar</type>
<scope>test</scope>
<optional>false</optional>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.36</version>
<type>jar</type>
<scope>test</scope>
<optional>false</optional>
</dependency>
<!-- Source: https://mvnrepository.com/artifact/tools.jackson.core/jackson-core -->
<dependency>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>3.1.0</version>
<type>jar</type>
<scope>compile</scope>
<optional>false</optional>
</dependency>
<!-- Source: https://mvnrepository.com/artifact/tools.jackson.core/jackson-databind -->
<dependency>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>3.1.0</version>
<type>jar</type>
<scope>compile</scope>
<optional>false</optional>
</dependency>
<!-- Source: https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.21</version>
<type>jar</type>
<scope>compile</scope>
<optional>false</optional>
</dependency>
<!-- Source: https://mvnrepository.com/artifact/org.bouncycastle/bc-fips -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bc-fips</artifactId>
<version>2.1.2</version>
<type>jar</type>
<scope>test</scope>
<optional>false</optional>
</dependency>
<!-- Source: https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.12.0</version>
<scope>test</scope>
<type>jar</type>
<optional>false</optional>
</dependency>
<!-- Source: https://mvnrepository.com/artifact/org.slf4j/slf4j-nop -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>2.0.17</version>
<type>jar</type>
<scope>test</scope>
<optional>false</optional>
</dependency>
</dependencies>

<build>
Expand Down
117 changes: 73 additions & 44 deletions src/main/java/io/fusionauth/http/AbstractHttpHelper.java
Original file line number Diff line number Diff line change
@@ -1,57 +1,86 @@
/*
* Copyright (c) 2020, FusionAuth, All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/

package io.fusionauth.http;

import io.fusionauth.jwks.JSONWebKeySetHelper;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;

/**
* @author Daniel DeGroff
*/
public abstract class AbstractHttpHelper {
protected static <T> T get(HttpURLConnection urlConnection, Function<InputStream, T> consumer, BiFunction<String, Throwable, ? extends RuntimeException> exception) {
String endpoint = urlConnection.getURL().toString();

try {
urlConnection.setRequestMethod("GET");
urlConnection.connect();
} catch (Exception e) {
throw exception.apply("Failed to connect to [" + endpoint + "].", e);
}

int status;
try {
status = urlConnection.getResponseCode();
} catch (Exception e) {
throw exception.apply("Failed to make a request to [" + endpoint + "].", e);
}

if (status < 200 || status > 299) {
throw exception.apply("Failed to make a request to [" + endpoint + "], a status code of [" + status + "] was returned.", null);
}

try (InputStream is = new BufferedInputStream(urlConnection.getInputStream())) {
return consumer.apply(is);
} catch (Exception e) {
throw exception.apply("Failed to parse the response as JSON from [" + endpoint + "].", e);
}
}

protected static HttpURLConnection buildURLConnection(String endpoint) {
try {
HttpURLConnection urlConnection = (HttpURLConnection) new URL(endpoint).openConnection();
urlConnection.setDoOutput(true);
urlConnection.setConnectTimeout(10_000);
urlConnection.setReadTimeout(10_000);
urlConnection.addRequestProperty("User-Agent", "fusionauth-jwt (https://github.com/FusionAuth/fusionauth-jwt)");
return urlConnection;
} catch (IOException e) {
throw new JSONWebKeySetHelper.JSONWebKeySetException("Failed to build connection to [" + endpoint + "].", e);
}
}

private static volatile HttpClient HTTP_CLIENT = HttpClient.newBuilder().connectTimeout(Duration.ofMillis(10_000)).build();

public static void setHttpClient(HttpClient client) {
HTTP_CLIENT = client;
}

protected static <T> T get(HttpRequest request, Function<InputStream, T> consumer,
BiFunction<String, Throwable, ? extends RuntimeException> exception) {
String endpoint = request.uri().toString();

HttpResponse<InputStream> response;
try {
response = HTTP_CLIENT.send(request, HttpResponse.BodyHandlers.ofInputStream());
} catch (Exception e) {
throw exception.apply("Failed to make a request to [" + endpoint + "].", e);
}

int status = response.statusCode();
if (status < 200 || status > 299) {
throw exception.apply(
"Failed to make a request to [" + endpoint + "], a status code of [" + status + "] was returned.",
null);
}

try (InputStream is = response.body()) {
return consumer.apply(is);
} catch (Exception e) {
throw exception.apply("Failed to parse the response as JSON from [" + endpoint + "].", e);
}
}

protected static HttpRequest buildRequest(String endpoint, Consumer<HttpRequest.Builder> consumer) {
try {
HttpRequest.Builder builder = HttpRequest.newBuilder()
.uri(URI.create(endpoint))
.timeout(Duration.ofMillis(10_000))
.header("User-Agent", "fusionauth-jwt (https://github.com/FusionAuth/fusionauth-jwt)")
.GET();

if (consumer != null) {
consumer.accept(builder);
}

return builder.build();
} catch (Exception e) {
throw new JSONWebKeySetHelper.JSONWebKeySetException(
"Failed to build connection to [" + endpoint + "].", e);
}
}

}
Loading