Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP Proxy test #8235

Merged
merged 2 commits into from
Feb 3, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 208 additions & 0 deletions container-tests/src/test/java/okhttp3/containers/BasicProxyTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
package okhttp3.containers

import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.isEqualTo
import java.net.HttpURLConnection
import java.net.Proxy
import java.net.URI
import javax.net.ssl.HttpsURLConnection
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient
import okhttp3.Protocol
import okhttp3.Request
import okhttp3.containers.BasicMockServerTest.Companion.MOCKSERVER_IMAGE
import okhttp3.containers.BasicMockServerTest.Companion.trustMockServer
import okio.buffer
import okio.source
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import org.mockserver.client.MockServerClient
import org.mockserver.configuration.Configuration
import org.mockserver.logging.MockServerLogger
import org.mockserver.model.HttpRequest.request
import org.mockserver.model.HttpResponse.response
import org.mockserver.proxyconfiguration.ProxyConfiguration
import org.mockserver.socket.tls.KeyStoreFactory
import org.testcontainers.containers.MockServerContainer
import org.testcontainers.junit.jupiter.Container
import org.testcontainers.junit.jupiter.Testcontainers

@Testcontainers
class BasicProxyTest {
@Container
val mockServer: MockServerContainer =
MockServerContainer(MOCKSERVER_IMAGE)
.withNetworkAliases("mockserver")

@Test
fun testOkHttpDirect() {
testRequest {
val client = OkHttpClient()

val response =
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)
}
}

@Test
fun testOkHttpProxied() {
testRequest {
it.withProxyConfiguration(ProxyConfiguration.proxyConfiguration(ProxyConfiguration.Type.HTTP, it.remoteAddress()))

val client =
OkHttpClient.Builder()
.proxy(Proxy(Proxy.Type.HTTP, it.remoteAddress()))
.build()

val response =
client.newCall(
Request((mockServer.endpoint + "/person?name=peter").toHttpUrl()),
).execute()

assertThat(response.body.string()).contains("Peter the person")
}
}

@Test
fun testOkHttpSecureDirect() {
testRequest {
val client =
OkHttpClient.Builder()
.trustMockServer()
.build()

val response =
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)
}
}

@Test
fun testOkHttpSecureProxiedHttp1() {
testRequest {
val client =
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()

assertThat(response.body.string()).contains("Peter the person")
assertThat(response.protocol).isEqualTo(Protocol.HTTP_1_1)
}
}

@Test
@Disabled("https://github.com/square/okhttp/issues/8233")
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Failing with

java.io.IOException: Required SETTINGS preface not received
	at okhttp3.internal.http2.Http2Reader.readConnectionPreface(Http2Reader.kt:76)
	at okhttp3.internal.http2.Http2Connection$ReaderRunnable.invoke(Http2Connection.kt:635)
	at okhttp3.internal.http2.Http2Connection$ReaderRunnable.invoke(Http2Connection.kt:627)
	at okhttp3.internal.concurrent.TaskQueue$execute$1.runOnce(TaskQueue.kt:119)
	at okhttp3.internal.concurrent.TaskRunner.runTask(TaskRunner.kt:124)
	at okhttp3.internal.concurrent.TaskRunner.access$runTask(TaskRunner.kt:44)
	at okhttp3.internal.concurrent.TaskRunner$runnable$1.run(TaskRunner.kt:73)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1583)

fun testOkHttpSecureProxiedHttp2() {
testRequest {
val client =
OkHttpClient.Builder()
.trustMockServer()
.proxy(Proxy(Proxy.Type.HTTP, it.remoteAddress()))
.protocols(listOf(Protocol.HTTP_2, Protocol.HTTP_1_1))
.build()

val response =
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)
}
}

@Test
fun testUrlConnectionDirect() {
testRequest {
val url = URI(mockServer.endpoint + "/person?name=peter").toURL()

val connection = url.openConnection() as HttpURLConnection

assertThat(connection.inputStream.source().buffer().readUtf8()).contains("Peter the person")
}
}

@Test
fun testUrlConnectionPlaintextProxied() {
testRequest {
val proxy =
Proxy(
Proxy.Type.HTTP,
it.remoteAddress(),
)

val url = URI(mockServer.endpoint + "/person?name=peter").toURL()

val connection = url.openConnection(proxy) as HttpURLConnection

assertThat(connection.inputStream.source().buffer().readUtf8()).contains("Peter the person")
}
}

@Test
fun testUrlConnectionSecureDirect() {
val keyStoreFactory = KeyStoreFactory(Configuration.configuration(), MockServerLogger())
HttpsURLConnection.setDefaultSSLSocketFactory(keyStoreFactory.sslContext().socketFactory)

testRequest {
val url = URI(mockServer.secureEndpoint + "/person?name=peter").toURL()

val connection = url.openConnection() as HttpURLConnection

assertThat(connection.inputStream.source().buffer().readUtf8()).contains("Peter the person")
}
}

@Test
fun testUrlConnectionSecureProxied() {
val keyStoreFactory = KeyStoreFactory(Configuration.configuration(), MockServerLogger())
HttpsURLConnection.setDefaultSSLSocketFactory(keyStoreFactory.sslContext().socketFactory)

testRequest {
val proxy =
Proxy(
Proxy.Type.HTTP,
it.remoteAddress(),
)

val url = URI(mockServer.secureEndpoint + "/person?name=peter").toURL()

val connection = url.openConnection(proxy) as HttpURLConnection

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")
.withQueryStringParameter("name", "peter")

mockServerClient
.`when`(
request,
)
.respond(response().withBody("Peter the person!"))

function(mockServerClient)
}
}
}
Loading