Github: okhttp 分析版本: 930d4d0
Bridges from application code to network code
class BridgeInterceptor(private val cookieJar: CookieJar) : Interceptor { @Throws(IOException::class) override fun intercept(chain: Interceptor.Chain): Response { val userRequest = chain.request() val requestBuilder = userRequest.newBuilder() val body = userRequest.body // 对请求头的补充 if (body != null) { val contentType = body.contentType() if (contentType != null) { requestBuilder.header("Content-Type", contentType.toString()) } val contentLength = body.contentLength() if (contentLength != -1L) { requestBuilder.header("Content-Length", contentLength.toString()) requestBuilder.removeHeader("Transfer-Encoding") } else { requestBuilder.header("Transfer-Encoding", "chunked") requestBuilder.removeHeader("Content-Length") } } if (userRequest.header("Host") == null) { requestBuilder.header("Host", userRequest.url.toHostHeader()) } // 默认保持连接 Keep-Alive if (userRequest.header("Connection") == null) { requestBuilder.header("Connection", "Keep-Alive") } // 默认 GZIP 压缩 // If we add an "Accept-Encoding: gzip" header field we're responsible for also decompressing // the transfer stream. var transparentGzip = false if (userRequest.header("Accept-Encoding") == null && userRequest.header("Range") == null) { transparentGzip = true requestBuilder.header("Accept-Encoding", "gzip") } // cookies 信息 val cookies = cookieJar.loadForRequest(userRequest.url) if (cookies.isNotEmpty()) { requestBuilder.header("Cookie", cookieHeader(cookies)) } if (userRequest.header("User-Agent") == null) { requestBuilder.header("User-Agent", userAgent) } // 丢给下一个拦截器发送网络请求 val networkResponse = chain.proceed(requestBuilder.build()) // 接受服务器返回的 Cookies cookieJar.receiveHeaders(userRequest.url, networkResponse.headers()) val responseBuilder = networkResponse.newBuilder() .request(userRequest) if (transparentGzip && "gzip".equals(networkResponse.header("Content-Encoding"), ignoreCase = true) && networkResponse.promisesBody()) { // 当服务器返回的数据是 GZIP 压缩的,那么客户端就进行解压操作 val responseBody = networkResponse.body() if (responseBody != null) { val gzipSource = GzipSource(responseBody.source()) val strippedHeaders = networkResponse.headers().newBuilder() .removeAll("Content-Encoding") .removeAll("Content-Length") .build() responseBuilder.headers(strippedHeaders) val contentType = networkResponse.header("Content-Type") responseBuilder.body(RealResponseBody(contentType, -1L, gzipSource.buffer())) } } // 构建 Response return responseBuilder.build() } /** Returns a 'Cookie' HTTP request header with all cookies, like `a=b; c=d`. */ private fun cookieHeader(cookies: List<Cookie>): String = buildString { cookies.forEachIndexed { index, cookie -> if (index > 0) append("; ") append(cookie.name).append('=').append(cookie.value) } } }
因为用户在构建一个 Request 对象的时侯往往只会简单设置 url, RequestBody 等几个属性,但是真正要发送一个请求实际上没这么简单,在原来的基础上添加了很多请求头