diff --git a/mockwebserver-deprecated/src/main/kotlin/okhttp3/mockwebserver/DeprecationBridge.kt b/mockwebserver-deprecated/src/main/kotlin/okhttp3/mockwebserver/DeprecationBridge.kt index 3335e6943..d6813ff4b 100644 --- a/mockwebserver-deprecated/src/main/kotlin/okhttp3/mockwebserver/DeprecationBridge.kt +++ b/mockwebserver-deprecated/src/main/kotlin/okhttp3/mockwebserver/DeprecationBridge.kt @@ -102,9 +102,9 @@ internal fun mockwebserver3.RecordedRequest.unwrap(): RecordedRequest = sequenceNumber = sequenceNumber, failure = failure, method = method, - path = path, + path = url.encodedPath, handshake = handshake, - requestUrl = requestUrl, + requestUrl = url, ) private fun MockResponse.wrapSocketPolicy(): mockwebserver3.SocketPolicy = diff --git a/mockwebserver/api/mockwebserver3.api b/mockwebserver/api/mockwebserver3.api index 9423c2c0a..0a0a9a58b 100644 --- a/mockwebserver/api/mockwebserver3.api +++ b/mockwebserver/api/mockwebserver3.api @@ -145,8 +145,8 @@ public class mockwebserver3/QueueDispatcher : mockwebserver3/Dispatcher { } public final class mockwebserver3/RecordedRequest { - public fun (ILokhttp3/Handshake;Ljava/util/List;Lokhttp3/HttpUrl;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lokhttp3/Headers;Lokio/ByteString;JLjava/util/List;Ljava/io/IOException;)V - public synthetic fun (ILokhttp3/Handshake;Ljava/util/List;Lokhttp3/HttpUrl;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lokhttp3/Headers;Lokio/ByteString;JLjava/util/List;Ljava/io/IOException;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (ILokhttp3/Handshake;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lokhttp3/HttpUrl;Lokhttp3/Headers;Lokio/ByteString;JLjava/util/List;Ljava/io/IOException;)V + public synthetic fun (ILokhttp3/Handshake;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lokhttp3/HttpUrl;Lokhttp3/Headers;Lokio/ByteString;JLjava/util/List;Ljava/io/IOException;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun getBody ()Lokio/ByteString; public final fun getBodySize ()J public final fun getChunkSizes ()Ljava/util/List; @@ -155,10 +155,11 @@ public final class mockwebserver3/RecordedRequest { public final fun getHandshakeServerNames ()Ljava/util/List; public final fun getHeaders ()Lokhttp3/Headers; public final fun getMethod ()Ljava/lang/String; - public final fun getPath ()Ljava/lang/String; public final fun getRequestLine ()Ljava/lang/String; - public final fun getRequestUrl ()Lokhttp3/HttpUrl; public final fun getSequenceNumber ()I + public final fun getTarget ()Ljava/lang/String; + public final fun getUrl ()Lokhttp3/HttpUrl; + public final fun getVersion ()Ljava/lang/String; public fun toString ()Ljava/lang/String; } diff --git a/mockwebserver/src/main/kotlin/mockwebserver3/MockWebServer.kt b/mockwebserver/src/main/kotlin/mockwebserver3/MockWebServer.kt index a0b0dd6cf..b277e5dab 100644 --- a/mockwebserver/src/main/kotlin/mockwebserver3/MockWebServer.kt +++ b/mockwebserver/src/main/kotlin/mockwebserver3/MockWebServer.kt @@ -63,9 +63,12 @@ import mockwebserver3.SocketPolicy.ShutdownInputAtEnd import mockwebserver3.SocketPolicy.ShutdownOutputAtEnd import mockwebserver3.SocketPolicy.ShutdownServerAfterResponse import mockwebserver3.SocketPolicy.StallSocketAtStart +import mockwebserver3.internal.DEFAULT_REQUEST_LINE import mockwebserver3.internal.RecordedRequest +import mockwebserver3.internal.RequestLine import mockwebserver3.internal.ThrottledSink import mockwebserver3.internal.TriggerSink +import mockwebserver3.internal.decodeRequestLine import mockwebserver3.internal.sleepWhileOpen import okhttp3.Headers import okhttp3.Headers.Companion.headersOf @@ -656,7 +659,7 @@ public class MockWebServer : Closeable { ) { val request = RecordedRequest( - "", + DEFAULT_REQUEST_LINE, headersOf(), emptyList(), 0L, @@ -677,7 +680,7 @@ public class MockWebServer : Closeable { sink: BufferedSink, sequenceNumber: Int, ): RecordedRequest { - var request = "" + var request: RequestLine = DEFAULT_REQUEST_LINE val headers = Headers.Builder() var contentLength = -1L var chunked = false @@ -686,10 +689,11 @@ public class MockWebServer : Closeable { var failure: IOException? = null try { - request = source.readUtf8LineStrict() - if (request.isEmpty()) { + val requestLineString = source.readUtf8LineStrict() + if (requestLineString.isEmpty()) { throw ProtocolException("no request because the stream is exhausted") } + request = decodeRequestLine(requestLineString) while (true) { val header = source.readUtf8LineStrict() @@ -752,8 +756,7 @@ public class MockWebServer : Closeable { } } - val method = request.substringBefore(' ') - require(!hasBody || HttpMethod.permitsRequestBody(method)) { + require(!hasBody || HttpMethod.permitsRequestBody(request.method)) { "Request must not have a body: $request" } } catch (e: IOException) { @@ -828,7 +831,7 @@ public class MockWebServer : Closeable { minimumDeflateSize = 0L, webSocketCloseTimeout = RealWebSocket.CANCEL_AFTER_CLOSE_MILLIS, ) - val name = "MockWebServer WebSocket ${request.path!!}" + val name = "MockWebServer WebSocket ${request.url.encodedPath}" webSocket.initReaderAndWriter(name, streams) try { webSocket.loopReader(fancyResponse) @@ -1051,7 +1054,12 @@ public class MockWebServer : Closeable { } val body = Buffer() - val requestLine = "$method $path HTTP/1.1" + val requestLine = + RequestLine( + method = method, + target = path, + version = "HTTP/1.1", + ) var exception: IOException? = null if (readBody && peek.socketHandler == null && peek.socketPolicy !is DoNotReadRequestBody) { try { @@ -1170,7 +1178,12 @@ public class MockWebServer : Closeable { for ((name, value) in pushPromiseHeaders) { pushedHeaders.add(Header(name, value)) } - val requestLine = "${pushPromise.method} ${pushPromise.path} HTTP/1.1" + val requestLine = + RequestLine( + method = pushPromise.method, + target = pushPromise.path, + version = "HTTP/1.1", + ) val chunkSizes = emptyList() // No chunked encoding for HTTP/2. requestQueue.add( RecordedRequest( diff --git a/mockwebserver/src/main/kotlin/mockwebserver3/RecordedRequest.kt b/mockwebserver/src/main/kotlin/mockwebserver3/RecordedRequest.kt index 0271d6e3e..a9ebc77a2 100644 --- a/mockwebserver/src/main/kotlin/mockwebserver3/RecordedRequest.kt +++ b/mockwebserver/src/main/kotlin/mockwebserver3/RecordedRequest.kt @@ -42,10 +42,24 @@ public class RecordedRequest( * cleartext and may be monitored or blocked by a proxy or other middlebox. */ public val handshakeServerNames: List, - public val requestUrl: HttpUrl?, - public val requestLine: String, - public val method: String?, - public val path: String?, + public val method: String, + /** + * The request target from the original HTTP request. + * + * For origin-form requests this is a path like `/index.html`, that is combined with the `Host` + * header to create the request URL. + * + * For HTTP proxy requests this will be either an absolute-form string like + * `http://example.com/index.html` (HTTP proxy) or an authority-form string like + * `example.com:443` (HTTPS proxy). + * + * For OPTIONS requests, this may be an asterisk, `*`. + */ + public val target: String, + /** A string like `HTTP/1.1`. */ + public val version: String, + /** The request URL built using the request line, headers, and local host name. */ + public val url: HttpUrl, /** All headers. */ public val headers: Headers, /** The body of this request, or [ByteString.EMPTY] if it has none. This may be truncated. */ @@ -63,5 +77,8 @@ public class RecordedRequest( */ public val failure: IOException? = null, ) { + public val requestLine: String + get() = "$method $target $version" + public override fun toString(): String = requestLine } diff --git a/mockwebserver/src/main/kotlin/mockwebserver3/internal/RecordedRequestFactory.kt b/mockwebserver/src/main/kotlin/mockwebserver3/internal/RecordedRequestFactory.kt index d832a525a..000de9712 100644 --- a/mockwebserver/src/main/kotlin/mockwebserver3/internal/RecordedRequestFactory.kt +++ b/mockwebserver/src/main/kotlin/mockwebserver3/internal/RecordedRequestFactory.kt @@ -17,6 +17,7 @@ package mockwebserver3.internal import java.io.IOException import java.net.Inet6Address +import java.net.ProtocolException import java.net.Socket import javax.net.ssl.SSLSocket import mockwebserver3.RecordedRequest @@ -24,12 +25,13 @@ import okhttp3.Handshake import okhttp3.Handshake.Companion.handshake import okhttp3.Headers import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import okhttp3.internal.platform.Platform import okio.Buffer internal fun RecordedRequest( - requestLine: String, + requestLine: RequestLine, headers: Headers, chunkSizes: List, bodySize: Long, @@ -52,45 +54,22 @@ internal fun RecordedRequest( handshakeServerNames = listOf() } - val requestUrl: HttpUrl? - val method: String? - val path: String? - if (requestLine.isNotEmpty()) { - val methodEnd = requestLine.indexOf(' ') - val urlEnd = requestLine.indexOf(' ', methodEnd + 1) - method = requestLine.substring(0, methodEnd) - var urlPart = requestLine.substring(methodEnd + 1, urlEnd) - if (!urlPart.startsWith("/")) { - urlPart = "/" + val requestUrl = + when (requestLine.method) { + "CONNECT" -> "${socket.scheme}://${requestLine.target}/".toHttpUrlOrNull() + else -> null } - path = urlPart - - val scheme = if (socket is SSLSocket) "https" else "http" - val localPort = socket.localPort - val hostAndPort = - headers[":authority"] - ?: headers["Host"] - ?: when (val inetAddress = socket.localAddress) { - is Inet6Address -> "[${inetAddress.hostAddress}]:$localPort" - else -> "${inetAddress.hostAddress}:$localPort" - } - - // Allow null in failure case to allow for testing bad requests - requestUrl = "$scheme://$hostAndPort$path".toHttpUrlOrNull() - } else { - requestUrl = null - method = null - path = null - } + ?: requestLine.target.toHttpUrlOrNull() + ?: requestUrl(socket, requestLine, headers) return RecordedRequest( sequenceNumber = sequenceNumber, handshake = handshake, handshakeServerNames = handshakeServerNames, - requestUrl = requestUrl, - requestLine = requestLine, - method = method, - path = path, + method = requestLine.method, + target = requestLine.target, + version = requestLine.version, + url = requestUrl, headers = headers, body = body.readByteString(), bodySize = bodySize, @@ -98,3 +77,66 @@ internal fun RecordedRequest( failure = failure, ) } + +internal fun decodeRequestLine(requestLine: String?): RequestLine { + val parts = + when { + requestLine != null -> requestLine.split(' ', limit = 3) + else -> return DEFAULT_REQUEST_LINE + } + + if (parts.size != 3) { + throw ProtocolException("unexpected request line: $requestLine") + } + + return RequestLine( + method = parts[0], + target = parts[1], + version = parts[2], + ) +} + +internal class RequestLine( + val method: String, + val target: String, + val version: String, +) { + override fun toString() = "$method $target $version" +} + +internal val DEFAULT_REQUEST_LINE = + RequestLine( + method = "GET", + target = "/", + version = "HTTP/1.1", + ) + +private val Socket.scheme: String + get() = + when (this) { + is SSLSocket -> "https" + else -> "http" + } + +private fun requestUrl( + socket: Socket, + requestLine: RequestLine, + headers: Headers, +): HttpUrl { + val hostAndPort = + headers[":authority"] + ?: headers["Host"] + ?: when (val inetAddress = socket.localAddress) { + is Inet6Address -> "[${inetAddress.hostAddress}]:${socket.localPort}" + else -> "${inetAddress.hostAddress}:${socket.localPort}" + } + + // For OPTIONS, the request target may be a '*', like 'OPTIONS * HTTP/1.1'. + val path = + when { + requestLine.method == "OPTIONS" && requestLine.target == "*" -> "/" + else -> requestLine.target + } + + return "${socket.scheme}://$hostAndPort$path".toHttpUrl() +} diff --git a/mockwebserver/src/test/java/mockwebserver3/CustomDispatcherTest.kt b/mockwebserver/src/test/java/mockwebserver3/CustomDispatcherTest.kt index e65501909..6288f60b4 100644 --- a/mockwebserver/src/test/java/mockwebserver3/CustomDispatcherTest.kt +++ b/mockwebserver/src/test/java/mockwebserver3/CustomDispatcherTest.kt @@ -63,7 +63,7 @@ class CustomDispatcherTest { val dispatcher: Dispatcher = object : Dispatcher() { override fun dispatch(request: RecordedRequest): MockResponse { - if (request.path == firstRequest) { + if (request.url.encodedPath == firstRequest) { latch.await() } return MockResponse() diff --git a/mockwebserver/src/test/java/mockwebserver3/MockResponseSniTest.kt b/mockwebserver/src/test/java/mockwebserver3/MockResponseSniTest.kt index ccd93438c..4db63dffc 100644 --- a/mockwebserver/src/test/java/mockwebserver3/MockResponseSniTest.kt +++ b/mockwebserver/src/test/java/mockwebserver3/MockResponseSniTest.kt @@ -135,7 +135,7 @@ class MockResponseSniTest { assertThat(response.isSuccessful).isTrue() val recordedRequest = server.takeRequest() - assertThat(recordedRequest.requestUrl!!.host).isEqualTo("header-host") + assertThat(recordedRequest.url.host).isEqualTo("header-host") // https://github.com/bcgit/bc-java/issues/1773 if (!platform.isBouncyCastle()) { @@ -147,7 +147,7 @@ class MockResponseSniTest { @Test fun ipv6() { val recordedRequest = requestToHostnameViaProxy("2607:f8b0:400b:804::200e") - assertThat(recordedRequest.requestUrl!!.host).isEqualTo("2607:f8b0:400b:804::200e") + assertThat(recordedRequest.url.host).isEqualTo("2607:f8b0:400b:804::200e") assertThat(recordedRequest.handshakeServerNames).isEmpty() } @@ -155,14 +155,14 @@ class MockResponseSniTest { @Test fun ipv4() { val recordedRequest = requestToHostnameViaProxy("76.223.91.57") - assertThat(recordedRequest.requestUrl!!.host).isEqualTo("76.223.91.57") + assertThat(recordedRequest.url.host).isEqualTo("76.223.91.57") assertThat(recordedRequest.handshakeServerNames).isEmpty() } @Test fun regularHostname() { val recordedRequest = requestToHostnameViaProxy("cash.app") - assertThat(recordedRequest.requestUrl!!.host).isEqualTo("cash.app") + assertThat(recordedRequest.url.host).isEqualTo("cash.app") // https://github.com/bcgit/bc-java/issues/1773 if (!platform.isBouncyCastle()) { assertThat(recordedRequest.handshakeServerNames).containsExactly("cash.app") diff --git a/mockwebserver/src/test/java/mockwebserver3/MockWebServerTest.kt b/mockwebserver/src/test/java/mockwebserver3/MockWebServerTest.kt index d2d993059..1fe0f0f82 100644 --- a/mockwebserver/src/test/java/mockwebserver3/MockWebServerTest.kt +++ b/mockwebserver/src/test/java/mockwebserver3/MockWebServerTest.kt @@ -543,8 +543,8 @@ class MockWebServerTest { assertThat(request.requestLine).isEqualTo( "GET /a/deep/path?key=foo%20bar HTTP/1.1", ) - val requestUrl = request.requestUrl - assertThat(requestUrl!!.scheme).isEqualTo("http") + val requestUrl = request.url + assertThat(requestUrl.scheme).isEqualTo("http") assertThat(requestUrl.host).isEqualTo(server.hostName) assertThat(requestUrl.port).isEqualTo(server.port) assertThat(requestUrl.encodedPath).isEqualTo("/a/deep/path") @@ -663,7 +663,7 @@ class MockWebServerTest { val reader = BufferedReader(InputStreamReader(connection.inputStream, UTF_8)) assertThat(reader.readLine()).isEqualTo("abc") val request = server.takeRequest() - assertThat(request.requestUrl!!.scheme).isEqualTo("https") + assertThat(request.url.scheme).isEqualTo("https") val handshake = request.handshake assertThat(handshake!!.tlsVersion).isNotNull() assertThat(handshake.cipherSuite).isNotNull() @@ -727,7 +727,7 @@ class MockWebServerTest { val reader = BufferedReader(InputStreamReader(connection.inputStream, UTF_8)) assertThat(reader.readLine()).isEqualTo("abc") val request = server.takeRequest() - assertThat(request.requestUrl!!.scheme).isEqualTo("https") + assertThat(request.url.scheme).isEqualTo("https") val handshake = request.handshake assertThat(handshake!!.tlsVersion).isNotNull() assertThat(handshake.cipherSuite).isNotNull() @@ -756,7 +756,7 @@ class MockWebServerTest { assertThat(response.body.string()).isEqualTo("Result") } val recordedRequest = server.takeRequest() - assertThat(recordedRequest.requestUrl).isEqualTo("http://android.com/".toHttpUrl()) + assertThat(recordedRequest.url).isEqualTo("http://android.com/".toHttpUrl()) } @Test diff --git a/mockwebserver/src/test/java/mockwebserver3/RecordedRequestTest.kt b/mockwebserver/src/test/java/mockwebserver3/RecordedRequestTest.kt index f9a473bb7..fb7936269 100644 --- a/mockwebserver/src/test/java/mockwebserver3/RecordedRequestTest.kt +++ b/mockwebserver/src/test/java/mockwebserver3/RecordedRequestTest.kt @@ -20,7 +20,9 @@ import assertk.assertThat import assertk.assertions.isEqualTo import java.net.InetAddress import java.net.Socket +import mockwebserver3.internal.DEFAULT_REQUEST_LINE import mockwebserver3.internal.RecordedRequest +import mockwebserver3.internal.decodeRequestLine import okhttp3.Headers import okhttp3.Headers.Companion.headersOf import okio.Buffer @@ -37,8 +39,53 @@ class RecordedRequestTest { localAddress = InetAddress.getByAddress("127.0.0.1", byteArrayOf(127, 0, 0, 1)), localPort = 80, ) - val request = RecordedRequest("GET / HTTP/1.1", headers, emptyList(), 0, Buffer(), 0, socket) - assertThat(request.requestUrl.toString()).isEqualTo("http://127.0.0.1/") + val request = RecordedRequest(DEFAULT_REQUEST_LINE, headers, emptyList(), 0, Buffer(), 0, socket) + assertThat(request.url.toString()).isEqualTo("http://127.0.0.1/") + } + + @Test fun testAuthorityForm() { + val socket = + FakeSocket( + localAddress = InetAddress.getByAddress("127.0.0.1", byteArrayOf(127, 0, 0, 1)), + localPort = 80, + ) + val requestLine = decodeRequestLine("CONNECT example.com:8080 HTTP/1.1") + val request = RecordedRequest(requestLine, headers, emptyList(), 0, Buffer(), 0, socket) + assertThat(request.target).isEqualTo("example.com:8080") + assertThat(request.url.toString()).isEqualTo("http://example.com:8080/") + } + + @Test fun testAbsoluteForm() { + val socket = + FakeSocket( + localAddress = InetAddress.getByAddress("127.0.0.1", byteArrayOf(127, 0, 0, 1)), + localPort = 80, + ) + val requestLine = decodeRequestLine("GET http://example.com:8080/index.html HTTP/1.1") + val request = RecordedRequest(requestLine, headers, emptyList(), 0, Buffer(), 0, socket) + assertThat(request.target).isEqualTo("http://example.com:8080/index.html") + assertThat(request.url.toString()).isEqualTo("http://example.com:8080/index.html") + } + + @Test fun testAsteriskForm() { + val socket = + FakeSocket( + localAddress = InetAddress.getByAddress("127.0.0.1", byteArrayOf(127, 0, 0, 1)), + localPort = 80, + ) + val requestLine = decodeRequestLine("OPTIONS * HTTP/1.1") + val request = + RecordedRequest( + requestLine, + headers, + emptyList(), + 0, + Buffer(), + 0, + socket, + ) + assertThat(request.target).isEqualTo("*") + assertThat(request.url.toString()).isEqualTo("http://127.0.0.1/") } @Test fun testIpv6() { @@ -51,8 +98,8 @@ class RecordedRequestTest { ), localPort = 80, ) - val request = RecordedRequest("GET / HTTP/1.1", headers, emptyList(), 0, Buffer(), 0, socket) - assertThat(request.requestUrl.toString()).isEqualTo("http://[::1]/") + val request = RecordedRequest(DEFAULT_REQUEST_LINE, headers, emptyList(), 0, Buffer(), 0, socket) + assertThat(request.url.toString()).isEqualTo("http://[::1]/") } @Test fun testUsesLocal() { @@ -61,8 +108,8 @@ class RecordedRequestTest { localAddress = InetAddress.getByAddress("127.0.0.1", byteArrayOf(127, 0, 0, 1)), localPort = 80, ) - val request = RecordedRequest("GET / HTTP/1.1", headers, emptyList(), 0, Buffer(), 0, socket) - assertThat(request.requestUrl.toString()).isEqualTo("http://127.0.0.1/") + val request = RecordedRequest(DEFAULT_REQUEST_LINE, headers, emptyList(), 0, Buffer(), 0, socket) + assertThat(request.url.toString()).isEqualTo("http://127.0.0.1/") } @Test fun testHostname() { @@ -76,8 +123,8 @@ class RecordedRequestTest { ), localPort = 80, ) - val request = RecordedRequest("GET / HTTP/1.1", headers, emptyList(), 0, Buffer(), 0, socket) - assertThat(request.requestUrl.toString()).isEqualTo("http://host-from-header.com/") + val request = RecordedRequest(DEFAULT_REQUEST_LINE, headers, emptyList(), 0, Buffer(), 0, socket) + assertThat(request.url.toString()).isEqualTo("http://host-from-header.com/") } private class FakeSocket( diff --git a/okhttp-dnsoverhttps/src/test/java/okhttp3/dnsoverhttps/DnsOverHttpsTest.kt b/okhttp-dnsoverhttps/src/test/java/okhttp3/dnsoverhttps/DnsOverHttpsTest.kt index 5f5934fde..e2939b2f2 100644 --- a/okhttp-dnsoverhttps/src/test/java/okhttp3/dnsoverhttps/DnsOverHttpsTest.kt +++ b/okhttp-dnsoverhttps/src/test/java/okhttp3/dnsoverhttps/DnsOverHttpsTest.kt @@ -85,8 +85,8 @@ class DnsOverHttpsTest { assertThat(result).isEqualTo(listOf(address("157.240.1.18"))) val recordedRequest = server.takeRequest() assertThat(recordedRequest.method).isEqualTo("GET") - assertThat(recordedRequest.path) - .isEqualTo("/lookup?ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ") + assertThat(recordedRequest.url.encodedQuery) + .isEqualTo("ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ") } @Test @@ -114,10 +114,10 @@ class DnsOverHttpsTest { assertThat(request1.method).isEqualTo("GET") val request2 = server.takeRequest() assertThat(request2.method).isEqualTo("GET") - assertThat(listOf(request1.path, request2.path)) + assertThat(listOf(request1.url.encodedQuery, request2.url.encodedQuery)) .containsExactlyInAnyOrder( - "/lookup?ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ", - "/lookup?ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AABwAAQ", + "ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ", + "ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AABwAAQ", ) } @@ -138,8 +138,8 @@ class DnsOverHttpsTest { } val recordedRequest = server.takeRequest() assertThat(recordedRequest.method).isEqualTo("GET") - assertThat(recordedRequest.path) - .isEqualTo("/lookup?ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ") + assertThat(recordedRequest.url.encodedQuery) + .isEqualTo("ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ") } @Test @@ -197,8 +197,8 @@ class DnsOverHttpsTest { assertThat(result).containsExactly(address("157.240.1.18")) var recordedRequest = server.takeRequest() assertThat(recordedRequest.method).isEqualTo("GET") - assertThat(recordedRequest.path) - .isEqualTo("/lookup?ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ") + assertThat(recordedRequest.url.encodedQuery) + .isEqualTo("ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ") assertThat(cacheEvents()).containsExactly("CacheMiss") @@ -212,8 +212,8 @@ class DnsOverHttpsTest { assertThat(result).containsExactly(address("157.240.1.18")) recordedRequest = server.takeRequest() assertThat(recordedRequest.method).isEqualTo("GET") - assertThat(recordedRequest.path) - .isEqualTo("/lookup?ct&dns=AAABAAABAAAAAAAAA3d3dwZnb29nbGUDY29tAAABAAE") + assertThat(recordedRequest.url.encodedQuery) + .isEqualTo("ct&dns=AAABAAABAAAAAAAAA3d3dwZnb29nbGUDY29tAAABAAE") assertThat(cacheEvents()).containsExactly("CacheMiss") } @@ -239,8 +239,8 @@ class DnsOverHttpsTest { assertThat(result).containsExactly(address("157.240.1.18")) var recordedRequest = server.takeRequest() assertThat(recordedRequest.method).isEqualTo("POST") - assertThat(recordedRequest.path) - .isEqualTo("/lookup?ct") + assertThat(recordedRequest.url.encodedQuery) + .isEqualTo("ct") assertThat(cacheEvents()).containsExactly("CacheMiss") @@ -254,8 +254,8 @@ class DnsOverHttpsTest { assertThat(result).containsExactly(address("157.240.1.18")) recordedRequest = server.takeRequest(0, TimeUnit.MILLISECONDS)!! assertThat(recordedRequest.method).isEqualTo("POST") - assertThat(recordedRequest.path) - .isEqualTo("/lookup?ct") + assertThat(recordedRequest.url.encodedQuery) + .isEqualTo("ct") assertThat(cacheEvents()).containsExactly("CacheMiss") } @@ -278,8 +278,8 @@ class DnsOverHttpsTest { assertThat(result).containsExactly(address("157.240.1.18")) var recordedRequest = server.takeRequest(0, TimeUnit.SECONDS) assertThat(recordedRequest!!.method).isEqualTo("GET") - assertThat(recordedRequest.path).isEqualTo( - "/lookup?ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ", + assertThat(recordedRequest.url.encodedQuery).isEqualTo( + "ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ", ) assertThat(cacheEvents()).containsExactly("CacheMiss") @@ -298,8 +298,8 @@ class DnsOverHttpsTest { assertThat(result).isEqualTo(listOf(address("157.240.1.18"))) recordedRequest = server.takeRequest(0, TimeUnit.SECONDS) assertThat(recordedRequest!!.method).isEqualTo("GET") - assertThat(recordedRequest.path) - .isEqualTo("/lookup?ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ") + assertThat(recordedRequest.url.encodedQuery) + .isEqualTo("ct&dns=AAABAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ") assertThat(cacheEvents()).containsExactly("CacheMiss") } diff --git a/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/RequestLine.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/RequestLine.kt index 6fd058ba7..426bfb4df 100644 --- a/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/RequestLine.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http/RequestLine.kt @@ -15,7 +15,6 @@ */ package okhttp3.internal.http -import java.net.HttpURLConnection import java.net.Proxy import okhttp3.HttpUrl import okhttp3.Request diff --git a/okhttp/src/jvmTest/kotlin/okhttp3/CallTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/CallTest.kt index 080395a2b..74db985cc 100644 --- a/okhttp/src/jvmTest/kotlin/okhttp3/CallTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/CallTest.kt @@ -2581,7 +2581,7 @@ open class CallTest { assertThat(response.body.string()).isEqualTo("Page 2") val redirectRequest = server2.takeRequest() assertThat(redirectRequest.headers["Authorization"]).isNull() - assertThat(redirectRequest.path).isEqualTo("/b") + assertThat(redirectRequest.url.encodedPath).isEqualTo("/b") } @Test @@ -2902,7 +2902,7 @@ open class CallTest { assertFailsWith { call.execute() } - assertThat(server.takeRequest().path).isEqualTo("/a") + assertThat(server.takeRequest().url.encodedPath).isEqualTo("/a") } @Test @@ -2946,7 +2946,7 @@ open class CallTest { } callA.enqueue(callback) callB.enqueue(callback) - assertThat(server.takeRequest().path).isEqualTo("/a") + assertThat(server.takeRequest().url.encodedPath).isEqualTo("/a") callback.await(requestA.url).assertBody("A") // At this point we know the callback is ready, and that it will receive a cancel failure. callback.await(requestB.url).assertFailure("Canceled", "Socket closed") @@ -2976,7 +2976,7 @@ open class CallTest { } } call.enqueue(callback) - assertThat(server.takeRequest().path).isEqualTo("/a") + assertThat(server.takeRequest().url.encodedPath).isEqualTo("/a") callback.await(requestA.url).assertFailure( "Canceled", "stream was reset: CANCEL", @@ -3956,11 +3956,11 @@ open class CallTest { val connect = server.takeRequest() assertThat(connect.method).isEqualTo("CONNECT") assertThat(connect.headers["Proxy-Authorization"]).isEqualTo(credential) - assertThat(connect.path).isEqualTo("/") + assertThat(connect.url.encodedPath).isEqualTo("/") val get = server.takeRequest() assertThat(get.method).isEqualTo("GET") assertThat(get.headers["Proxy-Authorization"]).isNull() - assertThat(get.path).isEqualTo("/foo") + assertThat(get.url.encodedPath).isEqualTo("/foo") } @Test @@ -4267,7 +4267,7 @@ open class CallTest { assertThat(get.requestLine).isEqualTo("GET / HTTP/1.1") assertThat(get.headers["Host"]).isEqualTo("[::1]:$port") assertThat(get.headers[":authority"]).isNull() - assertThat(get.requestUrl).isEqualTo(url) + assertThat(get.url).isEqualTo(url) } @Test @@ -4301,7 +4301,7 @@ open class CallTest { assertThat(get.headers[":authority"]).isEqualTo( "[::1]:$port", ) - assertThat(get.requestUrl).isEqualTo(url) + assertThat(get.url).isEqualTo(url) } @Test @@ -4335,7 +4335,7 @@ open class CallTest { "127.0.0.1:$port", ) assertThat(get.headers[":authority"]).isNull() - assertThat(get.requestUrl).isEqualTo(url) + assertThat(get.url).isEqualTo(url) } @Test @@ -4363,7 +4363,7 @@ open class CallTest { assertThat(get.requestLine).isEqualTo("GET / HTTP/1.1") assertThat(get.headers["Host"]).isNull() assertThat(get.headers[":authority"]).isEqualTo("127.0.0.1:$port") - assertThat(get.requestUrl).isEqualTo(url) + assertThat(get.url).isEqualTo(url) } @Test @@ -4391,7 +4391,7 @@ open class CallTest { assertThat(get.requestLine).isEqualTo("GET / HTTP/1.1") assertThat(get.headers["Host"]).isEqualTo("any-host-name:$port") assertThat(get.headers[":authority"]).isNull() - assertThat(get.requestUrl).isEqualTo(url) + assertThat(get.url).isEqualTo(url) } @Test @@ -4419,7 +4419,7 @@ open class CallTest { assertThat(get.requestLine).isEqualTo("GET / HTTP/1.1") assertThat(get.headers["Host"]).isNull() assertThat(get.headers[":authority"]).isEqualTo("any-host-name:$port") - assertThat(get.requestUrl).isEqualTo(url) + assertThat(get.url).isEqualTo(url) } /** Use a proxy to fake IPv6 connectivity, even if localhost doesn't have IPv6. */ diff --git a/okhttp/src/jvmTest/kotlin/okhttp3/URLConnectionTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/URLConnectionTest.kt index 179ef4f23..67d9e9dc8 100644 --- a/okhttp/src/jvmTest/kotlin/okhttp3/URLConnectionTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/URLConnectionTest.kt @@ -653,7 +653,7 @@ class URLConnectionTest { val response = getResponse(newRequest("/foo")) assertContent("this response comes via SSL", response) val failHandshakeRequest = server.takeRequest() - assertThat(failHandshakeRequest.requestLine).isEmpty() + assertThat(failHandshakeRequest.requestLine).isEqualTo("GET / HTTP/1.1") val fallbackRequest = server.takeRequest() assertThat(fallbackRequest.requestLine).isEqualTo("GET /foo HTTP/1.1") assertThat(fallbackRequest.handshake?.tlsVersion).isIn(TlsVersion.TLS_1_2, TlsVersion.TLS_1_3) @@ -2591,7 +2591,7 @@ class URLConnectionTest { assertContent("Page 2", getResponse(newRequest("/a"))) val redirectRequest = server2.takeRequest() assertThat(redirectRequest.headers["Authorization"]).isNull() - assertThat(redirectRequest.path).isEqualTo("/b") + assertThat(redirectRequest.url.encodedPath).isEqualTo("/b") } @Test @@ -3513,9 +3513,9 @@ class URLConnectionTest { } } val requestA = server.takeRequest() - assertThat(requestA.path).isEqualTo("/a") + assertThat(requestA.url.encodedPath).isEqualTo("/a") val requestB = server.takeRequest() - assertThat(requestB.path).isEqualTo("/b") + assertThat(requestB.url.encodedPath).isEqualTo("/b") assertThat(requestB.body.utf8()).isEqualTo(requestBody) } diff --git a/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/HttpOverHttp2Test.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/HttpOverHttp2Test.kt index d9f66c38d..aa2ff0b8a 100644 --- a/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/HttpOverHttp2Test.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/HttpOverHttp2Test.kt @@ -596,9 +596,9 @@ class HttpOverHttp2Test { val response = call.execute() assertThat(response.body.string()).isEqualTo("This is the new location!") val request1 = server.takeRequest() - assertThat(request1.path).isEqualTo("/") + assertThat(request1.url.encodedPath).isEqualTo("/") val request2 = server.takeRequest() - assertThat(request2.path).isEqualTo("/foo") + assertThat(request2.url.encodedPath).isEqualTo("/foo") } @ParameterizedTest @@ -2158,11 +2158,11 @@ class HttpOverHttp2Test { assertThat(call2Connect.sequenceNumber).isEqualTo(0) val call2Get = server.takeRequest() assertThat(call2Get.method).isEqualTo("GET") - assertThat(call2Get.path).isEqualTo("/call2") + assertThat(call2Get.url.encodedPath).isEqualTo("/call2") assertThat(call2Get.sequenceNumber).isEqualTo(0) val call1Get = server.takeRequest() assertThat(call1Get.method).isEqualTo("GET") - assertThat(call1Get.path).isEqualTo("/call1") + assertThat(call1Get.url.encodedPath).isEqualTo("/call1") assertThat(call1Get.sequenceNumber).isEqualTo(1) assertThat(client.connectionPool.connectionCount()).isEqualTo(1) }