接下来分析Transport中HttpTransport部分,主要分析数据发送和数据接收流程。
一、重要的类简述
1.HttpTransport包装版的数据请求通道,包含httpConnection成员变量,所有的数据操作都是通过httpConnection操作。
2.HttpConnection数据操作,包含souce和sink两个成员变量,由socket包装而成。HttpConnection操作数据通过source和sink处理。
二、流程分析
1.HttpTransport.java
1 | public void writeRequestHeaders(Request request) throws IOException { |
http请求由三部分组成,分别是:请求行、消息报头、请求正文。首先创建请求行,然后通过httpConnection发送请求头和请求行。
2.HttpConnection.java
1 | /** Returns bytes of a request header for sending on an HTTP transport. */ |
这个部分很简单,就是按照http协议格式发送数据。
- HttpTransport.java 获取Request body Sink
1
2
3
4
5
6
7
8
9
10
11
12
13
14public Sink createRequestBody(Request request, long contentLength) throws IOException {
if ("chunked".equalsIgnoreCase(request.header("Transfer-Encoding"))) {
// Stream a request body of unknown length.
return httpConnection.newChunkedSink();
}
if (contentLength != -1) {
// Stream a request body of a known length.
return httpConnection.newFixedLengthSink(contentLength);
}
throw new IllegalStateException(
"Cannot stream a request body without chunked encoding or a known content length!");
}
4.HttpTransport.java
1 | public void finishRequest() throws IOException { |
5.HttpTransport.java
1 | public void flush() throws IOException { |
以上两部的目的是将之前写入sink的请求行、消息报头、请求正文发送出去。
6.HttpTransport.java
1 | public Response.Builder readResponseHeaders() throws IOException { |
7.HttpTransport.java
1 | public Response.Builder readResponse() throws IOException { |
读取响应头。
8.HttpTransport.java
1 | public ResponseBody openResponseBody(Response response) throws IOException { |
获取响应正文的数据。 getTransferStream这一步很关键,获取的是HttpConnection中的一个内部类Source。
9.HttpEngine.java
1 | public Response getResponse() { |
之前几步已经分析,最后请求的数据会赋值给userResponse,最后获取的时候直接返回userResponse。
10.HttpEngine.java
1 | public void releaseConnection() throws IOException { |
11.HttpTransport.java
1 | public void releaseConnectionOnIdle() throws IOException { |
释放资源,如果连接可重用则httpConnection.poolOnIdle()放置到连接池中,否则httpConnection.closeOnIdle()关闭连接。