From ea720d32b50d0055be26fa3e9b9cd03460d3e737 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Tue, 17 Oct 2023 02:03:16 +0100 Subject: [PATCH] [4.x] Add test for 103 handling (#8055) * Add test for 103 handling * Minimise changes * Simplify name --- .../okhttp3/mockwebserver/MockResponse.kt | 6 +++ .../okhttp3/mockwebserver/MockWebServer.kt | 7 ++++ okhttp/src/test/java/okhttp3/CallTest.java | 37 +++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/mockwebserver/src/main/kotlin/okhttp3/mockwebserver/MockResponse.kt b/mockwebserver/src/main/kotlin/okhttp3/mockwebserver/MockResponse.kt index e61479bcb569..0cd4451b42cf 100644 --- a/mockwebserver/src/main/kotlin/okhttp3/mockwebserver/MockResponse.kt +++ b/mockwebserver/src/main/kotlin/okhttp3/mockwebserver/MockResponse.kt @@ -29,6 +29,8 @@ class MockResponse : Cloneable { @set:JvmName("status") var status: String = "" + internal var informationalResponses: List = listOf() + private var headersBuilder = Headers.Builder() private var trailersBuilder = Headers.Builder() @@ -347,6 +349,10 @@ class MockResponse : Cloneable { override fun toString() = status + fun addInformationalResponse(informationalResponse: MockResponse): MockResponse = apply { + informationalResponses += informationalResponse + } + companion object { private const val CHUNKED_BODY_HEADER = "Transfer-encoding: chunked" } diff --git a/mockwebserver/src/main/kotlin/okhttp3/mockwebserver/MockWebServer.kt b/mockwebserver/src/main/kotlin/okhttp3/mockwebserver/MockWebServer.kt index 65622104cc9a..29d1a55255f8 100644 --- a/mockwebserver/src/main/kotlin/okhttp3/mockwebserver/MockWebServer.kt +++ b/mockwebserver/src/main/kotlin/okhttp3/mockwebserver/MockWebServer.kt @@ -1026,6 +1026,13 @@ class MockWebServer : ExternalResource(), Closeable { readBody = true } + peek.informationalResponses.forEach { + val informationalHeader = + listOf(Header(Header.RESPONSE_STATUS, it.status.replace("HTTP/1.1 ", ""))) + stream.writeHeaders(informationalHeader, outFinished = false, flushHeaders = true) + stream.connection.flush() + } + val body = Buffer() val requestLine = "$method $path HTTP/1.1" var exception: IOException? = null diff --git a/okhttp/src/test/java/okhttp3/CallTest.java b/okhttp/src/test/java/okhttp3/CallTest.java index d27e56f6a186..4c01db100d9e 100644 --- a/okhttp/src/test/java/okhttp3/CallTest.java +++ b/okhttp/src/test/java/okhttp3/CallTest.java @@ -2812,6 +2812,43 @@ public void cancelWhileRequestHeadersAreSent_HTTP_2() throws Exception { assertThat(recordedRequest.getBody().readUtf8()).isEqualTo("abc"); } + @Test + public void serverRespondsWithEarlyHintsHttp2() throws Exception { + enableProtocol(Protocol.HTTP_2); + server.enqueue( + new MockResponse() + .addInformationalResponse( + new MockResponse().setResponseCode(103).addHeader("Link", "; rel=preload; as=style") + ) + ); + Request request = new Request.Builder() + .url(server.url("/")) + .post(RequestBody.create("abc", MediaType.get("text/plain"))) + .build(); + executeSynchronously(request) + .assertFailure(SocketTimeoutException.class); + } + + @Test + public void serverRespondsWithEarlyHintsHttp1() throws Exception { + server.enqueue( + new MockResponse() + .addInformationalResponse( + new MockResponse().setResponseCode(103).addHeader("Link", "; rel=preload; as=style") + ) + ); + Request request = new Request.Builder() + .url(server.url("/")) + .post(RequestBody.create("abc", MediaType.get("text/plain"))) + .build(); + executeSynchronously(request) + .assertSuccessful() + .assertCode(200); + RecordedRequest recordedRequest = server.takeRequest(); + assertThat(recordedRequest.getBody().readUtf8()).isEqualTo("abc"); + assertThat(recordedRequest.getHeader("Link")).isNull(); + } + @Test public void serverRespondsWithUnsolicited100Continue_HTTP2() throws Exception { enableProtocol(Protocol.HTTP_2); serverRespondsWithUnsolicited100Continue();