码迷,mamicode.com
首页 > Web开发 > 详细

Http协议

时间:2016-05-18 18:09:43      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:

URI

URI是uniform locator identifier的缩写,意义为统一资源标识符.包括两个子分类,一个是URL(uniform resource locator),另一个是URN(uniform resource name).

URL格式

例 : http://user:pass@www.example.com:80/dir/index.htm?uid=1#ch1

样例 描述
http:// scheme,用于描述请求所使用的协议类型
user:pass 登录信息
www.example.com 服务器地址
:80 服务器端口(可选)默认80
/dir/index.htm 带层次的文件路径
?uid=1 查询字符串
ch1 片段表示符号(可选)

简单的http协议

请求报文

请求报文是由请求方法,请求URI、协议版本、可选的首部字段和内容实体构成的
请求头和请求体之间必须要有一个空行用以标识请求头的结束,不可以省略

响应报文

响应报文基本上由协议版本、状态码、用以解释原因的原因短语、可选的首部响应字段、以及实体主体构成。
响应头和响应体之间必须要有一个空行用以标识响应头的结束,不可以省略

HTTP是不保存状态的协议

HTTP是一种无状态(stateless)的协议。HTTP协议自身不对请求和响应之间的通信状态进行保存。也就是说在HTTP这一层对请求和响应都不进行持久化处理。
虽然HTTP/1.1是无状态协议,但可以在HTTP之上保存状态,典型的就是cookie的使用

请求URI

样例 描述
GET http://hackr.com/index.htm HTTP/1.1 URI为完整URI的请求URI
GET /index.htm HTTP/1.1 Host : hackr.com 在首部字段Host中写明网络域名或者IP地址
OPTIONS * HTTP/1.1 不获取固定资源,而是对服务器本身发起请求可以省略URL

HTTP方法种类

HTTP方法(斜体为HTTP/1.1新增) 描述
GET 用来访问已经被URI识别过的资源.指定的资源经服务器端解析后返回响应内容.如果是文本则原样返回,如果是程序就执行后返回
POST POST方法用来传输实体的主体.虽然用GET方法也可以进行传输,但是一般不用GET方法进行传输.而是用POST方法.虽说POST和GET功能很相似,但是POST的主要目标不是获取响应的实体内容.
PUT PUT方法主要用来传输文件.就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存请求到URI指定的位置.因为不带验证,存在安全性问题,PUT方法很少使用.
HEAD HEAD方法和GET方法一样,只是不返回报文的主体部分.用于确定URI的有效性及资源的更新日期时间等.
DELETE 用于删除URI指定的文件,由于和PUT一样的原因,DELETE一般不使用.
OPTIONS 询问服务器支持的HTTP方法.
CONNECT 要求用隧道协议连接代理,CONNECT要求与代理服务器之间建立隧道,进行TCP通信.主要使用SSL和TLS协议把通信内容加密后经网络隧道传输.CONNECT方法格式:connect 代理服务器名:端口号 HTTP版本
TRACE 和traceroute类似,了解即可,主要记忆TCP中的traceroute原理

HTTP方法相关特性

HTTP方法 特性 备注
GET 无副作用,幂等,不可带 Request Body 其实也可以带上数据在请求URL中,理论无限制长度,但是一般浏览器都会限制长度,2048以内一般是安全的
POST 无副作用,幂等,不可带 Request Body
PUT 无副作用,幂等,不可带 Request Body
HEAD 无副作用,幂等,不可带 Request Body

上表中说的不可以带一般不那么绝对,如果强行在GET或者DELETE中带上请求体,一般的服务器也是可以识别的

持久连接

HTTP/1.1中,所有连接默认都是持久连接.
HTTP/1.0中使用请求头 connection:keep-alive.
持久连接能够复用已经建立的TCP连接,节省了TCP建立的握手过程,提高效率.想使用持久连接需要服务器端和客户端都支持.

管线化

