如何判断一个HTTP连接的结束?
case 1:有Content-Length
依据Content-Length判断接收数据完成,来结束连接。
case2: 请求头带Connection字段
2.1 close
表明客户端或服务器想要关闭该网络连接,这是 HTTP/1.0 请求的默认值。
由server负责主动关闭。
2.2 keep-alive
表明客户端想要保持该网络连接打开,HTTP/1.1 的请求默认使用一个持久连接。
由server负责主动关闭。
case3:chunked响应
3.1 终止块
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
7\r\n
Mozilla\r\n
9\r\n
Developer\r\n
7\r\n
Network\r\n
0\r\n
\r\n
终止块是一个长度为0的分块,即其是0后面跟着两个CRLF。没有Trailer,则可以认为结束。(但chunk内容可能是二进制,所以不能直接匹配最后的两个CRLF,需要先匹配每个chunk的长度,然后再偏移,逐步找到最后结束。)
3.2 有trailer
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
Trailer: Expires
7\r\n
Mozilla\r\n
9\r\n
Developer\r\n
7\r\n
Network\r\n
0\r\n
Expires: Wed, 21 Oct 2015 07:28:00 GMT\r\n
\r\n
如果携带了trailer(消息头中可以搜索到Trailer字段),则在终止块(此时是单个CRLF)后,还需要再寻找一个结束符(两个CRLF)。处理完Trailer之后,可以认为结束。
Trailer头中绝不能有以下三个字段:
. Transfer-Encoding
. Content-Length
. Trailer
case4: range请求
4.1 206 Partial Content响应
4.1.1 包含一个区间
有Content-Range,但Content-Type中没有multipart。有Content-Length且是resp的完整长度。可以依据content-length来判断结束并做close。
HTTP/1.1 206 Partial Content
Content-Range: bytes 21010-47021/47022
Content-Length: 26012
Content-Type: image/gif
4.1.2包含多个区间
Content-Type中指明了multipart/byteranges
HTTP/1.1 206 Partial Content
Accept-Ranges: bytes
Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5
Content-Length: 385
--3d6b6a416f9b5
Content-Type: text/html
Content-Range: bytes 100-200/1270
eta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="vieport" content
--3d6b6a416f9b5
Content-Type: text/html
Content-Range: bytes 300-400/1270
-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: "Open Sans", "Helvetica
--3d6b6a416f9b5--
如何判断结束?
1. 要判断是multipart/byteranges,然后获取到boundary
Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5
2. 利用“--boundary”分割每个部分(每个部分内容还有content-range字段标识长度)
最后一个boundary之后,如何判断结束???
在协议层无法判断结束,只能在业务层(比如数据本身是结构化的,可判断结束的)判断。
问题
1、Transfer-Length和Content-Length不能同时出现?
Transfer-Length不是HTTP头字段?是表达动态长度的?
2、Transfer-Length和Transfer-Encoding一定同时出现?
总结
1、有Transfer-Encoding字段(其值不是identity),则Content-Length字段被忽略。
2、一个HTTP请求,如果有消息体,但没有Content-Length,那么server就应该回复400。
If a request contains a message-body and a Content-Length is not given, the server SHOULD respond with 400 (bad request).
3、Transfer-Encoding vs Content-Encoding
Transfer-Encoding 是一个逐跳传输消息首部,即仅应用于两个节点之间的消息传递,而不是所请求的资源本身。要将压缩后的数据应用于整个连接,要使用端到端传输消息首部 Content-Encoding 。
网友评论