in ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt [37:99]
override suspend fun execute(data: HttpRequestData): HttpResponseData {
val callContext = callContext()
val requestTime = GMTDate()
val url: String = URLBuilder().takeFrom(data.url).buildString()
val outgoingContent: OutgoingContent = data.body
val contentLength: Long? = data.headers[HttpHeaders.ContentLength]?.toLong()
?: outgoingContent.contentLength
val connection: HttpURLConnection = getProxyAwareConnection(url).apply {
connectTimeout = config.connectTimeout
readTimeout = config.socketTimeout
setupTimeoutAttributes(data)
if (this is HttpsURLConnection) {
config.sslManager(this)
}
requestMethod = data.method.value
useCaches = false
instanceFollowRedirects = false
mergeHeaders(data.headers, outgoingContent) { key: String, value: String ->
addRequestProperty(key, value)
}
config.requestConfig(this)
if (outgoingContent !is OutgoingContent.NoContent) {
if (data.method in listOf(HttpMethod.Get, HttpMethod.Head)) error(
"Request of type ${data.method} couldn't send a body with the [Android] engine."
)
if (contentLength == null && getRequestProperty(HttpHeaders.TransferEncoding) == null) {
addRequestProperty(HttpHeaders.TransferEncoding, "chunked")
}
contentLength?.let { setFixedLengthStreamingMode(it.toInt()) } ?: setChunkedStreamingMode(0)
doOutput = true
outgoingContent.writeTo(outputStream, callContext)
}
}
connection.timeoutAwareConnect(data)
val responseCode = connection.responseCode
val responseMessage = connection.responseMessage
val statusCode = responseMessage?.let { HttpStatusCode(responseCode, it) } ?: HttpStatusCode.fromValue(responseCode)
val content: ByteReadChannel = connection.content(callContext, data)
val headerFields: MutableMap<String?, MutableList<String>> = connection.headerFields
val version: HttpProtocolVersion = HttpProtocolVersion.HTTP_1_1
val responseHeaders = HeadersBuilder().apply {
headerFields.forEach { (key: String?, values: MutableList<String>) ->
if (key != null) appendAll(key, values)
}
}.build()
return HttpResponseData(statusCode, requestTime, responseHeaders, version, content, callContext)
}