管线化是指,不用等待上一个请求的响应就连续发送其他HTTP请求.这样就可以同时发送多个请求,而不需要停止等待

使用Cookie的状态管理

Cookie通过在请求和响应报文中添加Cookie信息来控制和保存客户端的状态
服务器通过Set-Control字段通知客户端保存Cookie.客户端将在下次请求中加入Cookie发送出去.服务器收到Cookie之后对比服务器数据,读取客户端的状态.

HTTP报文内的HTTP信息

Http报文

HTTP报文包括请求头和请求体,用空行(CR+LF)来区分.通常不一定要有报文主体

请求报文和状态报文的结构

名称 描述
请求行 包含用于请求的方法,请求URL和HTTP版本
状态行 包含响应结果的状态码,原因短语和HTTP版本
首部字段 包含表示请求和响应的各种条件和属性的各类首部.
其他 可能包含HTTP的RFC的未定义首部

编码提升传输速率

压缩传输会提升传输速率,但是消耗CPU资源
可以通过内容编码来进行保温的压缩.内容编码指明应用在实体内容上的编码格式,并保持实体信息的原样压缩.内容编码后的实体由客户端进行解码.
常用的内容编码有以下几种:

  • gzip(GNU zip)
  • compress(UNIX系统标准压缩)
  • deflate(zlib)
  • identity(不进行编码)

分割发送分块传输编码

把实体分块的功能称为分块传输编码
分块传输的每一个块都会使用16进制来标记块大小,实体最后一块用0(CR+LF)来标记.客户端负责解码分块传输.
HTTP/1.1中存在一种称为传输编码的机制,在通信时按照某种编码方式传输,但只用于分块传输.

获取部分内容

请求头 Range 用来指定下载的实体范围:Range: bytes =5001-10000.使用Range可以实现断点续传.
Range支持以下几种格式: Range: bytes=-5000(从头到5000)、Range: bytes=2001-10000、Range: bytes=-5000,7000-8000(多重范围).

返回结果的HTTP状态码

状态码告知客户端服务器端返回的请求结果

响应类别一般有以下5种.

状态码 类别 原因短语
1XX Informational 接收的请求正在处理
2XX Success 请求正常处理完毕
3XX Redirection 需要进行附加操作以完成请求
4XX Client Error 服务器无法处理请求
5XX Server Error 服务器处理请求出错

仅RFC2616上就记录了40多种状态码,常用的只有14种,下面来介绍一下这具有代表性的14个.

状态码 描述
200 OK 客户端发来的请求被服务器端正确处理了
204 No Content 服务器接收的请求已经被成功处理,但是返回报文中不包含request body.即,如果返回204给浏览器,那么浏览器的界面不更新.一般用于客户端发给服务器,服务器不需要返回信息的情况下使用.
206 Partial Content 客户端使用Range请求时,服务器成功执行范围请求
301 Moved Permanent 永久性重定向,表示资源已经永久的重定向至别处URI.
302 Found 临时性重定向,更新本次访问地址.下次还可以继续使用原地址
303 See Other 和302有相同的功能,但是303明确表示客户端使用GET方法获取资源,这一点和302有区别
304 Not Modified 已经找到了所求资源,但是和附加条件不符.304不返回任何响应的主体部分.304虽然划分在3XX类别,但是和重定向没有关系.
307 Temporary Redirect 临时重定向,该状态码与302 Found有相同的含义.尽管302标准禁止把POST改成GET,但是实际上大家都会这么干.307遵照浏览器标准,不会从POST变成GET.但是各个浏览器处理该响应的方式都不一定相同.
400 Bad Request 报文语法错误.浏览器会像200 OK 一样对该该状态码.
401 Unauthorized表示发送请求需要有HTTP认证的认证信息.另外若之前已经进行过一次请求,则表示用户认证失败
403 Forbidden 对请求资源的访问被服务器拒绝,但是没有给出具体说明.如果要进行说明,可以在实体的主体部分进
404 Not Found 没有找到所需要访问的资源
500 Internal Server Error 服务器端在执行请求时发生了错误.
503 Service Unavailable 服务器超负载或者停机维护,现在无法处理

