mirror of
https://github.com/square/okhttp.git
synced 2025-04-19 07:42:15 +03:00
Update dependency com.diffplug.spotless:spotless-plugin-gradle to v7 (#8702)
* Update dependency com.diffplug.spotless:spotless-plugin-gradle to v7 * Reformat --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jake Wharton <jw@squareup.com>
This commit is contained in:
parent
c4d472cab7
commit
a51cfbf841
@ -58,10 +58,12 @@ class AndroidAsyncDnsTest {
|
||||
private val localhost: HandshakeCertificates by lazy {
|
||||
// Generate a self-signed cert for the server to serve and the client to trust.
|
||||
val heldCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.addSubjectAlternativeName("localhost")
|
||||
.build()
|
||||
return@lazy HandshakeCertificates.Builder()
|
||||
return@lazy HandshakeCertificates
|
||||
.Builder()
|
||||
.addPlatformTrustedCertificates()
|
||||
.heldCertificate(heldCertificate)
|
||||
.addTrustedCertificate(heldCertificate.certificate)
|
||||
@ -73,7 +75,8 @@ class AndroidAsyncDnsTest {
|
||||
assumeTrue("Supported on API 29+", Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
|
||||
client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.dns(AsyncDns.toDns(AndroidAsyncDns.IPv4, AndroidAsyncDns.IPv6))
|
||||
.sslSocketFactory(localhost.sslSocketFactory(), localhost.trustManager)
|
||||
.build()
|
||||
@ -187,7 +190,8 @@ class AndroidAsyncDnsTest {
|
||||
connectivityManager.activeNetwork ?: throw AssumptionViolatedException("No active network")
|
||||
|
||||
val client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.dns(AsyncDns.toDns(AndroidAsyncDns.IPv4, AndroidAsyncDns.IPv6))
|
||||
.socketFactory(network.socketFactory)
|
||||
.build()
|
||||
|
@ -110,7 +110,8 @@ class OkHttpTest {
|
||||
private var client: OkHttpClient = clientTestRule.newClient()
|
||||
|
||||
private val moshi =
|
||||
Moshi.Builder()
|
||||
Moshi
|
||||
.Builder()
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
|
||||
@ -144,17 +145,18 @@ class OkHttpTest {
|
||||
val request = Request.Builder().url("https://api.twitter.com/robots.txt").build()
|
||||
|
||||
val clientCertificates =
|
||||
HandshakeCertificates.Builder()
|
||||
HandshakeCertificates
|
||||
.Builder()
|
||||
.addPlatformTrustedCertificates()
|
||||
.apply {
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
addInsecureHost(server.hostName)
|
||||
}
|
||||
}
|
||||
.build()
|
||||
}.build()
|
||||
|
||||
client =
|
||||
client.newBuilder()
|
||||
client
|
||||
.newBuilder()
|
||||
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager)
|
||||
.build()
|
||||
|
||||
@ -194,14 +196,16 @@ class OkHttpTest {
|
||||
var socketClass: String? = null
|
||||
|
||||
val clientCertificates =
|
||||
HandshakeCertificates.Builder()
|
||||
HandshakeCertificates
|
||||
.Builder()
|
||||
.addPlatformTrustedCertificates()
|
||||
.addInsecureHost(server.hostName)
|
||||
.build()
|
||||
|
||||
// Need fresh client to reset sslSocketFactoryOrNull
|
||||
client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.eventListenerFactory(
|
||||
clientTestRule.wrap(
|
||||
object : EventListener() {
|
||||
@ -213,8 +217,7 @@ class OkHttpTest {
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager)
|
||||
).sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager)
|
||||
.build()
|
||||
|
||||
val response = client.newCall(request).execute()
|
||||
@ -257,7 +260,8 @@ class OkHttpTest {
|
||||
}
|
||||
|
||||
val clientCertificates =
|
||||
HandshakeCertificates.Builder()
|
||||
HandshakeCertificates
|
||||
.Builder()
|
||||
.addPlatformTrustedCertificates()
|
||||
.addInsecureHost(server.hostName)
|
||||
.build()
|
||||
@ -268,7 +272,8 @@ class OkHttpTest {
|
||||
|
||||
// Need fresh client to reset sslSocketFactoryOrNull
|
||||
client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.eventListenerFactory(
|
||||
clientTestRule.wrap(
|
||||
object : EventListener() {
|
||||
@ -280,8 +285,7 @@ class OkHttpTest {
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager)
|
||||
).sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager)
|
||||
.build()
|
||||
|
||||
val response = client.newCall(request).execute()
|
||||
@ -322,16 +326,18 @@ class OkHttpTest {
|
||||
var socketClass: String? = null
|
||||
|
||||
val clientCertificates =
|
||||
HandshakeCertificates.Builder()
|
||||
.addPlatformTrustedCertificates().apply {
|
||||
HandshakeCertificates
|
||||
.Builder()
|
||||
.addPlatformTrustedCertificates()
|
||||
.apply {
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
addInsecureHost(server.hostName)
|
||||
}
|
||||
}
|
||||
.build()
|
||||
}.build()
|
||||
|
||||
client =
|
||||
client.newBuilder()
|
||||
client
|
||||
.newBuilder()
|
||||
.eventListenerFactory(
|
||||
clientTestRule.wrap(
|
||||
object : EventListener() {
|
||||
@ -343,8 +349,7 @@ class OkHttpTest {
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager)
|
||||
).sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager)
|
||||
.build()
|
||||
|
||||
val response = client.newCall(request).execute()
|
||||
@ -458,7 +463,8 @@ class OkHttpTest {
|
||||
enableTls()
|
||||
|
||||
val certificatePinner =
|
||||
CertificatePinner.Builder()
|
||||
CertificatePinner
|
||||
.Builder()
|
||||
.add(server.hostName, "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
|
||||
.build()
|
||||
client = client.newBuilder().certificatePinner(certificatePinner).build()
|
||||
@ -479,12 +485,12 @@ class OkHttpTest {
|
||||
enableTls()
|
||||
|
||||
val certificatePinner =
|
||||
CertificatePinner.Builder()
|
||||
CertificatePinner
|
||||
.Builder()
|
||||
.add(
|
||||
server.hostName,
|
||||
CertificatePinner.pin(handshakeCertificates.trustManager.acceptedIssuers[0]),
|
||||
)
|
||||
.build()
|
||||
).build()
|
||||
client = client.newBuilder().certificatePinner(certificatePinner).build()
|
||||
|
||||
server.enqueue(MockResponse(body = "abc"))
|
||||
@ -517,10 +523,23 @@ class OkHttpTest {
|
||||
|
||||
assertEquals(
|
||||
listOf(
|
||||
"CallStart", "ProxySelectStart", "ProxySelectEnd", "DnsStart", "DnsEnd",
|
||||
"ConnectStart", "SecureConnectStart", "SecureConnectEnd", "ConnectEnd",
|
||||
"ConnectionAcquired", "RequestHeadersStart", "RequestHeadersEnd", "ResponseHeadersStart",
|
||||
"ResponseHeadersEnd", "ResponseBodyStart", "ResponseBodyEnd", "ConnectionReleased",
|
||||
"CallStart",
|
||||
"ProxySelectStart",
|
||||
"ProxySelectEnd",
|
||||
"DnsStart",
|
||||
"DnsEnd",
|
||||
"ConnectStart",
|
||||
"SecureConnectStart",
|
||||
"SecureConnectEnd",
|
||||
"ConnectEnd",
|
||||
"ConnectionAcquired",
|
||||
"RequestHeadersStart",
|
||||
"RequestHeadersEnd",
|
||||
"ResponseHeadersStart",
|
||||
"ResponseHeadersEnd",
|
||||
"ResponseBodyStart",
|
||||
"ResponseBodyEnd",
|
||||
"ConnectionReleased",
|
||||
"CallEnd",
|
||||
),
|
||||
eventListener.recordedEventTypes(),
|
||||
@ -535,8 +554,14 @@ class OkHttpTest {
|
||||
assertEquals(
|
||||
listOf(
|
||||
"CallStart",
|
||||
"ConnectionAcquired", "RequestHeadersStart", "RequestHeadersEnd", "ResponseHeadersStart",
|
||||
"ResponseHeadersEnd", "ResponseBodyStart", "ResponseBodyEnd", "ConnectionReleased",
|
||||
"ConnectionAcquired",
|
||||
"RequestHeadersStart",
|
||||
"RequestHeadersEnd",
|
||||
"ResponseHeadersStart",
|
||||
"ResponseHeadersEnd",
|
||||
"ResponseBodyStart",
|
||||
"ResponseBodyEnd",
|
||||
"ConnectionReleased",
|
||||
"CallEnd",
|
||||
),
|
||||
eventListener.recordedEventTypes(),
|
||||
@ -550,20 +575,26 @@ class OkHttpTest {
|
||||
enableTls()
|
||||
|
||||
client =
|
||||
client.newBuilder().eventListenerFactory(
|
||||
clientTestRule.wrap(
|
||||
object : EventListener() {
|
||||
override fun connectionAcquired(
|
||||
call: Call,
|
||||
connection: Connection,
|
||||
) {
|
||||
val sslSocket = connection.socket() as SSLSocket
|
||||
client
|
||||
.newBuilder()
|
||||
.eventListenerFactory(
|
||||
clientTestRule.wrap(
|
||||
object : EventListener() {
|
||||
override fun connectionAcquired(
|
||||
call: Call,
|
||||
connection: Connection,
|
||||
) {
|
||||
val sslSocket = connection.socket() as SSLSocket
|
||||
|
||||
sessionIds.add(sslSocket.session.id.toByteString().hex())
|
||||
}
|
||||
},
|
||||
),
|
||||
).build()
|
||||
sessionIds.add(
|
||||
sslSocket.session.id
|
||||
.toByteString()
|
||||
.hex(),
|
||||
)
|
||||
}
|
||||
},
|
||||
),
|
||||
).build()
|
||||
|
||||
server.enqueue(MockResponse(body = "abc1"))
|
||||
server.enqueue(MockResponse(body = "abc2"))
|
||||
@ -590,13 +621,18 @@ class OkHttpTest {
|
||||
assumeNetwork()
|
||||
|
||||
client =
|
||||
client.newBuilder()
|
||||
client
|
||||
.newBuilder()
|
||||
.eventListenerFactory(clientTestRule.wrap(LoggingEventListener.Factory()))
|
||||
.build()
|
||||
|
||||
val dohDns = buildCloudflareIp(client)
|
||||
val dohEnabledClient =
|
||||
client.newBuilder().eventListener(EventListener.NONE).dns(dohDns).build()
|
||||
client
|
||||
.newBuilder()
|
||||
.eventListener(EventListener.NONE)
|
||||
.dns(dohDns)
|
||||
.build()
|
||||
|
||||
dohEnabledClient.get("https://www.twitter.com/robots.txt")
|
||||
dohEnabledClient.get("https://www.facebook.com/robots.txt")
|
||||
@ -630,7 +666,8 @@ class OkHttpTest {
|
||||
val hostnameVerifier = HostnameVerifier { _, _ -> true }
|
||||
|
||||
client =
|
||||
client.newBuilder()
|
||||
client
|
||||
.newBuilder()
|
||||
.sslSocketFactory(sslSocketFactory, trustManager)
|
||||
.hostnameVerifier(hostnameVerifier)
|
||||
.build()
|
||||
@ -649,17 +686,15 @@ class OkHttpTest {
|
||||
|
||||
val delegatingSocketFactory =
|
||||
object : DelegatingSSLSocketFactory(sslSocketFactory) {
|
||||
override fun configureSocket(sslSocket: SSLSocket): SSLSocket {
|
||||
return object : DelegatingSSLSocket(sslSocket) {
|
||||
override fun getApplicationProtocol(): String {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun configureSocket(sslSocket: SSLSocket): SSLSocket =
|
||||
object : DelegatingSSLSocket(sslSocket) {
|
||||
override fun getApplicationProtocol(): String = throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client =
|
||||
client.newBuilder()
|
||||
client
|
||||
.newBuilder()
|
||||
.sslSocketFactory(delegatingSocketFactory, trustManager)
|
||||
.build()
|
||||
|
||||
@ -714,7 +749,8 @@ class OkHttpTest {
|
||||
val hostnameVerifier = HostnameVerifier { _, _ -> true }
|
||||
|
||||
client =
|
||||
client.newBuilder()
|
||||
client
|
||||
.newBuilder()
|
||||
.sslSocketFactory(sslSocketFactory, trustManager)
|
||||
.hostnameVerifier(hostnameVerifier)
|
||||
.build()
|
||||
@ -748,7 +784,13 @@ class OkHttpTest {
|
||||
}
|
||||
is CertificateException -> {
|
||||
assertTrue(ioe.cause?.cause is IllegalArgumentException)
|
||||
assertEquals(true, ioe.cause?.cause?.message?.startsWith("Invalid input to toASCII"))
|
||||
assertEquals(
|
||||
true,
|
||||
ioe.cause
|
||||
?.cause
|
||||
?.message
|
||||
?.startsWith("Invalid input to toASCII"),
|
||||
)
|
||||
}
|
||||
else -> throw ioe
|
||||
}
|
||||
@ -767,9 +809,12 @@ class OkHttpTest {
|
||||
var socketClass: String? = null
|
||||
|
||||
val trustManager =
|
||||
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).apply {
|
||||
init(null as KeyStore?)
|
||||
}.trustManagers.first() as X509TrustManager
|
||||
TrustManagerFactory
|
||||
.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
||||
.apply {
|
||||
init(null as KeyStore?)
|
||||
}.trustManagers
|
||||
.first() as X509TrustManager
|
||||
|
||||
val sslContext =
|
||||
Platform.get().newSSLContext().apply {
|
||||
@ -778,7 +823,8 @@ class OkHttpTest {
|
||||
}
|
||||
|
||||
client =
|
||||
client.newBuilder()
|
||||
client
|
||||
.newBuilder()
|
||||
.sslSocketFactory(sslContext.socketFactory, trustManager)
|
||||
.eventListenerFactory(
|
||||
clientTestRule.wrap(
|
||||
@ -791,8 +837,7 @@ class OkHttpTest {
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
.build()
|
||||
).build()
|
||||
|
||||
val request = Request.Builder().url("https://facebook.com/robots.txt").build()
|
||||
|
||||
@ -820,7 +865,8 @@ class OkHttpTest {
|
||||
val calls = mutableMapOf<String, AtomicInteger>()
|
||||
|
||||
override fun publish(record: LogRecord) {
|
||||
calls.getOrPut(record.loggerName) { AtomicInteger(0) }
|
||||
calls
|
||||
.getOrPut(record.loggerName) { AtomicInteger(0) }
|
||||
.incrementAndGet()
|
||||
}
|
||||
|
||||
@ -833,26 +879,33 @@ class OkHttpTest {
|
||||
level = Level.FINEST
|
||||
}
|
||||
|
||||
Logger.getLogger("")
|
||||
Logger
|
||||
.getLogger("")
|
||||
.addHandler(testHandler)
|
||||
Logger.getLogger("okhttp3")
|
||||
Logger
|
||||
.getLogger("okhttp3")
|
||||
.addHandler(testHandler)
|
||||
Logger.getLogger(Http2::class.java.name)
|
||||
Logger
|
||||
.getLogger(Http2::class.java.name)
|
||||
.addHandler(testHandler)
|
||||
Logger.getLogger(TaskRunner::class.java.name)
|
||||
Logger
|
||||
.getLogger(TaskRunner::class.java.name)
|
||||
.addHandler(testHandler)
|
||||
Logger.getLogger(OkHttpClient::class.java.name)
|
||||
Logger
|
||||
.getLogger(OkHttpClient::class.java.name)
|
||||
.addHandler(testHandler)
|
||||
|
||||
server.enqueue(MockResponse(body = "abc"))
|
||||
|
||||
val request =
|
||||
Request.Builder()
|
||||
Request
|
||||
.Builder()
|
||||
.url(server.url("/"))
|
||||
.build()
|
||||
|
||||
val response =
|
||||
client.newCall(request)
|
||||
client
|
||||
.newCall(request)
|
||||
.execute()
|
||||
|
||||
response.use {
|
||||
@ -878,16 +931,19 @@ class OkHttpTest {
|
||||
|
||||
try {
|
||||
client =
|
||||
client.newBuilder()
|
||||
client
|
||||
.newBuilder()
|
||||
.cache(cache)
|
||||
.build()
|
||||
|
||||
val request =
|
||||
Request.Builder()
|
||||
Request
|
||||
.Builder()
|
||||
.url(server.url("/"))
|
||||
.build()
|
||||
|
||||
client.newCall(request)
|
||||
client
|
||||
.newCall(request)
|
||||
.execute()
|
||||
.use {
|
||||
assertEquals(200, it.code)
|
||||
@ -898,7 +954,8 @@ class OkHttpTest {
|
||||
assertTrue(it.cacheControl.isPublic)
|
||||
}
|
||||
|
||||
client.newCall(request)
|
||||
client
|
||||
.newCall(request)
|
||||
.execute()
|
||||
.use {
|
||||
assertEquals(200, it.code)
|
||||
@ -923,20 +980,21 @@ class OkHttpTest {
|
||||
}
|
||||
}
|
||||
|
||||
fun buildCloudflareIp(bootstrapClient: OkHttpClient): DnsOverHttps {
|
||||
return DnsOverHttps.Builder().client(bootstrapClient)
|
||||
fun buildCloudflareIp(bootstrapClient: OkHttpClient): DnsOverHttps =
|
||||
DnsOverHttps
|
||||
.Builder()
|
||||
.client(bootstrapClient)
|
||||
.url("https://1.1.1.1/dns-query".toHttpUrl())
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun enableTls() {
|
||||
client =
|
||||
client.newBuilder()
|
||||
client
|
||||
.newBuilder()
|
||||
.sslSocketFactory(
|
||||
handshakeCertificates.sslSocketFactory(),
|
||||
handshakeCertificates.trustManager,
|
||||
)
|
||||
.build()
|
||||
).build()
|
||||
server.useHttps(handshakeCertificates.sslSocketFactory())
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,8 @@ class StrictModeTest {
|
||||
@After
|
||||
fun cleanup() {
|
||||
StrictMode.setThreadPolicy(
|
||||
ThreadPolicy.Builder()
|
||||
ThreadPolicy
|
||||
.Builder()
|
||||
.permitAll()
|
||||
.build(),
|
||||
)
|
||||
@ -60,12 +61,12 @@ class StrictModeTest {
|
||||
|
||||
private fun applyStrictMode() {
|
||||
StrictMode.setThreadPolicy(
|
||||
ThreadPolicy.Builder()
|
||||
ThreadPolicy
|
||||
.Builder()
|
||||
.detectCustomSlowCalls()
|
||||
.penaltyListener({ it.run() }) {
|
||||
violations.add(it)
|
||||
}
|
||||
.build(),
|
||||
}.build(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -56,16 +56,17 @@ class AlpnOverrideTest {
|
||||
@Test
|
||||
fun getWithCustomSocketFactory() {
|
||||
client =
|
||||
client.newBuilder()
|
||||
client
|
||||
.newBuilder()
|
||||
.sslSocketFactory(CustomSSLSocketFactory(client.sslSocketFactory), client.x509TrustManager!!)
|
||||
.connectionSpecs(
|
||||
listOf(
|
||||
ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
||||
ConnectionSpec
|
||||
.Builder(ConnectionSpec.MODERN_TLS)
|
||||
.supportsTlsExtensions(false)
|
||||
.build(),
|
||||
),
|
||||
)
|
||||
.eventListener(
|
||||
).eventListener(
|
||||
object : EventListener() {
|
||||
override fun connectionAcquired(
|
||||
call: Call,
|
||||
@ -76,11 +77,11 @@ class AlpnOverrideTest {
|
||||
println("Negotiated " + sslSocket.applicationProtocol)
|
||||
}
|
||||
},
|
||||
)
|
||||
.build()
|
||||
).build()
|
||||
|
||||
val request =
|
||||
Request.Builder()
|
||||
Request
|
||||
.Builder()
|
||||
.url("https://www.google.com")
|
||||
.build()
|
||||
client.newCall(request).execute().use { response ->
|
||||
|
@ -77,7 +77,8 @@ class LetsEncryptClientTest {
|
||||
""".trimIndent().decodeCertificatePem()
|
||||
|
||||
val handshakeCertificates =
|
||||
HandshakeCertificates.Builder()
|
||||
HandshakeCertificates
|
||||
.Builder()
|
||||
// TODO reenable in official answers
|
||||
// .addPlatformTrustedCertificates()
|
||||
.addTrustedCertificate(cert)
|
||||
@ -93,7 +94,8 @@ class LetsEncryptClientTest {
|
||||
val client = clientBuilder.build()
|
||||
|
||||
val request =
|
||||
Request.Builder()
|
||||
Request
|
||||
.Builder()
|
||||
.url("https://valid-isrgrootx1.letsencrypt.org/robots.txt")
|
||||
.build()
|
||||
client.newCall(request).execute().use { response ->
|
||||
|
@ -40,7 +40,8 @@ import org.junit.jupiter.api.Test
|
||||
@Tag("Remote")
|
||||
class SniOverrideTest {
|
||||
var client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.build()
|
||||
|
||||
@Test
|
||||
@ -64,7 +65,8 @@ class SniOverrideTest {
|
||||
}
|
||||
|
||||
client =
|
||||
client.newBuilder()
|
||||
client
|
||||
.newBuilder()
|
||||
.sslSocketFactory(CustomSSLSocketFactory(client.sslSocketFactory), client.x509TrustManager!!)
|
||||
.hostnameVerifier { hostname, session ->
|
||||
val s = "hostname: $hostname peerHost:${session.peerHost}"
|
||||
@ -80,11 +82,11 @@ class SniOverrideTest {
|
||||
} catch (e: Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
.build()
|
||||
}.build()
|
||||
|
||||
val request =
|
||||
Request.Builder()
|
||||
Request
|
||||
.Builder()
|
||||
.url("https://sni.cloudflaressl.com/cdn-cgi/trace")
|
||||
.header("Host", "cloudflare-dns.com")
|
||||
.build()
|
||||
@ -99,14 +101,15 @@ class SniOverrideTest {
|
||||
@Test
|
||||
fun getWithDns() {
|
||||
client =
|
||||
client.newBuilder()
|
||||
client
|
||||
.newBuilder()
|
||||
.dns {
|
||||
Dns.SYSTEM.lookup("sni.cloudflaressl.com")
|
||||
}
|
||||
.build()
|
||||
}.build()
|
||||
|
||||
val request =
|
||||
Request.Builder()
|
||||
Request
|
||||
.Builder()
|
||||
.url("https://cloudflare-dns.com/cdn-cgi/trace")
|
||||
.build()
|
||||
client.newCall(request).execute().use { response ->
|
||||
|
@ -40,7 +40,9 @@ import org.robolectric.ParameterizedRobolectricTestRunner
|
||||
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters
|
||||
|
||||
@RunWith(ParameterizedRobolectricTestRunner::class)
|
||||
class AndroidSocketAdapterTest(val adapter: SocketAdapter) {
|
||||
class AndroidSocketAdapterTest(
|
||||
val adapter: SocketAdapter,
|
||||
) {
|
||||
val context: SSLContext by lazy {
|
||||
val provider: Provider = Conscrypt.newProviderBuilder().provideTrustManager(true).build()
|
||||
|
||||
@ -95,12 +97,11 @@ class AndroidSocketAdapterTest(val adapter: SocketAdapter) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@Parameters(name = "{0}")
|
||||
fun data(): Collection<SocketAdapter> {
|
||||
return listOfNotNull(
|
||||
fun data(): Collection<SocketAdapter> =
|
||||
listOfNotNull(
|
||||
DeferredSocketAdapter(ConscryptSocketAdapter.factory),
|
||||
DeferredSocketAdapter(AndroidSocketAdapter.factory("org.conscrypt")),
|
||||
StandardAndroidSocketAdapter.buildIfSupported("org.conscrypt"),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,8 @@ class RobolectricOkHttpClientTest {
|
||||
fun setUp() {
|
||||
context = ApplicationProvider.getApplicationContext<Application>()
|
||||
client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.cache(Cache(FakeFileSystem(), "/cache".toPath(), 10_000_000))
|
||||
.build()
|
||||
}
|
||||
@ -62,7 +63,8 @@ class RobolectricOkHttpClientTest {
|
||||
val request = Request("https://www.google.com/robots.txt".toHttpUrl())
|
||||
|
||||
val networkRequest =
|
||||
request.newBuilder()
|
||||
request
|
||||
.newBuilder()
|
||||
.build()
|
||||
|
||||
val call = client.newCall(networkRequest)
|
||||
|
@ -15,8 +15,8 @@
|
||||
*/
|
||||
|
||||
// https://www.eclipse.org/jetty/documentation/current/alpn-chapter.html#alpn-versions
|
||||
private fun alpnBootVersionForPatchVersion(patchVersion: Int): String? {
|
||||
return when (patchVersion) {
|
||||
private fun alpnBootVersionForPatchVersion(patchVersion: Int): String? =
|
||||
when (patchVersion) {
|
||||
in 0..24 -> "8.1.0.v20141016"
|
||||
in 25..30 -> "8.1.2.v20141202"
|
||||
in 31..50 -> "8.1.3.v20150130"
|
||||
@ -32,7 +32,6 @@ private fun alpnBootVersionForPatchVersion(patchVersion: Int): String? {
|
||||
in 191..242 -> "8.1.13.v20181017"
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the alpn-boot version specific to this OpenJDK 8 JVM, or null if this is not a Java 8 VM.
|
||||
|
@ -39,8 +39,12 @@ private fun Project.applyOsgi(
|
||||
val osgi = project.sourceSets.create("osgi")
|
||||
val osgiApi = project.configurations.getByName(osgiApiConfigurationName)
|
||||
val kotlinOsgi =
|
||||
extensions.getByType(VersionCatalogsExtension::class.java).named("libs")
|
||||
.findLibrary("kotlin.stdlib.osgi").get().get()
|
||||
extensions
|
||||
.getByType(VersionCatalogsExtension::class.java)
|
||||
.named("libs")
|
||||
.findLibrary("kotlin.stdlib.osgi")
|
||||
.get()
|
||||
.get()
|
||||
|
||||
project.dependencies {
|
||||
osgiApi(kotlinOsgi)
|
||||
|
@ -66,7 +66,8 @@ class BasicLoomTest {
|
||||
assertThat(System.getProperty("jdk.tracePinnedThreads")).isNotEmpty()
|
||||
|
||||
client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.trustMockServer()
|
||||
.dispatcher(Dispatcher(newVirtualThreadPerTaskExecutor()))
|
||||
.build()
|
||||
@ -83,19 +84,18 @@ class BasicLoomTest {
|
||||
assertThat(capturedOut.toString()).isEmpty()
|
||||
}
|
||||
|
||||
private fun newVirtualThreadPerTaskExecutor(): ExecutorService {
|
||||
return Executors::class.java.getMethod("newVirtualThreadPerTaskExecutor").invoke(null) as ExecutorService
|
||||
}
|
||||
private fun newVirtualThreadPerTaskExecutor(): ExecutorService =
|
||||
Executors::class.java.getMethod("newVirtualThreadPerTaskExecutor").invoke(null) as ExecutorService
|
||||
|
||||
@Test
|
||||
fun testHttpsRequest() {
|
||||
MockServerClient(mockServer.host, mockServer.serverPort).use { mockServerClient ->
|
||||
mockServerClient
|
||||
.`when`(
|
||||
request().withPath("/person")
|
||||
request()
|
||||
.withPath("/person")
|
||||
.withQueryStringParameter("name", "peter"),
|
||||
)
|
||||
.respond(response().withBody("Peter the person!"))
|
||||
).respond(response().withBody("Peter the person!"))
|
||||
|
||||
val results =
|
||||
(1..20).map {
|
||||
|
@ -40,7 +40,8 @@ class BasicMockServerTest {
|
||||
val mockServer: MockServerContainer = MockServerContainer(MOCKSERVER_IMAGE)
|
||||
|
||||
val client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.trustMockServer()
|
||||
.build()
|
||||
|
||||
@ -49,10 +50,10 @@ class BasicMockServerTest {
|
||||
MockServerClient(mockServer.host, mockServer.serverPort).use { mockServerClient ->
|
||||
mockServerClient
|
||||
.`when`(
|
||||
request().withPath("/person")
|
||||
request()
|
||||
.withPath("/person")
|
||||
.withQueryStringParameter("name", "peter"),
|
||||
)
|
||||
.respond(response().withBody("Peter the person!"))
|
||||
).respond(response().withBody("Peter the person!"))
|
||||
|
||||
val response = client.newCall(Request((mockServer.endpoint + "/person?name=peter").toHttpUrl())).execute()
|
||||
|
||||
@ -65,10 +66,10 @@ class BasicMockServerTest {
|
||||
MockServerClient(mockServer.host, mockServer.serverPort).use { mockServerClient ->
|
||||
mockServerClient
|
||||
.`when`(
|
||||
request().withPath("/person")
|
||||
request()
|
||||
.withPath("/person")
|
||||
.withQueryStringParameter("name", "peter"),
|
||||
)
|
||||
.respond(response().withBody("Peter the person!"))
|
||||
).respond(response().withBody("Peter the person!"))
|
||||
|
||||
val response = client.newCall(Request((mockServer.secureEndpoint + "/person?name=peter").toHttpUrl())).execute()
|
||||
|
||||
|
@ -55,9 +55,10 @@ class BasicProxyTest {
|
||||
val client = OkHttpClient()
|
||||
|
||||
val response =
|
||||
client.newCall(
|
||||
Request((mockServer.endpoint + "/person?name=peter").toHttpUrl()),
|
||||
).execute()
|
||||
client
|
||||
.newCall(
|
||||
Request((mockServer.endpoint + "/person?name=peter").toHttpUrl()),
|
||||
).execute()
|
||||
|
||||
assertThat(response.body.string()).contains("Peter the person")
|
||||
assertThat(response.protocol).isEqualTo(Protocol.HTTP_1_1)
|
||||
@ -70,14 +71,16 @@ class BasicProxyTest {
|
||||
it.withProxyConfiguration(ProxyConfiguration.proxyConfiguration(ProxyConfiguration.Type.HTTP, it.remoteAddress()))
|
||||
|
||||
val client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.proxy(Proxy(Proxy.Type.HTTP, it.remoteAddress()))
|
||||
.build()
|
||||
|
||||
val response =
|
||||
client.newCall(
|
||||
Request((mockServer.endpoint + "/person?name=peter").toHttpUrl()),
|
||||
).execute()
|
||||
client
|
||||
.newCall(
|
||||
Request((mockServer.endpoint + "/person?name=peter").toHttpUrl()),
|
||||
).execute()
|
||||
|
||||
assertThat(response.body.string()).contains("Peter the person")
|
||||
}
|
||||
@ -87,14 +90,16 @@ class BasicProxyTest {
|
||||
fun testOkHttpSecureDirect() {
|
||||
testRequest {
|
||||
val client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.trustMockServer()
|
||||
.build()
|
||||
|
||||
val response =
|
||||
client.newCall(
|
||||
Request((mockServer.secureEndpoint + "/person?name=peter").toHttpUrl()),
|
||||
).execute()
|
||||
client
|
||||
.newCall(
|
||||
Request((mockServer.secureEndpoint + "/person?name=peter").toHttpUrl()),
|
||||
).execute()
|
||||
|
||||
assertThat(response.body.string()).contains("Peter the person")
|
||||
assertThat(response.protocol).isEqualTo(Protocol.HTTP_2)
|
||||
@ -105,16 +110,18 @@ class BasicProxyTest {
|
||||
fun testOkHttpSecureProxiedHttp1() {
|
||||
testRequest {
|
||||
val client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.trustMockServer()
|
||||
.proxy(Proxy(Proxy.Type.HTTP, it.remoteAddress()))
|
||||
.protocols(listOf(Protocol.HTTP_1_1))
|
||||
.build()
|
||||
|
||||
val response =
|
||||
client.newCall(
|
||||
Request((mockServer.secureEndpoint + "/person?name=peter").toHttpUrl()),
|
||||
).execute()
|
||||
client
|
||||
.newCall(
|
||||
Request((mockServer.secureEndpoint + "/person?name=peter").toHttpUrl()),
|
||||
).execute()
|
||||
|
||||
assertThat(response.body.string()).contains("Peter the person")
|
||||
assertThat(response.protocol).isEqualTo(Protocol.HTTP_1_1)
|
||||
@ -128,7 +135,12 @@ class BasicProxyTest {
|
||||
|
||||
val connection = url.openConnection() as HttpURLConnection
|
||||
|
||||
assertThat(connection.inputStream.source().buffer().readUtf8()).contains("Peter the person")
|
||||
assertThat(
|
||||
connection.inputStream
|
||||
.source()
|
||||
.buffer()
|
||||
.readUtf8(),
|
||||
).contains("Peter the person")
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,7 +157,12 @@ class BasicProxyTest {
|
||||
|
||||
val connection = url.openConnection(proxy) as HttpURLConnection
|
||||
|
||||
assertThat(connection.inputStream.source().buffer().readUtf8()).contains("Peter the person")
|
||||
assertThat(
|
||||
connection.inputStream
|
||||
.source()
|
||||
.buffer()
|
||||
.readUtf8(),
|
||||
).contains("Peter the person")
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,7 +176,12 @@ class BasicProxyTest {
|
||||
|
||||
val connection = url.openConnection() as HttpURLConnection
|
||||
|
||||
assertThat(connection.inputStream.source().buffer().readUtf8()).contains("Peter the person")
|
||||
assertThat(
|
||||
connection.inputStream
|
||||
.source()
|
||||
.buffer()
|
||||
.readUtf8(),
|
||||
).contains("Peter the person")
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,21 +201,26 @@ class BasicProxyTest {
|
||||
|
||||
val connection = url.openConnection(proxy) as HttpURLConnection
|
||||
|
||||
assertThat(connection.inputStream.source().buffer().readUtf8()).contains("Peter the person")
|
||||
assertThat(
|
||||
connection.inputStream
|
||||
.source()
|
||||
.buffer()
|
||||
.readUtf8(),
|
||||
).contains("Peter the person")
|
||||
}
|
||||
}
|
||||
|
||||
private fun testRequest(function: (MockServerClient) -> Unit) {
|
||||
MockServerClient(mockServer.host, mockServer.serverPort).use { mockServerClient ->
|
||||
val request =
|
||||
request().withPath("/person")
|
||||
request()
|
||||
.withPath("/person")
|
||||
.withQueryStringParameter("name", "peter")
|
||||
|
||||
mockServerClient
|
||||
.`when`(
|
||||
request,
|
||||
)
|
||||
.respond(response().withBody("Peter the person!"))
|
||||
).respond(response().withBody("Peter the person!"))
|
||||
|
||||
function(mockServerClient)
|
||||
}
|
||||
|
@ -56,20 +56,22 @@ class SocksProxyTest {
|
||||
MockServerClient(mockServer.host, mockServer.serverPort).use { mockServerClient ->
|
||||
mockServerClient
|
||||
.`when`(
|
||||
request().withPath("/person")
|
||||
request()
|
||||
.withPath("/person")
|
||||
.withQueryStringParameter("name", "peter"),
|
||||
)
|
||||
.respond(response().withBody("Peter the person!"))
|
||||
).respond(response().withBody("Peter the person!"))
|
||||
|
||||
val client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.proxy(Proxy(SOCKS, InetSocketAddress(socks5Proxy.host, socks5Proxy.firstMappedPort)))
|
||||
.build()
|
||||
|
||||
val response =
|
||||
client.newCall(
|
||||
Request("http://mockserver:1080/person?name=peter".toHttpUrl()),
|
||||
).execute()
|
||||
client
|
||||
.newCall(
|
||||
Request("http://mockserver:1080/person?name=peter".toHttpUrl()),
|
||||
).execute()
|
||||
|
||||
assertThat(response.body.string()).contains("Peter the person")
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ gradlePlugin-kotlinSerialization = { module = "org.jetbrains.kotlin:kotlin-seria
|
||||
gradlePlugin-mavenPublish = "com.vanniktech:gradle-maven-publish-plugin:0.31.0"
|
||||
gradlePlugin-mavenSympathy = "io.github.usefulness.maven-sympathy:io.github.usefulness.maven-sympathy.gradle.plugin:0.3.0"
|
||||
gradlePlugin-shadow = "gradle.plugin.com.github.johnrengelman:shadow:8.0.0"
|
||||
gradlePlugin-spotless = "com.diffplug.spotless:spotless-plugin-gradle:6.25.0"
|
||||
gradlePlugin-spotless = "com.diffplug.spotless:spotless-plugin-gradle:7.0.2"
|
||||
guava-jre = "com.google.guava:guava:33.4.0-jre"
|
||||
hamcrestLibrary = "org.hamcrest:hamcrest-library:3.0"
|
||||
httpClient5 = "org.apache.httpcomponents.client5:httpclient5:5.4.2"
|
||||
|
@ -36,13 +36,9 @@ internal fun Dispatcher.wrap(): mockwebserver3.Dispatcher {
|
||||
|
||||
val delegate = this
|
||||
return object : mockwebserver3.Dispatcher() {
|
||||
override fun dispatch(request: mockwebserver3.RecordedRequest): mockwebserver3.MockResponse {
|
||||
return delegate.dispatch(request.unwrap()).wrap()
|
||||
}
|
||||
override fun dispatch(request: mockwebserver3.RecordedRequest): mockwebserver3.MockResponse = delegate.dispatch(request.unwrap()).wrap()
|
||||
|
||||
override fun peek(): mockwebserver3.MockResponse {
|
||||
return delegate.peek().wrap()
|
||||
}
|
||||
override fun peek(): mockwebserver3.MockResponse = delegate.peek().wrap()
|
||||
|
||||
override fun shutdown() {
|
||||
delegate.shutdown()
|
||||
@ -86,17 +82,16 @@ internal fun MockResponse.wrap(): mockwebserver3.MockResponse {
|
||||
return result.build()
|
||||
}
|
||||
|
||||
private fun PushPromise.wrap(): mockwebserver3.PushPromise {
|
||||
return mockwebserver3.PushPromise(
|
||||
private fun PushPromise.wrap(): mockwebserver3.PushPromise =
|
||||
mockwebserver3.PushPromise(
|
||||
method = method,
|
||||
path = path,
|
||||
headers = headers,
|
||||
response = response.wrap(),
|
||||
)
|
||||
}
|
||||
|
||||
internal fun mockwebserver3.RecordedRequest.unwrap(): RecordedRequest {
|
||||
return RecordedRequest(
|
||||
internal fun mockwebserver3.RecordedRequest.unwrap(): RecordedRequest =
|
||||
RecordedRequest(
|
||||
requestLine = requestLine,
|
||||
headers = headers,
|
||||
chunkSizes = chunkSizes,
|
||||
@ -109,10 +104,9 @@ internal fun mockwebserver3.RecordedRequest.unwrap(): RecordedRequest {
|
||||
handshake = handshake,
|
||||
requestUrl = requestUrl,
|
||||
)
|
||||
}
|
||||
|
||||
private fun MockResponse.wrapSocketPolicy(): mockwebserver3.SocketPolicy {
|
||||
return when (val socketPolicy = socketPolicy) {
|
||||
private fun MockResponse.wrapSocketPolicy(): mockwebserver3.SocketPolicy =
|
||||
when (val socketPolicy = socketPolicy) {
|
||||
SocketPolicy.SHUTDOWN_SERVER_AFTER_RESPONSE -> ShutdownServerAfterResponse
|
||||
SocketPolicy.KEEP_OPEN -> KeepOpen
|
||||
SocketPolicy.DISCONNECT_AT_END -> DisconnectAtEnd
|
||||
@ -129,4 +123,3 @@ private fun MockResponse.wrapSocketPolicy(): mockwebserver3.SocketPolicy {
|
||||
SocketPolicy.RESET_STREAM_AT_START -> ResetStreamAtStart(http2ErrorCode)
|
||||
else -> error("Unexpected SocketPolicy: $socketPolicy")
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,7 @@ abstract class Dispatcher {
|
||||
@Throws(InterruptedException::class)
|
||||
abstract fun dispatch(request: RecordedRequest): MockResponse
|
||||
|
||||
open fun peek(): MockResponse {
|
||||
return MockResponse().apply { this.socketPolicy = SocketPolicy.KEEP_OPEN }
|
||||
}
|
||||
open fun peek(): MockResponse = MockResponse().apply { this.socketPolicy = SocketPolicy.KEEP_OPEN }
|
||||
|
||||
open fun shutdown() {}
|
||||
}
|
||||
|
@ -29,7 +29,9 @@ import okhttp3.HttpUrl
|
||||
import okhttp3.Protocol
|
||||
import org.junit.rules.ExternalResource
|
||||
|
||||
class MockWebServer : ExternalResource(), Closeable {
|
||||
class MockWebServer :
|
||||
ExternalResource(),
|
||||
Closeable {
|
||||
@ExperimentalOkHttpApi
|
||||
val delegate = mockwebserver3.MockWebServer()
|
||||
|
||||
@ -176,17 +178,13 @@ class MockWebServer : ExternalResource(), Closeable {
|
||||
}
|
||||
|
||||
@Throws(InterruptedException::class)
|
||||
fun takeRequest(): RecordedRequest {
|
||||
return delegate.takeRequest().unwrap()
|
||||
}
|
||||
fun takeRequest(): RecordedRequest = delegate.takeRequest().unwrap()
|
||||
|
||||
@Throws(InterruptedException::class)
|
||||
fun takeRequest(
|
||||
timeout: Long,
|
||||
unit: TimeUnit,
|
||||
): RecordedRequest? {
|
||||
return delegate.takeRequest(timeout, unit)?.unwrap()
|
||||
}
|
||||
): RecordedRequest? = delegate.takeRequest(timeout, unit)?.unwrap()
|
||||
|
||||
@JvmName("-deprecated_requestCount")
|
||||
@Deprecated(
|
||||
|
@ -21,13 +21,9 @@ class QueueDispatcher : Dispatcher() {
|
||||
internal val delegate = QueueDispatcher()
|
||||
|
||||
@Throws(InterruptedException::class)
|
||||
override fun dispatch(request: RecordedRequest): MockResponse {
|
||||
throw UnsupportedOperationException("unexpected call")
|
||||
}
|
||||
override fun dispatch(request: RecordedRequest): MockResponse = throw UnsupportedOperationException("unexpected call")
|
||||
|
||||
override fun peek(): MockResponse {
|
||||
throw UnsupportedOperationException("unexpected call")
|
||||
}
|
||||
override fun peek(): MockResponse = throw UnsupportedOperationException("unexpected call")
|
||||
|
||||
fun enqueueResponse(response: MockResponse) {
|
||||
delegate.enqueueResponse(response.wrap())
|
||||
|
@ -266,11 +266,19 @@ class MockWebServerTest {
|
||||
server.enqueue(MockResponse()) // The jdk's HttpUrlConnection is a bastard.
|
||||
server.enqueue(MockResponse())
|
||||
try {
|
||||
server.url("/a").toUrl().openConnection().getInputStream()
|
||||
server
|
||||
.url("/a")
|
||||
.toUrl()
|
||||
.openConnection()
|
||||
.getInputStream()
|
||||
fail<Any>()
|
||||
} catch (expected: IOException) {
|
||||
}
|
||||
server.url("/b").toUrl().openConnection().getInputStream() // Should succeed.
|
||||
server
|
||||
.url("/b")
|
||||
.toUrl()
|
||||
.openConnection()
|
||||
.getInputStream() // Should succeed.
|
||||
}
|
||||
|
||||
/**
|
||||
@ -452,7 +460,11 @@ class MockWebServerTest {
|
||||
object : Statement() {
|
||||
override fun evaluate() {
|
||||
called.set(true)
|
||||
server.url("/").toUrl().openConnection().connect()
|
||||
server
|
||||
.url("/")
|
||||
.toUrl()
|
||||
.openConnection()
|
||||
.connect()
|
||||
}
|
||||
},
|
||||
Description.EMPTY,
|
||||
@ -460,7 +472,11 @@ class MockWebServerTest {
|
||||
statement.evaluate()
|
||||
assertThat(called.get()).isTrue()
|
||||
try {
|
||||
server.url("/").toUrl().openConnection().connect()
|
||||
server
|
||||
.url("/")
|
||||
.toUrl()
|
||||
.openConnection()
|
||||
.connect()
|
||||
fail<Any>()
|
||||
} catch (expected: ConnectException) {
|
||||
}
|
||||
@ -593,20 +609,24 @@ class MockWebServerTest {
|
||||
platform.assumeNotBouncyCastle()
|
||||
platform.assumeNotConscrypt()
|
||||
val clientCa =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(0)
|
||||
.build()
|
||||
val serverCa =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(0)
|
||||
.build()
|
||||
val serverCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.signedBy(serverCa)
|
||||
.addSubjectAlternativeName(server.hostName)
|
||||
.build()
|
||||
val serverHandshakeCertificates =
|
||||
HandshakeCertificates.Builder()
|
||||
HandshakeCertificates
|
||||
.Builder()
|
||||
.addTrustedCertificate(clientCa.certificate)
|
||||
.heldCertificate(serverCertificate)
|
||||
.build()
|
||||
@ -614,11 +634,13 @@ class MockWebServerTest {
|
||||
server.enqueue(MockResponse().setBody("abc"))
|
||||
server.requestClientAuth()
|
||||
val clientCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.signedBy(clientCa)
|
||||
.build()
|
||||
val clientHandshakeCertificates =
|
||||
HandshakeCertificates.Builder()
|
||||
HandshakeCertificates
|
||||
.Builder()
|
||||
.addTrustedCertificate(serverCa.certificate)
|
||||
.heldCertificate(clientCertificate)
|
||||
.build()
|
||||
|
@ -33,7 +33,11 @@ class MockWebServerRuleTest {
|
||||
object : Statement() {
|
||||
override fun evaluate() {
|
||||
called.set(true)
|
||||
rule.server.url("/").toUrl().openConnection().connect()
|
||||
rule.server
|
||||
.url("/")
|
||||
.toUrl()
|
||||
.openConnection()
|
||||
.connect()
|
||||
}
|
||||
},
|
||||
Description.EMPTY,
|
||||
@ -41,7 +45,11 @@ class MockWebServerRuleTest {
|
||||
statement.evaluate()
|
||||
assertThat(called.get()).isTrue()
|
||||
try {
|
||||
rule.server.url("/").toUrl().openConnection().connect()
|
||||
rule.server
|
||||
.url("/")
|
||||
.toUrl()
|
||||
.openConnection()
|
||||
.connect()
|
||||
fail()
|
||||
} catch (expected: ConnectException) {
|
||||
}
|
||||
|
@ -43,7 +43,11 @@ import org.junit.jupiter.api.extension.ParameterResolver
|
||||
*/
|
||||
@ExperimentalOkHttpApi
|
||||
class MockWebServerExtension :
|
||||
BeforeEachCallback, AfterEachCallback, ParameterResolver, BeforeAllCallback, AfterAllCallback {
|
||||
BeforeEachCallback,
|
||||
AfterEachCallback,
|
||||
ParameterResolver,
|
||||
BeforeAllCallback,
|
||||
AfterAllCallback {
|
||||
private val ExtensionContext.resource: ServersForTest
|
||||
get() =
|
||||
getStore(namespace).getOrComputeIfAbsent(this.uniqueId) {
|
||||
@ -54,13 +58,12 @@ class MockWebServerExtension :
|
||||
private val servers = mutableMapOf<String, MockWebServer>()
|
||||
private var started = false
|
||||
|
||||
fun server(name: String): MockWebServer {
|
||||
return servers.getOrPut(name) {
|
||||
fun server(name: String): MockWebServer =
|
||||
servers.getOrPut(name) {
|
||||
MockWebServer().also {
|
||||
if (started) it.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun startAll() {
|
||||
started = true
|
||||
@ -87,9 +90,7 @@ class MockWebServerExtension :
|
||||
override fun supportsParameter(
|
||||
parameterContext: ParameterContext,
|
||||
extensionContext: ExtensionContext,
|
||||
): Boolean {
|
||||
return parameterContext.parameter.type === MockWebServer::class.java
|
||||
}
|
||||
): Boolean = parameterContext.parameter.type === MockWebServer::class.java
|
||||
|
||||
@Suppress("NewApi")
|
||||
override fun resolveParameter(
|
||||
|
@ -34,9 +34,7 @@ abstract class Dispatcher {
|
||||
* can return other values to test HTTP edge cases, such as unhappy socket policies or throttled
|
||||
* request bodies.
|
||||
*/
|
||||
open fun peek(): MockResponse {
|
||||
return MockResponse(socketPolicy = KeepOpen)
|
||||
}
|
||||
open fun peek(): MockResponse = MockResponse(socketPolicy = KeepOpen)
|
||||
|
||||
/**
|
||||
* Release any resources held by this dispatcher. Any requests that are currently being dispatched
|
||||
|
@ -196,7 +196,8 @@ class MockResponse {
|
||||
this.streamHandlerVar = null
|
||||
this.webSocketListenerVar = null
|
||||
this.headers =
|
||||
Headers.Builder()
|
||||
Headers
|
||||
.Builder()
|
||||
.add("Content-Length", "0")
|
||||
this.trailers = Headers.Builder()
|
||||
this.throttleBytesPerPeriod = Long.MAX_VALUE
|
||||
|
@ -219,14 +219,14 @@ class MockWebServer : Closeable {
|
||||
*
|
||||
* @param path the request path, such as "/".
|
||||
*/
|
||||
fun url(path: String): HttpUrl {
|
||||
return HttpUrl.Builder()
|
||||
fun url(path: String): HttpUrl =
|
||||
HttpUrl
|
||||
.Builder()
|
||||
.scheme(if (sslSocketFactory != null) "https" else "http")
|
||||
.host(hostName)
|
||||
.port(port)
|
||||
.build()
|
||||
.resolve(path)!!
|
||||
}
|
||||
|
||||
/**
|
||||
* Serve requests with HTTPS rather than otherwise.
|
||||
@ -426,7 +426,9 @@ class MockWebServer : Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
internal inner class SocketHandler(private val raw: Socket) {
|
||||
internal inner class SocketHandler(
|
||||
private val raw: Socket,
|
||||
) {
|
||||
private var sequenceNumber = 0
|
||||
|
||||
@Throws(Exception::class)
|
||||
@ -496,7 +498,8 @@ class MockWebServer : Closeable {
|
||||
if (protocol === Protocol.HTTP_2 || protocol === Protocol.H2_PRIOR_KNOWLEDGE) {
|
||||
val http2SocketHandler = Http2SocketHandler(socket, protocol)
|
||||
val connection =
|
||||
Http2Connection.Builder(false, taskRunner)
|
||||
Http2Connection
|
||||
.Builder(false, taskRunner)
|
||||
.socket(socket)
|
||||
.listener(http2SocketHandler)
|
||||
.build()
|
||||
@ -707,12 +710,13 @@ class MockWebServer : Closeable {
|
||||
var hasBody = false
|
||||
val policy = dispatcher.peek()
|
||||
val requestBodySink =
|
||||
requestBody.withThrottlingAndSocketPolicy(
|
||||
policy = policy,
|
||||
disconnectHalfway = policy.socketPolicy == DisconnectDuringRequestBody,
|
||||
expectedByteCount = contentLength,
|
||||
socket = socket,
|
||||
).buffer()
|
||||
requestBody
|
||||
.withThrottlingAndSocketPolicy(
|
||||
policy = policy,
|
||||
disconnectHalfway = policy.socketPolicy == DisconnectDuringRequestBody,
|
||||
expectedByteCount = contentLength,
|
||||
socket = socket,
|
||||
).buffer()
|
||||
requestBodySink.use {
|
||||
when {
|
||||
policy.socketPolicy is DoNotReadRequestBody -> {
|
||||
@ -772,7 +776,8 @@ class MockWebServer : Closeable {
|
||||
) {
|
||||
val key = request.headers["Sec-WebSocket-Key"]
|
||||
val webSocketResponse =
|
||||
response.newBuilder()
|
||||
response
|
||||
.newBuilder()
|
||||
.setHeader("Sec-WebSocket-Accept", WebSocketProtocol.acceptHeader(key!!))
|
||||
.build()
|
||||
writeHttpResponse(socket, sink, webSocketResponse)
|
||||
@ -781,12 +786,14 @@ class MockWebServer : Closeable {
|
||||
val scheme = if (request.handshake != null) "https" else "http"
|
||||
val authority = request.headers["Host"] // Has host and port.
|
||||
val fancyRequest =
|
||||
Request.Builder()
|
||||
Request
|
||||
.Builder()
|
||||
.url("$scheme://$authority/")
|
||||
.headers(request.headers)
|
||||
.build()
|
||||
val fancyResponse =
|
||||
Response.Builder()
|
||||
Response
|
||||
.Builder()
|
||||
.code(webSocketResponse.code)
|
||||
.message(webSocketResponse.message)
|
||||
.headers(webSocketResponse.headers)
|
||||
@ -842,12 +849,13 @@ class MockWebServer : Closeable {
|
||||
val body = response.body ?: return
|
||||
sleepNanos(response.bodyDelayNanos)
|
||||
val responseBodySink =
|
||||
sink.withThrottlingAndSocketPolicy(
|
||||
policy = response,
|
||||
disconnectHalfway = response.socketPolicy == DisconnectDuringResponseBody,
|
||||
expectedByteCount = body.contentLength,
|
||||
socket = socket,
|
||||
).buffer()
|
||||
sink
|
||||
.withThrottlingAndSocketPolicy(
|
||||
policy = response,
|
||||
disconnectHalfway = response.socketPolicy == DisconnectDuringResponseBody,
|
||||
expectedByteCount = body.contentLength,
|
||||
socket = socket,
|
||||
).buffer()
|
||||
body.writeTo(responseBodySink)
|
||||
responseBodySink.emit()
|
||||
|
||||
@ -1044,12 +1052,13 @@ class MockWebServer : Closeable {
|
||||
try {
|
||||
val contentLengthString = headers["content-length"]
|
||||
val requestBodySink =
|
||||
body.withThrottlingAndSocketPolicy(
|
||||
policy = peek,
|
||||
disconnectHalfway = peek.socketPolicy == DisconnectDuringRequestBody,
|
||||
expectedByteCount = contentLengthString?.toLong() ?: Long.MAX_VALUE,
|
||||
socket = socket,
|
||||
).buffer()
|
||||
body
|
||||
.withThrottlingAndSocketPolicy(
|
||||
policy = peek,
|
||||
disconnectHalfway = peek.socketPolicy == DisconnectDuringRequestBody,
|
||||
expectedByteCount = contentLengthString?.toLong() ?: Long.MAX_VALUE,
|
||||
socket = socket,
|
||||
).buffer()
|
||||
requestBodySink.use {
|
||||
it.writeAll(stream.getSource())
|
||||
}
|
||||
@ -1116,12 +1125,14 @@ class MockWebServer : Closeable {
|
||||
if (body != null) {
|
||||
sleepNanos(bodyDelayNanos)
|
||||
val responseBodySink =
|
||||
stream.getSink().withThrottlingAndSocketPolicy(
|
||||
policy = response,
|
||||
disconnectHalfway = response.socketPolicy == DisconnectDuringResponseBody,
|
||||
expectedByteCount = body.contentLength,
|
||||
socket = socket,
|
||||
).buffer()
|
||||
stream
|
||||
.getSink()
|
||||
.withThrottlingAndSocketPolicy(
|
||||
policy = response,
|
||||
disconnectHalfway = response.socketPolicy == DisconnectDuringResponseBody,
|
||||
expectedByteCount = body.contentLength,
|
||||
socket = socket,
|
||||
).buffer()
|
||||
responseBodySink.use {
|
||||
body.writeTo(responseBodySink)
|
||||
}
|
||||
|
@ -53,9 +53,7 @@ open class QueueDispatcher : Dispatcher() {
|
||||
return result
|
||||
}
|
||||
|
||||
override fun peek(): MockResponse {
|
||||
return responseQueue.peek() ?: failFastResponse ?: super.peek()
|
||||
}
|
||||
override fun peek(): MockResponse = responseQueue.peek() ?: failFastResponse ?: super.peek()
|
||||
|
||||
open fun enqueueResponse(response: MockResponse) {
|
||||
responseQueue.add(response)
|
||||
|
@ -90,8 +90,8 @@ class CustomDispatcherTest {
|
||||
private fun buildRequestThread(
|
||||
path: String,
|
||||
responseCode: AtomicInteger,
|
||||
): Thread {
|
||||
return Thread {
|
||||
): Thread =
|
||||
Thread {
|
||||
val url = mockWebServer.url(path).toUrl()
|
||||
val conn: HttpURLConnection
|
||||
try {
|
||||
@ -100,5 +100,4 @@ class CustomDispatcherTest {
|
||||
} catch (ignored: IOException) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,17 +61,22 @@ class MockResponseSniTest {
|
||||
}
|
||||
|
||||
val client =
|
||||
clientTestRule.newClientBuilder()
|
||||
clientTestRule
|
||||
.newClientBuilder()
|
||||
.sslSocketFactory(
|
||||
handshakeCertificates.sslSocketFactory(),
|
||||
handshakeCertificates.trustManager,
|
||||
)
|
||||
.dns(dns)
|
||||
).dns(dns)
|
||||
.build()
|
||||
|
||||
server.enqueue(MockResponse())
|
||||
|
||||
val url = server.url("/").newBuilder().host("localhost.localdomain").build()
|
||||
val url =
|
||||
server
|
||||
.url("/")
|
||||
.newBuilder()
|
||||
.host("localhost.localdomain")
|
||||
.build()
|
||||
val call = client.newCall(Request(url = url))
|
||||
val response = call.execute()
|
||||
assertThat(response.isSuccessful).isTrue()
|
||||
@ -90,12 +95,14 @@ class MockResponseSniTest {
|
||||
@Test
|
||||
fun domainFronting() {
|
||||
val heldCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.commonName("server name")
|
||||
.addSubjectAlternativeName("url-host.com")
|
||||
.build()
|
||||
val handshakeCertificates =
|
||||
HandshakeCertificates.Builder()
|
||||
HandshakeCertificates
|
||||
.Builder()
|
||||
.heldCertificate(heldCertificate)
|
||||
.addTrustedCertificate(heldCertificate.certificate)
|
||||
.build()
|
||||
@ -107,12 +114,12 @@ class MockResponseSniTest {
|
||||
}
|
||||
|
||||
val client =
|
||||
clientTestRule.newClientBuilder()
|
||||
clientTestRule
|
||||
.newClientBuilder()
|
||||
.sslSocketFactory(
|
||||
handshakeCertificates.sslSocketFactory(),
|
||||
handshakeCertificates.trustManager,
|
||||
)
|
||||
.dns(dns)
|
||||
).dns(dns)
|
||||
.build()
|
||||
|
||||
server.enqueue(MockResponse())
|
||||
@ -168,24 +175,26 @@ class MockResponseSniTest {
|
||||
*/
|
||||
private fun requestToHostnameViaProxy(hostnameOrIpAddress: String): RecordedRequest {
|
||||
val heldCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.commonName("server name")
|
||||
.addSubjectAlternativeName(hostnameOrIpAddress)
|
||||
.build()
|
||||
val handshakeCertificates =
|
||||
HandshakeCertificates.Builder()
|
||||
HandshakeCertificates
|
||||
.Builder()
|
||||
.heldCertificate(heldCertificate)
|
||||
.addTrustedCertificate(heldCertificate.certificate)
|
||||
.build()
|
||||
server.useHttps(handshakeCertificates.sslSocketFactory())
|
||||
|
||||
val client =
|
||||
clientTestRule.newClientBuilder()
|
||||
clientTestRule
|
||||
.newClientBuilder()
|
||||
.sslSocketFactory(
|
||||
handshakeCertificates.sslSocketFactory(),
|
||||
handshakeCertificates.trustManager,
|
||||
)
|
||||
.proxy(server.toProxyAddress())
|
||||
).proxy(server.toProxyAddress())
|
||||
.build()
|
||||
|
||||
server.enqueue(MockResponse(inTunnel = true))
|
||||
@ -195,7 +204,9 @@ class MockResponseSniTest {
|
||||
client.newCall(
|
||||
Request(
|
||||
url =
|
||||
server.url("/").newBuilder()
|
||||
server
|
||||
.url("/")
|
||||
.newBuilder()
|
||||
.host(hostnameOrIpAddress)
|
||||
.build(),
|
||||
),
|
||||
|
@ -130,7 +130,8 @@ class MockWebServerTest {
|
||||
@Test
|
||||
fun mockResponseAddHeader() {
|
||||
val builder =
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.clearHeaders()
|
||||
.addHeader("Cookie: s=square")
|
||||
.addHeader("Cookie", "a=android")
|
||||
@ -140,7 +141,8 @@ class MockWebServerTest {
|
||||
@Test
|
||||
fun mockResponseSetHeader() {
|
||||
val builder =
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.clearHeaders()
|
||||
.addHeader("Cookie: s=square")
|
||||
.addHeader("Cookie: a=android")
|
||||
@ -152,7 +154,8 @@ class MockWebServerTest {
|
||||
@Test
|
||||
fun mockResponseSetHeaders() {
|
||||
val builder =
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.clearHeaders()
|
||||
.addHeader("Cookie: s=square")
|
||||
.addHeader("Cookies: delicious")
|
||||
@ -180,14 +183,16 @@ class MockWebServerTest {
|
||||
@Test
|
||||
fun redirect() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.code(HttpURLConnection.HTTP_MOVED_TEMP)
|
||||
.addHeader("Location: " + server.url("/new-path"))
|
||||
.body("This page has moved!")
|
||||
.build(),
|
||||
)
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("This is the new location!")
|
||||
.build(),
|
||||
)
|
||||
@ -212,7 +217,8 @@ class MockWebServerTest {
|
||||
} catch (ignored: InterruptedException) {
|
||||
}
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("enqueued in the background")
|
||||
.build(),
|
||||
)
|
||||
@ -225,7 +231,8 @@ class MockWebServerTest {
|
||||
@Test
|
||||
fun nonHexadecimalChunkSize() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("G\r\nxxxxxxxxxxxxxxxx\r\n0\r\n\r\n")
|
||||
.clearHeaders()
|
||||
.addHeader("Transfer-encoding: chunked")
|
||||
@ -243,14 +250,16 @@ class MockWebServerTest {
|
||||
@Test
|
||||
fun responseTimeout() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("ABC")
|
||||
.clearHeaders()
|
||||
.addHeader("Content-Length: 4")
|
||||
.build(),
|
||||
)
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("DEF")
|
||||
.build(),
|
||||
)
|
||||
@ -280,19 +289,28 @@ class MockWebServerTest {
|
||||
@Test
|
||||
fun disconnectAtStart() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.socketPolicy(DisconnectAtStart)
|
||||
.build(),
|
||||
)
|
||||
server.enqueue(MockResponse()) // The jdk's HttpUrlConnection is a bastard.
|
||||
server.enqueue(MockResponse())
|
||||
try {
|
||||
server.url("/a").toUrl().openConnection().getInputStream()
|
||||
server
|
||||
.url("/a")
|
||||
.toUrl()
|
||||
.openConnection()
|
||||
.getInputStream()
|
||||
fail<Unit>()
|
||||
} catch (expected: IOException) {
|
||||
// Expected.
|
||||
}
|
||||
server.url("/b").toUrl().openConnection().getInputStream() // Should succeed.
|
||||
server
|
||||
.url("/b")
|
||||
.toUrl()
|
||||
.openConnection()
|
||||
.getInputStream() // Should succeed.
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -300,7 +318,12 @@ class MockWebServerTest {
|
||||
server.enqueue(MockResponse(body = "A"))
|
||||
(server.dispatcher as QueueDispatcher).clear()
|
||||
server.enqueue(MockResponse(body = "B"))
|
||||
val inputStream = server.url("/a").toUrl().openConnection().getInputStream()
|
||||
val inputStream =
|
||||
server
|
||||
.url("/a")
|
||||
.toUrl()
|
||||
.openConnection()
|
||||
.getInputStream()
|
||||
assertThat(inputStream!!.read()).isEqualTo('B'.code)
|
||||
}
|
||||
|
||||
@ -312,7 +335,8 @@ class MockWebServerTest {
|
||||
fun throttleRequest() {
|
||||
assumeNotWindows()
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.throttleBody(3, 500, TimeUnit.MILLISECONDS)
|
||||
.build(),
|
||||
)
|
||||
@ -335,7 +359,8 @@ class MockWebServerTest {
|
||||
fun throttleResponse() {
|
||||
assumeNotWindows()
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("ABCDEF")
|
||||
.throttleBody(3, 500, TimeUnit.MILLISECONDS)
|
||||
.build(),
|
||||
@ -360,7 +385,8 @@ class MockWebServerTest {
|
||||
fun delayResponse() {
|
||||
assumeNotWindows()
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("ABCDEF")
|
||||
.bodyDelay(1, TimeUnit.SECONDS)
|
||||
.build(),
|
||||
@ -378,7 +404,8 @@ class MockWebServerTest {
|
||||
@Test
|
||||
fun disconnectRequestHalfway() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.socketPolicy(DisconnectDuringRequestBody)
|
||||
.build(),
|
||||
)
|
||||
@ -413,7 +440,8 @@ class MockWebServerTest {
|
||||
@Test
|
||||
fun disconnectResponseHalfway() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("ab")
|
||||
.socketPolicy(DisconnectDuringResponseBody)
|
||||
.build(),
|
||||
@ -497,7 +525,8 @@ class MockWebServerTest {
|
||||
@Test
|
||||
fun requestUrlReconstructed() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("hello world")
|
||||
.build(),
|
||||
)
|
||||
@ -522,7 +551,8 @@ class MockWebServerTest {
|
||||
@Test
|
||||
fun shutdownServerAfterRequest() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.socketPolicy(ShutdownServerAfterResponse)
|
||||
.build(),
|
||||
)
|
||||
@ -540,7 +570,8 @@ class MockWebServerTest {
|
||||
@Test
|
||||
fun http100Continue() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("response")
|
||||
.build(),
|
||||
)
|
||||
@ -559,7 +590,8 @@ class MockWebServerTest {
|
||||
@Test
|
||||
fun multiple1xxResponses() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.add100Continue()
|
||||
.add100Continue()
|
||||
.body("response")
|
||||
@ -615,7 +647,8 @@ class MockWebServerTest {
|
||||
val handshakeCertificates = platform.localhostHandshakeCertificates()
|
||||
server.useHttps(handshakeCertificates.sslSocketFactory())
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("abc")
|
||||
.build(),
|
||||
)
|
||||
@ -643,36 +676,43 @@ class MockWebServerTest {
|
||||
platform.assumeNotConscrypt()
|
||||
|
||||
val clientCa =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(0)
|
||||
.build()
|
||||
val serverCa =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(0)
|
||||
.build()
|
||||
val serverCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.signedBy(serverCa)
|
||||
.addSubjectAlternativeName(server.hostName)
|
||||
.build()
|
||||
val serverHandshakeCertificates =
|
||||
HandshakeCertificates.Builder()
|
||||
HandshakeCertificates
|
||||
.Builder()
|
||||
.addTrustedCertificate(clientCa.certificate)
|
||||
.heldCertificate(serverCertificate)
|
||||
.build()
|
||||
server.useHttps(serverHandshakeCertificates.sslSocketFactory())
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("abc")
|
||||
.build(),
|
||||
)
|
||||
server.requestClientAuth()
|
||||
val clientCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.signedBy(clientCa)
|
||||
.build()
|
||||
val clientHandshakeCertificates =
|
||||
HandshakeCertificates.Builder()
|
||||
HandshakeCertificates
|
||||
.Builder()
|
||||
.addTrustedCertificate(serverCa.certificate)
|
||||
.heldCertificate(clientCertificate)
|
||||
.build()
|
||||
@ -697,12 +737,14 @@ class MockWebServerTest {
|
||||
@Test
|
||||
fun proxiedRequestGetsCorrectRequestUrl() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("Result")
|
||||
.build(),
|
||||
)
|
||||
val proxiedClient =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.proxy(server.toProxyAddress())
|
||||
.readTimeout(Duration.ofMillis(100))
|
||||
.build()
|
||||
|
@ -55,7 +55,8 @@ class Http2Server(
|
||||
throw ProtocolException("Protocol $protocol unsupported")
|
||||
}
|
||||
val connection =
|
||||
Http2Connection.Builder(false, TaskRunner.INSTANCE)
|
||||
Http2Connection
|
||||
.Builder(false, TaskRunner.INSTANCE)
|
||||
.socket(sslSocket)
|
||||
.listener(this)
|
||||
.build()
|
||||
@ -179,8 +180,8 @@ class Http2Server(
|
||||
}
|
||||
}
|
||||
|
||||
private fun contentType(file: File): String {
|
||||
return when {
|
||||
private fun contentType(file: File): String =
|
||||
when {
|
||||
file.name.endsWith(".css") -> "text/css"
|
||||
file.name.endsWith(".gif") -> "image/gif"
|
||||
file.name.endsWith(".html") -> "text/html"
|
||||
@ -190,7 +191,6 @@ class Http2Server(
|
||||
file.name.endsWith(".png") -> "image/png"
|
||||
else -> "text/plain"
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val logger: Logger = Logger.getLogger(Http2Server::class.java.name)
|
||||
|
@ -64,16 +64,20 @@ class Main : CliktCommand(name = NAME) {
|
||||
"--connect-timeout",
|
||||
).help(
|
||||
"Maximum time allowed for connection (seconds)",
|
||||
).int().default(DEFAULT_TIMEOUT)
|
||||
).int()
|
||||
.default(DEFAULT_TIMEOUT)
|
||||
|
||||
val readTimeout: Int by option("--read-timeout").help("Maximum time allowed for reading data (seconds)").int()
|
||||
val readTimeout: Int by option("--read-timeout")
|
||||
.help("Maximum time allowed for reading data (seconds)")
|
||||
.int()
|
||||
.default(DEFAULT_TIMEOUT)
|
||||
|
||||
val callTimeout: Int by option(
|
||||
"--call-timeout",
|
||||
).help(
|
||||
"Maximum time allowed for the entire call (seconds)",
|
||||
).int().default(DEFAULT_TIMEOUT)
|
||||
).int()
|
||||
.default(DEFAULT_TIMEOUT)
|
||||
|
||||
val followRedirects: Boolean by option("-L", "--location").help("Follow redirects").flag()
|
||||
|
||||
@ -163,9 +167,12 @@ class Main : CliktCommand(name = NAME) {
|
||||
}
|
||||
|
||||
private fun createInsecureSslSocketFactory(trustManager: TrustManager): SSLSocketFactory =
|
||||
Platform.get().newSSLContext().apply {
|
||||
init(null, arrayOf(trustManager), null)
|
||||
}.socketFactory
|
||||
Platform
|
||||
.get()
|
||||
.newSSLContext()
|
||||
.apply {
|
||||
init(null, arrayOf(trustManager), null)
|
||||
}.socketFactory
|
||||
|
||||
private fun createInsecureHostnameVerifier(): HostnameVerifier = HostnameVerifier { _, _ -> true }
|
||||
}
|
||||
|
@ -68,9 +68,7 @@ private fun Main.mediaType(): MediaType? {
|
||||
return mimeType.toMediaTypeOrNull()
|
||||
}
|
||||
|
||||
private fun isSpecialHeader(s: String): Boolean {
|
||||
return s.equals("Content-Type", ignoreCase = true)
|
||||
}
|
||||
private fun isSpecialHeader(s: String): Boolean = s.equals("Content-Type", ignoreCase = true)
|
||||
|
||||
fun Main.commonRun() {
|
||||
client = createClient()
|
||||
|
@ -19,7 +19,5 @@ import java.util.logging.LogRecord
|
||||
import java.util.logging.SimpleFormatter
|
||||
|
||||
object MessageFormatter : SimpleFormatter() {
|
||||
override fun format(record: LogRecord): String {
|
||||
return String.format("%s%n", record.message)
|
||||
}
|
||||
override fun format(record: LogRecord): String = String.format("%s%n", record.message)
|
||||
}
|
||||
|
@ -123,20 +123,18 @@ class MainTest {
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromArgs(vararg args: String): Main {
|
||||
return Main().apply {
|
||||
fun fromArgs(vararg args: String): Main =
|
||||
Main().apply {
|
||||
parse(args.toList())
|
||||
}
|
||||
}
|
||||
|
||||
private fun bodyAsString(body: RequestBody?): String {
|
||||
return try {
|
||||
private fun bodyAsString(body: RequestBody?): String =
|
||||
try {
|
||||
val buffer = Buffer()
|
||||
body!!.writeTo(buffer)
|
||||
buffer.readString(body.contentType()!!.charset()!!)
|
||||
} catch (e: IOException) {
|
||||
throw RuntimeException(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,10 +26,12 @@ import okhttp3.brotli.internal.uncompress
|
||||
* responses. n.b. this replaces the transparent gzip compression in BridgeInterceptor.
|
||||
*/
|
||||
object BrotliInterceptor : Interceptor {
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
return if (chain.request().header("Accept-Encoding") == null) {
|
||||
override fun intercept(chain: Interceptor.Chain): Response =
|
||||
if (chain.request().header("Accept-Encoding") == null) {
|
||||
val request =
|
||||
chain.request().newBuilder()
|
||||
chain
|
||||
.request()
|
||||
.newBuilder()
|
||||
.header("Accept-Encoding", "br,gzip")
|
||||
.build()
|
||||
|
||||
@ -39,5 +41,4 @@ object BrotliInterceptor : Interceptor {
|
||||
} else {
|
||||
chain.proceed(chain.request())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,8 @@ fun uncompress(response: Response): Response {
|
||||
else -> return response
|
||||
}
|
||||
|
||||
return response.newBuilder()
|
||||
return response
|
||||
.newBuilder()
|
||||
.removeHeader("Content-Encoding")
|
||||
.removeHeader("Content-Length")
|
||||
.body(decompressedSource.asResponseBody(body.contentType(), -1))
|
||||
|
@ -121,8 +121,9 @@ class BrotliInterceptorTest {
|
||||
url: String,
|
||||
bodyHex: ByteString,
|
||||
fn: Response.Builder.() -> Unit = {},
|
||||
): Response {
|
||||
return Response.Builder()
|
||||
): Response =
|
||||
Response
|
||||
.Builder()
|
||||
.body(bodyHex.toResponseBody("text/plain".toMediaType()))
|
||||
.code(200)
|
||||
.message("OK")
|
||||
@ -130,5 +131,4 @@ class BrotliInterceptorTest {
|
||||
.protocol(Protocol.HTTP_2)
|
||||
.apply(fn)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,8 @@ import okhttp3.Request
|
||||
|
||||
fun main() {
|
||||
val client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.addInterceptor(BrotliInterceptor)
|
||||
.build()
|
||||
|
||||
|
@ -88,7 +88,8 @@ class ExecuteAsyncTest {
|
||||
fun timeoutCall() {
|
||||
runTest {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.bodyDelay(5, TimeUnit.SECONDS)
|
||||
.body("abc")
|
||||
.build(),
|
||||
@ -117,7 +118,8 @@ class ExecuteAsyncTest {
|
||||
fun cancelledCall() {
|
||||
runTest {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.bodyDelay(5, TimeUnit.SECONDS)
|
||||
.body("abc")
|
||||
.build(),
|
||||
@ -187,7 +189,8 @@ class ExecuteAsyncTest {
|
||||
/** A call that keeps track of whether its response body is closed. */
|
||||
private class ClosableCall : FailingCall() {
|
||||
private val response =
|
||||
Response.Builder()
|
||||
Response
|
||||
.Builder()
|
||||
.request(Request("https://example.com/".toHttpUrl()))
|
||||
.protocol(Protocol.HTTP_1_1)
|
||||
.message("OK")
|
||||
@ -205,8 +208,7 @@ class ExecuteAsyncTest {
|
||||
}
|
||||
}.buffer()
|
||||
},
|
||||
)
|
||||
.build()
|
||||
).build()
|
||||
|
||||
var responseClosed = false
|
||||
var canceled = false
|
||||
|
@ -202,23 +202,27 @@ class DnsOverHttps internal constructor(
|
||||
hostname: String,
|
||||
type: Int,
|
||||
): Request =
|
||||
Request.Builder().header("Accept", DNS_MESSAGE.toString()).apply {
|
||||
val query = DnsRecordCodec.encodeQuery(hostname, type)
|
||||
Request
|
||||
.Builder()
|
||||
.header("Accept", DNS_MESSAGE.toString())
|
||||
.apply {
|
||||
val query = DnsRecordCodec.encodeQuery(hostname, type)
|
||||
|
||||
if (post) {
|
||||
url(url)
|
||||
.cacheUrlOverride(
|
||||
url.newBuilder()
|
||||
.addQueryParameter("hostname", hostname).build(),
|
||||
)
|
||||
.post(query.toRequestBody(DNS_MESSAGE))
|
||||
} else {
|
||||
val encoded = query.base64Url().replace("=", "")
|
||||
val requestUrl = url.newBuilder().addQueryParameter("dns", encoded).build()
|
||||
if (post) {
|
||||
url(url)
|
||||
.cacheUrlOverride(
|
||||
url
|
||||
.newBuilder()
|
||||
.addQueryParameter("hostname", hostname)
|
||||
.build(),
|
||||
).post(query.toRequestBody(DNS_MESSAGE))
|
||||
} else {
|
||||
val encoded = query.base64Url().replace("=", "")
|
||||
val requestUrl = url.newBuilder().addQueryParameter("dns", encoded).build()
|
||||
|
||||
url(requestUrl)
|
||||
}
|
||||
}.build()
|
||||
url(requestUrl)
|
||||
}
|
||||
}.build()
|
||||
|
||||
class Builder {
|
||||
internal var client: OkHttpClient? = null
|
||||
@ -299,8 +303,6 @@ class DnsOverHttps internal constructor(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun isPrivateHost(host: String): Boolean {
|
||||
return PublicSuffixDatabase.get().getEffectiveTldPlusOne(host) == null
|
||||
}
|
||||
internal fun isPrivateHost(host: String): Boolean = PublicSuffixDatabase.get().getEffectiveTldPlusOne(host) == null
|
||||
}
|
||||
}
|
||||
|
@ -37,28 +37,29 @@ internal object DnsRecordCodec {
|
||||
host: String,
|
||||
type: Int,
|
||||
): ByteString =
|
||||
Buffer().apply {
|
||||
writeShort(0) // query id
|
||||
writeShort(256) // flags with recursion
|
||||
writeShort(1) // question count
|
||||
writeShort(0) // answerCount
|
||||
writeShort(0) // authorityResourceCount
|
||||
writeShort(0) // additional
|
||||
Buffer()
|
||||
.apply {
|
||||
writeShort(0) // query id
|
||||
writeShort(256) // flags with recursion
|
||||
writeShort(1) // question count
|
||||
writeShort(0) // answerCount
|
||||
writeShort(0) // authorityResourceCount
|
||||
writeShort(0) // additional
|
||||
|
||||
val nameBuf = Buffer()
|
||||
val labels = host.split('.').dropLastWhile { it.isEmpty() }
|
||||
for (label in labels) {
|
||||
val utf8ByteCount = label.utf8Size()
|
||||
require(utf8ByteCount == label.length.toLong()) { "non-ascii hostname: $host" }
|
||||
nameBuf.writeByte(utf8ByteCount.toInt())
|
||||
nameBuf.writeUtf8(label)
|
||||
}
|
||||
nameBuf.writeByte(0) // end
|
||||
val nameBuf = Buffer()
|
||||
val labels = host.split('.').dropLastWhile { it.isEmpty() }
|
||||
for (label in labels) {
|
||||
val utf8ByteCount = label.utf8Size()
|
||||
require(utf8ByteCount == label.length.toLong()) { "non-ascii hostname: $host" }
|
||||
nameBuf.writeByte(utf8ByteCount.toInt())
|
||||
nameBuf.writeUtf8(label)
|
||||
}
|
||||
nameBuf.writeByte(0) // end
|
||||
|
||||
nameBuf.copyTo(this, 0, nameBuf.size)
|
||||
writeShort(type)
|
||||
writeShort(1) // CLASS_IN
|
||||
}.readByteString()
|
||||
nameBuf.copyTo(this, 0, nameBuf.size)
|
||||
writeShort(type)
|
||||
writeShort(1) // CLASS_IN
|
||||
}.readByteString()
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun decodeAnswers(
|
||||
|
@ -59,7 +59,8 @@ class DnsOverHttpsTest {
|
||||
private val cacheFs = FakeFileSystem()
|
||||
private val eventListener = RecordingEventListener()
|
||||
private val bootstrapClient =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.protocols(listOf(Protocol.HTTP_2, Protocol.HTTP_1_1))
|
||||
.eventListener(eventListener)
|
||||
.build()
|
||||
@ -186,8 +187,7 @@ class DnsOverHttpsTest {
|
||||
"0000818000010003000000000567726170680866616365626f6f6b03636f6d0000010001c00c000500010" +
|
||||
"0000a6d000603617069c012c0300005000100000cde000c04737461720463313072c012c04200010001000" +
|
||||
"0003b00049df00112",
|
||||
)
|
||||
.newBuilder()
|
||||
).newBuilder()
|
||||
.setHeader("cache-control", "private, max-age=298")
|
||||
.build(),
|
||||
)
|
||||
@ -229,8 +229,7 @@ class DnsOverHttpsTest {
|
||||
"0000818000010003000000000567726170680866616365626f6f6b03636f6d0000010001c00c000500010" +
|
||||
"0000a6d000603617069c012c0300005000100000cde000c04737461720463313072c012c04200010001000" +
|
||||
"0003b00049df00112",
|
||||
)
|
||||
.newBuilder()
|
||||
).newBuilder()
|
||||
.setHeader("cache-control", "private, max-age=298")
|
||||
.build(),
|
||||
)
|
||||
@ -271,8 +270,7 @@ class DnsOverHttpsTest {
|
||||
"0000818000010003000000000567726170680866616365626f6f6b03636f6d0000010001c00c000500010" +
|
||||
"0000a6d000603617069c012c0300005000100000cde000c04737461720463313072c012c04200010001000" +
|
||||
"0003b00049df00112",
|
||||
)
|
||||
.newBuilder()
|
||||
).newBuilder()
|
||||
.setHeader("cache-control", "max-age=1")
|
||||
.build(),
|
||||
)
|
||||
@ -292,8 +290,7 @@ class DnsOverHttpsTest {
|
||||
"0000818000010003000000000567726170680866616365626f6f6b03636f6d0000010001c00c000500010" +
|
||||
"0000a6d000603617069c012c0300005000100000cde000c04737461720463313072c012c04200010001000" +
|
||||
"0003b00049df00112",
|
||||
)
|
||||
.newBuilder()
|
||||
).newBuilder()
|
||||
.setHeader("cache-control", "max-age=1")
|
||||
.build(),
|
||||
)
|
||||
@ -307,19 +304,18 @@ class DnsOverHttpsTest {
|
||||
assertThat(cacheEvents()).containsExactly("CacheMiss")
|
||||
}
|
||||
|
||||
private fun cacheEvents(): List<String> {
|
||||
return eventListener.recordedEventTypes().filter { it.contains("Cache") }.also {
|
||||
private fun cacheEvents(): List<String> =
|
||||
eventListener.recordedEventTypes().filter { it.contains("Cache") }.also {
|
||||
eventListener.clearAllEvents()
|
||||
}
|
||||
}
|
||||
|
||||
private fun dnsResponse(s: String): MockResponse {
|
||||
return MockResponse.Builder()
|
||||
private fun dnsResponse(s: String): MockResponse =
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body(Buffer().write(s.decodeHex()))
|
||||
.addHeader("content-type", "application/dns-message")
|
||||
.addHeader("content-length", s.length / 2)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun buildLocalhost(
|
||||
bootstrapClient: OkHttpClient,
|
||||
@ -327,7 +323,9 @@ class DnsOverHttpsTest {
|
||||
post: Boolean = false,
|
||||
): DnsOverHttps {
|
||||
val url = server.url("/lookup?ct")
|
||||
return DnsOverHttps.Builder().client(bootstrapClient)
|
||||
return DnsOverHttps
|
||||
.Builder()
|
||||
.client(bootstrapClient)
|
||||
.includeIPv6(includeIPv6)
|
||||
.resolvePrivateAddresses(true)
|
||||
.url(url)
|
||||
|
@ -39,9 +39,7 @@ class DnsRecordCodecTest {
|
||||
private fun encodeQuery(
|
||||
host: String,
|
||||
type: Int,
|
||||
): String {
|
||||
return DnsRecordCodec.encodeQuery(host, type).base64Url().replace("=", "")
|
||||
}
|
||||
): String = DnsRecordCodec.encodeQuery(host, type).base64Url().replace("=", "")
|
||||
|
||||
@Test
|
||||
fun testGoogleDotComEncodingWithIPv6() {
|
||||
|
@ -26,73 +26,73 @@ import okhttp3.OkHttpClient
|
||||
* https://github.com/curl/curl/wiki/DNS-over-HTTPS
|
||||
*/
|
||||
object DohProviders {
|
||||
private fun buildGoogle(bootstrapClient: OkHttpClient): DnsOverHttps {
|
||||
return DnsOverHttps.Builder()
|
||||
private fun buildGoogle(bootstrapClient: OkHttpClient): DnsOverHttps =
|
||||
DnsOverHttps
|
||||
.Builder()
|
||||
.client(bootstrapClient)
|
||||
.url("https://dns.google/dns-query".toHttpUrl())
|
||||
.bootstrapDnsHosts(getByIp("8.8.4.4"), getByIp("8.8.8.8"))
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun buildGooglePost(bootstrapClient: OkHttpClient): DnsOverHttps {
|
||||
return DnsOverHttps.Builder()
|
||||
private fun buildGooglePost(bootstrapClient: OkHttpClient): DnsOverHttps =
|
||||
DnsOverHttps
|
||||
.Builder()
|
||||
.client(bootstrapClient)
|
||||
.url("https://dns.google/dns-query".toHttpUrl())
|
||||
.bootstrapDnsHosts(getByIp("8.8.4.4"), getByIp("8.8.8.8"))
|
||||
.post(true)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun buildCloudflareIp(bootstrapClient: OkHttpClient): DnsOverHttps {
|
||||
return DnsOverHttps.Builder()
|
||||
private fun buildCloudflareIp(bootstrapClient: OkHttpClient): DnsOverHttps =
|
||||
DnsOverHttps
|
||||
.Builder()
|
||||
.client(bootstrapClient)
|
||||
.url("https://1.1.1.1/dns-query".toHttpUrl())
|
||||
.includeIPv6(false)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun buildCloudflare(bootstrapClient: OkHttpClient): DnsOverHttps {
|
||||
return DnsOverHttps.Builder()
|
||||
private fun buildCloudflare(bootstrapClient: OkHttpClient): DnsOverHttps =
|
||||
DnsOverHttps
|
||||
.Builder()
|
||||
.client(bootstrapClient)
|
||||
.url("https://1.1.1.1/dns-query".toHttpUrl())
|
||||
.bootstrapDnsHosts(getByIp("1.1.1.1"), getByIp("1.0.0.1"))
|
||||
.includeIPv6(false)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun buildCloudflarePost(bootstrapClient: OkHttpClient): DnsOverHttps {
|
||||
return DnsOverHttps.Builder()
|
||||
private fun buildCloudflarePost(bootstrapClient: OkHttpClient): DnsOverHttps =
|
||||
DnsOverHttps
|
||||
.Builder()
|
||||
.client(bootstrapClient)
|
||||
.url("https://cloudflare-dns.com/dns-query".toHttpUrl())
|
||||
.bootstrapDnsHosts(getByIp("1.1.1.1"), getByIp("1.0.0.1"))
|
||||
.includeIPv6(false)
|
||||
.post(true)
|
||||
.build()
|
||||
}
|
||||
|
||||
fun buildCleanBrowsing(bootstrapClient: OkHttpClient): DnsOverHttps {
|
||||
return DnsOverHttps.Builder()
|
||||
fun buildCleanBrowsing(bootstrapClient: OkHttpClient): DnsOverHttps =
|
||||
DnsOverHttps
|
||||
.Builder()
|
||||
.client(bootstrapClient)
|
||||
.url("https://doh.cleanbrowsing.org/doh/family-filter/".toHttpUrl())
|
||||
.includeIPv6(false)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun buildChantra(bootstrapClient: OkHttpClient): DnsOverHttps {
|
||||
return DnsOverHttps.Builder()
|
||||
private fun buildChantra(bootstrapClient: OkHttpClient): DnsOverHttps =
|
||||
DnsOverHttps
|
||||
.Builder()
|
||||
.client(bootstrapClient)
|
||||
.url("https://dns.dnsoverhttps.net/dns-query".toHttpUrl())
|
||||
.includeIPv6(false)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun buildCryptoSx(bootstrapClient: OkHttpClient): DnsOverHttps {
|
||||
return DnsOverHttps.Builder()
|
||||
private fun buildCryptoSx(bootstrapClient: OkHttpClient): DnsOverHttps =
|
||||
DnsOverHttps
|
||||
.Builder()
|
||||
.client(bootstrapClient)
|
||||
.url("https://doh.crypto.sx/dns-query".toHttpUrl())
|
||||
.includeIPv6(false)
|
||||
.build()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun providers(
|
||||
@ -100,8 +100,8 @@ object DohProviders {
|
||||
http2Only: Boolean,
|
||||
workingOnly: Boolean,
|
||||
getOnly: Boolean,
|
||||
): List<DnsOverHttps> {
|
||||
return buildList {
|
||||
): List<DnsOverHttps> =
|
||||
buildList {
|
||||
add(buildGoogle(client))
|
||||
if (!getOnly) {
|
||||
add(buildGooglePost(client))
|
||||
@ -117,14 +117,12 @@ object DohProviders {
|
||||
}
|
||||
add(buildChantra(client))
|
||||
}
|
||||
}
|
||||
|
||||
private fun getByIp(host: String): InetAddress {
|
||||
return try {
|
||||
private fun getByIp(host: String): InetAddress =
|
||||
try {
|
||||
InetAddress.getByName(host)
|
||||
} catch (e: UnknownHostException) {
|
||||
// unlikely
|
||||
throw RuntimeException(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +74,8 @@ fun main() {
|
||||
val url = "https://dns.cloudflare.com/.not-so-well-known/run-dmc-query".toHttpUrl()
|
||||
val badProviders =
|
||||
listOf(
|
||||
DnsOverHttps.Builder()
|
||||
DnsOverHttps
|
||||
.Builder()
|
||||
.client(bootstrapClient)
|
||||
.url(url)
|
||||
.post(true)
|
||||
@ -84,7 +85,8 @@ fun main() {
|
||||
println("cached first run\n****************\n")
|
||||
names = listOf("google.com", "graph.facebook.com")
|
||||
bootstrapClient =
|
||||
bootstrapClient.newBuilder()
|
||||
bootstrapClient
|
||||
.newBuilder()
|
||||
.cache(dnsCache)
|
||||
.build()
|
||||
dnsProviders =
|
||||
|
@ -36,23 +36,21 @@ import okio.source
|
||||
object HpackJsonUtil {
|
||||
@Suppress("unused")
|
||||
private val MOSHI =
|
||||
Moshi.Builder()
|
||||
Moshi
|
||||
.Builder()
|
||||
.add(
|
||||
object : Any() {
|
||||
@ToJson fun byteStringToJson(byteString: ByteString) = byteString.hex()
|
||||
|
||||
@FromJson fun byteStringFromJson(json: String) = json.decodeHex()
|
||||
},
|
||||
)
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
).add(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
private val STORY_JSON_ADAPTER = MOSHI.adapter(Story::class.java)
|
||||
|
||||
private val fileSystem = FileSystem.SYSTEM
|
||||
|
||||
private fun readStory(source: BufferedSource): Story {
|
||||
return STORY_JSON_ADAPTER.fromJson(source)!!
|
||||
}
|
||||
private fun readStory(source: BufferedSource): Story = STORY_JSON_ADAPTER.fromJson(source)!!
|
||||
|
||||
private fun readStory(file: Path): Story {
|
||||
fileSystem.read(file) {
|
||||
|
@ -55,9 +55,11 @@ fun generateMappingTableFile(data: IdnaMappingTableData): FileSpec {
|
||||
val packageName = "okhttp3.internal.idn"
|
||||
val idnaMappingTable = ClassName(packageName, "IdnaMappingTable")
|
||||
|
||||
return FileSpec.builder(packageName, "IdnaMappingTableInstance")
|
||||
return FileSpec
|
||||
.builder(packageName, "IdnaMappingTableInstance")
|
||||
.addProperty(
|
||||
PropertySpec.builder("IDNA_MAPPING_TABLE", idnaMappingTable)
|
||||
PropertySpec
|
||||
.builder("IDNA_MAPPING_TABLE", idnaMappingTable)
|
||||
.addModifiers(KModifier.INTERNAL)
|
||||
.initializer(
|
||||
"""
|
||||
@ -71,18 +73,16 @@ fun generateMappingTableFile(data: IdnaMappingTableData): FileSpec {
|
||||
data.sections.escapeDataString(),
|
||||
data.ranges.escapeDataString(),
|
||||
data.mappings.escapeDataString(),
|
||||
)
|
||||
.build(),
|
||||
)
|
||||
.build()
|
||||
).build(),
|
||||
).build()
|
||||
}
|
||||
|
||||
/**
|
||||
* KotlinPoet doesn't really know what to do with a string containing NUL, BEL, DEL, etc. We also
|
||||
* don't want to perform `trimMargin()` at runtime.
|
||||
*/
|
||||
fun String.escapeDataString(): String {
|
||||
return buildString {
|
||||
fun String.escapeDataString(): String =
|
||||
buildString {
|
||||
for (codePoint in this@escapeDataString.codePoints()) {
|
||||
when (codePoint) {
|
||||
in 0..0x20,
|
||||
@ -97,4 +97,3 @@ fun String.escapeDataString(): String {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +110,11 @@ fun buildIdnaMappingTableData(table: SimpleIdnaMappingTable): IdnaMappingTableDa
|
||||
internal fun inlineDeltaOrNull(mapping: Mapping): MappedRange.InlineDelta? {
|
||||
if (mapping.hasSingleSourceCodePoint) {
|
||||
val sourceCodePoint = mapping.sourceCodePoint0
|
||||
val mappedCodePoints = mapping.mappedTo.utf8().codePoints().toList()
|
||||
val mappedCodePoints =
|
||||
mapping.mappedTo
|
||||
.utf8()
|
||||
.codePoints()
|
||||
.toList()
|
||||
if (mappedCodePoints.size == 1) {
|
||||
val codePointDelta = mappedCodePoints.single() - sourceCodePoint
|
||||
if (MappedRange.InlineDelta.MAX_VALUE >= abs(codePointDelta)) {
|
||||
@ -262,8 +266,8 @@ internal fun mergeAdjacentRanges(mappings: List<Mapping>): List<Mapping> {
|
||||
return result
|
||||
}
|
||||
|
||||
internal fun canonicalizeType(type: Int): Int {
|
||||
return when (type) {
|
||||
internal fun canonicalizeType(type: Int): Int =
|
||||
when (type) {
|
||||
TYPE_IGNORED -> TYPE_IGNORED
|
||||
|
||||
TYPE_MAPPED,
|
||||
@ -279,7 +283,6 @@ internal fun canonicalizeType(type: Int): Int {
|
||||
|
||||
else -> error("unexpected type: $type")
|
||||
}
|
||||
}
|
||||
|
||||
internal infix fun Byte.and(mask: Int): Int = toInt() and mask
|
||||
|
||||
|
@ -225,10 +225,11 @@ class MappingTablesTest {
|
||||
sourceCodePoint1 = sourceCodePoint1,
|
||||
type = TYPE_MAPPED,
|
||||
mappedTo =
|
||||
Buffer().also {
|
||||
for (cp in mappedToCodePoints) {
|
||||
it.writeUtf8CodePoint(cp)
|
||||
}
|
||||
}.readByteString(),
|
||||
Buffer()
|
||||
.also {
|
||||
for (cp in mappedToCodePoints) {
|
||||
it.writeUtf8CodePoint(cp)
|
||||
}
|
||||
}.readByteString(),
|
||||
)
|
||||
}
|
||||
|
@ -31,7 +31,9 @@ import okhttp3.internal.platform.Platform.Companion.WARN
|
||||
import okhttp3.internal.trimSubstring
|
||||
|
||||
/** A cookie jar that delegates to a [java.net.CookieHandler]. */
|
||||
class JavaNetCookieJar(private val cookieHandler: CookieHandler) : CookieJar {
|
||||
class JavaNetCookieJar(
|
||||
private val cookieHandler: CookieHandler,
|
||||
) : CookieJar {
|
||||
override fun saveFromResponse(
|
||||
url: HttpUrl,
|
||||
cookies: List<Cookie>,
|
||||
@ -112,7 +114,8 @@ class JavaNetCookieJar(private val cookieHandler: CookieHandler) : CookieJar {
|
||||
}
|
||||
|
||||
result.add(
|
||||
Cookie.Builder()
|
||||
Cookie
|
||||
.Builder()
|
||||
.name(name)
|
||||
.value(value)
|
||||
.domain(url.host)
|
||||
|
@ -326,14 +326,17 @@ class HttpLoggingInterceptor
|
||||
if (queryParamsNameToRedact.isEmpty() || url.querySize == 0) {
|
||||
return url.toString()
|
||||
}
|
||||
return url.newBuilder().query(null).apply {
|
||||
for (i in 0 until url.querySize) {
|
||||
val parameterName = url.queryParameterName(i)
|
||||
val newValue = if (parameterName in queryParamsNameToRedact) "██" else url.queryParameterValue(i)
|
||||
return url
|
||||
.newBuilder()
|
||||
.query(null)
|
||||
.apply {
|
||||
for (i in 0 until url.querySize) {
|
||||
val parameterName = url.queryParameterName(i)
|
||||
val newValue = if (parameterName in queryParamsNameToRedact) "██" else url.queryParameterValue(i)
|
||||
|
||||
addEncodedQueryParameter(parameterName, newValue)
|
||||
}
|
||||
}.toString()
|
||||
addEncodedQueryParameter(parameterName, newValue)
|
||||
}
|
||||
}.toString()
|
||||
}
|
||||
|
||||
private fun logHeader(
|
||||
|
@ -73,7 +73,8 @@ class HttpLoggingInterceptorTest {
|
||||
fun setUp(server: MockWebServer) {
|
||||
this.server = server
|
||||
client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.addNetworkInterceptor(
|
||||
Interceptor { chain ->
|
||||
when {
|
||||
@ -81,14 +82,12 @@ class HttpLoggingInterceptorTest {
|
||||
else -> chain.proceed(chain.request())
|
||||
}
|
||||
},
|
||||
)
|
||||
.addNetworkInterceptor(networkInterceptor)
|
||||
).addNetworkInterceptor(networkInterceptor)
|
||||
.addInterceptor(applicationInterceptor)
|
||||
.sslSocketFactory(
|
||||
handshakeCertificates.sslSocketFactory(),
|
||||
handshakeCertificates.trustManager,
|
||||
)
|
||||
.hostnameVerifier(hostnameVerifier)
|
||||
).hostnameVerifier(hostnameVerifier)
|
||||
.build()
|
||||
host = "${server.hostName}:${server.port}"
|
||||
url = server.url("/")
|
||||
@ -153,7 +152,8 @@ class HttpLoggingInterceptorTest {
|
||||
fun basicResponseBody() {
|
||||
setLevel(Level.BASIC)
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("Hello!")
|
||||
.setHeader("Content-Type", PLAIN)
|
||||
.build(),
|
||||
@ -174,7 +174,8 @@ class HttpLoggingInterceptorTest {
|
||||
fun basicChunkedResponseBody() {
|
||||
setLevel(Level.BASIC)
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.chunkedBody("Hello!", 2)
|
||||
.setHeader("Content-Type", PLAIN)
|
||||
.build(),
|
||||
@ -320,7 +321,8 @@ class HttpLoggingInterceptorTest {
|
||||
extraNetworkInterceptor =
|
||||
Interceptor { chain: Interceptor.Chain ->
|
||||
chain.proceed(
|
||||
chain.request()
|
||||
chain
|
||||
.request()
|
||||
.newBuilder()
|
||||
.header("Content-Length", "2")
|
||||
.header("Content-Type", "text/plain-ish")
|
||||
@ -328,11 +330,12 @@ class HttpLoggingInterceptorTest {
|
||||
)
|
||||
}
|
||||
server.enqueue(MockResponse())
|
||||
client.newCall(
|
||||
request()
|
||||
.post("Hi?".toRequestBody(PLAIN))
|
||||
.build(),
|
||||
).execute()
|
||||
client
|
||||
.newCall(
|
||||
request()
|
||||
.post("Hi?".toRequestBody(PLAIN))
|
||||
.build(),
|
||||
).execute()
|
||||
applicationLogs
|
||||
.assertLogEqual("--> POST $url")
|
||||
.assertLogEqual("Content-Type: text/plain; charset=utf-8")
|
||||
@ -361,7 +364,8 @@ class HttpLoggingInterceptorTest {
|
||||
fun headersResponseBody() {
|
||||
setLevel(Level.HEADERS)
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("Hello!")
|
||||
.setHeader("Content-Type", PLAIN)
|
||||
.build(),
|
||||
@ -430,7 +434,8 @@ class HttpLoggingInterceptorTest {
|
||||
|
||||
private fun bodyGetNoBody(code: Int) {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.status("HTTP/1.1 $code No Content")
|
||||
.build(),
|
||||
)
|
||||
@ -495,7 +500,8 @@ class HttpLoggingInterceptorTest {
|
||||
fun bodyResponseBody() {
|
||||
setLevel(Level.BODY)
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("Hello!")
|
||||
.setHeader("Content-Type", PLAIN)
|
||||
.build(),
|
||||
@ -532,7 +538,8 @@ class HttpLoggingInterceptorTest {
|
||||
fun bodyResponseBodyChunked() {
|
||||
setLevel(Level.BODY)
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.chunkedBody("Hello!", 2)
|
||||
.setHeader("Content-Type", PLAIN)
|
||||
.build(),
|
||||
@ -569,18 +576,20 @@ class HttpLoggingInterceptorTest {
|
||||
fun bodyRequestGzipEncoded() {
|
||||
setLevel(Level.BODY)
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.setHeader("Content-Type", PLAIN)
|
||||
.body(Buffer().writeUtf8("Uncompressed"))
|
||||
.build(),
|
||||
)
|
||||
val response =
|
||||
client.newCall(
|
||||
request()
|
||||
.addHeader("Content-Encoding", "gzip")
|
||||
.post("Uncompressed".toRequestBody().gzip())
|
||||
.build(),
|
||||
).execute()
|
||||
client
|
||||
.newCall(
|
||||
request()
|
||||
.addHeader("Content-Encoding", "gzip")
|
||||
.post("Uncompressed".toRequestBody().gzip())
|
||||
.build(),
|
||||
).execute()
|
||||
val responseBody = response.body
|
||||
assertThat(responseBody.string(), "Expected response body to be valid")
|
||||
.isEqualTo("Uncompressed")
|
||||
@ -608,7 +617,8 @@ class HttpLoggingInterceptorTest {
|
||||
fun bodyResponseGzipEncoded() {
|
||||
setLevel(Level.BODY)
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.setHeader("Content-Encoding", "gzip")
|
||||
.setHeader("Content-Type", PLAIN)
|
||||
.body(Buffer().write("H4sIAAAAAAAAAPNIzcnJ11HwQKIAdyO+9hMAAAA=".decodeBase64()!!))
|
||||
@ -649,7 +659,8 @@ class HttpLoggingInterceptorTest {
|
||||
fun bodyResponseUnknownEncoded() {
|
||||
setLevel(Level.BODY)
|
||||
server.enqueue(
|
||||
MockResponse.Builder() // It's invalid to return this if not requested, but the server might anyway
|
||||
MockResponse
|
||||
.Builder() // It's invalid to return this if not requested, but the server might anyway
|
||||
.setHeader("Content-Encoding", "br")
|
||||
.setHeader("Content-Type", PLAIN)
|
||||
.body(Buffer().write("iwmASGVsbG8sIEhlbGxvLCBIZWxsbwoD".decodeBase64()!!))
|
||||
@ -685,7 +696,8 @@ class HttpLoggingInterceptorTest {
|
||||
fun bodyResponseIsStreaming() {
|
||||
setLevel(Level.BODY)
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.setHeader("Content-Type", "text/event-stream")
|
||||
.chunkedBody(
|
||||
"""
|
||||
@ -701,8 +713,7 @@ class HttpLoggingInterceptorTest {
|
||||
|
|
||||
""".trimMargin(),
|
||||
8,
|
||||
)
|
||||
.build(),
|
||||
).build(),
|
||||
)
|
||||
val response = client.newCall(request().build()).execute()
|
||||
response.body.close()
|
||||
@ -732,7 +743,8 @@ class HttpLoggingInterceptorTest {
|
||||
fun bodyGetMalformedCharset() {
|
||||
setLevel(Level.BODY)
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.setHeader("Content-Type", "text/html; charset=0")
|
||||
.body("Body with unknown charset")
|
||||
.build(),
|
||||
@ -778,7 +790,8 @@ class HttpLoggingInterceptorTest {
|
||||
buffer.writeUtf8CodePoint(0x1a)
|
||||
buffer.writeUtf8CodePoint(0x0a)
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body(buffer)
|
||||
.setHeader("Content-Type", "image/png; charset=utf-8")
|
||||
.build(),
|
||||
@ -813,7 +826,8 @@ class HttpLoggingInterceptorTest {
|
||||
fun connectFail() {
|
||||
setLevel(Level.BASIC)
|
||||
client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.dns { hostname: String? -> throw UnknownHostException("reason") }
|
||||
.addInterceptor(applicationInterceptor)
|
||||
.build()
|
||||
@ -859,13 +873,16 @@ class HttpLoggingInterceptorTest {
|
||||
)
|
||||
applicationInterceptor.redactHeader("sEnSiTiVe")
|
||||
client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.addNetworkInterceptor(networkInterceptor)
|
||||
.addInterceptor(applicationInterceptor)
|
||||
.build()
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
.addHeader("SeNsItIvE", "Value").addHeader("Not-Sensitive", "Value")
|
||||
MockResponse
|
||||
.Builder()
|
||||
.addHeader("SeNsItIvE", "Value")
|
||||
.addHeader("Not-Sensitive", "Value")
|
||||
.build(),
|
||||
)
|
||||
val response =
|
||||
@ -875,8 +892,7 @@ class HttpLoggingInterceptorTest {
|
||||
.addHeader("SeNsItIvE", "Value")
|
||||
.addHeader("Not-Sensitive", "Value")
|
||||
.build(),
|
||||
)
|
||||
.execute()
|
||||
).execute()
|
||||
response.body.close()
|
||||
applicationLogs
|
||||
.assertLogEqual("--> GET $url")
|
||||
@ -923,12 +939,14 @@ class HttpLoggingInterceptorTest {
|
||||
applicationInterceptor.redactQueryParams("user", "PassworD")
|
||||
|
||||
client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.addNetworkInterceptor(networkInterceptor)
|
||||
.addInterceptor(applicationInterceptor)
|
||||
.build()
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.build(),
|
||||
)
|
||||
val response =
|
||||
@ -936,8 +954,7 @@ class HttpLoggingInterceptorTest {
|
||||
.newCall(
|
||||
request()
|
||||
.build(),
|
||||
)
|
||||
.execute()
|
||||
).execute()
|
||||
response.body.close()
|
||||
val redactedUrl = networkInterceptor.redactUrl(url)
|
||||
val redactedUrlPattern = redactedUrl.replace("?", """\?""")
|
||||
@ -976,12 +993,14 @@ class HttpLoggingInterceptorTest {
|
||||
applicationInterceptor.redactQueryParams("user", "PassworD")
|
||||
|
||||
client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.addNetworkInterceptor(networkInterceptor)
|
||||
.addInterceptor(applicationInterceptor)
|
||||
.build()
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.build(),
|
||||
)
|
||||
val response =
|
||||
@ -989,8 +1008,7 @@ class HttpLoggingInterceptorTest {
|
||||
.newCall(
|
||||
request()
|
||||
.build(),
|
||||
)
|
||||
.execute()
|
||||
).execute()
|
||||
response.body.close()
|
||||
val redactedUrl = networkInterceptor.redactUrl(url)
|
||||
val redactedUrlPattern = redactedUrl.replace("?", """\?""")
|
||||
@ -1011,24 +1029,21 @@ class HttpLoggingInterceptorTest {
|
||||
url = server.url("/")
|
||||
setLevel(Level.BODY)
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("Hello response!")
|
||||
.build(),
|
||||
)
|
||||
val asyncRequestBody: RequestBody =
|
||||
object : RequestBody() {
|
||||
override fun contentType(): MediaType? {
|
||||
return null
|
||||
}
|
||||
override fun contentType(): MediaType? = null
|
||||
|
||||
override fun writeTo(sink: BufferedSink) {
|
||||
sink.writeUtf8("Hello request!")
|
||||
sink.close()
|
||||
}
|
||||
|
||||
override fun isDuplex(): Boolean {
|
||||
return true
|
||||
}
|
||||
override fun isDuplex(): Boolean = true
|
||||
}
|
||||
val request =
|
||||
request()
|
||||
@ -1053,7 +1068,8 @@ class HttpLoggingInterceptorTest {
|
||||
url = server.url("/")
|
||||
setLevel(Level.BODY)
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("Hello response!")
|
||||
.build(),
|
||||
)
|
||||
@ -1089,9 +1105,7 @@ class HttpLoggingInterceptorTest {
|
||||
.assertNoMoreLogs()
|
||||
}
|
||||
|
||||
private fun request(): Request.Builder {
|
||||
return Request.Builder().url(url)
|
||||
}
|
||||
private fun request(): Request.Builder = Request.Builder().url(url)
|
||||
|
||||
internal class LogRecorder(
|
||||
val prefix: Regex = Regex(""),
|
||||
|
@ -62,13 +62,13 @@ class LoggingEventListenerTest {
|
||||
fun setUp(server: MockWebServer) {
|
||||
this.server = server
|
||||
client =
|
||||
clientTestRule.newClientBuilder()
|
||||
clientTestRule
|
||||
.newClientBuilder()
|
||||
.eventListenerFactory(loggingEventListenerFactory)
|
||||
.sslSocketFactory(
|
||||
handshakeCertificates.sslSocketFactory(),
|
||||
handshakeCertificates.trustManager,
|
||||
)
|
||||
.retryOnConnectionFailure(false)
|
||||
).retryOnConnectionFailure(false)
|
||||
.build()
|
||||
url = server.url("/")
|
||||
}
|
||||
@ -77,7 +77,8 @@ class LoggingEventListenerTest {
|
||||
fun get() {
|
||||
assumeNotWindows()
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body("Hello!")
|
||||
.setHeader("Content-Type", PLAIN)
|
||||
.build(),
|
||||
@ -97,8 +98,7 @@ class LoggingEventListenerTest {
|
||||
Regex(
|
||||
"""connectionAcquired: Connection\{${url.host}:\d+, proxy=DIRECT hostAddress=${url.host}/.+ cipherSuite=none protocol=http/1\.1\}""",
|
||||
),
|
||||
)
|
||||
.assertLogMatch(Regex("""requestHeadersStart"""))
|
||||
).assertLogMatch(Regex("""requestHeadersStart"""))
|
||||
.assertLogMatch(Regex("""requestHeadersEnd"""))
|
||||
.assertLogMatch(Regex("""responseHeadersStart"""))
|
||||
.assertLogMatch(Regex("""responseHeadersEnd: Response\{protocol=http/1\.1, code=200, message=OK, url=$url\}"""))
|
||||
@ -126,8 +126,7 @@ class LoggingEventListenerTest {
|
||||
Regex(
|
||||
"""connectionAcquired: Connection\{${url.host}:\d+, proxy=DIRECT hostAddress=${url.host}/.+ cipherSuite=none protocol=http/1\.1\}""",
|
||||
),
|
||||
)
|
||||
.assertLogMatch(Regex("""requestHeadersStart"""))
|
||||
).assertLogMatch(Regex("""requestHeadersStart"""))
|
||||
.assertLogMatch(Regex("""requestHeadersEnd"""))
|
||||
.assertLogMatch(Regex("""requestBodyStart"""))
|
||||
.assertLogMatch(Regex("""requestBodyEnd: byteCount=6"""))
|
||||
@ -162,12 +161,10 @@ class LoggingEventListenerTest {
|
||||
Regex(
|
||||
"""secureConnectEnd: Handshake\{tlsVersion=TLS_1_[23] cipherSuite=TLS_.* peerCertificates=\[CN=localhost] localCertificates=\[]\}""",
|
||||
),
|
||||
)
|
||||
.assertLogMatch(Regex("""connectEnd: h2"""))
|
||||
).assertLogMatch(Regex("""connectEnd: h2"""))
|
||||
.assertLogMatch(
|
||||
Regex("""connectionAcquired: Connection\{${url.host}:\d+, proxy=DIRECT hostAddress=${url.host}/.+ cipherSuite=.+ protocol=h2\}"""),
|
||||
)
|
||||
.assertLogMatch(Regex("""requestHeadersStart"""))
|
||||
).assertLogMatch(Regex("""requestHeadersStart"""))
|
||||
.assertLogMatch(Regex("""requestHeadersEnd"""))
|
||||
.assertLogMatch(Regex("""responseHeadersStart"""))
|
||||
.assertLogMatch(Regex("""responseHeadersEnd: Response\{protocol=h2, code=200, message=, url=$url\}"""))
|
||||
@ -181,7 +178,8 @@ class LoggingEventListenerTest {
|
||||
@Test
|
||||
fun dnsFail() {
|
||||
client =
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.dns { _ -> throw UnknownHostException("reason") }
|
||||
.eventListenerFactory(loggingEventListenerFactory)
|
||||
.build()
|
||||
@ -205,7 +203,8 @@ class LoggingEventListenerTest {
|
||||
server.useHttps(handshakeCertificates.sslSocketFactory())
|
||||
server.protocols = Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1)
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.socketPolicy(FailHandshake)
|
||||
.build(),
|
||||
)
|
||||
@ -227,13 +226,11 @@ class LoggingEventListenerTest {
|
||||
Regex(
|
||||
"""connectFailed: null \S+(?:SSLProtocolException|SSLHandshakeException|TlsFatalAlert): (?:Unexpected handshake message: client_hello|Handshake message sequence violation, 1|Read error|Handshake failed|unexpected_message\(10\)).*""",
|
||||
),
|
||||
)
|
||||
.assertLogMatch(
|
||||
).assertLogMatch(
|
||||
Regex(
|
||||
"""callFailed: \S+(?:SSLProtocolException|SSLHandshakeException|TlsFatalAlert): (?:Unexpected handshake message: client_hello|Handshake message sequence violation, 1|Read error|Handshake failed|unexpected_message\(10\)).*""",
|
||||
),
|
||||
)
|
||||
.assertNoMoreLogs()
|
||||
).assertNoMoreLogs()
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -241,7 +238,12 @@ class LoggingEventListenerTest {
|
||||
val request = Request.Builder().url(url).build()
|
||||
val call = client.newCall(request)
|
||||
val response =
|
||||
Response.Builder().request(request).code(200).message("").protocol(Protocol.HTTP_2)
|
||||
Response
|
||||
.Builder()
|
||||
.request(request)
|
||||
.code(200)
|
||||
.message("")
|
||||
.protocol(Protocol.HTTP_2)
|
||||
.build()
|
||||
val listener = loggingEventListenerFactory.create(call)
|
||||
listener.cacheConditionalHit(call, response)
|
||||
@ -256,9 +258,7 @@ class LoggingEventListenerTest {
|
||||
.assertNoMoreLogs()
|
||||
}
|
||||
|
||||
private fun request(): Request.Builder {
|
||||
return Request.Builder().url(url)
|
||||
}
|
||||
private fun request(): Request.Builder = Request.Builder().url(url)
|
||||
|
||||
companion object {
|
||||
private val PLAIN = "text/plain".toMediaType()
|
||||
|
@ -116,7 +116,8 @@ class OsgiTest {
|
||||
private fun RepositoryPlugin.deployClassPath() {
|
||||
val classpath = System.getProperty("java.class.path")
|
||||
val entries =
|
||||
classpath.split(File.pathSeparator.toRegex())
|
||||
classpath
|
||||
.split(File.pathSeparator.toRegex())
|
||||
.dropLastWhile { it.isEmpty() }
|
||||
.toTypedArray()
|
||||
for (classPathEntry in entries) {
|
||||
|
@ -29,8 +29,8 @@ object EventSources {
|
||||
fun createFactory(client: OkHttpClient) = createFactory(client as Call.Factory)
|
||||
|
||||
@JvmStatic
|
||||
fun createFactory(callFactory: Call.Factory): EventSource.Factory {
|
||||
return EventSource.Factory { request, listener ->
|
||||
fun createFactory(callFactory: Call.Factory): EventSource.Factory =
|
||||
EventSource.Factory { request, listener ->
|
||||
val actualRequest =
|
||||
if (request.header("Accept") == null) {
|
||||
request.newBuilder().addHeader("Accept", "text/event-stream").build()
|
||||
@ -42,7 +42,6 @@ object EventSources {
|
||||
connect(callFactory)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun processResponse(
|
||||
|
@ -28,7 +28,9 @@ import okhttp3.sse.EventSourceListener
|
||||
internal class RealEventSource(
|
||||
private val request: Request,
|
||||
private val listener: EventSourceListener,
|
||||
) : EventSource, ServerSentEventReader.Callback, Callback {
|
||||
) : EventSource,
|
||||
ServerSentEventReader.Callback,
|
||||
Callback {
|
||||
private var call: Call? = null
|
||||
|
||||
@Volatile private var canceled = false
|
||||
|
@ -48,7 +48,8 @@ class EventSourceHttpTest {
|
||||
private val eventListener = RecordingEventListener()
|
||||
private val listener = EventSourceRecorder()
|
||||
private var client =
|
||||
clientTestRule.newClientBuilder()
|
||||
clientTestRule
|
||||
.newClientBuilder()
|
||||
.eventListenerFactory(clientTestRule.wrap(eventListener))
|
||||
.build()
|
||||
|
||||
@ -65,7 +66,8 @@ class EventSourceHttpTest {
|
||||
@Test
|
||||
fun event() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body(
|
||||
"""
|
||||
|data: hey
|
||||
@ -85,7 +87,8 @@ class EventSourceHttpTest {
|
||||
@RetryingTest(5)
|
||||
fun cancelInEventShortCircuits() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body(
|
||||
"""
|
||||
|data: hey
|
||||
@ -104,7 +107,8 @@ class EventSourceHttpTest {
|
||||
@Test
|
||||
fun badContentType() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body(
|
||||
"""
|
||||
|data: hey
|
||||
@ -121,15 +125,15 @@ class EventSourceHttpTest {
|
||||
@Test
|
||||
fun badResponseCode() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body(
|
||||
"""
|
||||
|data: hey
|
||||
|
|
||||
|
|
||||
""".trimMargin(),
|
||||
)
|
||||
.setHeader("content-type", "text/event-stream")
|
||||
).setHeader("content-type", "text/event-stream")
|
||||
.code(401)
|
||||
.build(),
|
||||
)
|
||||
@ -140,11 +144,13 @@ class EventSourceHttpTest {
|
||||
@Test
|
||||
fun fullCallTimeoutDoesNotApplyOnceConnected() {
|
||||
client =
|
||||
client.newBuilder()
|
||||
client
|
||||
.newBuilder()
|
||||
.callTimeout(250, TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.bodyDelay(500, TimeUnit.MILLISECONDS)
|
||||
.setHeader("content-type", "text/event-stream")
|
||||
.body("data: hey\n\n")
|
||||
@ -160,11 +166,13 @@ class EventSourceHttpTest {
|
||||
@Test
|
||||
fun fullCallTimeoutAppliesToSetup() {
|
||||
client =
|
||||
client.newBuilder()
|
||||
client
|
||||
.newBuilder()
|
||||
.callTimeout(250, TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.headersDelay(500, TimeUnit.MILLISECONDS)
|
||||
.setHeader("content-type", "text/event-stream")
|
||||
.body("data: hey\n\n")
|
||||
@ -177,15 +185,15 @@ class EventSourceHttpTest {
|
||||
@Test
|
||||
fun retainsAccept() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body(
|
||||
"""
|
||||
|data: hey
|
||||
|
|
||||
|
|
||||
""".trimMargin(),
|
||||
)
|
||||
.setHeader("content-type", "text/event-stream")
|
||||
).setHeader("content-type", "text/event-stream")
|
||||
.build(),
|
||||
)
|
||||
newEventSource("text/plain")
|
||||
@ -198,7 +206,8 @@ class EventSourceHttpTest {
|
||||
@Test
|
||||
fun setsMissingAccept() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body(
|
||||
"""
|
||||
|data: hey
|
||||
@ -219,7 +228,8 @@ class EventSourceHttpTest {
|
||||
@Test
|
||||
fun eventListenerEvents() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body(
|
||||
"""
|
||||
|data: hey
|
||||
@ -256,7 +266,8 @@ class EventSourceHttpTest {
|
||||
|
||||
private fun newEventSource(accept: String? = null): EventSource {
|
||||
val builder =
|
||||
Request.Builder()
|
||||
Request
|
||||
.Builder()
|
||||
.url(server.url("/"))
|
||||
if (accept != null) {
|
||||
builder.header("Accept", accept)
|
||||
|
@ -78,10 +78,9 @@ class EventSourceRecorder : EventSourceListener() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun nextEvent(): Any {
|
||||
return events.poll(10, TimeUnit.SECONDS)
|
||||
private fun nextEvent(): Any =
|
||||
events.poll(10, TimeUnit.SECONDS)
|
||||
?: throw AssertionError("Timed out waiting for event.")
|
||||
}
|
||||
|
||||
fun assertExhausted() {
|
||||
assertThat(events).isEmpty()
|
||||
|
@ -55,7 +55,8 @@ class EventSourcesHttpTest {
|
||||
@Test
|
||||
fun processResponse() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body(
|
||||
"""
|
||||
|data: hey
|
||||
@ -66,7 +67,8 @@ class EventSourcesHttpTest {
|
||||
.build(),
|
||||
)
|
||||
val request =
|
||||
Request.Builder()
|
||||
Request
|
||||
.Builder()
|
||||
.url(server.url("/"))
|
||||
.build()
|
||||
val response = client.newCall(request).execute()
|
||||
@ -79,7 +81,8 @@ class EventSourcesHttpTest {
|
||||
@Test
|
||||
fun cancelShortCircuits() {
|
||||
server.enqueue(
|
||||
MockResponse.Builder()
|
||||
MockResponse
|
||||
.Builder()
|
||||
.body(
|
||||
"""
|
||||
|data: hey
|
||||
@ -91,7 +94,8 @@ class EventSourcesHttpTest {
|
||||
)
|
||||
listener.enqueueCancel() // Will cancel in onOpen().
|
||||
val request =
|
||||
Request.Builder()
|
||||
Request
|
||||
.Builder()
|
||||
.url(server.url("/"))
|
||||
.build()
|
||||
val response = client.newCall(request).execute()
|
||||
|
@ -23,30 +23,22 @@ import javax.net.ssl.SSLSessionContext
|
||||
import javax.security.cert.X509Certificate
|
||||
|
||||
/** An [SSLSession] that delegates all calls. */
|
||||
abstract class DelegatingSSLSession(protected val delegate: SSLSession?) : SSLSession {
|
||||
override fun getId(): ByteArray {
|
||||
return delegate!!.id
|
||||
}
|
||||
abstract class DelegatingSSLSession(
|
||||
protected val delegate: SSLSession?,
|
||||
) : SSLSession {
|
||||
override fun getId(): ByteArray = delegate!!.id
|
||||
|
||||
override fun getSessionContext(): SSLSessionContext {
|
||||
return delegate!!.sessionContext
|
||||
}
|
||||
override fun getSessionContext(): SSLSessionContext = delegate!!.sessionContext
|
||||
|
||||
override fun getCreationTime(): Long {
|
||||
return delegate!!.creationTime
|
||||
}
|
||||
override fun getCreationTime(): Long = delegate!!.creationTime
|
||||
|
||||
override fun getLastAccessedTime(): Long {
|
||||
return delegate!!.lastAccessedTime
|
||||
}
|
||||
override fun getLastAccessedTime(): Long = delegate!!.lastAccessedTime
|
||||
|
||||
override fun invalidate() {
|
||||
delegate!!.invalidate()
|
||||
}
|
||||
|
||||
override fun isValid(): Boolean {
|
||||
return delegate!!.isValid
|
||||
}
|
||||
override fun isValid(): Boolean = delegate!!.isValid
|
||||
|
||||
override fun putValue(
|
||||
s: String,
|
||||
@ -55,62 +47,36 @@ abstract class DelegatingSSLSession(protected val delegate: SSLSession?) : SSLSe
|
||||
delegate!!.putValue(s, o)
|
||||
}
|
||||
|
||||
override fun getValue(s: String): Any {
|
||||
return delegate!!.getValue(s)
|
||||
}
|
||||
override fun getValue(s: String): Any = delegate!!.getValue(s)
|
||||
|
||||
override fun removeValue(s: String) {
|
||||
delegate!!.removeValue(s)
|
||||
}
|
||||
|
||||
override fun getValueNames(): Array<String> {
|
||||
return delegate!!.valueNames
|
||||
}
|
||||
override fun getValueNames(): Array<String> = delegate!!.valueNames
|
||||
|
||||
@Throws(SSLPeerUnverifiedException::class)
|
||||
override fun getPeerCertificates(): Array<Certificate>? {
|
||||
return delegate!!.peerCertificates
|
||||
}
|
||||
override fun getPeerCertificates(): Array<Certificate>? = delegate!!.peerCertificates
|
||||
|
||||
override fun getLocalCertificates(): Array<Certificate>? {
|
||||
return delegate!!.localCertificates
|
||||
}
|
||||
override fun getLocalCertificates(): Array<Certificate>? = delegate!!.localCertificates
|
||||
|
||||
@Throws(SSLPeerUnverifiedException::class)
|
||||
override fun getPeerCertificateChain(): Array<X509Certificate> {
|
||||
return delegate!!.peerCertificateChain
|
||||
}
|
||||
override fun getPeerCertificateChain(): Array<X509Certificate> = delegate!!.peerCertificateChain
|
||||
|
||||
@Throws(SSLPeerUnverifiedException::class)
|
||||
override fun getPeerPrincipal(): Principal {
|
||||
return delegate!!.peerPrincipal
|
||||
}
|
||||
override fun getPeerPrincipal(): Principal = delegate!!.peerPrincipal
|
||||
|
||||
override fun getLocalPrincipal(): Principal {
|
||||
return delegate!!.localPrincipal
|
||||
}
|
||||
override fun getLocalPrincipal(): Principal = delegate!!.localPrincipal
|
||||
|
||||
override fun getCipherSuite(): String {
|
||||
return delegate!!.cipherSuite
|
||||
}
|
||||
override fun getCipherSuite(): String = delegate!!.cipherSuite
|
||||
|
||||
override fun getProtocol(): String {
|
||||
return delegate!!.protocol
|
||||
}
|
||||
override fun getProtocol(): String = delegate!!.protocol
|
||||
|
||||
override fun getPeerHost(): String {
|
||||
return delegate!!.peerHost
|
||||
}
|
||||
override fun getPeerHost(): String = delegate!!.peerHost
|
||||
|
||||
override fun getPeerPort(): Int {
|
||||
return delegate!!.peerPort
|
||||
}
|
||||
override fun getPeerPort(): Int = delegate!!.peerPort
|
||||
|
||||
override fun getPacketBufferSize(): Int {
|
||||
return delegate!!.packetBufferSize
|
||||
}
|
||||
override fun getPacketBufferSize(): Int = delegate!!.packetBufferSize
|
||||
|
||||
override fun getApplicationBufferSize(): Int {
|
||||
return delegate!!.applicationBufferSize
|
||||
}
|
||||
override fun getApplicationBufferSize(): Int = delegate!!.applicationBufferSize
|
||||
}
|
||||
|
@ -29,7 +29,9 @@ import javax.net.ssl.SSLSession
|
||||
import javax.net.ssl.SSLSocket
|
||||
|
||||
/** An [SSLSocket] that delegates all calls. */
|
||||
abstract class DelegatingSSLSocket(protected val delegate: SSLSocket?) : SSLSocket() {
|
||||
abstract class DelegatingSSLSocket(
|
||||
protected val delegate: SSLSocket?,
|
||||
) : SSLSocket() {
|
||||
@Throws(IOException::class)
|
||||
override fun shutdownInput() {
|
||||
delegate!!.shutdownInput()
|
||||
@ -40,33 +42,23 @@ abstract class DelegatingSSLSocket(protected val delegate: SSLSocket?) : SSLSock
|
||||
delegate!!.shutdownOutput()
|
||||
}
|
||||
|
||||
override fun getSupportedCipherSuites(): Array<String> {
|
||||
return delegate!!.supportedCipherSuites
|
||||
}
|
||||
override fun getSupportedCipherSuites(): Array<String> = delegate!!.supportedCipherSuites
|
||||
|
||||
override fun getEnabledCipherSuites(): Array<String> {
|
||||
return delegate!!.enabledCipherSuites
|
||||
}
|
||||
override fun getEnabledCipherSuites(): Array<String> = delegate!!.enabledCipherSuites
|
||||
|
||||
override fun setEnabledCipherSuites(suites: Array<String>) {
|
||||
delegate!!.enabledCipherSuites = suites
|
||||
}
|
||||
|
||||
override fun getSupportedProtocols(): Array<String> {
|
||||
return delegate!!.supportedProtocols
|
||||
}
|
||||
override fun getSupportedProtocols(): Array<String> = delegate!!.supportedProtocols
|
||||
|
||||
override fun getEnabledProtocols(): Array<String> {
|
||||
return delegate!!.enabledProtocols
|
||||
}
|
||||
override fun getEnabledProtocols(): Array<String> = delegate!!.enabledProtocols
|
||||
|
||||
override fun setEnabledProtocols(protocols: Array<String>) {
|
||||
delegate!!.enabledProtocols = protocols
|
||||
}
|
||||
|
||||
override fun getSession(): SSLSession {
|
||||
return delegate!!.session
|
||||
}
|
||||
override fun getSession(): SSLSession = delegate!!.session
|
||||
|
||||
override fun addHandshakeCompletedListener(listener: HandshakeCompletedListener) {
|
||||
delegate!!.addHandshakeCompletedListener(listener)
|
||||
@ -85,9 +77,7 @@ abstract class DelegatingSSLSocket(protected val delegate: SSLSocket?) : SSLSock
|
||||
delegate!!.useClientMode = mode
|
||||
}
|
||||
|
||||
override fun getUseClientMode(): Boolean {
|
||||
return delegate!!.useClientMode
|
||||
}
|
||||
override fun getUseClientMode(): Boolean = delegate!!.useClientMode
|
||||
|
||||
override fun setNeedClientAuth(need: Boolean) {
|
||||
delegate!!.needClientAuth = need
|
||||
@ -97,25 +87,17 @@ abstract class DelegatingSSLSocket(protected val delegate: SSLSocket?) : SSLSock
|
||||
delegate!!.wantClientAuth = want
|
||||
}
|
||||
|
||||
override fun getNeedClientAuth(): Boolean {
|
||||
return delegate!!.needClientAuth
|
||||
}
|
||||
override fun getNeedClientAuth(): Boolean = delegate!!.needClientAuth
|
||||
|
||||
override fun getWantClientAuth(): Boolean {
|
||||
return delegate!!.wantClientAuth
|
||||
}
|
||||
override fun getWantClientAuth(): Boolean = delegate!!.wantClientAuth
|
||||
|
||||
override fun setEnableSessionCreation(flag: Boolean) {
|
||||
delegate!!.enableSessionCreation = flag
|
||||
}
|
||||
|
||||
override fun getEnableSessionCreation(): Boolean {
|
||||
return delegate!!.enableSessionCreation
|
||||
}
|
||||
override fun getEnableSessionCreation(): Boolean = delegate!!.enableSessionCreation
|
||||
|
||||
override fun getSSLParameters(): SSLParameters {
|
||||
return delegate!!.sslParameters
|
||||
}
|
||||
override fun getSSLParameters(): SSLParameters = delegate!!.sslParameters
|
||||
|
||||
override fun setSSLParameters(p: SSLParameters) {
|
||||
delegate!!.sslParameters = p
|
||||
@ -126,61 +108,37 @@ abstract class DelegatingSSLSocket(protected val delegate: SSLSocket?) : SSLSock
|
||||
delegate!!.close()
|
||||
}
|
||||
|
||||
override fun getInetAddress(): InetAddress {
|
||||
return delegate!!.inetAddress
|
||||
}
|
||||
override fun getInetAddress(): InetAddress = delegate!!.inetAddress
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun getInputStream(): InputStream {
|
||||
return delegate!!.inputStream
|
||||
}
|
||||
override fun getInputStream(): InputStream = delegate!!.inputStream
|
||||
|
||||
@Throws(SocketException::class)
|
||||
override fun getKeepAlive(): Boolean {
|
||||
return delegate!!.keepAlive
|
||||
}
|
||||
override fun getKeepAlive(): Boolean = delegate!!.keepAlive
|
||||
|
||||
override fun getLocalAddress(): InetAddress {
|
||||
return delegate!!.localAddress
|
||||
}
|
||||
override fun getLocalAddress(): InetAddress = delegate!!.localAddress
|
||||
|
||||
override fun getLocalPort(): Int {
|
||||
return delegate!!.localPort
|
||||
}
|
||||
override fun getLocalPort(): Int = delegate!!.localPort
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun getOutputStream(): OutputStream {
|
||||
return delegate!!.outputStream
|
||||
}
|
||||
override fun getOutputStream(): OutputStream = delegate!!.outputStream
|
||||
|
||||
override fun getPort(): Int {
|
||||
return delegate!!.port
|
||||
}
|
||||
override fun getPort(): Int = delegate!!.port
|
||||
|
||||
@Throws(SocketException::class)
|
||||
override fun getSoLinger(): Int {
|
||||
return delegate!!.soLinger
|
||||
}
|
||||
override fun getSoLinger(): Int = delegate!!.soLinger
|
||||
|
||||
@Throws(SocketException::class)
|
||||
override fun getReceiveBufferSize(): Int {
|
||||
return delegate!!.receiveBufferSize
|
||||
}
|
||||
override fun getReceiveBufferSize(): Int = delegate!!.receiveBufferSize
|
||||
|
||||
@Throws(SocketException::class)
|
||||
override fun getSendBufferSize(): Int {
|
||||
return delegate!!.sendBufferSize
|
||||
}
|
||||
override fun getSendBufferSize(): Int = delegate!!.sendBufferSize
|
||||
|
||||
@Throws(SocketException::class)
|
||||
override fun getSoTimeout(): Int {
|
||||
return delegate!!.soTimeout
|
||||
}
|
||||
override fun getSoTimeout(): Int = delegate!!.soTimeout
|
||||
|
||||
@Throws(SocketException::class)
|
||||
override fun getTcpNoDelay(): Boolean {
|
||||
return delegate!!.tcpNoDelay
|
||||
}
|
||||
override fun getTcpNoDelay(): Boolean = delegate!!.tcpNoDelay
|
||||
|
||||
@Throws(SocketException::class)
|
||||
override fun setKeepAlive(keepAlive: Boolean) {
|
||||
@ -215,29 +173,17 @@ abstract class DelegatingSSLSocket(protected val delegate: SSLSocket?) : SSLSock
|
||||
delegate!!.tcpNoDelay = on
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return delegate!!.toString()
|
||||
}
|
||||
override fun toString(): String = delegate!!.toString()
|
||||
|
||||
override fun getLocalSocketAddress(): SocketAddress {
|
||||
return delegate!!.localSocketAddress
|
||||
}
|
||||
override fun getLocalSocketAddress(): SocketAddress = delegate!!.localSocketAddress
|
||||
|
||||
override fun getRemoteSocketAddress(): SocketAddress {
|
||||
return delegate!!.remoteSocketAddress
|
||||
}
|
||||
override fun getRemoteSocketAddress(): SocketAddress = delegate!!.remoteSocketAddress
|
||||
|
||||
override fun isBound(): Boolean {
|
||||
return delegate!!.isBound
|
||||
}
|
||||
override fun isBound(): Boolean = delegate!!.isBound
|
||||
|
||||
override fun isConnected(): Boolean {
|
||||
return delegate!!.isConnected
|
||||
}
|
||||
override fun isConnected(): Boolean = delegate!!.isConnected
|
||||
|
||||
override fun isClosed(): Boolean {
|
||||
return delegate!!.isClosed
|
||||
}
|
||||
override fun isClosed(): Boolean = delegate!!.isClosed
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun bind(localAddr: SocketAddress) {
|
||||
@ -257,13 +203,9 @@ abstract class DelegatingSSLSocket(protected val delegate: SSLSocket?) : SSLSock
|
||||
delegate!!.connect(remoteAddr, timeout)
|
||||
}
|
||||
|
||||
override fun isInputShutdown(): Boolean {
|
||||
return delegate!!.isInputShutdown
|
||||
}
|
||||
override fun isInputShutdown(): Boolean = delegate!!.isInputShutdown
|
||||
|
||||
override fun isOutputShutdown(): Boolean {
|
||||
return delegate!!.isOutputShutdown
|
||||
}
|
||||
override fun isOutputShutdown(): Boolean = delegate!!.isOutputShutdown
|
||||
|
||||
@Throws(SocketException::class)
|
||||
override fun setReuseAddress(reuse: Boolean) {
|
||||
@ -271,9 +213,7 @@ abstract class DelegatingSSLSocket(protected val delegate: SSLSocket?) : SSLSock
|
||||
}
|
||||
|
||||
@Throws(SocketException::class)
|
||||
override fun getReuseAddress(): Boolean {
|
||||
return delegate!!.reuseAddress
|
||||
}
|
||||
override fun getReuseAddress(): Boolean = delegate!!.reuseAddress
|
||||
|
||||
@Throws(SocketException::class)
|
||||
override fun setOOBInline(oobinline: Boolean) {
|
||||
@ -281,9 +221,7 @@ abstract class DelegatingSSLSocket(protected val delegate: SSLSocket?) : SSLSock
|
||||
}
|
||||
|
||||
@Throws(SocketException::class)
|
||||
override fun getOOBInline(): Boolean {
|
||||
return delegate!!.oobInline
|
||||
}
|
||||
override fun getOOBInline(): Boolean = delegate!!.oobInline
|
||||
|
||||
@Throws(SocketException::class)
|
||||
override fun setTrafficClass(value: Int) {
|
||||
@ -291,36 +229,25 @@ abstract class DelegatingSSLSocket(protected val delegate: SSLSocket?) : SSLSock
|
||||
}
|
||||
|
||||
@Throws(SocketException::class)
|
||||
override fun getTrafficClass(): Int {
|
||||
return delegate!!.trafficClass
|
||||
}
|
||||
override fun getTrafficClass(): Int = delegate!!.trafficClass
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun sendUrgentData(value: Int) {
|
||||
delegate!!.sendUrgentData(value)
|
||||
}
|
||||
|
||||
override fun getChannel(): SocketChannel {
|
||||
return delegate!!.channel
|
||||
}
|
||||
override fun getChannel(): SocketChannel = delegate!!.channel
|
||||
|
||||
override fun getHandshakeSession(): SSLSession {
|
||||
return delegate!!.handshakeSession
|
||||
}
|
||||
override fun getHandshakeSession(): SSLSession = delegate!!.handshakeSession
|
||||
|
||||
override fun getApplicationProtocol(): String {
|
||||
return delegate!!.applicationProtocol
|
||||
}
|
||||
override fun getApplicationProtocol(): String = delegate!!.applicationProtocol
|
||||
|
||||
override fun getHandshakeApplicationProtocol(): String {
|
||||
return delegate!!.handshakeApplicationProtocol
|
||||
}
|
||||
override fun getHandshakeApplicationProtocol(): String = delegate!!.handshakeApplicationProtocol
|
||||
|
||||
override fun setHandshakeApplicationProtocolSelector(selector: BiFunction<SSLSocket, MutableList<String>, String>?) {
|
||||
delegate!!.handshakeApplicationProtocolSelector = selector
|
||||
}
|
||||
|
||||
override fun getHandshakeApplicationProtocolSelector(): BiFunction<SSLSocket, MutableList<String>, String> {
|
||||
return delegate!!.handshakeApplicationProtocolSelector
|
||||
}
|
||||
override fun getHandshakeApplicationProtocolSelector(): BiFunction<SSLSocket, MutableList<String>, String> =
|
||||
delegate!!.handshakeApplicationProtocolSelector
|
||||
}
|
||||
|
@ -25,7 +25,9 @@ import javax.net.ssl.SSLSocketFactory
|
||||
* A [SSLSocketFactory] that delegates calls. Sockets can be configured after creation by
|
||||
* overriding [.configureSocket].
|
||||
*/
|
||||
open class DelegatingSSLSocketFactory(private val delegate: SSLSocketFactory) : SSLSocketFactory() {
|
||||
open class DelegatingSSLSocketFactory(
|
||||
private val delegate: SSLSocketFactory,
|
||||
) : SSLSocketFactory() {
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(): SSLSocket {
|
||||
val sslSocket = delegate.createSocket() as SSLSocket
|
||||
@ -72,13 +74,9 @@ open class DelegatingSSLSocketFactory(private val delegate: SSLSocketFactory) :
|
||||
return configureSocket(sslSocket)
|
||||
}
|
||||
|
||||
override fun getDefaultCipherSuites(): Array<String> {
|
||||
return delegate.defaultCipherSuites
|
||||
}
|
||||
override fun getDefaultCipherSuites(): Array<String> = delegate.defaultCipherSuites
|
||||
|
||||
override fun getSupportedCipherSuites(): Array<String> {
|
||||
return delegate.supportedCipherSuites
|
||||
}
|
||||
override fun getSupportedCipherSuites(): Array<String> = delegate.supportedCipherSuites
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(
|
||||
|
@ -24,7 +24,9 @@ import javax.net.ServerSocketFactory
|
||||
* A [ServerSocketFactory] that delegates calls. Sockets can be configured after creation by
|
||||
* overriding [.configureServerSocket].
|
||||
*/
|
||||
open class DelegatingServerSocketFactory(private val delegate: ServerSocketFactory) : ServerSocketFactory() {
|
||||
open class DelegatingServerSocketFactory(
|
||||
private val delegate: ServerSocketFactory,
|
||||
) : ServerSocketFactory() {
|
||||
@Throws(IOException::class)
|
||||
override fun createServerSocket(): ServerSocket {
|
||||
val serverSocket = delegate.createServerSocket()
|
||||
|
@ -24,7 +24,9 @@ import javax.net.SocketFactory
|
||||
* A [SocketFactory] that delegates calls. Sockets can be configured after creation by
|
||||
* overriding [.configureSocket].
|
||||
*/
|
||||
open class DelegatingSocketFactory(private val delegate: SocketFactory) : SocketFactory() {
|
||||
open class DelegatingSocketFactory(
|
||||
private val delegate: SocketFactory,
|
||||
) : SocketFactory() {
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(): Socket {
|
||||
val socket = delegate.createSocket()
|
||||
|
@ -45,9 +45,7 @@ class FakeDns : Dns {
|
||||
fun lookup(
|
||||
hostname: String,
|
||||
index: Int,
|
||||
): InetAddress {
|
||||
return hostAddresses[hostname]!![index]
|
||||
}
|
||||
): InetAddress = hostAddresses[hostname]!![index]
|
||||
|
||||
@Throws(UnknownHostException::class)
|
||||
override fun lookup(hostname: String): List<InetAddress> {
|
||||
|
@ -23,101 +23,62 @@ import javax.net.ssl.SSLSession
|
||||
import javax.net.ssl.SSLSessionContext
|
||||
import javax.security.cert.X509Certificate
|
||||
|
||||
class FakeSSLSession(vararg val certificates: Certificate) : SSLSession {
|
||||
override fun getApplicationBufferSize(): Int {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
class FakeSSLSession(
|
||||
vararg val certificates: Certificate,
|
||||
) : SSLSession {
|
||||
override fun getApplicationBufferSize(): Int = throw UnsupportedOperationException()
|
||||
|
||||
override fun getCipherSuite(): String {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun getCipherSuite(): String = throw UnsupportedOperationException()
|
||||
|
||||
override fun getCreationTime(): Long {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun getCreationTime(): Long = throw UnsupportedOperationException()
|
||||
|
||||
override fun getId(): ByteArray {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun getId(): ByteArray = throw UnsupportedOperationException()
|
||||
|
||||
override fun getLastAccessedTime(): Long {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun getLastAccessedTime(): Long = throw UnsupportedOperationException()
|
||||
|
||||
override fun getLocalCertificates(): Array<Certificate> {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun getLocalCertificates(): Array<Certificate> = throw UnsupportedOperationException()
|
||||
|
||||
override fun getLocalPrincipal(): Principal {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun getLocalPrincipal(): Principal = throw UnsupportedOperationException()
|
||||
|
||||
override fun getPacketBufferSize(): Int {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun getPacketBufferSize(): Int = throw UnsupportedOperationException()
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@Throws(SSLPeerUnverifiedException::class)
|
||||
override fun getPeerCertificates(): Array<Certificate> {
|
||||
return if (certificates.isEmpty()) {
|
||||
override fun getPeerCertificates(): Array<Certificate> =
|
||||
if (certificates.isEmpty()) {
|
||||
throw SSLPeerUnverifiedException("peer not authenticated")
|
||||
} else {
|
||||
certificates as Array<Certificate>
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(
|
||||
SSLPeerUnverifiedException::class,
|
||||
)
|
||||
override fun getPeerCertificateChain(): Array<X509Certificate> {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun getPeerCertificateChain(): Array<X509Certificate> = throw UnsupportedOperationException()
|
||||
|
||||
override fun getPeerHost(): String {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun getPeerHost(): String = throw UnsupportedOperationException()
|
||||
|
||||
override fun getPeerPort(): Int {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun getPeerPort(): Int = throw UnsupportedOperationException()
|
||||
|
||||
@Throws(SSLPeerUnverifiedException::class)
|
||||
override fun getPeerPrincipal(): Principal {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun getPeerPrincipal(): Principal = throw UnsupportedOperationException()
|
||||
|
||||
override fun getProtocol(): String {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun getProtocol(): String = throw UnsupportedOperationException()
|
||||
|
||||
override fun getSessionContext(): SSLSessionContext {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun getSessionContext(): SSLSessionContext = throw UnsupportedOperationException()
|
||||
|
||||
override fun putValue(
|
||||
s: String,
|
||||
obj: Any,
|
||||
) {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
): Unit = throw UnsupportedOperationException()
|
||||
|
||||
override fun removeValue(s: String) {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun removeValue(s: String): Unit = throw UnsupportedOperationException()
|
||||
|
||||
override fun getValue(s: String): Any {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun getValue(s: String): Any = throw UnsupportedOperationException()
|
||||
|
||||
override fun getValueNames(): Array<String> {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun getValueNames(): Array<String> = throw UnsupportedOperationException()
|
||||
|
||||
override fun invalidate() {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun invalidate(): Unit = throw UnsupportedOperationException()
|
||||
|
||||
override fun isValid(): Boolean {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun isValid(): Boolean = throw UnsupportedOperationException()
|
||||
}
|
||||
|
@ -18,34 +18,26 @@ package okhttp3
|
||||
import java.io.IOException
|
||||
import okio.BufferedSink
|
||||
|
||||
open class ForwardingRequestBody(delegate: RequestBody?) : RequestBody() {
|
||||
open class ForwardingRequestBody(
|
||||
delegate: RequestBody?,
|
||||
) : RequestBody() {
|
||||
private val delegate: RequestBody
|
||||
|
||||
fun delegate(): RequestBody {
|
||||
return delegate
|
||||
}
|
||||
fun delegate(): RequestBody = delegate
|
||||
|
||||
override fun contentType(): MediaType? {
|
||||
return delegate.contentType()
|
||||
}
|
||||
override fun contentType(): MediaType? = delegate.contentType()
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun contentLength(): Long {
|
||||
return delegate.contentLength()
|
||||
}
|
||||
override fun contentLength(): Long = delegate.contentLength()
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun writeTo(sink: BufferedSink) {
|
||||
delegate.writeTo(sink)
|
||||
}
|
||||
|
||||
override fun isDuplex(): Boolean {
|
||||
return delegate.isDuplex()
|
||||
}
|
||||
override fun isDuplex(): Boolean = delegate.isDuplex()
|
||||
|
||||
override fun toString(): String {
|
||||
return javaClass.simpleName + "(" + delegate.toString() + ")"
|
||||
}
|
||||
override fun toString(): String = javaClass.simpleName + "(" + delegate.toString() + ")"
|
||||
|
||||
init {
|
||||
requireNotNull(delegate) { "delegate == null" }
|
||||
|
@ -17,28 +17,20 @@ package okhttp3
|
||||
|
||||
import okio.BufferedSource
|
||||
|
||||
open class ForwardingResponseBody(delegate: ResponseBody?) : ResponseBody() {
|
||||
open class ForwardingResponseBody(
|
||||
delegate: ResponseBody?,
|
||||
) : ResponseBody() {
|
||||
private val delegate: ResponseBody
|
||||
|
||||
fun delegate(): ResponseBody {
|
||||
return delegate
|
||||
}
|
||||
fun delegate(): ResponseBody = delegate
|
||||
|
||||
override fun contentType(): MediaType? {
|
||||
return delegate.contentType()
|
||||
}
|
||||
override fun contentType(): MediaType? = delegate.contentType()
|
||||
|
||||
override fun contentLength(): Long {
|
||||
return delegate.contentLength()
|
||||
}
|
||||
override fun contentLength(): Long = delegate.contentLength()
|
||||
|
||||
override fun source(): BufferedSource {
|
||||
return delegate.source()
|
||||
}
|
||||
override fun source(): BufferedSource = delegate.source()
|
||||
|
||||
override fun toString(): String {
|
||||
return javaClass.simpleName + "(" + delegate.toString() + ")"
|
||||
}
|
||||
override fun toString(): String = javaClass.simpleName + "(" + delegate.toString() + ")"
|
||||
|
||||
init {
|
||||
requireNotNull(delegate) { "delegate == null" }
|
||||
|
@ -20,7 +20,10 @@ import java.util.logging.Handler
|
||||
import java.util.logging.LogRecord
|
||||
|
||||
object JsseDebugLogging {
|
||||
data class JsseDebugMessage(val message: String, val param: String?) {
|
||||
data class JsseDebugMessage(
|
||||
val message: String,
|
||||
val param: String?,
|
||||
) {
|
||||
enum class Type {
|
||||
Handshake,
|
||||
Plaintext,
|
||||
@ -47,13 +50,12 @@ object JsseDebugLogging {
|
||||
else -> Type.Unknown
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return if (param != null) {
|
||||
override fun toString(): String =
|
||||
if (param != null) {
|
||||
message + "\n" + param
|
||||
} else {
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun quietDebug(message: JsseDebugMessage) {
|
||||
|
@ -47,7 +47,9 @@ import org.junit.jupiter.api.extension.ExtensionContext
|
||||
* Use [newClient] as a factory for a OkHttpClient instances. These instances are specifically
|
||||
* configured for testing.
|
||||
*/
|
||||
class OkHttpClientTestRule : BeforeEachCallback, AfterEachCallback {
|
||||
class OkHttpClientTestRule :
|
||||
BeforeEachCallback,
|
||||
AfterEachCallback {
|
||||
private val clientEventsList = mutableListOf<String>()
|
||||
private var testClient: OkHttpClient? = null
|
||||
private var uncaughtException: Throwable? = null
|
||||
@ -160,35 +162,33 @@ class OkHttpClientTestRule : BeforeEachCallback, AfterEachCallback {
|
||||
val backend = TaskRunner.RealBackend(loomThreadFactory())
|
||||
val taskRunner = TaskRunner(backend)
|
||||
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.connectionPool(
|
||||
buildConnectionPool(
|
||||
connectionListener = connectionListener,
|
||||
taskRunner = taskRunner,
|
||||
),
|
||||
)
|
||||
.dispatcher(Dispatcher(backend.executor))
|
||||
).dispatcher(Dispatcher(backend.executor))
|
||||
.taskRunnerInternal(taskRunner)
|
||||
} else {
|
||||
OkHttpClient.Builder()
|
||||
OkHttpClient
|
||||
.Builder()
|
||||
.connectionPool(ConnectionPool(connectionListener = connectionListener))
|
||||
}
|
||||
|
||||
private fun loomThreadFactory(): ThreadFactory {
|
||||
val ofVirtual = Thread::class.java.getMethod("ofVirtual").invoke(null)
|
||||
|
||||
return Class.forName("java.lang.Thread\$Builder")
|
||||
return Class
|
||||
.forName("java.lang.Thread\$Builder")
|
||||
.getMethod("factory")
|
||||
.invoke(ofVirtual) as ThreadFactory
|
||||
}
|
||||
|
||||
private fun isLoom(): Boolean {
|
||||
return getPlatformSystemProperty() == LOOM_PROPERTY
|
||||
}
|
||||
private fun isLoom(): Boolean = getPlatformSystemProperty() == LOOM_PROPERTY
|
||||
|
||||
fun newClientBuilder(): OkHttpClient.Builder {
|
||||
return newClient().newBuilder()
|
||||
}
|
||||
fun newClientBuilder(): OkHttpClient.Builder = newClient().newBuilder()
|
||||
|
||||
@Synchronized private fun addEvent(event: String) {
|
||||
if (recordEvents) {
|
||||
@ -302,10 +302,9 @@ class OkHttpClientTestRule : BeforeEachCallback, AfterEachCallback {
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private fun ExtensionContext.isFlaky(): Boolean {
|
||||
return (testMethod.orElseGet { null }?.isAnnotationPresent(Flaky::class.java) == true) ||
|
||||
private fun ExtensionContext.isFlaky(): Boolean =
|
||||
(testMethod.orElseGet { null }?.isAnnotationPresent(Flaky::class.java) == true) ||
|
||||
(testClass.orElseGet { null }?.isAnnotationPresent(Flaky::class.java) == true)
|
||||
}
|
||||
|
||||
@Synchronized private fun logEvents() {
|
||||
// Will be ineffective if test overrides the listener
|
||||
@ -318,9 +317,7 @@ class OkHttpClientTestRule : BeforeEachCallback, AfterEachCallback {
|
||||
}
|
||||
}
|
||||
|
||||
fun recordedConnectionEventTypes(): List<String> {
|
||||
return connectionListener.recordedEventTypes()
|
||||
}
|
||||
fun recordedConnectionEventTypes(): List<String> = connectionListener.recordedEventTypes()
|
||||
|
||||
companion object {
|
||||
/**
|
||||
|
@ -87,10 +87,10 @@ open class RecordingConnectionListener(
|
||||
|
||||
if (elapsedMs != -1L) {
|
||||
assertThat(
|
||||
TimeUnit.NANOSECONDS.toMillis(actualElapsedNs)
|
||||
TimeUnit.NANOSECONDS
|
||||
.toMillis(actualElapsedNs)
|
||||
.toDouble(),
|
||||
)
|
||||
.isCloseTo(elapsedMs.toDouble(), 100.0)
|
||||
).isCloseTo(elapsedMs.toDouble(), 100.0)
|
||||
}
|
||||
|
||||
return result
|
||||
|
@ -28,9 +28,7 @@ class RecordingCookieJar : CookieJar {
|
||||
requestCookies.add(cookies.toList())
|
||||
}
|
||||
|
||||
fun takeResponseCookies(): List<Cookie> {
|
||||
return responseCookies.removeFirst()
|
||||
}
|
||||
fun takeResponseCookies(): List<Cookie> = responseCookies.removeFirst()
|
||||
|
||||
fun assertResponseCookies(vararg cookies: String?) {
|
||||
assertThat(takeResponseCookies().map(Cookie::toString)).containsExactly(*cookies)
|
||||
@ -43,7 +41,5 @@ class RecordingCookieJar : CookieJar {
|
||||
responseCookies.add(cookies)
|
||||
}
|
||||
|
||||
override fun loadForRequest(url: HttpUrl): List<Cookie> {
|
||||
return if (requestCookies.isEmpty()) emptyList() else requestCookies.removeFirst()
|
||||
}
|
||||
override fun loadForRequest(url: HttpUrl): List<Cookie> = if (requestCookies.isEmpty()) emptyList() else requestCookies.removeFirst()
|
||||
}
|
||||
|
@ -97,9 +97,7 @@ open class RecordingEventListener(
|
||||
|
||||
inline fun <reified T : CallEvent> removeUpToEvent(): T = removeUpToEvent(T::class.java)
|
||||
|
||||
inline fun <reified T : CallEvent> findEvent(): T {
|
||||
return eventSequence.first { it is T } as T
|
||||
}
|
||||
inline fun <reified T : CallEvent> findEvent(): T = eventSequence.first { it is T } as T
|
||||
|
||||
/**
|
||||
* Remove and return the next event from the recorded sequence.
|
||||
@ -123,10 +121,10 @@ open class RecordingEventListener(
|
||||
|
||||
if (elapsedMs != -1L) {
|
||||
assertThat(
|
||||
TimeUnit.NANOSECONDS.toMillis(actualElapsedNs)
|
||||
TimeUnit.NANOSECONDS
|
||||
.toMillis(actualElapsedNs)
|
||||
.toDouble(),
|
||||
)
|
||||
.isCloseTo(elapsedMs.toDouble(), 100.0)
|
||||
).isCloseTo(elapsedMs.toDouble(), 100.0)
|
||||
}
|
||||
|
||||
return result
|
||||
|
@ -37,8 +37,8 @@ class SpecificHostSocketFactory(
|
||||
hostMapping[requested] = real
|
||||
}
|
||||
|
||||
override fun createSocket(): Socket {
|
||||
return object : Socket() {
|
||||
override fun createSocket(): Socket =
|
||||
object : Socket() {
|
||||
override fun connect(
|
||||
endpoint: SocketAddress?,
|
||||
timeout: Int,
|
||||
@ -49,5 +49,4 @@ class SpecificHostSocketFactory(
|
||||
super.connect(inetSocketAddress, timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,9 +36,7 @@ object TestUtil {
|
||||
@JvmStatic val isGraalVmImage = System.getProperty("org.graalvm.nativeimage.imagecode") != null
|
||||
|
||||
@JvmStatic
|
||||
fun headerEntries(vararg elements: String?): List<Header> {
|
||||
return List(elements.size / 2) { Header(elements[it * 2]!!, elements[it * 2 + 1]!!) }
|
||||
}
|
||||
fun headerEntries(vararg elements: String?): List<Header> = List(elements.size / 2) { Header(elements[it * 2]!!, elements[it * 2 + 1]!!) }
|
||||
|
||||
@JvmStatic
|
||||
fun repeat(
|
||||
@ -125,15 +123,12 @@ object TestUtil {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun threadFactory(name: String): ThreadFactory {
|
||||
return object : ThreadFactory {
|
||||
fun threadFactory(name: String): ThreadFactory =
|
||||
object : ThreadFactory {
|
||||
private var nextId = 1
|
||||
|
||||
override fun newThread(runnable: Runnable): Thread {
|
||||
return Thread(runnable, "$name-${nextId++}")
|
||||
}
|
||||
override fun newThread(runnable: Runnable): Thread = Thread(runnable, "$name-${nextId++}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getEnv(name: String) = System.getenv(name)
|
||||
|
@ -102,8 +102,8 @@ class TestValueFactory : Closeable {
|
||||
taskRunner: TaskRunner = this.taskRunner,
|
||||
maxIdleConnections: Int = Int.MAX_VALUE,
|
||||
routePlanner: RoutePlanner? = null,
|
||||
): RealConnectionPool {
|
||||
return RealConnectionPool(
|
||||
): RealConnectionPool =
|
||||
RealConnectionPool(
|
||||
taskRunner = taskRunner,
|
||||
maxIdleConnections = maxIdleConnections,
|
||||
keepAliveDuration = 100L,
|
||||
@ -129,7 +129,6 @@ class TestValueFactory : Closeable {
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/** Returns an address that's without an SSL socket factory or hostname verifier. */
|
||||
fun newAddress(
|
||||
@ -137,8 +136,8 @@ class TestValueFactory : Closeable {
|
||||
uriPort: Int = this.uriPort,
|
||||
proxy: Proxy? = null,
|
||||
proxySelector: ProxySelector = this.proxySelector,
|
||||
): Address {
|
||||
return Address(
|
||||
): Address =
|
||||
Address(
|
||||
uriHost = uriHost,
|
||||
uriPort = uriPort,
|
||||
dns = dns,
|
||||
@ -152,7 +151,6 @@ class TestValueFactory : Closeable {
|
||||
connectionSpecs = connectionSpecs,
|
||||
proxySelector = proxySelector,
|
||||
)
|
||||
}
|
||||
|
||||
fun newHttpsAddress(
|
||||
uriHost: String = this.uriHost,
|
||||
@ -161,8 +159,8 @@ class TestValueFactory : Closeable {
|
||||
proxySelector: ProxySelector = this.proxySelector,
|
||||
sslSocketFactory: SSLSocketFactory? = this.sslSocketFactory,
|
||||
hostnameVerifier: HostnameVerifier? = this.hostnameVerifier,
|
||||
): Address {
|
||||
return Address(
|
||||
): Address =
|
||||
Address(
|
||||
uriHost = uriHost,
|
||||
uriPort = uriPort,
|
||||
dns = dns,
|
||||
@ -176,22 +174,20 @@ class TestValueFactory : Closeable {
|
||||
connectionSpecs = connectionSpecs,
|
||||
proxySelector = proxySelector,
|
||||
)
|
||||
}
|
||||
|
||||
fun newRoute(
|
||||
address: Address = newAddress(),
|
||||
proxy: Proxy = this.proxy,
|
||||
socketAddress: InetSocketAddress = InetSocketAddress.createUnresolved(uriHost, uriPort),
|
||||
): Route {
|
||||
return Route(
|
||||
): Route =
|
||||
Route(
|
||||
address = address,
|
||||
proxy = proxy,
|
||||
socketAddress = socketAddress,
|
||||
)
|
||||
}
|
||||
|
||||
fun newChain(call: RealCall): RealInterceptorChain {
|
||||
return RealInterceptorChain(
|
||||
fun newChain(call: RealCall): RealInterceptorChain =
|
||||
RealInterceptorChain(
|
||||
call = call,
|
||||
interceptors = listOf(),
|
||||
index = 0,
|
||||
@ -201,7 +197,6 @@ class TestValueFactory : Closeable {
|
||||
readTimeoutMillis = 10_000,
|
||||
writeTimeoutMillis = 10_000,
|
||||
)
|
||||
}
|
||||
|
||||
fun newRoutePlanner(
|
||||
client: OkHttpClient,
|
||||
|
@ -26,9 +26,7 @@ import okio.buffer
|
||||
/** Rewrites the request body sent to the server to be all uppercase. */
|
||||
class UppercaseRequestInterceptor : Interceptor {
|
||||
@Throws(IOException::class)
|
||||
override fun intercept(chain: Chain): Response {
|
||||
return chain.proceed(uppercaseRequest(chain.request()))
|
||||
}
|
||||
override fun intercept(chain: Chain): Response = chain.proceed(uppercaseRequest(chain.request()))
|
||||
|
||||
/** Returns a request that transforms `request` to be all uppercase. */
|
||||
private fun uppercaseRequest(request: Request): Request {
|
||||
@ -39,13 +37,14 @@ class UppercaseRequestInterceptor : Interceptor {
|
||||
delegate().writeTo(uppercaseSink(sink).buffer())
|
||||
}
|
||||
}
|
||||
return request.newBuilder()
|
||||
return request
|
||||
.newBuilder()
|
||||
.method(request.method, uppercaseBody)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun uppercaseSink(sink: Sink): Sink {
|
||||
return object : ForwardingSink(sink) {
|
||||
private fun uppercaseSink(sink: Sink): Sink =
|
||||
object : ForwardingSink(sink) {
|
||||
@Throws(IOException::class)
|
||||
override fun write(
|
||||
source: Buffer,
|
||||
@ -59,5 +58,4 @@ class UppercaseRequestInterceptor : Interceptor {
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,18 +25,15 @@ import okio.buffer
|
||||
/** Rewrites the response body returned from the server to be all uppercase. */
|
||||
class UppercaseResponseInterceptor : Interceptor {
|
||||
@Throws(IOException::class)
|
||||
override fun intercept(chain: Chain): Response {
|
||||
return uppercaseResponse(chain.proceed(chain.request()))
|
||||
}
|
||||
override fun intercept(chain: Chain): Response = uppercaseResponse(chain.proceed(chain.request()))
|
||||
|
||||
private fun uppercaseResponse(response: Response): Response {
|
||||
val uppercaseBody: ResponseBody =
|
||||
object : ForwardingResponseBody(response.body) {
|
||||
override fun source(): BufferedSource {
|
||||
return uppercaseSource(delegate().source()).buffer()
|
||||
}
|
||||
override fun source(): BufferedSource = uppercaseSource(delegate().source()).buffer()
|
||||
}
|
||||
return response.newBuilder()
|
||||
return response
|
||||
.newBuilder()
|
||||
.body(uppercaseBody)
|
||||
.build()
|
||||
}
|
||||
|
@ -46,7 +46,8 @@ class RecordingOkAuthenticator(
|
||||
407 -> "Proxy-Authorization"
|
||||
else -> "Authorization"
|
||||
}
|
||||
return response.request.newBuilder()
|
||||
return response.request
|
||||
.newBuilder()
|
||||
.addHeader(header, credential)
|
||||
.build()
|
||||
}
|
||||
|
@ -349,7 +349,8 @@ class TaskFaker : Closeable {
|
||||
*/
|
||||
private inner class TaskFakerBlockingQueue<T>(
|
||||
val delegate: BlockingQueue<T>,
|
||||
) : AbstractQueue<T>(), BlockingQueue<T> {
|
||||
) : AbstractQueue<T>(),
|
||||
BlockingQueue<T> {
|
||||
override val size: Int = delegate.size
|
||||
|
||||
private var editCount = 0
|
||||
|
@ -36,9 +36,7 @@ class AsyncRequestBody : RequestBody() {
|
||||
override fun isDuplex(): Boolean = true
|
||||
|
||||
@Throws(InterruptedException::class)
|
||||
fun takeSink(): BufferedSink {
|
||||
return requestBodySinks.poll(5, SECONDS) ?: throw AssertionError("no sink to take")
|
||||
}
|
||||
fun takeSink(): BufferedSink = requestBodySinks.poll(5, SECONDS) ?: throw AssertionError("no sink to take")
|
||||
|
||||
fun assertNoMoreSinks() {
|
||||
assertTrue(requestBodySinks.isEmpty())
|
||||
|
@ -21,7 +21,9 @@ import okhttp3.internal.http2.flowcontrol.WindowCounter
|
||||
/**
|
||||
* ConnectionListener that outputs CSV for flow control of client receiving streams.
|
||||
*/
|
||||
class Http2FlowControlConnectionListener : ConnectionListener(), FlowControlListener {
|
||||
class Http2FlowControlConnectionListener :
|
||||
ConnectionListener(),
|
||||
FlowControlListener {
|
||||
val start = System.currentTimeMillis()
|
||||
|
||||
override fun receivingStreamWindowChanged(
|
||||
|
@ -21,7 +21,9 @@ import okio.Path
|
||||
import okio.Sink
|
||||
import okio.Source
|
||||
|
||||
class LoggingFilesystem(fileSystem: FileSystem) : ForwardingFileSystem(fileSystem) {
|
||||
class LoggingFilesystem(
|
||||
fileSystem: FileSystem,
|
||||
) : ForwardingFileSystem(fileSystem) {
|
||||
fun log(line: String) {
|
||||
println(line)
|
||||
}
|
||||
|
@ -62,7 +62,9 @@ open class PlatformRule
|
||||
constructor(
|
||||
val requiredPlatformName: String? = null,
|
||||
val platform: Platform? = null,
|
||||
) : BeforeEachCallback, AfterEachCallback, InvocationInterceptor {
|
||||
) : BeforeEachCallback,
|
||||
AfterEachCallback,
|
||||
InvocationInterceptor {
|
||||
private val versionChecks = mutableListOf<Pair<Matcher<out Any>, Matcher<out Any>>>()
|
||||
|
||||
override fun beforeEach(context: ExtensionContext) {
|
||||
@ -157,34 +159,26 @@ open class PlatformRule
|
||||
description.appendText(platform)
|
||||
}
|
||||
|
||||
override fun matches(item: Any?): Boolean {
|
||||
return getPlatformSystemProperty() == platform
|
||||
}
|
||||
override fun matches(item: Any?): Boolean = getPlatformSystemProperty() == platform
|
||||
}
|
||||
|
||||
fun fromMajor(version: Int): Matcher<PlatformVersion> {
|
||||
return object : TypeSafeMatcher<PlatformVersion>() {
|
||||
fun fromMajor(version: Int): Matcher<PlatformVersion> =
|
||||
object : TypeSafeMatcher<PlatformVersion>() {
|
||||
override fun describeTo(description: Description) {
|
||||
description.appendText("JDK with version from $version")
|
||||
}
|
||||
|
||||
override fun matchesSafely(item: PlatformVersion): Boolean {
|
||||
return item.majorVersion >= version
|
||||
}
|
||||
override fun matchesSafely(item: PlatformVersion): Boolean = item.majorVersion >= version
|
||||
}
|
||||
}
|
||||
|
||||
fun onMajor(version: Int): Matcher<PlatformVersion> {
|
||||
return object : TypeSafeMatcher<PlatformVersion>() {
|
||||
fun onMajor(version: Int): Matcher<PlatformVersion> =
|
||||
object : TypeSafeMatcher<PlatformVersion>() {
|
||||
override fun describeTo(description: Description) {
|
||||
description.appendText("JDK with version $version")
|
||||
}
|
||||
|
||||
override fun matchesSafely(item: PlatformVersion): Boolean {
|
||||
return item.majorVersion == version
|
||||
}
|
||||
override fun matchesSafely(item: PlatformVersion): Boolean = item.majorVersion == version
|
||||
}
|
||||
}
|
||||
|
||||
fun rethrowIfNotExpected(e: Throwable) {
|
||||
versionChecks.forEach { (versionMatcher, failureMatcher) ->
|
||||
@ -336,20 +330,18 @@ open class PlatformRule
|
||||
assumeTrue(PlatformVersion.majorVersion == majorVersion)
|
||||
}
|
||||
|
||||
fun androidSdkVersion(): Int? {
|
||||
return if (Platform.isAndroid) {
|
||||
fun androidSdkVersion(): Int? =
|
||||
if (Platform.isAndroid) {
|
||||
Build.VERSION.SDK_INT
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun localhostHandshakeCertificates(): HandshakeCertificates {
|
||||
return when {
|
||||
fun localhostHandshakeCertificates(): HandshakeCertificates =
|
||||
when {
|
||||
isBouncyCastle() -> localhostHandshakeCertificatesWithRsa2048
|
||||
else -> localhost()
|
||||
}
|
||||
}
|
||||
|
||||
val isAndroid: Boolean
|
||||
get() = Platform.Companion.isAndroid
|
||||
@ -373,12 +365,14 @@ open class PlatformRule
|
||||
*/
|
||||
private val localhostHandshakeCertificatesWithRsa2048: HandshakeCertificates by lazy {
|
||||
val heldCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.commonName("localhost")
|
||||
.addSubjectAlternativeName("localhost")
|
||||
.rsa2048()
|
||||
.build()
|
||||
return@lazy HandshakeCertificates.Builder()
|
||||
return@lazy HandshakeCertificates
|
||||
.Builder()
|
||||
.heldCertificate(heldCertificate)
|
||||
.addTrustedCertificate(heldCertificate.certificate)
|
||||
.build()
|
||||
@ -398,7 +392,8 @@ open class PlatformRule
|
||||
}
|
||||
|
||||
val provider =
|
||||
Conscrypt.newProviderBuilder()
|
||||
Conscrypt
|
||||
.newProviderBuilder()
|
||||
.provideTrustManager(true)
|
||||
.build()
|
||||
Security.insertProviderAt(provider, 1)
|
||||
@ -499,7 +494,10 @@ open class PlatformRule
|
||||
}
|
||||
|
||||
val isCorrettoInstalled: Boolean =
|
||||
isCorrettoSupported && Security.getProviders()
|
||||
.first().name == AmazonCorrettoCryptoProvider.PROVIDER_NAME
|
||||
isCorrettoSupported &&
|
||||
Security
|
||||
.getProviders()
|
||||
.first()
|
||||
.name == AmazonCorrettoCryptoProvider.PROVIDER_NAME
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,5 @@ object PlatformVersion {
|
||||
}
|
||||
}
|
||||
|
||||
fun getJvmSpecVersion(): String {
|
||||
return System.getProperty("java.specification.version", "unknown")
|
||||
}
|
||||
fun getJvmSpecVersion(): String = System.getProperty("java.specification.version", "unknown")
|
||||
}
|
||||
|
@ -38,9 +38,7 @@ class OkHttpClientTestRuleTest {
|
||||
|
||||
val thread =
|
||||
object : Thread() {
|
||||
override fun run() {
|
||||
throw RuntimeException("boom!")
|
||||
}
|
||||
override fun run(): Unit = throw RuntimeException("boom!")
|
||||
}
|
||||
thread.start()
|
||||
thread.join()
|
||||
|
@ -66,13 +66,12 @@ fun String.decodeCertificatePem(): X509Certificate {
|
||||
*
|
||||
* [rfc_7468]: https://tools.ietf.org/html/rfc7468
|
||||
*/
|
||||
fun X509Certificate.certificatePem(): String {
|
||||
return buildString {
|
||||
fun X509Certificate.certificatePem(): String =
|
||||
buildString {
|
||||
append("-----BEGIN CERTIFICATE-----\n")
|
||||
encodeBase64Lines(encoded.toByteString())
|
||||
append("-----END CERTIFICATE-----\n")
|
||||
}
|
||||
}
|
||||
|
||||
internal fun StringBuilder.encodeBase64Lines(data: ByteString) {
|
||||
val base64 = data.base64()
|
||||
|
@ -93,11 +93,10 @@ class HandshakeCertificates private constructor(
|
||||
|
||||
fun sslSocketFactory(): SSLSocketFactory = sslContext().socketFactory
|
||||
|
||||
fun sslContext(): SSLContext {
|
||||
return Platform.get().newSSLContext().apply {
|
||||
fun sslContext(): SSLContext =
|
||||
Platform.get().newSSLContext().apply {
|
||||
init(arrayOf<KeyManager>(keyManager), arrayOf<TrustManager>(trustManager), SecureRandom())
|
||||
}
|
||||
}
|
||||
|
||||
class Builder {
|
||||
private var heldCertificate: HeldCertificate? = null
|
||||
|
@ -159,13 +159,12 @@ class HeldCertificate(
|
||||
* [rfc_5208]: https://tools.ietf.org/html/rfc5208
|
||||
* [rfc_7468]: https://tools.ietf.org/html/rfc7468
|
||||
*/
|
||||
fun privateKeyPkcs8Pem(): String {
|
||||
return buildString {
|
||||
fun privateKeyPkcs8Pem(): String =
|
||||
buildString {
|
||||
append("-----BEGIN PRIVATE KEY-----\n")
|
||||
encodeBase64Lines(keyPair.private.encoded.toByteString())
|
||||
append("-----END PRIVATE KEY-----\n")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the RSA private key encoded in [PKCS #1][rfc_8017] [PEM format][rfc_7468].
|
||||
@ -358,7 +357,9 @@ class HeldCertificate(
|
||||
issuerKeyPair = signedBy!!.keyPair
|
||||
issuer =
|
||||
CertificateAdapters.rdnSequence.fromDer(
|
||||
signedBy!!.certificate.subjectX500Principal.encoded.toByteString(),
|
||||
signedBy!!
|
||||
.certificate.subjectX500Principal.encoded
|
||||
.toByteString(),
|
||||
)
|
||||
} else {
|
||||
issuerKeyPair = subjectKeyPair
|
||||
@ -477,8 +478,8 @@ class HeldCertificate(
|
||||
return result
|
||||
}
|
||||
|
||||
private fun signatureAlgorithm(signedByKeyPair: KeyPair): AlgorithmIdentifier {
|
||||
return when (signedByKeyPair.private) {
|
||||
private fun signatureAlgorithm(signedByKeyPair: KeyPair): AlgorithmIdentifier =
|
||||
when (signedByKeyPair.private) {
|
||||
is RSAPrivateKey ->
|
||||
AlgorithmIdentifier(
|
||||
algorithm = SHA256_WITH_RSA_ENCRYPTION,
|
||||
@ -490,14 +491,12 @@ class HeldCertificate(
|
||||
parameters = ByteString.EMPTY,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateKeyPair(): KeyPair {
|
||||
return KeyPairGenerator.getInstance(keyAlgorithm).run {
|
||||
private fun generateKeyPair(): KeyPair =
|
||||
KeyPairGenerator.getInstance(keyAlgorithm).run {
|
||||
initialize(keySize, SecureRandom())
|
||||
generateKeyPair()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val DEFAULT_DURATION_MILLIS = 1000L * 60 * 60 * 24 // 24 hours.
|
||||
|
@ -35,12 +35,14 @@ object TlsUtil {
|
||||
private val localhost: HandshakeCertificates by lazy {
|
||||
// Generate a self-signed cert for the server to serve and the client to trust.
|
||||
val heldCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.commonName("localhost")
|
||||
.addSubjectAlternativeName("localhost")
|
||||
.addSubjectAlternativeName("localhost.localdomain")
|
||||
.build()
|
||||
return@lazy HandshakeCertificates.Builder()
|
||||
return@lazy HandshakeCertificates
|
||||
.Builder()
|
||||
.heldCertificate(heldCertificate)
|
||||
.addTrustedCertificate(heldCertificate.certificate)
|
||||
.build()
|
||||
@ -110,10 +112,9 @@ object TlsUtil {
|
||||
return result[0] as X509KeyManager
|
||||
}
|
||||
|
||||
private fun newEmptyKeyStore(keyStoreType: String?): KeyStore {
|
||||
return KeyStore.getInstance(keyStoreType ?: KeyStore.getDefaultType()).apply {
|
||||
private fun newEmptyKeyStore(keyStoreType: String?): KeyStore =
|
||||
KeyStore.getInstance(keyStoreType ?: KeyStore.getDefaultType()).apply {
|
||||
val inputStream: InputStream? = null // By convention, 'null' creates an empty key store.
|
||||
load(inputStream, password)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,9 +42,7 @@ internal object CertificateAdapters {
|
||||
*/
|
||||
internal val time: DerAdapter<Long> =
|
||||
object : DerAdapter<Long> {
|
||||
override fun matches(header: DerHeader): Boolean {
|
||||
return Adapters.UTC_TIME.matches(header) || Adapters.GENERALIZED_TIME.matches(header)
|
||||
}
|
||||
override fun matches(header: DerHeader): Boolean = Adapters.UTC_TIME.matches(header) || Adapters.GENERALIZED_TIME.matches(header)
|
||||
|
||||
override fun fromDer(reader: DerReader): Long {
|
||||
val peekHeader =
|
||||
@ -215,17 +213,18 @@ internal object CertificateAdapters {
|
||||
* that follows.
|
||||
*/
|
||||
private val extensionValue: BasicDerAdapter<Any?> =
|
||||
Adapters.usingTypeHint { typeHint ->
|
||||
when (typeHint) {
|
||||
ObjectIdentifiers.SUBJECT_ALTERNATIVE_NAME -> subjectAlternativeName
|
||||
ObjectIdentifiers.BASIC_CONSTRAINTS -> basicConstraints
|
||||
else -> null
|
||||
}
|
||||
}.withExplicitBox(
|
||||
tagClass = Adapters.OCTET_STRING.tagClass,
|
||||
tag = Adapters.OCTET_STRING.tag,
|
||||
forceConstructed = false,
|
||||
)
|
||||
Adapters
|
||||
.usingTypeHint { typeHint ->
|
||||
when (typeHint) {
|
||||
ObjectIdentifiers.SUBJECT_ALTERNATIVE_NAME -> subjectAlternativeName
|
||||
ObjectIdentifiers.BASIC_CONSTRAINTS -> basicConstraints
|
||||
else -> null
|
||||
}
|
||||
}.withExplicitBox(
|
||||
tagClass = Adapters.OCTET_STRING.tagClass,
|
||||
tag = Adapters.OCTET_STRING.tag,
|
||||
forceConstructed = false,
|
||||
)
|
||||
|
||||
/**
|
||||
* ```
|
||||
|
@ -135,11 +135,10 @@ internal interface DerAdapter<T> {
|
||||
}
|
||||
|
||||
/** Returns an adapter that returns a set of values of this type. */
|
||||
fun asSetOf(): BasicDerAdapter<List<T>> {
|
||||
return asSequenceOf(
|
||||
fun asSetOf(): BasicDerAdapter<List<T>> =
|
||||
asSequenceOf(
|
||||
name = "SET OF",
|
||||
tagClass = DerHeader.TAG_CLASS_UNIVERSAL,
|
||||
tag = 17L,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,9 @@ import okio.buffer
|
||||
* [x690]: https://www.itu.int/rec/T-REC-X.690
|
||||
* [asn1_and_der]: https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/
|
||||
*/
|
||||
internal class DerReader(source: Source) {
|
||||
internal class DerReader(
|
||||
source: Source,
|
||||
) {
|
||||
private val countingSource: CountingSource = CountingSource(source)
|
||||
private val source: BufferedSource = countingSource.buffer()
|
||||
|
||||
@ -312,9 +314,7 @@ internal class DerReader(source: Source) {
|
||||
}
|
||||
|
||||
/** Read a value as bytes without interpretation of its contents. */
|
||||
fun readUnknown(): ByteString {
|
||||
return source.readByteString(bytesLeft)
|
||||
}
|
||||
fun readUnknown(): ByteString = source.readByteString(bytesLeft)
|
||||
|
||||
override fun toString(): String = path.joinToString(separator = " / ")
|
||||
|
||||
@ -334,7 +334,9 @@ internal class DerReader(source: Source) {
|
||||
}
|
||||
|
||||
/** A source that keeps track of how many bytes it's consumed. */
|
||||
private class CountingSource(source: Source) : ForwardingSource(source) {
|
||||
private class CountingSource(
|
||||
source: Source,
|
||||
) : ForwardingSource(source) {
|
||||
var bytesRead = 0L
|
||||
|
||||
override fun read(
|
||||
|
@ -20,7 +20,9 @@ import okio.Buffer
|
||||
import okio.BufferedSink
|
||||
import okio.ByteString
|
||||
|
||||
internal class DerWriter(sink: BufferedSink) {
|
||||
internal class DerWriter(
|
||||
sink: BufferedSink,
|
||||
) {
|
||||
/** A stack of buffers that will be concatenated once we know the length of each. */
|
||||
private val stack = mutableListOf(sink)
|
||||
|
||||
|
@ -61,38 +61,46 @@ class HandshakeCertificatesTest {
|
||||
platform.assumeNotBouncyCastle()
|
||||
|
||||
val clientRoot =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(1)
|
||||
.build()
|
||||
val clientIntermediate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(0)
|
||||
.signedBy(clientRoot)
|
||||
.build()
|
||||
val clientCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.signedBy(clientIntermediate)
|
||||
.build()
|
||||
val serverRoot =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(1)
|
||||
.build()
|
||||
val serverIntermediate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(0)
|
||||
.signedBy(serverRoot)
|
||||
.build()
|
||||
val serverCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.signedBy(serverIntermediate)
|
||||
.build()
|
||||
val server =
|
||||
HandshakeCertificates.Builder()
|
||||
HandshakeCertificates
|
||||
.Builder()
|
||||
.addTrustedCertificate(clientRoot.certificate)
|
||||
.heldCertificate(serverCertificate, serverIntermediate.certificate)
|
||||
.build()
|
||||
val client =
|
||||
HandshakeCertificates.Builder()
|
||||
HandshakeCertificates
|
||||
.Builder()
|
||||
.addTrustedCertificate(serverRoot.certificate)
|
||||
.heldCertificate(clientCertificate, clientIntermediate.certificate)
|
||||
.build()
|
||||
@ -113,20 +121,24 @@ class HandshakeCertificatesTest {
|
||||
|
||||
@Test fun keyManager() {
|
||||
val root =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(1)
|
||||
.build()
|
||||
val intermediate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(0)
|
||||
.signedBy(root)
|
||||
.build()
|
||||
val certificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.signedBy(intermediate)
|
||||
.build()
|
||||
val handshakeCertificates =
|
||||
HandshakeCertificates.Builder()
|
||||
HandshakeCertificates
|
||||
.Builder()
|
||||
.addTrustedCertificate(root.certificate) // BouncyCastle requires at least one
|
||||
.heldCertificate(certificate, intermediate.certificate)
|
||||
.build()
|
||||
@ -140,7 +152,8 @@ class HandshakeCertificatesTest {
|
||||
|
||||
@Test fun platformTrustedCertificates() {
|
||||
val handshakeCertificates =
|
||||
HandshakeCertificates.Builder()
|
||||
HandshakeCertificates
|
||||
.Builder()
|
||||
.addPlatformTrustedCertificates()
|
||||
.build()
|
||||
val acceptedIssuers = handshakeCertificates.trustManager.acceptedIssuers
|
||||
|
@ -60,7 +60,8 @@ class HeldCertificateTest {
|
||||
fun customInterval() {
|
||||
// 5 seconds starting on 1970-01-01.
|
||||
val heldCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.validityInterval(5000L, 10000L)
|
||||
.build()
|
||||
val certificate = heldCertificate.certificate
|
||||
@ -72,7 +73,8 @@ class HeldCertificateTest {
|
||||
fun customDuration() {
|
||||
val now = System.currentTimeMillis()
|
||||
val heldCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.duration(5, TimeUnit.SECONDS)
|
||||
.build()
|
||||
val certificate = heldCertificate.certificate
|
||||
@ -87,7 +89,8 @@ class HeldCertificateTest {
|
||||
@Test
|
||||
fun subjectAlternativeNames() {
|
||||
val heldCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.addSubjectAlternativeName("1.1.1.1")
|
||||
.addSubjectAlternativeName("cash.app")
|
||||
.build()
|
||||
@ -101,7 +104,8 @@ class HeldCertificateTest {
|
||||
@Test
|
||||
fun commonName() {
|
||||
val heldCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.commonName("cash.app")
|
||||
.build()
|
||||
val certificate = heldCertificate.certificate
|
||||
@ -111,7 +115,8 @@ class HeldCertificateTest {
|
||||
@Test
|
||||
fun organizationalUnit() {
|
||||
val heldCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.commonName("cash.app")
|
||||
.organizationalUnit("cash")
|
||||
.build()
|
||||
@ -130,8 +135,7 @@ class HeldCertificateTest {
|
||||
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCApFHhtrLan28q+oMolZuaTfWBA0V5aM" +
|
||||
"Ivq32BsloQu6LlvX1wJ4YEoUCjDlPOtpht7XLbUmBnbIzN89XK4UJVM6Sqp3K88Km8z7gMrdrfTom/274wL25fICR+" +
|
||||
"yDEQ5fUVYBmJAKXZF1aoI0mIoEx0xFsQhIJ637v2MxJDupd61wIDAQAB"
|
||||
)
|
||||
.decodeBase64()!!
|
||||
).decodeBase64()!!
|
||||
val publicKey =
|
||||
keyFactory.generatePublic(
|
||||
X509EncodedKeySpec(publicKeyBytes.toByteArray()),
|
||||
@ -154,7 +158,8 @@ class HeldCertificateTest {
|
||||
PKCS8EncodedKeySpec(privateKeyBytes.toByteArray()),
|
||||
)
|
||||
val heldCertificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.keyPair(publicKey, privateKey)
|
||||
.commonName("cash.app")
|
||||
.validityInterval(0L, 1000L)
|
||||
@ -222,12 +227,14 @@ class HeldCertificateTest {
|
||||
@Test
|
||||
fun ecdsaSignedByRsa() {
|
||||
val root =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(0)
|
||||
.rsa2048()
|
||||
.build()
|
||||
val leaf =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(0)
|
||||
.ecdsa256()
|
||||
.signedBy(root)
|
||||
@ -239,12 +246,14 @@ class HeldCertificateTest {
|
||||
@Test
|
||||
fun rsaSignedByEcdsa() {
|
||||
val root =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(0)
|
||||
.ecdsa256()
|
||||
.build()
|
||||
val leaf =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(0)
|
||||
.rsa2048()
|
||||
.signedBy(root)
|
||||
|
@ -644,8 +644,7 @@ internal class DerCertificatesTest {
|
||||
"92bc50e78097f2e6a9768997e22f0d70000017173d326b3000004030046304402207" +
|
||||
"e112c029b93e0db15d1de40eddb9aa7a55eeb4b48ce8c94ddf8ed71331e931e02207" +
|
||||
"8281e3c39c8e643b901c2bc6c470aa0ed3ad01bf17f0f207dc0f8a5ab541a70"
|
||||
)
|
||||
.decodeHex(),
|
||||
).decodeHex(),
|
||||
),
|
||||
Extension(
|
||||
id = keyUsage,
|
||||
@ -724,7 +723,8 @@ internal class DerCertificatesTest {
|
||||
@Test
|
||||
fun `certificate attributes`() {
|
||||
val certificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(3)
|
||||
.commonName("Jurassic Park")
|
||||
.organizationalUnit("Gene Research")
|
||||
@ -767,7 +767,8 @@ internal class DerCertificatesTest {
|
||||
@Test
|
||||
fun `missing subject alternative names`() {
|
||||
val certificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(3)
|
||||
.commonName("Jurassic Park")
|
||||
.organizationalUnit("Gene Research")
|
||||
@ -817,7 +818,8 @@ internal class DerCertificatesTest {
|
||||
val privateKey = keyFactory.generatePrivate(PKCS8EncodedKeySpec(privateKeyBytes.toByteArray()))
|
||||
|
||||
val certificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.keyPair(publicKey, privateKey)
|
||||
.build()
|
||||
|
||||
@ -930,8 +932,7 @@ internal class DerCertificatesTest {
|
||||
"5f5pk8F3wcXzAeVw06z3k1IB41Tu6MX+CyPU+TeudRlz+wV8b0zDvK+EnRKCCbptVFj1Bkt8lQ4JfcnhAkAk2Y3G" +
|
||||
"z+HySrkcT7Cg12M/NkdUQnZe3jr88pt/+IGNwomc6Wt/mJ4fcWONTkGMcfOZff1NQeNXDAZ6941XCsIVAkASOg02" +
|
||||
"PlVHLidU7mIE65swMM5/RNhS4aFjez/MwxFNOHaxc9VgCwYPXCLOtdf7AVovdyG0XWgbUXH+NyxKwboE"
|
||||
)
|
||||
.decodeBase64()!!
|
||||
).decodeBase64()!!
|
||||
|
||||
val decoded = CertificateAdapters.privateKeyInfo.fromDer(privateKeyInfoByteString)
|
||||
|
||||
@ -946,12 +947,14 @@ internal class DerCertificatesTest {
|
||||
@Test
|
||||
fun `RSA issuer and signature`() {
|
||||
val root =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(0)
|
||||
.rsa2048()
|
||||
.build()
|
||||
val certificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.signedBy(root)
|
||||
.rsa2048()
|
||||
.build()
|
||||
@ -982,12 +985,14 @@ internal class DerCertificatesTest {
|
||||
@Test
|
||||
fun `EC issuer and signature`() {
|
||||
val root =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.certificateAuthority(0)
|
||||
.ecdsa256()
|
||||
.build()
|
||||
val certificate =
|
||||
HeldCertificate.Builder()
|
||||
HeldCertificate
|
||||
.Builder()
|
||||
.signedBy(root)
|
||||
.ecdsa256()
|
||||
.build()
|
||||
@ -1042,8 +1047,7 @@ internal class DerCertificatesTest {
|
||||
"LXLJCzNLJEJcgV9TjbVu33eQR23yMuXD+cZsqLMF+L5IIM47W8dlwKJvMy0xs7Jb1S3NOIhcoVu+XPzRsgKv8Yi2" +
|
||||
"B6l278RfzegiCx4vYJv0pBjFzizEiFH9bWTYIOlIJJSM57hoICgjCTS8BoEgndwWIyc/nEmlYaUwmCo9QynY+UmW" +
|
||||
"1WPWmVITEJPMdMK6AZqvvaWmuHJ6/vURaz+Hoc5D3z0yJDDCkv52bXV04ZoF6cbcWry7JvNA+djvay/4BRR4SZQ=="
|
||||
)
|
||||
.decodeBase64()!!
|
||||
).decodeBase64()!!
|
||||
|
||||
val decoded = CertificateAdapters.certificate.fromDer(certificateByteString)
|
||||
assertThat(decoded.subjectAlternativeNames).isEqualTo(
|
||||
@ -1079,17 +1083,15 @@ internal class DerCertificatesTest {
|
||||
}
|
||||
|
||||
/** Returns a byte string that differs from this one by one bit. */
|
||||
private fun ByteString.offByOneBit(): ByteString {
|
||||
return Buffer()
|
||||
private fun ByteString.offByOneBit(): ByteString =
|
||||
Buffer()
|
||||
.write(this, 0, size - 1)
|
||||
.writeByte(this[size - 1].toInt() xor 1)
|
||||
.readByteString()
|
||||
}
|
||||
|
||||
private fun date(s: String): Date {
|
||||
return SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").run {
|
||||
private fun date(s: String): Date =
|
||||
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").run {
|
||||
timeZone = TimeZone.getTimeZone("GMT")
|
||||
parse(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -974,10 +974,9 @@ internal class DerTest {
|
||||
}
|
||||
}
|
||||
|
||||
private fun date(s: String): Date {
|
||||
return SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").run {
|
||||
private fun date(s: String): Date =
|
||||
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").run {
|
||||
timeZone = TimeZone.getTimeZone("GMT")
|
||||
parse(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,9 @@ import okhttp3.internal.tls.TrustRootIndex
|
||||
|
||||
/** Android 10+ (API 29+). */
|
||||
@SuppressSignatureCheck
|
||||
class Android10Platform : Platform(), ContextAwarePlatform {
|
||||
class Android10Platform :
|
||||
Platform(),
|
||||
ContextAwarePlatform {
|
||||
override var applicationContext: Context? = null
|
||||
|
||||
private val socketAdapters =
|
||||
@ -51,7 +53,8 @@ class Android10Platform : Platform(), ContextAwarePlatform {
|
||||
).filter { it.isSupported() }
|
||||
|
||||
override fun trustManager(sslSocketFactory: SSLSocketFactory): X509TrustManager? =
|
||||
socketAdapters.find { it.matchesSocketFactory(sslSocketFactory) }
|
||||
socketAdapters
|
||||
.find { it.matchesSocketFactory(sslSocketFactory) }
|
||||
?.trustManager(sslSocketFactory)
|
||||
|
||||
override fun newSSLContext(): SSLContext {
|
||||
@ -72,7 +75,8 @@ class Android10Platform : Platform(), ContextAwarePlatform {
|
||||
protocols: List<Protocol>,
|
||||
) {
|
||||
// No TLS extensions if the socket class is custom.
|
||||
socketAdapters.find { it.matchesSocket(sslSocket) }
|
||||
socketAdapters
|
||||
.find { it.matchesSocket(sslSocket) }
|
||||
?.configureTlsExtensions(sslSocket, hostname, protocols)
|
||||
}
|
||||
|
||||
@ -80,13 +84,12 @@ class Android10Platform : Platform(), ContextAwarePlatform {
|
||||
// No TLS extensions if the socket class is custom.
|
||||
socketAdapters.find { it.matchesSocket(sslSocket) }?.getSelectedProtocol(sslSocket)
|
||||
|
||||
override fun getStackTraceForCloseable(closer: String): Any? {
|
||||
return if (Build.VERSION.SDK_INT >= 30) {
|
||||
override fun getStackTraceForCloseable(closer: String): Any? =
|
||||
if (Build.VERSION.SDK_INT >= 30) {
|
||||
CloseGuard().apply { open(closer) }
|
||||
} else {
|
||||
super.getStackTraceForCloseable(closer)
|
||||
}
|
||||
}
|
||||
|
||||
override fun logCloseableLeak(
|
||||
message: String,
|
||||
|
@ -45,7 +45,9 @@ import okhttp3.internal.tls.TrustRootIndex
|
||||
|
||||
/** Android 5 to 9 (API 21 to 28). */
|
||||
@SuppressSignatureCheck
|
||||
class AndroidPlatform : Platform(), ContextAwarePlatform {
|
||||
class AndroidPlatform :
|
||||
Platform(),
|
||||
ContextAwarePlatform {
|
||||
override var applicationContext: Context? = null
|
||||
|
||||
private val socketAdapters =
|
||||
@ -83,7 +85,8 @@ class AndroidPlatform : Platform(), ContextAwarePlatform {
|
||||
}
|
||||
|
||||
override fun trustManager(sslSocketFactory: SSLSocketFactory): X509TrustManager? =
|
||||
socketAdapters.find { it.matchesSocketFactory(sslSocketFactory) }
|
||||
socketAdapters
|
||||
.find { it.matchesSocketFactory(sslSocketFactory) }
|
||||
?.trustManager(sslSocketFactory)
|
||||
|
||||
override fun configureTlsExtensions(
|
||||
@ -92,7 +95,8 @@ class AndroidPlatform : Platform(), ContextAwarePlatform {
|
||||
protocols: List<@JvmSuppressWildcards Protocol>,
|
||||
) {
|
||||
// No TLS extensions if the socket class is custom.
|
||||
socketAdapters.find { it.matchesSocket(sslSocket) }
|
||||
socketAdapters
|
||||
.find { it.matchesSocket(sslSocket) }
|
||||
?.configureTlsExtensions(sslSocket, hostname, protocols)
|
||||
}
|
||||
|
||||
@ -156,8 +160,8 @@ class AndroidPlatform : Platform(), ContextAwarePlatform {
|
||||
private val trustManager: X509TrustManager,
|
||||
private val findByIssuerAndSignatureMethod: Method,
|
||||
) : TrustRootIndex {
|
||||
override fun findByIssuerAndSignature(cert: X509Certificate): X509Certificate? {
|
||||
return try {
|
||||
override fun findByIssuerAndSignature(cert: X509Certificate): X509Certificate? =
|
||||
try {
|
||||
val trustAnchor =
|
||||
findByIssuerAndSignatureMethod.invoke(
|
||||
trustManager,
|
||||
@ -169,7 +173,6 @@ class AndroidPlatform : Platform(), ContextAwarePlatform {
|
||||
} catch (_: InvocationTargetException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user