override suspend fun execute()

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)
    }