TIP:当301,302,303响应状态码返回时,几乎所有的浏览器都会把POST改成GET,并删除请求报文内的主体,之后请求会再次发送.301,302标准禁止把POST改成GET的,但是实际使用中大家都会这么做

与HTTP协作的WEB服务器

网关,代理与隧道

代理

代理服务器的基本行为就是接收客户端发送的请求后转发给其他的服务器.代理不改变请求URI,会直接发送给前方持有资源的目标服务器.持有资源的服务器称为源服务器,从源服务器返回的响应经过代理服务器再返回给客户端.
每次通过代理服务器转发请求或者响应时,会追加via信息.
代理分为两种

  • 缓存代理 :代理转发响应时,缓存代理(Caching Proxy)会预先将资源的副本(缓存)保存在代理服务器上;当代理再次接收到对相同资源的请求时,就可以直接从代理那里读取缓存.
  • 透明代理 :转发请求或响应时,不对报文做任何加工的代理类型被称为透明代理.反之,对报文内容进行加工的称为非透明代理.

网关

网关的功能和代理类似.但是网关能够提供非HTTP协议的服务.比如通过网关查询数据库,而不是直接查询.

隧道

隧道可按要求建立一条与其他服务器的同线路,届时使用SSL等加密手段进行通信.隧道的目的是确保客户端能与服务器端进行安全通信.隧道本身不会去解析HTTP请求.隧道会在通信双方断开连接时结束.

保存资源的缓存

缓存是资源副本,利用缓存可以节省时间和资源
缓存服务器是代理服务器的一种,并归类在缓存代理类型中.

缓存的有效期

就算有缓存,也不能一直用缓存,因为真正的资源可能已经更新了.即使有缓存,也会因为客户端要求,缓存有效期等原因,向源服务器确认资源有效性.

客户端的缓存

缓存也可以保存在客户端.和缓存服务器相同的是,如果客户端发现缓存失效,就会再次向服务器端请求刷新资源.

HTTP首部

HTTP首部字段

HTTP首部字段结构

HTTP首部字段由首部字段名和字段值构成,中间用冒号:分隔

首部字段名:首部字段值 

一个字段名可以对应多个值.例如

Keep-Alive: timeout=15, max=100

如果字段重复了会如何?
这种情况并没有明确的规定,有的浏览器优先处理最先出现的有些优先处理最后出现的

四种HTTP首部字段类型

  • 通用响应字段 :请求响应双方都会使用的首部
  • 请求响应字段 :客户端向服务端发送请求时使用的字段
  • 响应首部字段 :服务端发回响应时的字段
  • 实体首部字段:请求报文和响应报文的实体部分使用的首部

几个常用的首部字段

通用首部字段

字段名 说明 可用指令
Cache-Control 缓存控制字段 no-cache : 不使用缓存 no-storage : 不保存缓存 max-age : 失效时间 public : 其他用户也可以使用缓存 private :响应以特定用户作为对象
Connection 1.管理持久连接 2.控制不再转发给代理的首部字段 1.close : 关闭持久连接 Keep-Alive(HTTP/1.0) : 使用持久连接 2.希望代理删除后转发的字段
Date 创建HTTP报文的时间和日期 格式(HTTP/1.0):Date: Tue, 03 Jul 2012 04:40:59 GMT
Via 报文经过代理或网关时,会先在首部字段中附加该服务器的信息再进行转发 eg: Via: 1.0 gw.hackr.jp(Squid/3.1) *1.0表示经过服务器的HTTP版本
Upgrade 检测通信协议是否可以使用一个更高版本的协议进行,参数可以指定任意不同的协议 WebSocket

请求首部字段

