HTTP/1.1 默认的连接方式是长连接,不能通过简单的TCP连接关闭判断HttpMessage的结束。
以下是几种判断HttpMessage结束的方式:
1. HTTP协议约定status code 为1xx,204,304的应答消息不能包含消息体(Message Body), 直接忽略掉消息实体内容。
[适用于应答消息]
Http Message =Http Header
2. 如果请求消息的Method为HEAD,则直接忽略其消息体。[适用于请求消息]
Http Message =Http Header
3. 如果Http消息头部有“Transfer-Encoding:chunked”,则通过chunk size判断长度。
4. 如果Http消息头部有Content-Length且没有Transfer-Encoding(如果同时有Content-Length和Transfer-Encoding,则忽略Content-Length),
则通过Content-Length判断消息体长度。
5. 如果采用短连接(Http Message头部Connection:close),则直接可以通过服务器关闭连接来确定消息的传输长度。
[适用于应答消息,Http请求消息不能以这种方式确定长度]
6. 还可以通过接收消息超时判断,但是不可靠。Python Proxy实现的http代理服务器用到了超时机制,源码地址见References[7],仅100多行。
HTTP协议规范RFC 2616的4.4 Message Length中对相关内容有较多的描述(https://tools.ietf.org/html/rfc2616#section-4.4)。
一个实例,Python标准库httplib.py源码解读(http协议客户端的实现)
httplib最简单的使用方法:import httplib
conn = httplib.HTTPConnection("google.com")
conn.request('GET', '/')
print conn.getresponse().read()
conn.close()
但是一般不直接使用httplib,而是使用更高层的封装urllib,urllib2
conn = httplib.HTTPConnection("google.com")创建HTTPConnection对象,指定要请求的webserver.
conn.request('GET', '/')向google.com发送http请求,Method为GET
conn.getresponse()创建HTTPResponse对象,接收并读取http应答消息头,read()读取应答消息体。
函数调用关系:
getresponse()->[创建HTTPResponse对象response]-> response.begin()->response.read()
重点是begin()和read(),begin()完成了4件事:
(1)创建HTTPMess