Skip to content
This repository has been archived by the owner on May 5, 2021. It is now read-only.

Added support for client side certificate validation #8

Merged
merged 4 commits into from
Jul 31, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import me.nikhilchaudhari.asynkio.helper.Auth
import me.nikhilchaudhari.asynkio.request.RequestImpl
import me.nikhilchaudhari.asynkio.response.Response
import me.nikhilchaudhari.asynkio.response.ResponseImpl
import javax.net.ssl.SSLContext

const val DEFAULT_TIMEOUT = 30.0

Expand All @@ -15,7 +16,7 @@ fun delete(
url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null, json: Any? = null,
timeout: Double = DEFAULT_TIMEOUT, allowRedirects: Boolean? = null,
stream: Boolean = false, files: List<RawFiles> = listOf()
stream: Boolean = false, files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return request(
"DELETE",
Expand All @@ -28,7 +29,8 @@ fun delete(
timeout,
allowRedirects,
stream,
files
files,
sslContext
)
}

Expand All @@ -37,27 +39,27 @@ fun get(
url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null, json: Any? = null,
timeout: Double = DEFAULT_TIMEOUT, allowRedirects: Boolean? = null,
stream: Boolean = false, files: List<RawFiles> = listOf()
stream: Boolean = false, files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return request("GET", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files)
return request("GET", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files, sslContext)
}

@JvmOverloads
fun head(
url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null,
json: Any? = null, timeout: Double = DEFAULT_TIMEOUT, allowRedirects: Boolean? = null,
stream: Boolean = false, files: List<RawFiles> = listOf()
stream: Boolean = false, files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return request("HEAD", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files)
return request("HEAD", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files, sslContext)
}

@JvmOverloads
fun options(
url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null, json: Any? = null,
timeout: Double = DEFAULT_TIMEOUT, allowRedirects: Boolean? = null,
stream: Boolean = false, files: List<RawFiles> = listOf()
stream: Boolean = false, files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return request(
"OPTIONS",
Expand All @@ -70,7 +72,8 @@ fun options(
timeout,
allowRedirects,
stream,
files
files,
sslContext
)
}

Expand All @@ -79,42 +82,43 @@ fun patch(
url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null, json: Any? = null,
timeout: Double = DEFAULT_TIMEOUT, allowRedirects: Boolean? = null,
stream: Boolean = false, files: List<RawFiles> = listOf()
stream: Boolean = false, files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return request("PATCH", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files)
return request("PATCH", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files, sslContext)
}

@JvmOverloads
fun post(
url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null, json: Any? = null,
timeout: Double = DEFAULT_TIMEOUT, allowRedirects: Boolean? = null,
stream: Boolean = false, files: List<RawFiles> = listOf()
stream: Boolean = false, files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return request("POST", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files)
return request("POST", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files, sslContext)
}

@JvmOverloads
fun put(
url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null, json: Any? = null,
timeout: Double = DEFAULT_TIMEOUT, allowRedirects: Boolean? = null,
stream: Boolean = false, files: List<RawFiles> = listOf()
stream: Boolean = false, files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return request("PUT", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files)
return request("PUT", url, headers, params, auth, data, json, timeout, allowRedirects, stream, files, sslContext)
}

@JvmOverloads
fun request(
method: String, url: String, headers: Map<String, String?> = mapOf(),
params: Map<String, String> = mapOf(), auth: Auth? = null, data: Any? = null,
json: Any? = null, timeout: Double = DEFAULT_TIMEOUT,
allowRedirects: Boolean? = null, stream: Boolean = false, files: List<RawFiles> = listOf()
allowRedirects: Boolean? = null, stream: Boolean = false,
files: List<RawFiles> = listOf(), sslContext: SSLContext? = null
): Response {
return ResponseImpl(
RequestImpl(
method, url, params, headers, auth, data,
json, timeout, allowRedirects, stream, files
json, timeout, allowRedirects, stream, files, sslContext
)
).run {
this.init()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package me.nikhilchaudhari.asynkio.request

import me.nikhilchaudhari.asynkio.helper.RawFiles
import me.nikhilchaudhari.asynkio.helper.Auth
import javax.net.ssl.SSLContext

interface Request {

Expand Down Expand Up @@ -29,4 +30,6 @@ interface Request {

val files: List<RawFiles>

val sslContext: SSLContext?

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import java.io.ByteArrayOutputStream
import java.io.File
import java.io.InputStream
import java.util.*
import javax.net.ssl.SSLContext


class RequestImpl internal constructor(
Expand All @@ -31,7 +32,8 @@ class RequestImpl internal constructor(
override val timeout: Double,
allowRedirects: Boolean?,
override val stream: Boolean,
override val files: List<RawFiles>
override val files: List<RawFiles>,
override val sslContext: SSLContext?
) : Request {

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import java.nio.charset.Charset
import java.util.*
import java.util.zip.GZIPInputStream
import java.util.zip.InflaterInputStream
import javax.net.ssl.HttpsURLConnection


class ResponseImpl internal constructor(override val request: Request) : Response {
Expand Down Expand Up @@ -141,6 +142,13 @@ class ResponseImpl internal constructor(override val request: Request) : Respons
connection.connectTimeout = timeout
connection.readTimeout = timeout
},
{ response, connection ->
response.request.sslContext?.let {
if (connection is HttpsURLConnection) {
connection.sslSocketFactory = it.socketFactory
}
}
},
{ _, connection ->
connection.instanceFollowRedirects = false
}
Expand Down Expand Up @@ -201,7 +209,8 @@ class ResponseImpl internal constructor(override val request: Request) : Respons
timeout = this.timeout,
allowRedirects = false,
stream = this.stream,
files = this.files
files = this.files,
sslContext = this.sslContext
)
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package me.nikhilchaudhari.asynkioapp;

import org.junit.Test;

import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.util.Collections;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;

import me.nikhilchaudhari.asynkio.core.NetworkCall;
import me.nikhilchaudhari.asynkio.helper.RawFiles;
import me.nikhilchaudhari.asynkio.response.Response;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public class NetworkCallTest {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind writing this in kotlin.
you can add kotlin support for test folder as well in gradle

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, just changed it to kotlin.
But what do you mean exactly with:

you can add kotlin support for test folder as well in gradle

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot.
I thought kotlin dependency is not added for the test folder 🤦 .
but it already there, sorry my bad ✋.


@Test
public void executeGetRequestWithCertificateBasedClientAuthentication() throws Exception {
SSLContext sslContext = createSslContextWithKeyMaterial();

Response response = NetworkCall.get("https://client.badssl.com/",
Collections.<String, String>emptyMap(),
Collections.<String, String>emptyMap(),
null,
null,
null,
2.0,
true,
false,
Collections.<RawFiles>emptyList(),
sslContext);

int statusCode = response.getStatusCode();

if (statusCode == 400) {
System.out.println("Please validate if certificate is not expired");
} else {
assertThat(statusCode, is(200));
}
}

private SSLContext createSslContextWithKeyMaterial() throws Exception {
String keyStorePath = "src/test/resources/badssl.com-client.jks";
char[] keyStorePassword = "badssl.com".toCharArray();

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

try(InputStream keyStoreInputStream = Files.newInputStream(Paths.get(keyStorePath));) {
keyStore.load(keyStoreInputStream, keyStorePassword);
}

KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, keyStorePassword);
KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();

SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(keyManagers, null, null);
return sslContext;
}

}
Binary file added asynkio/src/test/resources/badssl.com-client.jks
Binary file not shown.