HTTP
http,基于tcp协议,位于网络分层模型的应用层,tcp则是位于传输层,所以说http是tcp的上层协议。
传输的基本单位:报文(由8位组字节流组成)。
绝对URI格式:
报文格式:
报文首部:
报文主体:请求报文一般为空(POST方法时不为空),在响应报文中则指的是所请求的资源内容
请求行:请求方法+URI+协议版本(GET /index.htm HTTP/1.1)
- 请求方法:
- GET:用于获取资源
- POST:用于传输实体主体
- PUT:用于传输文件(出于安全考虑,一般不使用,除非web架构存在安全验证机制)
- DELETE:用于删除文件(与PUT相反的方法,安全问题一样存在)
- HEAD:与GET方法一样,但是不返回报文主体部分,用于确认资源有效性等
- OPTIONS:用于询问支持的方法
- TRACE:路径追踪,发送请求时,加入Max-Forwards字段及其值,每经过一次服务器,字段值减1,数值为0时,停止传输,由最后收到请求的服务器返回200 OK的响应
- CONNECT:要求在与代理服务器建立隧道通信,实现用隧道进行TCP通信,HTTPS通信时用到
状态行:版本协议+状态码+原因短语(HTTP/1.1 200 OK)
- 状态码类别:
类别 | 原因短语 | |
---|---|---|
1XX | Informational(信息性状态码) | 接收的请求正在处理 |
2XX | Success(成功状态码) | 请求正常处理完毕 |
3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4XX | Client Error(客户端错误状态码) | 服务器无法处理请求 |
5XX | Server Error(服务器错误状态码) | 服务器处理请求出错 |
- 常见状态码:
- 200 OK :请求被正常处理
- 204 No Content:请求处理成功。但是没有资源返回
- 206 Partial Content:客户端进行范围请求时,服务器成功执行这部分请求。响应报文中包含由Content-Range指定范围的内容实体
- 301 Moved Permanently:资源的URI进行了永久性的更换
- 302 Found:资源URI进行了临时性更换
- 303 See Other:与302相同的功能,区别是要求客户端采用GET方法进行资源请求
- 304 Not Modified:客户端进行附加条件的请求(If-Match、If-Range),服务器允许请求资源,但条件未满足情况,表示服务器资源未改变,可直接使用未过期缓存,虽被划分到3xx类别,但与重定向没有关系
- 307 Temporary Redirect:与302含义相同,302禁止POST变成GET,但大家可能不遵守,307会遵照浏览器标准,不会从POST变GET
- 400 Bad Request:请求报文存在语法错误
- 401 Unauthorized:需要进行HTTP认证,若之前已经进行过1次请求,表示认证失败
- 403 Forbidden:访问被拒绝
- 404 Not Found:无法找到请求的资源,服务器拒绝请求时不想解释也可能会用
- 500 Internal Server Error:服务器在执行请求时发生错误,可能存在一些BUG或者临时的故障
- 503 Service Unavailable:服务器超负载或进行停机维护
请求首部字段、响应首部字段、通用首部字段,这3个首部字段的字段说明放置本文的最后,下面是Cookie
COOKIE:HTTP协议是一种无状态协议,也就是在HTTP级别,协议对于发送过的请求和响应都不做持久化处理。于是为了管理用户状态(如登录状态),引入了Cookie,web浏览器会将一些数据临时写入用户计算机,当用户再次访问时,将读取之前存放的Cookie进行通讯,在报文首部字段中,Cookie的首部字段为:
首部字段名 | 说明 | 首部类型 |
---|---|---|
Set-Cookie | 开始状态管理所使用的Cookie信息 | 响应首部字段 |
Cookie | 服务器接收到的Cookie信息 | 请求首部字段 |
Set-Cookie字段属性
属性 | 说明 |
---|---|
NAME=VALUE | 赋予Cookie的名称和其值(必需项) |
expires=DATE | Cookie的有效期(若不明确指定则默认浏览器关闭前为止) |
path=PATH | 将服务器上的文件目录作为Cookie的适用对象(不指定则默认文档所在的文件目录) |
domain=域名 | 作为Cookie适用对象的域名(不指定则默认创建Cookie的服务器域名) |
Secure | 仅在HTTPS安全通信时才会发送Cookie |
HttpOnly | 加以限制,使Cookie不能被JavaScript脚本访问 |
示例:
Set-Cookie:status=enable; expires=true; 05 Jul 2011 07:26:31 GMT; paht=/; domain=.hackr.jp;
Cookie:status=enable
用户身份认证
- BASIC认证(基本认证)
- 认证不够便捷灵活,安全等级不够,不常用
- DIGEST认证(摘要认证)
- 缺点与BASIC认证一样,不常用
- SSL客户端认证
- 通过第三方认证机构颁发证书进行认证,需要维护费用
- 一般都是通过双因素认证,不止证书认证,还包括了基于表单认证
- FromBase认证(基于表单认证)
- 并非HTTP协议中定义的。即是用户、密码登录的认证。比较灵活,其安全等级由Web服务端的架构安全性能决定,是大多数采用的方法
HTTPS
HTTP的缺点:
- 明文通信,内容可能被窃听
- 无身份验证,可能遭遇伪装
- 无验证报文完整性,可能遭篡改
HTTPS是身披SSL的HTTP
HTTPS=HTTP+加密+认证+完整性保护
- 加密
- 共享密钥加密:又称对称加密。用同一个密钥进行加密和解密,难点是如何将密钥安全的送到对方手上
- 公开密钥加密:使用一对非对称密钥进行加密。分为公钥和私钥,公钥可公开发布,私钥为私自持有。通讯时,请求端通过公钥加密,响应端通过私钥解密。
- 混合加密:公开密钥加密比共享密钥加密过程更为复杂,所以处理速度要更慢。综合2种的优缺点,HTTPS采用混合加密,先通过公开密钥加密
方式进行共享密钥的交换,然后用交换后的共享密钥进行加密通信。
- 认证
公开密钥加密,依然存在问题,就是无法确保用户拿到的公钥是发布者实际发布的公钥,于是有了第三方认证机构,可对发布的公钥进行数字认证颁发数字认证证书(EV SSL证书),但是向认证机构申请证书是需要费用的
认证过程:
HTTPS的安全通信过程:
- 客户端通过发送Client Hello报文开始SSL通信。报文中包含客户端支持的SSL的指定版本、加密组件(Cipher Suite)列表(所使用的加密算法及密钥长度等)。
- 服务器可进行SSL通信时,会以Server Hello 报文作为应答。和客户端一样,在报文中包含SSL版本以及加密组件。服务器的加密组件内容是从接受到的客户端加密组件内筛选出来的。
- 之后服务器发送Certificate报文。报文中包含公开密钥证书。
- 最后服务器发送Server Hello Done报文通知客户端,最初阶段的SSL握手协商部分结束。
- SSL第一次握手结束之后,客户端以Client Key Exchange报文作为回应。报文中包含通信加密中使用的一种被称为Pre-master secret的随机密码串。该报文已用步骤3中的公钥进行加密。
- 接着客户端继续发送Change Cipher Spec报文。该报文会提示服务器,在此报文之后的通信会采用Pre-master secret密钥加密。
- 客户端发送Finish报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。
- 服务器同样发送Change Cipher Spec报文。
- 服务器同样发送Finished报文。
- 服务器和客户端的Finished报文交换完毕之后。SSL连接就算建立完成。当然,通信会受到SSL的保护。从此处开始进行应用层协议的通信,即发送HTTP请求。
- 应用层协议通信,即发送HTTP响应。
- 最后由客户端断开连接。断开连接时,发送close_notify报文。上图做了一些省略,这步之后再发送TCP FIN报文来关闭与TCP的通信。
- 完整性
在以上流程中,应用层发送数据时会附加一种叫做MAC(Message Authentication Code)的报文摘要。MAC能够查知报文是否遭到篡改,从而保护报文的完整性。
SSL和TLS:TLS是以SSL为原型开发的协议,目前主流版本是SSL3.0和TLS1.0
HTTP的追加功能协议和HTTP2.0
SPDY
Google在2010年发布,旨在消除HTTP的瓶颈
- 一条连接上只可发送一个请求
- 请求只能从客户端开始。客户端不可以接收除响应以外的指令
- 请求/响应首部未经压缩就发送。首部信息越多延迟越大
- 发送冗长的首部。每次互相发送相同的首部造成的浪费较多
- 可任意选择数据压缩格式。非强制压缩发送
SPDY没有完全改写HTTP协议,而是在TCP/IP的应用层与传输层之间通过新加会话层的形式运作,考虑到安全问题,并规定通信中使用SSL。
SPDY设计
从而获得了以下功能
- 多路复用流
通过单一的TCP连接,可以无限制处理多个HTTP请求。所有请求的处理都在一条TCP连接上完成,因此TCP的处理效率得到提高 - 赋予请求优先级
SPDY不仅可以无限制地并发处理请求,还可以给请求逐个分配优先级顺序。这样主要是为了在发送多个请求时,解决因带宽低而导致响应变慢的问题 - 压缩HTTP首部
压缩HTTP请求和响应的首部。这样一来,通信产生的数据包流量和发送的字节数就更少了 - 推送功能
支持服务器主动向客户端推送数据的功能。这样,服务器可直接发送数据,而不必等待客户端的请求 - 服务器提示功能
服务器可以主动提示客户端请求所需的资源。由于在客户端发现资源之前就可以获知资源的存在,因此在资源已缓存等情况下,可以避免发送不必要的请求
全双工通信的WebSocket
不同于SPDY,WebSocket是应用层的另一种协议,替代了HTTP协议,具有以下特点:
- 推送功能
支持由服务器向客户端推送数据的推送功能。这样,服务器可直接发送数据,而不必等待客户端的请求 - 减少通信量
只要建立起WebSocket连接,就希望一直保持连接状态。和HTTP相比,不但每次连接时的总开销减少,而且由于WebSocket的首部信息很小,通信量也相应减少了
为了实现WebSocket通信,在HTTP连接建立之后,需要完成一次”握手”(Handshaking)的步骤
- 握手·请求
为了实现WebSocket通信,需要用到HTTP的Upgrade首部字段,告知服务器通信协议发生改变
GET /chat HTTP/1.1
HOST:server.example.com
Upgrade:websocket
Connection:Upgrade
Sec-WebSocket-Key:dGH1IHNhbXBsZSBub25jZQ==
Origin:http://example.com
Sec-WebSocket-Protocol:chat,superchat
Sec-WebSocket-Version:13
Sec-WebSocket-Key字段记录着握手过程中必不可少的键值。
Sec-WebSocket-Protocol中记录使用的子协议。
子协议按WebSocket协议标准在连接分开使用时,定义那些连接的名称。
- 握手·响应
对于之前的请求,返回状态码101 Switching Protocols的响应。
HTTP/1.1 101 Switching Protocols
Upgrade:websocket
Connection:Upgrade
Sec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbk+XOo=
Sec-WebSocket-Protocol:chat
Sec-WebSocket-Accept的字段值由握手中的Sec-WebSocket-Key字段值生成
成功握手确立WebSocket连接之后,通信不再使用HTTP的数据帧,而采用WebSocket独立的数据帧。
WebSocket通信流程:
HTTP2.0
协议基础
- SPDY
- HTTP Speed+Mobility
由微软公司起草,用于改善并提高移动端通信时的通信速度和性能标准。它建立在Google公司提出的SPDY与WebSocket的基础之上 - NetWork+Friendly HTTP Ugrade
主要是在移动端通信时改善HTTP性能的标准
HTTP/2.0围绕着主要的7项技术进行讨论,大都倾向于采用以下协议技术。
压缩 | SPDY、Friendly |
多路复用 | SPDY |
TLS义务化 | Speed+Mobility |
协商 | Speed+Mobility、Friendly |
客户端拉拽(Client Pull)/服务器推送(Server Push) | Speed+Mobility |
流量控制 | SPDY |
WebSocket | Speed+Mobility |
附
请求首部字段:
首部字段名 | 说明 |
---|---|
Accept | 用户代理可处理的媒体类型 |
Accept-Charset | 优先的字符集 |
Accept-Encoding | 优先的内容编码 |
Accept-Language | 优先的语言(自然语言) |
Authorization | Web认证信息 |
Expect | 期待服务器的特定行为 |
From | 用户的电子邮箱地址 |
Host | 请求资源所在服务器 |
If-Match | 比较实体标记(ETag) |
If-Modified-Since | 比较资源的更新时间 |
If-None-Match | 比较实体标记(与If-Match相反) |
If-Range | 资源未更新时发送实体Byte的范围请求 |
If-Unmodified-Since | 比较资源的更新时间(与If-Modified-Since相反) |
Max-Forwards | 最大传输逐跳数 |
Proxy-Authorization | 代理服务器要求客户端的认证信息 |
Range | 实体的字节范围请求 |
Referer | 对请求中URI的原始获取方 |
TE | 传输编码的优先级 |
User-Agent | HTTP客户端程序的信息 |
响应首部字段:
首部字段名 | 说明 |
---|---|
Accept-Ranges | 是否接受字节范围请求 |
Age | 推算资源创建经过时间 |
ETag | 资源的匹配信息 |
Location | 令客户端重定向至指定URI |
Proxy-Authenticate | 代理服务器对客户端的认证信息 |
Retry-After | 对再次发起请求的时机要求 |
Server | HTTP服务器的安装信息 |
Vary | 代理服务器缓存的管理信息 |
WWW-Authenticate | 服务器对客户端的认证信息 |
通用首部字段:
首部字段名 | 说明 |
---|---|
Cache-Control | 控制缓存的行为 |
Connection | 逐跳首部、连接的管理 |
Date | 创建报文的日期时间 |
Pragma | 报文指令 |
Trailer | 报文末端的首部一览 |
Transfer-Encoding | 指定报文主体的传输编码方式 |
Upgrade | 升级为其他协议 |
Via | 代理服务器的相关信息 |
Warning | 错误通知 |
实体首部字段:
首部字段名 | 说明 |
---|---|
Allow | 资源可支持的HTTP方法 |
Content-Encoding | 实体主体适用的编码方式 |
Content-Language | 实体主体的自然语言 |
Content-Length | 实体主体的大小(单位:字节) |
Content-Location | 替代对应资源的URI |
Content-MD5 | 实体主体的报文摘要 |
Content-Range | 实体主体的位置范围 |
Content-Type | 实体主体的媒体类型 |
Expires | 实体主体过期的日期时间 |
Last-Modified | 资源的最后修改日期时间 |