- toc
{:toc}
第三章 HTTP报文内的HTTP信息
HTTP报文
HTTP报文分为请求报文和响应报文两种,主要是由报文首部和报文主体两部分组成。
编码提升传输速率
为了提升传输速率,HTTP协议通常会对要传输的实体进行压缩,即内容编码。
内容编码致指明应用在实体内容上的编码格式,并保持实体信息原样压缩。内容编码后的实体由客户端接收并负责解码。常见的编码有:
- gzip (GNU zip)
- compress (UNIX系统标准压缩)
- deflate (zlib)
- identity (不进行编码)
分块编码 对于实体数据过大时,通常会把实体数据进行分块传输。分块编码会将实体主体分成多个部分快,客户端在接收到之后自行解码拼接。
发送多种数据类型
一个HTTP请求中可能还有文字,图片,视频等多种不同的数据类型,HTTP协议通过多部分对象集合,使得一份报文中可以含有多类型实体。通常实在上传图片或文本时使用。
多部分对象集合包含的对象:
- multipart/form-data : 表单文件上传
- multipart/byteranges : 状态码为206,响应报文中包含了多个范围的内容
多部分对象集合中的每个部分都含有首部字段,另外,还可以在某个部分中嵌套使用对象集合。
获取部分内容的范围请求
执行范围请求,需要在首部加上Range字段,例如
Range: bytes=500-1000
,表示只请求500-1000的字节范围的数据。Range: bytes=1000-
,表示请求1000字节以后的全部数据Range: bytes=-300, 500-1000
,表示请求0-300和500-1000两部分数据
请求成功,服务器会返回206 Partial Content
状态码,表示请求部分数据成功,如何数据已经全部请求完成,则返回200
例如:一个资源大小为200 bytes,HTTP请求的Range字段为Range: bytes=-300
,则一次请求就可以请求到全部数据,因此返回200,不会返回206
范围请求通常用于断点下载等操作。
内容协商返回最合适的内容
同一个页面服务器可能存在多份,比如英文页面,中文页面等。服务器会根据请求报文中的某些字段(语言,字符集,编码方式等)作为判断基准,返回最合适的页面。
相关的首部字段有
- Accept
- Accept-Charset
- Accept-Encoding
- Accept-Language
- Content-Language
第四章 返回结果的HTTP状态码
状态码的职责是当客户端发送请求时,描述返回的请求结果。状态码和状态不一致的现象也很常见。
2XX OK
- 200 OK 正常处理,HEAD请求成功,不返回内容实体,状态码也是200
- 204 No Content 请求已处理成功,但没有资源返回
- 206 Partial Content 请求成功,返回资源的某一部分
3XX 重定向
- 301 Moved Permanently 永久重定向,资源的URI已经更新
- 302 Found 临时重定向,URI已经更新,希望本次使用新的URI进行请求
- 303 See Other 资源的URI已经更新,请使用GET方法从新的URI获取资源。302和303功能类似,但303明确告诉客户端应该使用GET方法请求另一个URI。实际应用中,当301,302,303状态码返回时,几乎所有的浏览器都会把POST改为GET,
然后重新请求。 - 304 Not Modified 资源已找到,但未符合条件请求。条件请求 是指在首部添加
If-Match, If-Modified-Since, If-None-Match,If-Range,-IfUnmodified-Since
中的任何一个 - 307 TemporaryRedirect 临时重定向。与302有相同的含义。
4XX 客户端错误
- 400 Bad Request 请求报文中存在语法错误,服务器无法理解。
- 401 Unauthorized 发送的请求需要通过HTTP认证。当浏览器接受到401时,会弹出认证窗口,让用户填写用户名和密码
- 403 Forbidden 不允许访问该资源
- 404 Not Found 没有找到请求的资源
5XX 服务器错误
- 500 Internal Server Error 服务器发生错误
- 503 Service Unavailable 表示服务器暂时处于超负载或正在停机维护,现在无法处理请求。
第五章 与HTTP协作的Web服务器
用单台虚拟主机实现多个域名
同一台服务器可以搭建多个Web站点,这是利用了虚拟主机的功能。但是这就会导致多个域名在经过DNS解析后映射到了同一个IP地址。为了确定到底是访问那个域名,
HTTP请求中,必须在首部的Host字段完整的指定主机名或域名的URI
通信数据转发程序:代理,网关,隧道
- 代理:代理是一种有转发功能的应用程序,他接收由客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端
- 代理不会改变请求的URI,会直接发送给前方持有资源的目标服务器,即源服务器。
- 在HTTP请求中可以级联多台代理服务器
- 代理服务器的用途:
- 利用缓存技术减少网络带宽流量
- 组织内部针对特定网站的访问控制
- 代理的种类
- 缓存代理:将源服务器的资源副本保存在代理服务器上,这样当代理再次接到相同的请求是,就不需要从源服务器那里再次获取资源了
- 透明代理和非透明代理:不对报文进行加工,成为透明代理,否则成为非透明代理
- 网关:转发其他服务器通信数据的服务器
- 网关与代理类似,但它可以提供非HTTP服务,即经过网关可以向非HTTP服务器请求数据
- 利用网关能提高通信的安全性
- 隧道:在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序
- 隧道可按要求建立起一条与其他服务器的通信线路,届时可以使用SSL等加密手段进行通信。
- 隧道的目的是确保通信的安全性
- 隧道本身不会解析HTTP请求,不会到HTTP请求进行修改
保存资源的缓存
缓存是指资源的副本,利用缓存可以减少对源服务器的访问,从而节省通信流量和通信时间。
缓存服务器是代理服务器的一种,用于实现缓存。除了缓存服务器外,也可以包缓存保存在客户端的浏览器中。缓存都是有有效期的,
过了有效期就应该重新向源服务器请求最新的资源。
第六章 HTTP首部
HTTP报文首部字段
- 字段结构:
首部字段名:字段值
,例如Content-Type: text/html
,单个字段也可以有多个只,例如Keep-Alive: timeout=15, max=10
- 如果首部字段重复,即出现两个同名的字段,则有的浏览器处理第一次出现的字段,有的浏览器处理最后一次出现的首部字段,这个在规范中没有明确指出。
- 4种HTTP首部字段类型
- 通用首部字段:请求报文和响应报文都会使用的字段
- 请求首部字段:请求报文中使用的首部字段
- 响应首部字段:响应报文中使用的首部字段
- 实体首部字段:实体部分使用的首部字段
通用首部字段
- Cache-Control:指定缓存的工作机制
- Connection:控制不在转发给代理的首部字段,管理持久链接
- Date:表明创建HTTP报文的时间
- Pragma:指定是否允许代理服务器返回缓存资源,这是历史遗留字段,
- Trailer:说明在报文主体后会记录哪些首部字段,应用于分块传输编码
- Transfer-Encoding:规定了传输报文主体时采用的编码方式
- Upgrade:用于检测HTTP协议及其他协议是否可使用更高版本进行通信,该字段仅限于客户端与邻接服务器,因此需要在Connection中指定Upgrade
- Via:追踪客户端与服务器之间请求和响应的传输路径
- Warning:告知用于一些与缓存相关的问题的警告
*
请求首部字段
- Accept:通知服务器应该返回的资源类型以及类型的优先级,格式为
type/subtype
,例如text/html, image/jpeg
- Accept-Charset:通知服务器客户端支持的字符集及优先级
- Accept-Encoding:通知服务器客户端支持的内容编码及优先级
- Accept-Language:通知服务器客户端支持的语言及优先级
- Authorization:客户端的认证信息
- Form:告知服务器客户端的用户的电子邮箱地址,也可把电子邮箱记录在User-Agent中
- Host:告知服务器资源所处的主机名和端口号
- If-Match:告知服务器匹配资源所有的实体标记(ETag),只有资源的ETag与该字段值匹配,服务器才会返回请求,否则返回412
- If-Modified-Since:指定更新日期,如果在指定的日期之后资源有更新,则服务器处理请求,返回资源,否则返回304
- If-None-Match:与If-Match相反,只有资源的ETag与该字段值不匹配,服务器才会返回请求,否则返回412
- If-Range:告知服务器若If-Range的字段值(ETag或时间)和请求资源的ETag值或时间相一致时,作为范围请求处理,否则返回全体资源
- If-Unmodified-Since:与If-Modified-Since相反,如果在指定的日期之后资源无更新,则服务器处理请求,返回资源,否则返回412
- Max-Forwards:指定可经过的服务器最大数目,
- Proxy-Authorization:代理认证信息,与Authorization不同之处在于他是客户端与代理服务器之间的认证,而Authorization是客户端与源服务器之间的认证信息
- Range:请求资源的范围
- Referer:告知服务器请求的原始资源的URI
- TE:告知服务器客户端能够处理的响应的编码方式及优先级
- User-Agent:告知服务器浏览器的种类和用户名称等信息
响应首部字段
- Accept-Range:告知客户端服务器是否能处理范围请求,可以处理则字段值为bytes,反之则为none
- Age:告知客户端该响应是在多久前创建的,如果是缓存服务器,则必须加上Age字段,告知客户端该资源是多久前从源服务器获取的
- ETag:告知客户端实体的标识
- 强ETag值:无论实体发生多么细微的变化,都会改变ETag的值
- 弱ETag值:只有资源发生根本改变,产生差异时才会改变ETag值
- Location:告知客户端重定向的地址
- Proxy-Authenticate:告知客户端适用于代理服务器的认证方案
- Retry-After:告知客户端多久之后再次发送请求,主要配合503响应或3XX响应
- Server:告知客户端HTTP服务器的应用程序信息
- Vary:源服务器告知代理服务器,必须具有同Vary指定的字段相同的同的值的请求才能直接返回缓存,否则必须从源服务器上获取资源
- WWW-Authenticate:告知客户端适用于服务器的认证方案
实体首部字段
- Allow:告知客户端服务器能够支持的所有HTTP方法
- Content-Encoding:告知客户端服务器对实体的主体部分选用的编码方式
- Content-Language:告知客户端实体主体使用的自然语言
- Content-Length:告知客户端实体主体的大小(字节)
- Content-Location:报文主体返回资源对应的URI
- Content-MD5:报文主体部分的MD5值,用于校验主体部分是否完整
- Content-Range:告知客户端返回的实体是整个资源的那一部分,格式
500-1000/1000
- Content-Type:说明实体内对象的类型
- Expires:告知客户端或代理服务器资源失效的日期
- Last-Modified:指明资源最终修改的时间
为Cookie服务器的首部字段
- Set-Cookie:告知客户端各种状态信息以及Cookie的设置信息
- Cookie:告知服务器当前客户端的各种状态信息
其他首部字段
- X-Frame-Options:控制网站内容在其他Web网站的Frame标签内显示的问题,可防止点击劫持攻击
- X-XSS-Protection:控制浏览器XSS防护机制的开关
- DNT:告知服务器客户端拒绝提供个人信息
- P3P:让Web网站上的个人隐私变成一种仅供程序可理解的形式
第七章 确保Web安全的HTTPS
HTTP的缺点
- 通信使用明文可能会被窃听
- TCP/IP是可能被窃听的网络
- 使用加密处理防止被窃听
- 通信加密:对整个通信线路加密,通过SSL或TSL加密HTTP的通信内容,与SSL组合使用的HTTP成为HTTPS(超文本传输安全协议)
- 内容加密:对实体内容加密,客户端服务器要有相应的加密和解密机制
- 不验证通信方的身份就可能遭遇伪装
- 任何人都可能发起请求
- 查明对手的证书
- SSL不仅提供加密处理,还使用了证书手段,用于确定对方的身份
- 证书由值得信任的第三方机构颁发,用于证明服务器和客户端是实际存在的
- 无法证明报文完整性,可能已遭篡改
HTTP+加密+认证+完整性保护=HTTPS
- HTTP加上加密处理和认证以及完整性保护就是HTTPS
- HTTPS是身披SSL外壳的HTTP
- HTTPS并非一种新的协议,只是HTTP通信接口部分用SSL和TLS协议代替而已
- SSL是独立于HTTP的协议,所以不光是HTTP协议,其他运行在应用层的协议也可以配合SSL协议使用,SSL是当今世界应用最为广泛的网络安全技术
- 加密技术
- 共享密钥:即加密和解密使用同一个密钥的方式,也称为对称密钥加密
- 优点:速度快
- 缺点:密钥可能被劫持
- 公开密钥:使用两个密钥,公有密钥和私有密钥,公有密钥加密,私有密钥解密,又称为非对称加密
- 优点:安全性高,密钥不会被劫持
- 缺点:处理速度慢
- 共享密钥:即加密和解密使用同一个密钥的方式,也称为对称密钥加密
- HTTPS采用混合加密机制,即共享密钥和公开密钥混合的方式,一般情况下是使用公开密钥的方式传输共享密钥的密钥,当共享密钥的密钥被安全送达后,就可以
使用共享密钥来加密普通数据。
证明公开密钥正确性的证书
- 问题:如何确保公开密钥中的共有密钥在传输过程中不被篡改
- 解决方案:使用数字证书确保共有密钥的正确性
- 基本流程:
- 服务器从数字证书认证机构那里申请公钥证书,公钥证书包含服务器的公开密钥和数字证书认证机构的数字签名。
- 申请到公钥证书之后把这份公钥证书发送给用户
- 用户在拿到公钥证书后使用数字证书认证机构的公开密钥(一般浏览器都会内置常用认证机构的公开密钥)对证书进行验证
- 一旦认证通过就表示公钥证书中的服务器公钥是真实可靠的。
- 其他的一些概念
- EV SSL证书:用来证明服务器是否符合规范,服务器背后的运营企业是否真实存在的证书
- 客户端证书:用来证明客户端实际存在的证书
- 自签名证书:使用OpenSSL可以构建自己的证书认证机构,自己给自己颁发服务器证书,该证书一般不被浏览器信赖
HTTPS的安全通信机制
- SSL和TLS:TLS是在SSL基础上开发的协议。
- HTTPS会比相应的HTTP请求要慢,因为要做加密处理。所以除非敏感信息,否则一般情况下使用HTTP就可以了。