From 6b387cb97738adecfc4275b1da1f09acce2afee9 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Sun, 16 Oct 2022 21:32:03 +0100 Subject: [PATCH 1/2] Ignore early hints for 4.9.x (#7444) (cherry picked from commit b565eecf167918253145bce2c348b0bb0ef58b0c) --- .../internal/http/CallServerInterceptor.kt | 18 +++++++++++++++--- .../internal/http1/Http1ExchangeCodec.kt | 7 +++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http/CallServerInterceptor.kt b/okhttp/src/main/kotlin/okhttp3/internal/http/CallServerInterceptor.kt index 6801154b35c7..0f918a6cd396 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/http/CallServerInterceptor.kt +++ b/okhttp/src/main/kotlin/okhttp3/internal/http/CallServerInterceptor.kt @@ -18,8 +18,10 @@ package okhttp3.internal.http import java.io.IOException import java.net.ProtocolException import okhttp3.Interceptor +import okhttp3.Protocol import okhttp3.Response import okhttp3.internal.EMPTY_RESPONSE +import okhttp3.internal.connection.Exchange import okhttp3.internal.http2.ConnectionShutdownException import okio.buffer @@ -103,9 +105,8 @@ class CallServerInterceptor(private val forWebSocket: Boolean) : Interceptor { .receivedResponseAtMillis(System.currentTimeMillis()) .build() var code = response.code - if (code == 100) { - // Server sent a 100-continue even though we did not request one. Try again to read the - // actual response status. + + if (shouldIgnoreAndWaitForRealResponse(code, exchange)) { responseBuilder = exchange.readResponseHeaders(expectContinue = false)!! if (invokeStartEvent) { exchange.responseHeadersStart() @@ -148,4 +149,15 @@ class CallServerInterceptor(private val forWebSocket: Boolean) : Interceptor { throw e } } + + private fun shouldIgnoreAndWaitForRealResponse(code: Int, exchange: Exchange): Boolean = when { + // Server sent a 100-continue even though we did not request one. Try again to read the + // actual response status. + code == 100 -> true + + // Early Hints (103) but not supported yet in OkHttp + code == 103 -> true + + else -> false + } } diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt b/okhttp/src/main/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt index 87f516a69a75..55db543d960b 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt +++ b/okhttp/src/main/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt @@ -35,6 +35,8 @@ import okhttp3.internal.http.StatusLine import okhttp3.internal.http.StatusLine.Companion.HTTP_CONTINUE import okhttp3.internal.http.promisesBody import okhttp3.internal.http.receiveHeaders +import okhttp3.internal.http.HTTP_CONTINUE +import okhttp3.internal.http.HTTP_EARLY_HINTS import okhttp3.internal.skipAll import okio.Buffer import okio.BufferedSink @@ -193,6 +195,11 @@ class Http1ExchangeCodec( state = STATE_READ_RESPONSE_HEADERS responseBuilder } + statusLine.code == HTTP_EARLY_HINTS -> { + // Early Hints will mean a second header are coming. + state = STATE_READ_RESPONSE_HEADERS + responseBuilder + } else -> { state = STATE_OPEN_RESPONSE_BODY responseBuilder From db64e4ba766818eae9e150d1309e16b43d757417 Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Tue, 1 Nov 2022 16:04:45 +0000 Subject: [PATCH 2/2] Fix --- okhttp/src/main/kotlin/okhttp3/internal/http/StatusLine.kt | 1 + .../main/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http/StatusLine.kt b/okhttp/src/main/kotlin/okhttp3/internal/http/StatusLine.kt index dc28d2f40401..e47acb1794ba 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/http/StatusLine.kt +++ b/okhttp/src/main/kotlin/okhttp3/internal/http/StatusLine.kt @@ -46,6 +46,7 @@ class StatusLine( /** RFC 7540, Section 9.1.2. Retry these if the exchange used connection coalescing. */ const val HTTP_MISDIRECTED_REQUEST = 421 const val HTTP_CONTINUE = 100 + const val HTTP_EARLY_HINTS = 103 fun get(response: Response): StatusLine { return StatusLine(response.protocol, response.code, response.message) diff --git a/okhttp/src/main/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt b/okhttp/src/main/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt index 55db543d960b..a573b6986ff6 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt +++ b/okhttp/src/main/kotlin/okhttp3/internal/http1/Http1ExchangeCodec.kt @@ -33,10 +33,9 @@ import okhttp3.internal.http.ExchangeCodec import okhttp3.internal.http.RequestLine import okhttp3.internal.http.StatusLine import okhttp3.internal.http.StatusLine.Companion.HTTP_CONTINUE +import okhttp3.internal.http.StatusLine.Companion.HTTP_EARLY_HINTS import okhttp3.internal.http.promisesBody import okhttp3.internal.http.receiveHeaders -import okhttp3.internal.http.HTTP_CONTINUE -import okhttp3.internal.http.HTTP_EARLY_HINTS import okhttp3.internal.skipAll import okio.Buffer import okio.BufferedSink