您的位置:首页 > 理论基础 > 计算机网络

《图解HTTP》读书笔记

2015-10-25 22:10 267 查看

《图解HTTP》读书笔记

了解WEB及网络基础

URI

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

知识拓展

URL的缺陷是如果资源被移走了,那么就无法对对象进行描述了.URN的目标就是无论对象搬移到什么地方,URN都能为对象提供一个统一的名称.

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.1URI为完整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识别过的资源.指定的资源经服务器端解析后返回响应内容.如果是文本则原样返回,如果是程序就执行后返回
POSTPOST方法用来传输实体的主体.虽然用GET方法也可以进行传输,但是一般不用GET方法进行传输.而是用POST方法.虽说POST和GET功能很相似,但是POST的主要目标不是获取响应的实体内容.
PUTPUT方法主要用来传输文件.就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存请求到URI指定的位置.因为不带验证,存在安全性问题,PUT方法很少使用.
HEADHEAD方法和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以内一般是安全的
PUT无副作用,幂等,不可带 Request Body
POST无副作用,幂等,不可带 Request Body
DELETE无副作用,幂等,不可带 Request Body
上表中说的不可以带一般不那么绝对,如果强行在GET或者DELETE中带上请求体,一般的服务器也是可以识别的

持久连接

HTTP/1.1中,所有连接默认都是持久连接.

HTTP/1.0中使用请求头 connection:keep-alive.

持久连接能够复用已经建立的TCP连接,节省了TCP建立的握手过程,提高效率.想使用持久连接需要服务器端和客户端都支持.

管线化(pipeline)

管线化是指,不用等待上一个请求的响应就连续发送其他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种.

状态码类别原因短语
1XXInformational接收的请求正在处理
2XXSuccess请求正常处理完毕
3XXRedirection需要进行附加操作以完成请求
4XXClient Error服务器无法处理请求
5XXServer Error服务器处理请求出错
仅RFC2616上就记录了40多种状态码,常用的只有14种,下面来介绍一下这具有代表性的14个.

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

相互交换密钥的公开密钥加密技术

非对称加密

近代的加密方法中密钥是私密,算法是公开的(对称加密).但是如果密钥被攻击者拿到还是会被攻击.怎么样安全的传递密钥呢.一般使用非对称加密的方法,即使用一把公钥和一把私钥.公钥是公开的,私钥是私有的.服务端生成公钥和私钥后将公钥送给客户端,客户端使用公钥加密后,只有服务端的私钥才能解密.目前想要解密就需要短时间内对一个非常大的整数快速分解因数,目前来看不太现实.所以非对称加密可以保证安全.

HTTPS采用混合方式加密

HTTPS采用两种方式混合加密,非对称加密方式快速,但是处理速度慢.如果在正式传输大量数据时采用非对称加密会耗费大量资源.所以HTTPS先用非对称加密安全传送对称加密使用的密钥,然后使用对称加密.

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

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

使用这种方式加密的一般步骤是


服务器把自己的公开密钥登录至数字证书认证机构

数字证书认证机构用自己的私钥向服务器签署数字签名并颁发公钥证书

客户端拿到服务器的公钥之后,使用数字证书认证机构的公开密钥(一般内置在浏览器内部),向数字证书认证机构验证公钥证书上的数字签名,以确认服务器的公开密钥的真实性

使用服务器公钥加密后发送

服务器用私有密钥对报文解密



HTTPS的安全通信步骤

客户端通过发送Client Hello报文开始SSL通信.报文中包含客户端SSL版本,加密组件(Cliper Suite)列表(所使用的加密算法及密钥长度等)

服务端发送Server Hello报文应答.和客户端一样,报文中包含SSL版本和加密组件,加密组件是从客户端接收到的列表里面筛选的

之后发送Certificate报文.报文中包含公开密钥证书.

最后服务器发送Server Hello Done报文通知客户端最初阶段SSL握手结束

客户端发送Client Key Exchange报文作为回应.报文中包含加密通信中使用的一种被称为Pre-master secret(用于对称加密)的随机密码串.该报文使用步骤3的公钥进行加密(客户端应该通过CA验证机构验证此公钥)

客户端继续发送Change Cipher报文.该报文告诉服务器之后使用Pre-master secret密钥加密.

客户端发送Finished报文.该报文包含连接至今全部报文整体校验值.这次协商是否能够成功,要以服务器是否能正确解密该报文为判定标准

服务器发送Change Cipher报文

服务器发送Finished报文

连接建立完成,此处开始使用HTTP应用层协议的通信

客户端断开,发送close_notify报文

TCP协议四次挥手

SSL的慢速

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

确认用户身份的认证

认证方式描述
BasicHTTP/1.0 开始,使用base64编码后明文发送账号密码
DigestHTTP/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独立的数据帧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: