HTTP是Hyper Text TransferProtocol(超文本传输协议)的缩写。是万维网协会(World Wide Web Consortium)和Internet工作小组IETF(InternetEngineering Task Force)合作的结果,(他们)最终发布了一系列的RFC,RFC 1945定义了HTTP/1.0版本。其中最著名的就是RFC 2616。RFC 2616定义了今天普遍使用的一个版本——HTTP1.1。
HTTP协议通常承载于TCP协议之上,有时也承载于TLS或SSL协议层之上,这个时候,就成了我们常说的HTTPS
HTTP协议永远都是客户端发起请求,服务器回送响应。
HTTP协议是一个无状态的协议,同一个客户端的这次请求和上次请求是没有对应关系。
HOST头域指定请求资源的Intenet主机和端口号,必须表示请求url的原始服务器或网关的位置。HTTP/1.1请求必须包含主机头域,否则系统会以400状态码返回。
Referer头域允许客户端指定请求uri的源资源地址,这可以允许服务器生成回退链表,可用来登陆、优化cache等。他也允许废除的或错误的连接由于维护的目的被追踪。如果请求的uri没有自己的uri地址,Referer不能被发送。如果指定的是部分uri地址,则此地址应该是一个相对地址。
User-Agent头域的内容包含发出请求的用户信息。
Cache-Control指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age
Date头域表示消息发送的时间,时间的描述格式由rfc822定义。例如,Date:Mon,31Dec200104:25:57GMT。Date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。
HTTP通讯的基本单位,包括一个结构化的八元组序列并通过连接传输。
一个从客户端到服务器的请求信息包括应用于资源的方法、资源的标识符和协议的版本号。
一个从服务器返回的信息包括HTTP协议的版本号、请求的状态(例如“成功”或“没找到”)和文档的MIME类型。
由URI标识的网络数据对象或服务。
数据资源或来自服务资源的回映的一种特殊表示方法,它可能被包围在一个请求或响应信息中。一个实体包括实体头信息和实体的本身内容。
一个为发送请求目的而建立连接的应用程序。
初始化一个请求的客户机。它们是浏览器、编辑器或其它用户工具。
一个接受连接并对请求返回信息的应用程序。
是一个给定资源可以在其上驻留或被创建的服务器。
一个中间程序,它可以充当一个服务器,也可以充当一个客户机,为其它客户机建立请求。请求是通过可能的翻译在内部或经过传递到其它的服务器中。一个代理在发送请求信息之前,必须解释并且如果可能重写它。
代理经常作为通过防火墙的客户机端的门户,代理还可以作为一个帮助应用来通过协议处理没有被用户代理完成的请求。
一个作为其它服务器中间媒介的服务器。与代理不同的是,网关接受请求就好象对被请求的资源来说它就是源服务器;发出请求的客户机并没有意识到它在同网关打交道。
网关经常作为通过防火墙的服务器端的门户,网关还可以作为一个协议翻译器以便存取那些存储在非HTTP系统中的资源。
是作为两个连接中继的中介程序。一旦激活,通道便被认为不属于HTTP通讯,尽管通道可能是被一个HTTP请求初始化的。当被中继的连接两端关闭时,通道便消失。当一个门户(Portal)必须存在或中介(Intermediary)不能解释中继的通讯时通道被经常使用。
反应信息的局域存储。
状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:
1xx:指示信息--表示请求已接收,继续处理
2xx:成功--表示请求已被成功接收、理解、接受
3xx:重定向--要完成请求必须进行更进一步的操作
4xx:客户端错误--请求有语法错误或请求无法实现
5xx:服务器端错误--服务器未能实现合法的请求
100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本
200——交易成功
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成了部分用户的GET请求
300——请求的资源可在多处得到
301——删除请求数据
302——在其他地址发现了请求数据
303——建议客户访问其他URL或访问方式
304——客户端已经执行了GET,但文件未变化
305——请求的资源必须从服务器指定的地址得到
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除
400——错误请求,如语法错误
401——未授权
HTTP 401.1 - 未授权:登录失败
HTTP 401.2 - 未授权:服务器配置问题导致登录失败
HTTP 401.3 - ACL 禁止访问资源
HTTP 401.4 - 未授权:授权被筛选器拒绝
HTTP 401.5 - 未授权:ISAPI 或 CGI 授权失败
402——保留有效ChargeTo头响应
403——禁止访问
HTTP 403.1 禁止访问:禁止可执行访问
HTTP 403.2 - 禁止访问:禁止读访问
HTTP 403.3 - 禁止访问:禁止写访问
HTTP 403.4 - 禁止访问:要求 SSL
HTTP 403.5 - 禁止访问:要求 SSL 128
HTTP 403.6 - 禁止访问:IP 地址被拒绝
HTTP 403.7 - 禁止访问:要求客户证书
HTTP 403.8 - 禁止访问:禁止站点访问
HTTP 403.9 - 禁止访问:连接的用户过多
HTTP 403.10 - 禁止访问:配置无效
HTTP 403.11 - 禁止访问:密码更改
HTTP 403.12 - 禁止访问:映射器拒绝访问
HTTP 403.13 - 禁止访问:客户证书已被吊销
HTTP 403.15 - 禁止访问:客户访问许可过多
HTTP 403.16 - 禁止访问:客户证书不可信或者无效
HTTP 403.17 - 禁止访问:客户证书已经到期或者尚未生效
404——没有发现文件、查询或URl
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问
407——类似401,用户必须首先在代理服务器上得到授权
408——客户端没有在用户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且无进一步的参考地址
411——服务器拒绝用户定义的Content-Length属性请求
412——一个或多个请求头字段在当前请求中错误
413——请求的资源大于服务器允许的大小
414——请求的资源URL长于服务器允许的长度
415——请求资源不支持请求项目格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求长。
HTTP 500 - 内部服务器错误
HTTP 500.100 - 内部服务器错误 - ASP 错误
HTTP 500-11 服务器关闭
HTTP 500-12 应用程序重新启动
HTTP 500-13 - 服务器太忙
HTTP 500-14 - 应用程序无效
HTTP 500-15 - 不允许请求 global.asa
Error 501 - 未实现
HTTP 502 - 网关错误
客户端发送一个HTTP请求到服务器的请求消息包括以下格式:
请求行(request line)、请求头部(header)、空行和请求数据四个部分组成。
一般情况下,服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息。
HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。
根据HTTP标准,HTTP请求可以使用多种请求方法。
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
GET 请求指定的页面信息,并返回实体主体。 HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头 POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 PUT 从客户端向服务器传送的数据取代指定的文档的内容。 DELETE 请求服务器删除指定的页面。 CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。 OPTIONS 允许客户端查看服务器的性能。 TRACE 回显服务器收到的请求,主要用于测试或诊断。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。
若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。
HTTP cookies,通常又称作"cookies".一个cookie就是存储在用户主机浏览器中的一小段文本文件。Cookies是纯文本形式,它们不包含任何可执行代码。一个Web页面或服务器告之浏览器来将这些信息存储并且基于一系列规则在之后的每个请求中都将该信息返回至服务器。
Web服务器之后可以利用这些信息来标识用户。多数需要登录的站点通常会在你的认证信息通过后来设置一个cookie,之后只要这个cookie存在并且合法,你就可以自由的浏览这个站点的所有部分。再次,cookie只是包含了数据,就其本身而言并不有害。
http1.1中,client和server都是默认对方支持长链接的, 如果client使用http1.1协议,但又不希望使用长链接,则需要在header中指明connection的值为close;如果server方也不想支持长链接,则在response中也需要明确说明connection的值为close
HTTP协议没有对传输的数据大小进行限制,HTTP协议规范也没有对URL长度进行限制。
以下测试均在MAC OS中完成
在命令行键入如下命令后按回车:
telnet www.baidu.com 80
然后输入如下:
GET /index.html HTTP/1.1
需要按两个回车换行才能得到响应的消息,第一个回车换行是在命令后键入回车换行,是HTTP协议要求的。第二个是确认输入,发送请求。
返回信息如下:
HTTP/1.1 302 Moved Temporarily
Date: Sun, 02 Apr 2017 02:00:30 GMT
Content-Type: text/html
Content-Length: 215
Connection: Keep-Alive
Location: http://www.baidu.com/search/error.html
Server: BWS/1.1
X-UA-Compatible: IE=Edge,chrome=1
BDPAGETYPE: 3
Set-Cookie: BDSVRTM=0; path=/
<html>
<head><title>302Found</title></head>
<body bgcolor="white">
<center><h1>302Found</h1></center>
<hr><center>pr-nginx_1-0-330_BRANCHBranch
Time : Tue Mar 14 15:29:16 CST2017</center>
</body>
</html>
代码如下:
#coding=utf-8
import httplib
conn = httplib.HTTPConnection("www.python.org")
conn.request("GET", "/index.html")
r1 = conn.getresponse()
print r1.status,r1.reason
conn.request("GET", "/parrot.spam")
r2 = conn.getresponse()
print r2.status,r2.reason
conn2 = httplib.HTTPConnection("jia.360.cn")
conn2.request("GET", "/standard.html")
r3 = conn2.getresponse()
print r3.status
data = r3.read()
print data
其中httplib库——HTTP protocol client
httplib实现了HTTP和HTTPS的客户端协议,一般不直接使用,在python更高层的封装模块中(urllib,urllib2)使用了它的http实现。
urllib 和urllib2都是接受URL请求的相关模块,但是urllib2可以接受一个Request类的实例来设置URL请求的headers,urllib仅可以接受URL。
#coding=utf-8
import urllib
google = urllib.urlopen('http://www.baidu.com')
print 'http header:/n', google.info()
print 'http status:', google.getcode()
print 'url:', google.geturl()
for line in google: # 就像在操作本地文件
print line,
google.close()
将循环答应省略了。
http header:/n Date: Sun, 02 Apr 2017 04:03:16 GMT
Content-Type: text/html; charset=utf-8
Connection: Close
Vary: Accept-Encoding
Set-Cookie: BAIDUID=06C94B342BBCC927E7E0DEAE949B8576:FG=1; expires=Thu,31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BIDUPSID=06C94B342BBCC927E7E0DEAE949B8576; expires=Thu,31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1491105796; expires=Thu, 31-Dec-37 23:55:55 GMT;max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BDSVRTM=0; path=/
Set-Cookie: BD_HOME=0; path=/
Set-Cookie: H_PS_PSSID=1450_12896_21079_17001_22157; path=/;domain=.baidu.com
P3P: CP=" OTI DSP COR IVA OUR IND COM "
Cache-Control: private
Cxy_all: baidu+f3a74d24fe4fdb0791f152735ddfbcc5
Expires: Sun, 02 Apr 2017 04:03:09 GMT
X-Powered-By: HPHP
Server: BWS/1.1
X-UA-Compatible: IE=Edge,chrome=1
BDPAGETYPE: 1
BDQID: 0xa2b1f26e00021b9d
BDUSERID: 0
http status: 200
url: http://www.baidu.com
#coding=utf-8
importurllib2
response=urllib2.urlopen('http://www.douban.com')
html=response.read()
print html
#coding=utf-8
importurllib2
req = urllib2.Request("http://www.douban.com")
response = urllib2.urlopen(req)
html = response.read()
print html
urllib2.Request()的功能是构造一个请求信息,返回的req就是一个构造好的请求
urllib2.urlopen()的功能是发送刚刚构造好的请求req,并返回一个文件类的对象response,包括了所有的返回信息。
通过response.read()可以读取到response里面的html,通过response.info()可以读到一些额外的信息。
有时 程序也对,但是服务器拒绝你的访问。 问题出在请求中的头信息(header)。 有的服务端不喜欢程序来触摸它。这个时候你需要将你的程序伪装成浏览器来发出请求。请求的方式就包含在header中。
HTTP报文有两种:请求报文、响应报文.
可以使用使用Wireshark抓TCP、http包
在表达式中选择或输入http
加入过滤条件:
http and tcp.port == 80 and ip.addr == 192.168.1.35
http:指定网络协议
ip.addr == 127.0.0.1:指定服务器ip地址,请根据实际情况替换。
tcp.port == 80,指定端口号,请根据实际情况替换。
本地接口选择:Loopback:lo0.
apply之后可过滤得到两个数据包,分别是HTTP请求和HTTP响应。
在任意数据包上右击,选择Follow TCP Stream
过滤出和该HTTP数据包有关的TCP数据包,包括TCP 3次握手,TCP分片和组装等。
得到HTTP请求和响应
红色背景字体为HTTP请求,蓝色背景字体为HTTP响应
从User-Agent中可以看出,Mozilla/5.0 (Macintosh;Intel Mac OS X 10_12_3)
相对于火狐或谷歌浏览器中使用调试工具抓取HTTP数据包,使用wireshark要显得复杂些,但也可以达到最终效果。Wireshark抓包分为两个步骤,第一步设置合理的过滤条件,第二步在任意数据包中选择Follow TCP Stream。
Chrome 自带了一个功能非常强大的HTTP 抓包系统,非常适合调试程序,HTTP request header 和 response header 都可以很清楚的看到。这个抓包系统的使用也很方便,在地址栏输入chrome://net-internals/#requests即可进入。