美文网首页
6、okhttp源码解析-拦截器CallServerInterc

6、okhttp源码解析-拦截器CallServerInterc

作者: 飞奔的口罩 | 来源:发表于2020-08-31 11:00 被阅读0次

    1、okhttp源码解析-整体流程
    2、okhttp源码解析-拦截器RetryAndFllowUpInterceptor
    3、okhttp源码解析-拦截器BridgeInterceptor
    4、okhttp源码解析-拦截器CacheInterceptor
    5、okhttp源码解析-拦截器ConnectInterceptor
    6、okhttp源码解析-拦截器CallServerInterceptor
    7、okhttp源码解析-Dispatcher任务管理器

    CallServerInterceptor

    1、这个拦截器是最后一个官方拦截器。
    2、这个拦截器是处理输出流sink,接收流source的。

    一、源码分析

    上一节ConnectInterceptor,我们说到streamAllocation.newStream()在3.9v的时候。
    创建只创建了HttpCodec*,而在这个拦截器会通过HttpConnect.newStream()来创建HttpStream。

    • 1、httpCodec分为1和2,分别对应http1.*、http2.0的协议版本。http2.0不再是文本传输,而是二进制流传输数据。
    • 2、sink、source都属于okio的io流框架内容了。以后有时间我们来撸一撸okio的内容。
    @Override public Response intercept(Chain chain) throws IOException {
    
        // 1.获取几个前面拦截方法创建的,重要类
        HttpCodec httpCodec = ((RealInterceptorChain) chain).httpStream();
        StreamAllocation streamAllocation = ((RealInterceptorChain) chain).streamAllocation();
        Request request = chain.request();
        long sentRequestMillis = System.currentTimeMillis();
    
        //2. 先向sink(OutputStream)中写头信息
        httpCodec.writeRequestHeaders(request);
    
        Response.Builder responseBuilder = null;
    
       // 3.判断是否有请求实体的请求,用method判断
        if (HttpMethod.permitsRequestBody(request.method()) && request.body() != 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.
       
          //4. 如果头部添加了"100-continue", 相对于一次见到的握手操作,只有拿到服务的结果再继续
          if ("100-continue".equalsIgnoreCase(request.header("Expect"))) {
            httpCodec.flushRequest();
            responseBuilder = httpCodec.readResponseHeaders(true);
          }
    
          //5. 当前面的"100-continue",需要握手,但又握手失败,这个时候responseBuilder不是空的
          // Write the request body, unless an "Expect: 100-continue" expectation failed.
          if (responseBuilder == null) {
            Sink requestBodyOut = httpCodec.createRequestBody(request, request.body().contentLength());
            BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut);
    
            // 回调RequestBody的writeTo,写相应的数据
            request.body().writeTo(bufferedRequestBody);
            bufferedRequestBody.close();
          }
        }
    
        //6. 这里也是调用了一次 sink.flush()
        httpCodec.finishRequest();
    
        //7. 读取头部信息,状态码,信息等
        if (responseBuilder == null) {
          responseBuilder = httpCodec.readResponseHeaders(false);
        }
    
        //8. 构建Response, 写入原请求,握手情况,请求时间,得到的结果时间
        Response response = responseBuilder
            .request(request)
            .handshake(streamAllocation.connection().handshake())
            .sentRequestAtMillis(sentRequestMillis)
            .receivedResponseAtMillis(System.currentTimeMillis())
            .build();
    
        int code = response.code();
        //9. 通过状态码判断以及是否webSocket判断,是否返回一个空的body
        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 {
          //读取Body信息
          response = response.newBuilder()
              .body(httpCodec.openResponseBody(response))
              .build();
        }
    
        //10 .如果设置了连接 close ,断开连接
        if ("close".equalsIgnoreCase(response.request().header("Connection"))
            || "close".equalsIgnoreCase(response.header("Connection"))) {
          streamAllocation.noNewStreams();
        }
    
        //11. HTTP 204(no content) 代表响应报文中包含若干首部和一个状态行,但是没有实体的主体内容。
        //HTTP 205(reset content) 表示响应执行成功,重置页面(Form表单),方便用户下次输入
        //这里做了同样的处理,就是抛出协议异常。
        if ((code == 204 || code == 205) && response.body().contentLength() > 0) {
          throw new ProtocolException(
              "HTTP " + code + " had non-zero Content-Length: " + response.body().contentLength());
        }
    
        return response;
      }
    

    相关文章

      网友评论

          本文标题:6、okhttp源码解析-拦截器CallServerInterc

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