mirror of
https://github.com/square/okhttp.git
synced 2025-11-24 18:41:06 +03:00
Idiomatic Kotlin in MockResponse.kt
This commit is contained in:
@@ -31,7 +31,8 @@ abstract class Dispatcher {
|
||||
* request bodies.
|
||||
*/
|
||||
open fun peek(): MockResponse {
|
||||
return MockResponse().setSocketPolicy(SocketPolicy.KEEP_OPEN)
|
||||
val mockResponse = MockResponse()
|
||||
return mockResponse.apply { mockResponse.socketPolicy = SocketPolicy.KEEP_OPEN }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,10 @@ import java.util.concurrent.TimeUnit
|
||||
|
||||
/** A scripted response to be replayed by the mock web server. */
|
||||
class MockResponse : Cloneable {
|
||||
private var status: String = ""
|
||||
/** Returns the HTTP response line, such as "HTTP/1.1 200 OK". */
|
||||
@set:JvmName("status")
|
||||
var status: String = ""
|
||||
|
||||
private var headers = Headers.Builder()
|
||||
private var trailers = Headers.Builder()
|
||||
|
||||
@@ -36,8 +39,16 @@ class MockResponse : Cloneable {
|
||||
private var throttlePeriodAmount = 1L
|
||||
private var throttlePeriodUnit = TimeUnit.SECONDS
|
||||
|
||||
private var socketPolicy = SocketPolicy.KEEP_OPEN
|
||||
private var http2ErrorCode = -1
|
||||
@set:JvmName("socketPolicy")
|
||||
var socketPolicy = SocketPolicy.KEEP_OPEN
|
||||
|
||||
/**
|
||||
* Sets the [HTTP/2 error code](https://tools.ietf.org/html/rfc7540#section-7) to be
|
||||
* returned when resetting the stream.
|
||||
* This is only valid with [SocketPolicy.RESET_STREAM_AT_START].
|
||||
*/
|
||||
@set:JvmName("http2ErrorCode")
|
||||
var http2ErrorCode = -1
|
||||
|
||||
private var bodyDelayAmount = 0L
|
||||
private var bodyDelayUnit = TimeUnit.MILLISECONDS
|
||||
@@ -72,9 +83,21 @@ class MockResponse : Cloneable {
|
||||
return result
|
||||
}
|
||||
|
||||
/** Returns the HTTP response line, such as "HTTP/1.1 200 OK". */
|
||||
@JvmName("-deprecated_getStatus")
|
||||
@Deprecated(
|
||||
message = "moved to var",
|
||||
replaceWith = ReplaceWith(expression = "status"),
|
||||
level = DeprecationLevel.WARNING)
|
||||
fun getStatus(): String = status
|
||||
|
||||
@Deprecated(
|
||||
message = "moved to var. Replace setStatus(...) with status(...) to fix Java",
|
||||
replaceWith = ReplaceWith(expression = "apply { this.status = status }"),
|
||||
level = DeprecationLevel.WARNING)
|
||||
fun setStatus(status: String) = apply {
|
||||
this.status = status
|
||||
}
|
||||
|
||||
fun setResponseCode(code: Int): MockResponse {
|
||||
val reason = when (code) {
|
||||
in 100..199 -> "Informational"
|
||||
@@ -84,11 +107,7 @@ class MockResponse : Cloneable {
|
||||
in 500..599 -> "Server Error"
|
||||
else -> "Mock Response"
|
||||
}
|
||||
return setStatus("HTTP/1.1 $code $reason")
|
||||
}
|
||||
|
||||
fun setStatus(status: String) = apply {
|
||||
this.status = status
|
||||
return apply { status = "HTTP/1.1 $code $reason" }
|
||||
}
|
||||
|
||||
/** Returns the HTTP headers, such as "Content-Length: 0". */
|
||||
@@ -193,19 +212,32 @@ class MockResponse : Cloneable {
|
||||
fun setChunkedBody(body: String, maxChunkSize: Int): MockResponse =
|
||||
setChunkedBody(Buffer().writeUtf8(body), maxChunkSize)
|
||||
|
||||
@JvmName("-deprecated_getSocketPolicy")
|
||||
@Deprecated(
|
||||
message = "moved to var",
|
||||
replaceWith = ReplaceWith(expression = "socketPolicy"),
|
||||
level = DeprecationLevel.WARNING)
|
||||
fun getSocketPolicy() = socketPolicy
|
||||
|
||||
@Deprecated(
|
||||
message = "moved to var. Replace setSocketPolicy(...) with socketPolicy(...) to fix Java",
|
||||
replaceWith = ReplaceWith(expression = "apply { this.socketPolicy = socketPolicy }"),
|
||||
level = DeprecationLevel.WARNING)
|
||||
fun setSocketPolicy(socketPolicy: SocketPolicy) = apply {
|
||||
this.socketPolicy = socketPolicy
|
||||
}
|
||||
|
||||
@JvmName("-deprecated_getHttp2ErrorCode")
|
||||
@Deprecated(
|
||||
message = "moved to var",
|
||||
replaceWith = ReplaceWith(expression = "http2ErrorCode"),
|
||||
level = DeprecationLevel.WARNING)
|
||||
fun getHttp2ErrorCode() = http2ErrorCode
|
||||
|
||||
/**
|
||||
* Sets the [HTTP/2 error code](https://tools.ietf.org/html/rfc7540#section-7) to be
|
||||
* returned when resetting the stream.
|
||||
* This is only valid with [SocketPolicy.RESET_STREAM_AT_START].
|
||||
*/
|
||||
@Deprecated(
|
||||
message = "moved to var. Replace setHttp2ErrorCode(...) with http2ErrorCode(...) to fix Java",
|
||||
replaceWith = ReplaceWith(expression = "apply { this.http2ErrorCode = http2ErrorCode }"),
|
||||
level = DeprecationLevel.WARNING)
|
||||
fun setHttp2ErrorCode(http2ErrorCode: Int) = apply {
|
||||
this.http2ErrorCode = http2ErrorCode
|
||||
}
|
||||
@@ -264,7 +296,7 @@ class MockResponse : Cloneable {
|
||||
* This will overwrite any previously set status or body.
|
||||
*/
|
||||
fun withWebSocketUpgrade(listener: WebSocketListener) = apply {
|
||||
setStatus("HTTP/1.1 101 Switching Protocols")
|
||||
status = "HTTP/1.1 101 Switching Protocols"
|
||||
setHeader("Connection", "Upgrade")
|
||||
setHeader("Upgrade", "websocket")
|
||||
body = null
|
||||
|
||||
@@ -370,7 +370,7 @@ class MockWebServer : ExternalResource(), Closeable {
|
||||
return
|
||||
}
|
||||
|
||||
val socketPolicy = dispatcher.peek().getSocketPolicy()
|
||||
val socketPolicy = dispatcher.peek().socketPolicy
|
||||
if (socketPolicy === DISCONNECT_AT_START) {
|
||||
dispatchBookkeepingRequest(0, socket)
|
||||
socket.close()
|
||||
@@ -426,7 +426,7 @@ class MockWebServer : ExternalResource(), Closeable {
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun handle() {
|
||||
val socketPolicy = dispatcher.peek().getSocketPolicy()
|
||||
val socketPolicy = dispatcher.peek().socketPolicy
|
||||
var protocol = Protocol.HTTP_1_1
|
||||
val socket: Socket
|
||||
when {
|
||||
@@ -513,7 +513,7 @@ class MockWebServer : ExternalResource(), Closeable {
|
||||
val source = raw.source().buffer()
|
||||
val sink = raw.sink().buffer()
|
||||
while (true) {
|
||||
val socketPolicy = dispatcher.peek().getSocketPolicy()
|
||||
val socketPolicy = dispatcher.peek().socketPolicy
|
||||
check(processOneRequest(raw, source, sink)) { "Tunnel without any CONNECT!" }
|
||||
if (socketPolicy === UPGRADE_TO_SSL_AT_END) return
|
||||
}
|
||||
@@ -535,11 +535,11 @@ class MockWebServer : ExternalResource(), Closeable {
|
||||
requestQueue.add(request)
|
||||
|
||||
val response = dispatcher.dispatch(request)
|
||||
if (response.getSocketPolicy() === DISCONNECT_AFTER_REQUEST) {
|
||||
if (response.socketPolicy === DISCONNECT_AFTER_REQUEST) {
|
||||
socket.close()
|
||||
return false
|
||||
}
|
||||
if (response.getSocketPolicy() === NO_RESPONSE) {
|
||||
if (response.socketPolicy === NO_RESPONSE) {
|
||||
// This read should block until the socket is closed. (Because nobody is writing.)
|
||||
if (source.exhausted()) return false
|
||||
throw ProtocolException("unexpected data")
|
||||
@@ -563,7 +563,7 @@ class MockWebServer : ExternalResource(), Closeable {
|
||||
}
|
||||
|
||||
// See warnings associated with these socket policies in SocketPolicy.
|
||||
when (response.getSocketPolicy()) {
|
||||
when (response.socketPolicy) {
|
||||
DISCONNECT_AT_END -> {
|
||||
socket.close()
|
||||
return false
|
||||
@@ -644,7 +644,7 @@ class MockWebServer : ExternalResource(), Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
val socketPolicy = dispatcher.peek().getSocketPolicy()
|
||||
val socketPolicy = dispatcher.peek().socketPolicy
|
||||
if (expectContinue && socketPolicy === EXPECT_CONTINUE || socketPolicy === CONTINUE_ALWAYS) {
|
||||
sink.writeUtf8("HTTP/1.1 100 Continue\r\n")
|
||||
sink.writeUtf8("Content-Length: 0\r\n")
|
||||
@@ -703,7 +703,7 @@ class MockWebServer : ExternalResource(), Closeable {
|
||||
.url("$scheme://$authority/")
|
||||
.headers(request.headers)
|
||||
.build()
|
||||
val statusParts = response.getStatus().split(' ', limit = 3)
|
||||
val statusParts = response.status.split(' ', limit = 3)
|
||||
val fancyResponse = Response.Builder()
|
||||
.code(Integer.parseInt(statusParts[1]))
|
||||
.message(statusParts[2])
|
||||
@@ -735,7 +735,7 @@ class MockWebServer : ExternalResource(), Closeable {
|
||||
@Throws(IOException::class)
|
||||
private fun writeHttpResponse(socket: Socket, sink: BufferedSink, response: MockResponse) {
|
||||
sleepIfDelayed(response.getHeadersDelay(TimeUnit.MILLISECONDS))
|
||||
sink.writeUtf8(response.getStatus())
|
||||
sink.writeUtf8(response.status)
|
||||
sink.writeUtf8("\r\n")
|
||||
|
||||
writeHeaders(sink, response.getHeaders())
|
||||
@@ -789,9 +789,9 @@ class MockWebServer : ExternalResource(), Closeable {
|
||||
|
||||
val halfByteCount = byteCountNum / 2
|
||||
val disconnectHalfway = if (isRequest) {
|
||||
policy.getSocketPolicy() === DISCONNECT_DURING_REQUEST_BODY
|
||||
policy.socketPolicy === DISCONNECT_DURING_REQUEST_BODY
|
||||
} else {
|
||||
policy.getSocketPolicy() === DISCONNECT_DURING_RESPONSE_BODY
|
||||
policy.socketPolicy === DISCONNECT_DURING_RESPONSE_BODY
|
||||
}
|
||||
|
||||
while (!socket.isClosed) {
|
||||
@@ -879,9 +879,9 @@ class MockWebServer : ExternalResource(), Closeable {
|
||||
@Throws(IOException::class)
|
||||
override fun onStream(stream: Http2Stream) {
|
||||
val peekedResponse = dispatcher.peek()
|
||||
if (peekedResponse.getSocketPolicy() === RESET_STREAM_AT_START) {
|
||||
if (peekedResponse.socketPolicy === RESET_STREAM_AT_START) {
|
||||
dispatchBookkeepingRequest(sequenceNumber.getAndIncrement(), socket)
|
||||
stream.close(ErrorCode.fromHttp2(peekedResponse.getHttp2ErrorCode())!!, null)
|
||||
stream.close(ErrorCode.fromHttp2(peekedResponse.http2ErrorCode)!!, null)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -891,7 +891,7 @@ class MockWebServer : ExternalResource(), Closeable {
|
||||
|
||||
val response: MockResponse = dispatcher.dispatch(request)
|
||||
|
||||
if (response.getSocketPolicy() === DISCONNECT_AFTER_REQUEST) {
|
||||
if (response.socketPolicy === DISCONNECT_AFTER_REQUEST) {
|
||||
socket.close()
|
||||
return
|
||||
}
|
||||
@@ -902,7 +902,7 @@ class MockWebServer : ExternalResource(), Closeable {
|
||||
"and responded: $response protocol is $protocol")
|
||||
}
|
||||
|
||||
if (response.getSocketPolicy() === DISCONNECT_AT_END) {
|
||||
if (response.socketPolicy === DISCONNECT_AT_END) {
|
||||
val connection = stream.connection
|
||||
connection.shutdown(ErrorCode.NO_ERROR)
|
||||
}
|
||||
@@ -933,7 +933,7 @@ class MockWebServer : ExternalResource(), Closeable {
|
||||
val headers = httpHeaders.build()
|
||||
|
||||
val peek = dispatcher.peek()
|
||||
if (!readBody && peek.getSocketPolicy() === EXPECT_CONTINUE) {
|
||||
if (!readBody && peek.socketPolicy === EXPECT_CONTINUE) {
|
||||
val continueHeaders =
|
||||
listOf(Header(Header.RESPONSE_STATUS, "100 Continue".encodeUtf8()))
|
||||
stream.writeHeaders(continueHeaders, outFinished = false, flushHeaders = true)
|
||||
@@ -964,13 +964,14 @@ class MockWebServer : ExternalResource(), Closeable {
|
||||
val settings = response.settings
|
||||
stream.connection.setSettings(settings)
|
||||
|
||||
if (response.getSocketPolicy() === NO_RESPONSE) {
|
||||
if (response.socketPolicy === NO_RESPONSE) {
|
||||
return
|
||||
}
|
||||
val http2Headers = mutableListOf<Header>()
|
||||
val statusParts = response.getStatus().split(' ', limit = 3)
|
||||
val statusParts = response.status.split(' ', limit = 3)
|
||||
|
||||
if (statusParts.size < 2) {
|
||||
throw AssertionError("Unexpected status: ${response.getStatus()}")
|
||||
throw AssertionError("Unexpected status: ${response.status}")
|
||||
}
|
||||
// TODO: constants for well-known header names.
|
||||
http2Headers.add(Header(Header.RESPONSE_STATUS, statusParts[1]))
|
||||
|
||||
@@ -81,8 +81,10 @@ open class QueueDispatcher : Dispatcher() {
|
||||
* Enqueued on shutdown to release threads waiting on [dispatch]. Note that this response
|
||||
* isn't transmitted because the connection is closed before this response is returned.
|
||||
*/
|
||||
private val DEAD_LETTER = MockResponse()
|
||||
.setStatus("HTTP/1.1 $HTTP_UNAVAILABLE shutting down")
|
||||
private val DEAD_LETTER = run {
|
||||
val mockResponse = MockResponse()
|
||||
mockResponse.apply { mockResponse.status = "HTTP/1.1 $HTTP_UNAVAILABLE shutting down" }
|
||||
}
|
||||
|
||||
private val logger = Logger.getLogger(QueueDispatcher::class.java.name)
|
||||
}
|
||||
|
||||
@@ -682,10 +682,10 @@ class KotlinSourceModernTest {
|
||||
@Test @Ignore
|
||||
fun mockResponse() {
|
||||
var mockResponse: MockResponse = MockResponse()
|
||||
var status: String = mockResponse.getStatus()
|
||||
status = mockResponse.getStatus()
|
||||
mockResponse = mockResponse.setStatus("")
|
||||
mockResponse.setStatus("")
|
||||
var status: String = mockResponse.status
|
||||
status = mockResponse.status
|
||||
mockResponse = mockResponse.apply { mockResponse.status = "" }
|
||||
mockResponse.status = ""
|
||||
mockResponse = mockResponse.setResponseCode(0)
|
||||
var headers: Headers = mockResponse.getHeaders()
|
||||
headers = mockResponse.getHeaders()
|
||||
@@ -705,13 +705,14 @@ class KotlinSourceModernTest {
|
||||
mockResponse.setBody(Buffer())
|
||||
mockResponse = mockResponse.setChunkedBody(Buffer(), 0)
|
||||
mockResponse = mockResponse.setChunkedBody("", 0)
|
||||
var socketPolicy: SocketPolicy = mockResponse.getSocketPolicy()
|
||||
socketPolicy = mockResponse.getSocketPolicy()
|
||||
mockResponse = mockResponse.setSocketPolicy(SocketPolicy.KEEP_OPEN)
|
||||
var http2ErrorCode: Int = mockResponse.getHttp2ErrorCode()
|
||||
http2ErrorCode = mockResponse.getHttp2ErrorCode()
|
||||
mockResponse = mockResponse.setHttp2ErrorCode(0)
|
||||
mockResponse.setHttp2ErrorCode(0)
|
||||
var socketPolicy: SocketPolicy = mockResponse.socketPolicy
|
||||
socketPolicy = mockResponse.socketPolicy
|
||||
mockResponse = mockResponse.apply { mockResponse.socketPolicy = SocketPolicy.KEEP_OPEN }
|
||||
mockResponse.socketPolicy = SocketPolicy.KEEP_OPEN
|
||||
var http2ErrorCode: Int = mockResponse.http2ErrorCode
|
||||
http2ErrorCode = mockResponse.http2ErrorCode
|
||||
mockResponse = mockResponse.apply { mockResponse.http2ErrorCode = 0 }
|
||||
mockResponse.http2ErrorCode = 0
|
||||
mockResponse = mockResponse.throttleBody(0L, 0L, TimeUnit.SECONDS)
|
||||
var throttleBytesPerPeriod: Long = mockResponse.throttleBytesPerPeriod
|
||||
throttleBytesPerPeriod = mockResponse.throttleBytesPerPeriod
|
||||
|
||||
Reference in New Issue
Block a user