美文网首页Android
CallServerInterceptor

CallServerInterceptor

作者: 大佬的上半生 | 来源:发表于2019-10-24 17:21 被阅读0次

    CallServerInterceptor
    这是链中的最后一个拦截器。 它向服务器进行网络调用

    class CallServerInterceptor(private val forWebSocket: Boolean) : Interceptor {
    
      @Throws(IOException::class)
      override fun intercept(chain: Interceptor.Chain): Response {
        val realChain = chain as RealInterceptorChain
        val exchange = realChain.exchange()
        val request = realChain.request()
        val requestBody = request.body
        val sentRequestMillis = System.currentTimeMillis()
      //写入请求header
        exchange.writeRequestHeaders(request)
        var responseHeadersStarted = false
        var responseBuilder: Response.Builder? = null
        if (HttpMethod.permitsRequestBody(request.method) && requestBody != null) {
         //如果请求头的Expect: 100-continue时,只发送请求头
          if ("100-continue".equals(request.header("Expect"), ignoreCase = true)) {
            exchange.flushRequest()
            responseHeadersStarted = true
            exchange.responseHeadersStart()
            responseBuilder = exchange.readResponseHeaders(true)
          }
          if (responseBuilder == null) {
            if (requestBody.isDuplex()) {
              // 准备body,以便应用程序可以稍后发送请求正文。
              exchange.flushRequest()
              val bufferedRequestBody = exchange.createRequestBody(request, true).buffer()
              requestBody.writeTo(bufferedRequestBody)
            } else {
              // 如果满足“Expect:100-continue”期望,请入Body
              val bufferedRequestBody = exchange.createRequestBody(request, false).buffer()
              requestBody.writeTo(bufferedRequestBody)
              bufferedRequestBody.close()
            }
          } else {
            exchange.noRequestBody()
            if (!exchange.connection()!!.isMultiplexed) {
              // 如果未满足“Expect:100-continue”期望,则阻止HTTP / 1连接
                //在离开时保持连接状态
              exchange.noNewExchangesOnConnection()
            }
          }
        } else {
          exchange.noRequestBody()
        }
        //结束请求
        if (requestBody == null || !requestBody.isDuplex()) {
          exchange.finishRequest()
        }
        if (!responseHeadersStarted) {
          exchange.responseHeadersStart()
        }
    //构建响应体
        if (responseBuilder == null) {
          responseBuilder = exchange.readResponseHeaders(false)!!
        }
        var response = responseBuilder
            .request(request)
            .handshake(exchange.connection()!!.handshake())
            .sentRequestAtMillis(sentRequestMillis)
            .receivedResponseAtMillis(System.currentTimeMillis())
            .build()
        var code = response.code
        if (code == 100) {
          //服务器发送了100-continue,即使我们没有请求一个。
            //再试一次,看看实际的反应
          response = exchange.readResponseHeaders(false)!!
              .request(request)
              .handshake(exchange.connection()!!.handshake())
              .sentRequestAtMillis(sentRequestMillis)
              .receivedResponseAtMillis(System.currentTimeMillis())
              .build()
          code = response.code
        }
    
        exchange.responseHeadersEnd(response)
    
        response = if (forWebSocket && code == 101) {
          // 连接正在升级,但我们需要确保拦截器看到非空响应主体。
          response.newBuilder()
              .body(EMPTY_RESPONSE)
              .build()
        } else {
          response.newBuilder()
              .body(exchange.openResponseBody(response))
              .build()
        }
        if ("close".equals(response.request.header("Connection"), ignoreCase = true) ||
            "close".equals(response.header("Connection"), ignoreCase = true)) {
          exchange.noNewExchangesOnConnection()
        }
        if ((code == 204 || code == 205) && response.body?.contentLength() ?: -1L > 0L) {
          throw ProtocolException(
              "HTTP $code had non-zero Content-Length: ${response.body?.contentLength()}")
        }
    //返回响应
        return response
      }
    }
    
    1.写入header
      exchange.writeRequestHeaders(request)
    
    
    fun writeRequestHeaders(request: Request) {
        try {
          eventListener.requestHeadersStart(call)
          codec.writeRequestHeaders(request)
          eventListener.requestHeadersEnd(call, request)
        } catch (e: IOException) {
          eventListener.requestFailed(call, e)
          trackFailure(e)
          throw e
        }
      }
    
    2. 写入请求体requestBody.writeTo(bufferedRequestBody)
     if (requestBody.isDuplex()) {
              // Prepare a duplex body so that the application can send a request body later.
              exchange.flushRequest()
              val bufferedRequestBody = exchange.createRequestBody(request, true).buffer()
              requestBody.writeTo(bufferedRequestBody)
            } else {
              // Write the request body if the "Expect: 100-continue" expectation was met.
              val bufferedRequestBody = exchange.createRequestBody(request, false).buffer()
              requestBody.writeTo(bufferedRequestBody)
              bufferedRequestBody.close()
            }
    
     override fun writeTo(sink: BufferedSink) {
              sink.write(this@toRequestBody, offset, byteCount)
            }
    
    3. 获取响应 responseBuilder = exchange.readResponseHeaders(true)
    override fun readResponseHeaders(expectContinue: Boolean): Response.Builder? {
        check(state == STATE_OPEN_REQUEST_BODY || state == STATE_READ_RESPONSE_HEADERS) {
          "state: $state"
        }
    
        try {
          val statusLine = StatusLine.parse(readHeaderLine())
    
          val responseBuilder = Response.Builder()
              .protocol(statusLine.protocol)
              .code(statusLine.code)
              .message(statusLine.message)
              .headers(readHeaders())
    
          return when {
            expectContinue && statusLine.code == HTTP_CONTINUE -> {
              null
            }
            statusLine.code == HTTP_CONTINUE -> {
              state = STATE_READ_RESPONSE_HEADERS
              responseBuilder
            }
            else -> {
              state = STATE_OPEN_RESPONSE_BODY
              responseBuilder
            }
          }
        } catch (e: EOFException) {
          // Provide more context if the server ends the stream before sending a response.
          val address = realConnection?.route()?.address?.url?.redact() ?: "unknown"
          throw IOException("unexpected end of stream on $address", e)
        }
      }
    
    responseBuilder = exchange.readResponseHeaders(true)
    
    4. 构建 responseBuilder
     var response = responseBuilder
            .request(request)
            .handshake(exchange.connection()!!.handshake())
            .sentRequestAtMillis(sentRequestMillis)
            .receivedResponseAtMillis(System.currentTimeMillis())
            .build()
        var code = response.code
        if (code == 100) {
          // server sent a 100-continue even though we did not request one.
          // try again to read the actual response
          response = exchange.readResponseHeaders(false)!!
              .request(request)
              .handshake(exchange.connection()!!.handshake())
              .sentRequestAtMillis(sentRequestMillis)
              .receivedResponseAtMillis(System.currentTimeMillis())
              .build()
          code = response.code
        }
    
        exchange.responseHeadersEnd(response)
    
        response = if (forWebSocket && code == 101) {
          // Connection is upgrading, but we need to ensure interceptors see a non-null response body.
          response.newBuilder()
              .body(EMPTY_RESPONSE)
              .build()
        } else {
          response.newBuilder()
              .body(exchange.openResponseBody(response))
              .build()
        }
    

    最终实现ExchangeCodec 中的readHttp2HeadersList ()

      /** Returns headers for a name value block containing an HTTP/2 response. */
        fun readHttp2HeadersList(headerBlock: Headers, protocol: Protocol): Response.Builder {
          var statusLine: StatusLine? = null
          val headersBuilder = Headers.Builder()
          for (i in 0 until headerBlock.size) {
            val name = headerBlock.name(i)
            val value = headerBlock.value(i)
            if (name == RESPONSE_STATUS_UTF8) {
              statusLine = StatusLine.parse("HTTP/1.1 $value")
            } else if (name !in HTTP_2_SKIPPED_RESPONSE_HEADERS) {
              headersBuilder.addLenient(name, value)
            }
          }
          if (statusLine == null) throw ProtocolException("Expected ':status' header not present")
    
          return Response.Builder()
              .protocol(protocol)
              .code(statusLine.code)
              .message(statusLine.message)
              .headers(headersBuilder.build())
        }
    

    相关文章

      网友评论

        本文标题:CallServerInterceptor

        本文链接:https://www.haomeiwen.com/subject/ixosyctx.html