字段名 说明 可用指令
Accept 告诉服务器,客户端支持处理的媒体类型及相对优先级.使用type/subtype形式一次指定多个 text/html ,text/plain , image/jpeg,image/png, video/mpeg ,application/zip
Accept-Charset 告诉服务器端客户端支持的字符集及相对优先级,可以一次指定多个,由协商机制驱动 1iso-8859-5
Accept-Encoding 告诉服务器客户端支持的内容编码及优先级,可以一次指定多个 gzip
Accept-Language 告诉服务器客户端能够处理的语言集及优先级,可以一次指定多个 zh-cn,en_us
Authorization 用户代理的认证信息
Host 主机信息(唯一一个必须包含的首部字段),有可能一台主机上有绑定了多个域名,要用Host加以区分.如果没有,可以写空值Host: www.baidu.com
Range 请求某个实体的一部分 Range: 5001-10000
If-Match If-Modified-Since If-None-Match If-Range If-Unmodified-Since 条件请求,只有判断条件为真时.才会执行.eg : 只有当If-Match与ETag(实体标记)一致时,服务器才会接受请求 “123456”,Date: Tue, 03 Jul 2012 04:40:59 GMT
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36

响应首部字段

字段名 说明 可用指令
Accept-Ranges 告知客户端服务器端是否可以处理范围请求 bytes可以处理 none无法处理
Age 源服务器再多久前创建了响应 600
ETag 实体唯一性标识 资源更新时,也会更新.强ETag:微弱的变化也会更新.弱ETag:根本性变化才会更新,会附加W/
Location 配合3XX响应进行重定向 www.baidu.com
Server 服务器使用的服务器软件和系统版本 Apache/2.2.17

实体首部字段

字段名 说明 可用指令
Allow 服务器支持的请求方法 GET,POST
Content-Encoding、Content-Language、Content-Length、Content-MD5、Content-Location、Content-Range、Content-Type 内容相关属性,可见名知义 gzip、en_US
Last-Modified 最后更新时间 “123456”,Date: Tue, 03 Jul 2012 04:40:59 GMT

确保Web安全的HTTPS

HTTP缺点

通信使用明文会被窃听

TCP/IP会被传输

TCP/IP协议传输时,使用明文传输,所有传输的内容都可以被窃听,就算加密.密文还是可以被看见

加密处理防止窃听

  1. 用SSL或者TSL将整个通信线路加密
  2. 发送时对报文主体进行加密,这种方式由于没有对整个线路进行加密,所以还是可能被窃听

不验证通信方身份就可能遭遇伪装

任何人都可以发起请求

由于HTTP服务器会对请求照单全收,不会验证对端身份,所以会存在以下隐患

  1. 无法确定服务器是不是真的服务器,可能中途被伪装
  2. 无法确定响应真的返回给了客户端
  3. 无法确定客户端是否有访问权限
  4. 无意义的请求也会照单全收.无法防御DOS(Denial of Serve)攻击

查明对手的证书

SSL可以通过证书的方式来确认对端的身份.证书由第三方机构颁发,用于确定服务器和客户端实际存在.伪造证书从技术手段来说很困难

无法验证报文完整性,可能已经遭到篡改

接收到的内容可能有误

在请求或相应发出至接收的这段时间,如果报文被篡改无法察觉.这种攻击称为中间人攻击.

如何防止篡改

可以通过提供MD5或者SHA-1值得方式解决.但是还是无法保证绝对安全,因为MD5和SHA-1也会被篡改(XCode-Ghost事件).为了有效防止,可以使用HTTPS,SSL提供认证和加密处理及摘要功能.

HTTP + 加密 + 认证 + 完整性保护 = HTTPS

添加了加密和认证机制的HTTP就是HTTPS
HTTPS并非是应用层的新协议.只是HTTP通信接口使用SSL和TLS替代而已.使用SSL时,HTTP会先和SSL通信而不是先和TCP通信.
简而言之HTTPS就是HTTP套了一层SSL的壳子.

