美文网首页
探究OkHttpClient的运行原理(6---CallServ

探究OkHttpClient的运行原理(6---CallServ

作者: 零星瓢虫 | 来源:发表于2021-01-20 00:29 被阅读0次

    CallServerInterceptor

    本篇为 OkHttp 请求最后一个拦截器 CallServerInterceptor,即调用服务器的拦截;

    同样,直接查看 CallServerInterceptor 的 intercept 方法;

      @Override public Response intercept(Chain chain) throws IOException {
        RealInterceptorChain realChain = (RealInterceptorChain) chain; // 获取责任链
        HttpCodec httpCodec = realChain.httpStream();// 获取 上一个拦截器 ConnectInterceptor 创建的 HttpCodec 实例对象
        StreamAllocation streamAllocation = realChain.streamAllocation(); // 获取 StreamAllocation 实例对象
        RealConnection connection = (RealConnection) realChain.connection();// 获取 RealConnection
        Request request = realChain.request(); // 获取 Requset
    
        long sentRequestMillis = System.currentTimeMillis();
    
        realChain.eventListener().requestHeadersStart(realChain.call());// 监听回调
        httpCodec.writeRequestHeaders(request);// 写入请求头部数据
        realChain.eventListener().requestHeadersEnd(realChain.call(), request);// 监听回调
    
        Response.Builder responseBuilder = null;
        if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) { //允许的请求,且请求体不为null
          // If there's a "Expect: 100-continue" header on the request, wait for a "HTTP/1.1 100
          // Continue" response before transmitting the request body. If we don't get that, return
          // what we did get (such as a 4xx response) without ever transmitting the request body.
          if ("100-continue".equalsIgnoreCase(request.header("Expect"))) { // 是否允许请求
            httpCodec.flushRequest();
            realChain.eventListener().responseHeadersStart(realChain.call());
            responseBuilder = httpCodec.readResponseHeaders(true);
          }
          
          if (responseBuilder == null) { // 允许请求
            // Write the request body if the "Expect: 100-continue" expectation was met.
            realChain.eventListener().requestBodyStart(realChain.call());
            long contentLength = request.body().contentLength();
            CountingSink requestBodyOut =
                new CountingSink(httpCodec.createRequestBody(request, contentLength));
            BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut);
            //写入请求体数据
            request.body().writeTo(bufferedRequestBody);
            bufferedRequestBody.close();
            realChain.eventListener()
                .requestBodyEnd(realChain.call(), requestBodyOut.successfulCount);// 回调
          } else if (!connection.isMultiplexed()) {
            // If the "Expect: 100-continue" expectation wasn't met, prevent the HTTP/1 connection
            // from being reused. Otherwise we're still obligated to transmit the request body to
            // leave the connection in a consistent state.
            streamAllocation.noNewStreams();
          }
        }
    
        httpCodec.finishRequest();
    
        if (responseBuilder == null) {
          realChain.eventListener().responseHeadersStart(realChain.call());
          //读取请求头
          responseBuilder = httpCodec.readResponseHeaders(false);
        }
        // 获取相应
        Response response = responseBuilder
            .request(request)
            .handshake(streamAllocation.connection().handshake())
            .sentRequestAtMillis(sentRequestMillis)
            .receivedResponseAtMillis(System.currentTimeMillis())
            .build();
    
        int 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
          responseBuilder = httpCodec.readResponseHeaders(false);
    
          response = responseBuilder
                  .request(request)
                  .handshake(streamAllocation.connection().handshake())
                  .sentRequestAtMillis(sentRequestMillis)
                  .receivedResponseAtMillis(System.currentTimeMillis())
                  .build();
    
          code = response.code();
        }
    
        realChain.eventListener()
                .responseHeadersEnd(realChain.call(), response);
          //读取响应体内容
        if (forWebSocket && code == 101) {
          // Connection is upgrading, but we need to ensure interceptors see a non-null response body.
          response = response.newBuilder()
              .body(Util.EMPTY_RESPONSE)
              .build();
        } else {
          response = response.newBuilder()
              .body(httpCodec.openResponseBody(response))
              .build();
        }
    
        if ("close".equalsIgnoreCase(response.request().header("Connection"))
            || "close".equalsIgnoreCase(response.header("Connection"))) {
          streamAllocation.noNewStreams();
        }
    
        if ((code == 204 || code == 205) && response.body().contentLength() > 0) {
          throw new ProtocolException(
              "HTTP " + code + " had non-zero Content-Length: " + response.body().contentLength());
        }
    
        return response;
      }
    
    

    可以看到 CallServerInterceptor 主要做了四件事情;
    1 写入请求头
    2 写入请求体
    3 读取响应头
    4 读取响应体

    相关文章

      网友评论

          本文标题:探究OkHttpClient的运行原理(6---CallServ

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