证明公开密钥正确性的证书

非对称加密还是存在问题的,就是无法确定公开密钥的正确性.因为公开密钥在传输时也可能会被篡改.为了解决这一问题,可以使用数字证书认证机构(CA, Certificate Authority)和其相关机构颁发的公开密钥证书.
使用这种方式加密的一般步骤是

  1. 服务器把自己的公开密钥登录至数字证书认证机构
  2. 数字证书认证机构用自己的私钥向服务器签署数字签名并颁发公钥证书
  3. 客户端拿到服务器的公钥之后,使用数字证书认证机构的公开密钥(一般内置在浏览器内部),向数字证书认证机构验证公钥证书上的数字签名,以确认服务器的公开密钥的真实性
  4. 使用服务器公钥加密后发送
  5. 服务器用私有密钥对报文解密

HTTPS的安全通信步骤

  1. 客户端通过发送Client Hello报文开始SSL通信.报文中包含客户端SSL版本,加密组件(Cliper Suite)列表(所使用的加密算法及密钥长度等)
  2. 服务端发送Server Hello报文应答.和客户端一样,报文中包含SSL版本和加密组件,加密组件是从客户端接收到的列表里面筛选的
  3. 之后发送Certificate报文.报文中包含公开密钥证书.
  4. 最后服务器发送Server Hello Done报文通知客户端最初阶段SSL握手结束
  5. 客户端发送Client Key Exchange报文作为回应.报文中包含加密通信中使用的一种被称为Pre-master secret(用于对称加密)的随机密码串.该报文使用步骤3的公钥进行加密(客户端应该通过CA验证机构验证此公钥)
  6. 客户端继续发送Change Cipher报文.该报文告诉服务器之后使用Pre-master secret密钥加密.
  7. 客户端发送Finished报文.该报文包含连接至今全部报文整体校验值.这次协商是否能够成功,要以服务器是否能正确解密该报文为判定标准
  8. 服务器发送Change Cipher报文
  9. 服务器发送Finished报文
  10. 连接建立完成,此处开始使用HTTP应用层协议的通信
  11. 客户端断开,发送close_notify报文
  12. TCP协议四次挥手

SSL的慢速

因为SSL会不可避免的增加许多通信量,并且加解密操作会耗费CPU资源,所以并不是全部的网站都全站使用HTTPS.但是百度是全站HTTPS的.

确认用户身份的认证

认证方式 描述
Basic HTTP/1.0 开始,使用base64编码后明文发送账号密码
Digest HTTP/1.1加入 .通过认证质询方式认证.步骤: 1. 客户端发送认证请求 2.服务器端返回质询码 3.客户端返回计算后的响应码给服务器
SSL客户端认证 步骤: 1.接收到认证资源的请求,服务器要求客户端提供Certificate request报文,要求客户端提供证书 2.用户选择客户端证书,用Client Certificate报文发送给服务器端.3.服务器验证客户端的证书,然后开始HTTPS通信 大部分SSL一般使用证书 + SSL双因素认证机制.
表单认证机制 目前大部分的认证方式是表单认证方式.同时可以使用Session和Cookie来管理用户认证信息.

基于HTTP的功能追加协议

WebSocket

WebSocket是Web浏览器和Web服务器之间全双工通信标准.
一旦服务器和客户端之间建立起WebSocket,之后的所有通信都依靠这个专用协议进行.通信过程中可以发送JSON,XML,HTML或图片等任意格式的数据.
使用WebSocket可以完成:

  • 推送功能
  • 减少通信量

建立连接步骤 :

  1. 握手请求 发送Upgrade首部,请求切换协议
  2. 服务器返回状态码101Switching Protocols进行响应
  3. 连接建立之后不再采用HTTP协议,而是采用WebSocket独立的数据帧

Http协议

标签:

原文地址:http://blog.csdn.net/jly0612/article/details/51444863

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!