HTTP权威指南笔记

编程

第一部分、基本组成
一、HTTP报文
1.报文格式
报文的起始行和首部是以行分隔的,以回车换行CRLF进行结束。回车符ASCII码13,换行符ASCII码10.
请求报文格式
<method><request-URL><version>
<headers>

<entity-body>
响应报文格式
<version><status><reason-phrase>
<headers>

<entity-body>
2.HTTP方法
1)GET和HEAD被认为是安全方法
2)HEAD与GET方法的行为类似,但服务器在响应中只返回首部,不返回实体的主体部分。
HEAD可以用于判断资源类型,查看响应状态码(404是否存在等),资源是否被修改等。
3)PUT方法与GET相反,用于向服务器写入文档。让服务器用请求的主体部分创建一个由所请求的
URL命名的新文档。
4)POST用于向服务器输入数据,如表单数据。
5)TRACE请求,主要用于诊断网络,可以查看代理和其他应用程序对用户请求所产生的修改。
6)OPTIONS方法用于请求服务器支持哪些方法
7)DELETE方法,请求服务器删除所请求的资源。
3.HTTP首部
包括通用首部(客户端和服务器端都可以使用)、请求首部、响应首部、实体首部、扩展首部
1)通用信息首部
Connection 允许客户端和服务器指定与请求/响应有关的选项
Date 描述报文创建时间
MIME-Version 给出发送端的MIME版本
Trailer 如果报文使用了分块传输编码,就可以用这个首部列出位于报文拖挂部分的首部集合。
Transfer-Encoding 告知接收端,报文采用的编码方式
Update 给出了发送端可能想要"升级"使用的新版本或协议
Via 显示了报文经过的中间节点(代理、网关)
通用缓存首部
Cache-Control
Pragma
2)请求首部
Client-IP 客户机IP
From 客户机E-mail地址
Host 服务器的主机名和端口号
Referer 提供了包含当前请求URI的文档的URL
User-Agent 客户端应用程序名
Accept首部
Accept 告知服务器能接受的媒体类型
Accept-Charset 客户端能接受的字符集
Accept-Encoding 客户端能接受的编码方式
Accept-Language 客户端能接受的语言
条件请求首部
Expect 允许客户端列出某请求所要求的服务器行为
If-Match 如果实体标记与文档当前的实体标记相同,就获取这份文档。
If-None-Match 如果实体标记与文档当前的实体标记不相同,就获取这份文档。
If-Modified-Since 除非在某个指定的日期之后资源被修改过,否则就限制这个请求。
If-UnModified-Since 除非在某个指定的日期之后资源没有被修改过,否则就限制这个请求。
If-Range 允许对文档的某个范围进行条件请求。
Range 如果服务器支持范围请求,就请求资源的指定范围
安全请求首部
Authorization 包含了客户端提供给服务器的认证数据。
Cookie 向服务器传送安全cookie令牌
Cookie2 用来说明请求端支持的cookie版本。
代理请求首部
Max-Forward 与TRACE方法一起使用,最大转发次数
Proxy-Authorization 与Authorization首部相同,是在与代理建立连接时使用的。
Proxy-Connection 与Connection首部相同,是在与代理建立连接时使用的。
3)响应首部
Age 缓存持续时间
Public 服务器支持的请求方法列表
Retry-After 如果资源不可用,在此日期或时间重试
Server 服务器应用程序软件的名字和版本
Title HTML文档标题
Warning 比原因短语更详细的警告报文
协商首部
Accept-Range 服务器可接受的范围类型
安全响应首部
Proxy-Authenticate 来自代理的对客户端的质询列表
Set-Cookie 可以在客户端设置标识令牌
Set-Cookie2 类似Set-Cookie
WWW-Authenticate 来自服务器的对客户端的质询列表
4)实体首部
Allow 列出了可以对此实体执行的请求方法
Location 用于重定向
内容首部
Content-Base 解析主体中的相对URL时,所使用的基础URL
Content-Encoding 主体的编码方式
Content-Language 主体最适宜的自然语言
Content-Length 主体的长度
Content-Location 资源所处位置
Content-MD5 MD5校验和
Content-Range 该实体在整个资源中的字节范围
Content-Type 主体的对象类型
实体缓存首部
ETag 实体标记
Expires 过期时间
Last-Modified 最后一次修改时间

二、连接管理
1.TCP性能
影响TCP性能的关键因素包括:TCP连接建立握手、TCP慢启动拥塞控制、数据聚集的Nagle算法、用于捎带确认
的TCP延迟确认算法、TIME_WAIT时延和端口耗尽。
1)延迟确认
TCP的接收者收到报文后,需要向发送者会送小的确认分组,否则发送者会在等待窗口时间后,重发分组。
由于确认报文很小,TCP会在发往相同方向的输出分组中进行捎带,如果超过一定时间没有找到发出分组,才会将
确认分组单独发出。
HTTP具有双峰特征的请求-应答行为降低了捎带消息的可能。可以谨慎的调整或禁止延迟确认算法。
2)TCP慢启动
TCP连接会随时间进行自我调谐,起初会限制连接的最大速度,如果数据传输成功,就会随着时间的推移提高传输的
速度。这种调谐称为TCP慢启动,用于防止因特网的突然过载和拥塞。
3)Nagle算法与TCP_NODELAY
每个TCP段中至少装载了40个字节的标记和首部,如果发送大量小字节的分组,网络性能就会严重下降。
Nagle算法鼓励发送全尺寸分组,只有当所有分组都被确认之后,或缓存中积累了一个足够尺寸的分组时,才会将小分
组数据发送出去。
如果HTTP报文较短,则需要等待积累缓存。其次Nagle算法会阻止小片段数据的发送,直到收到确认分组,但确认分组
受延迟确认算法影响,也会延迟100~200毫秒。
HTTP应用程序常常会在自己的栈中设置TCP_NODELAY,禁用Nagle算法,提高性能。但这样做,要确保向TCP中写入
大块数据,防止产生大量小分组。
4)TIME_WAIT累积与端口耗尽
当某个TCP端点关闭TCP连接时,会在内存中维护一个小的控制块,用来记录最近关闭连接的IP地址和端口号。这类信息
只会维护一小段时间,通常是最大分段使用期的两倍左右(2MSL,通常为2分钟),以确保在这段时间内不会创建具有相同
地址和端口的新连接,以防止第二次连接接收到第一次的重复分组。
在与前端代理服务器等建立TCP连接时,一条TCP连接的4个值sourceIP,sourcePort,desIP,desPort:80中,只有源端口号可以
修改。由于可用的源端口号有限(如:60000个),在2MSL(如:120s)内,连接率就被限制在了60000/120=500次/秒,
超过就会出现端口耗尽,影响性能。大量打开的连接和控制块也会极大消耗性能。
2.连接
1)Connection首部
Connection首部可以设定一些选项用于相邻两个节点间的通信,而不会被传递给下一级的节点。由于Connection首部
不会将信息传递给下一条,所以将逐跳首部放入Connection中,称为对首部的保护。
Connection首部中可以指定close值,说明操作完成后需要关闭这条持久连接。
eg:Connection:meter,close,xxxxxx
2)并行连接
并行连接并不一定会更快,特别是客户端带宽不足时。但通过多个组件同时出现在页面上,可以给用户以
更快的错觉。
3)持久连接
A.初始化了对某台服务器HTTP请求的应用程序很可能会在不久后再次访问,这种性质称为站点本地性。
B.持久连接有两种类型:HTTP/1.0+的keep-alive连接,以及HTTP/1.1persistent连接,其中keep-alive正在被
逐步放弃。
3.Keep-Alive
1)连接建立
客户端向服务器发送包含Connection:Keep-Alive的首部,请求打开持久连接;服务器返回带有同样首部的回应,
如果没有返回Connection:Keep-Alive首部,则客户端认为服务器不支持Keep-Alive.
2)Keep-Alive选项
timeout:服务器希望连接保持的时间,这不是一个承诺值。
max:服务器还希望为多少个事务保持连接。
eg:Connection:Keep-Alive
Keep-Alive:max=5,timeout=120
3)连接限制
Keep-Alive默认不会开启,开启Keep-Alive需要依赖Content-Length确定报文分块。
Keep-Alive不是承诺的连接,双方可以随时断开连接。
4)哑代理
A.如果代理不能识别Connection首部,只是简单的将其转发给下一跳,则客户端和服务器都会认为已经建立了持久连接,
但代理并不支持,客户端的请求将被丢弃,而服务器则会保持该连接等待请求。
B.为避免盲中继,Connection、Proxy-Authenticate、Proxy-Connection、Transfer-Encoding、Upgrade首部都
不应该转发给下一跳。
C.当客户端和服务器间只有一个代理时,变通的做法是客户端向代理发送Proxy-Connection请求,如果代理可以识别,
就将Proxy-Connection请求转化为Connection请求,发送给服务器,否则Proxy-Connection请求将被发送给服务器,
并被忽略。
4.HTTP/1.1 persistent持久连接
与keep-alive不同HTTP/1.1持久连接是默认打开的,所有连接默认都是持久连接。需要显示的通过Connection:close
首部来关闭连接,但这不是承诺的。
连接上的报文应该指定Content-Length,或用分块编码方式传输。
一个客户端对服务器只能维持两条持久连接,以防服务器过载。如果有N个用户试图访问服务器,则代理最多要维持2N条
到服务器的连接。
5.管道化连接
HTTP/1.1允许在持久连接上使用管道连接,这是对keep-alive连接的进一步优化。
它可以将多条请求放入队列,当第一条请求正在流行服务器时,第二、三条请求也在发送了。
但HTTP客户端不应该使用管道化的方式发送有副作用的请求,比如post,非幂等请求等。
TCP连接的关闭
TCP连接是双向的,TCP连接的每一端都有一个输入队列和一个输出队列,用于数据的读或写。
如果将输入输出信道都关闭,称为完全关闭,如果只关闭其中一条称为半关闭。
正常情况下关闭输出信道通常是安全的,但关闭输入信道可能造成信息丢失。

三、web代理
1.报文追踪
1)via首部
A.via首部列出了报文途径的每个中间节点(代理或网关)的信息,报文每经过一个节点,
都必须将这个中间节点添加到Via列表的末尾。
eg:Via 1.1 proxy-62.xxx.net,1.0 cache.xxx.com.
B.代理可以用Via首部可以用来检测路由循环。代理在发送一条请求前,向Via首部插入一个与自身有关的独特字符串,
然后在后续输入中检测这个字符串,以检测是否存在路由环路。
C.Via可能泄露隐私和安全问题,可以为节点指定一个假名,避免暴露主机和端口。
2)TRACE方法
A.在HTTP/1.1中调价了TRACE方法,它不仅可以追踪报文经过了那些代理,还可以观察每个代理对报文进行了那些修改。
B.TRACE请求通过Content-Type:message/http,状态200 OK的报文返回信息。
当TRACE请求到达目的服务器时,整条请求报文都会被封装在一条HTTP响应的主体中会送给发送端。然后发送端可以检查
服务器收到的确切报文,以及经过的代理列表(通过via首部).
C.可以通过Max-Forwards来指定最大转发次数,当Max-Forwards递减为0时,即使接收者不是目的服务器,也必须将
TRACE报文会送给客户端。
eg:TRACE /index.html HTTP/1.1
HOST:xxxx.com
Max-Forwards:5
Accept:text/html
2.其他
A.OPTIONS:客户端可以与服务器进行交互,确定服务器的能力。
OPTIONS * HTTP/1.1 代表请求整个服务器所支持的功能。
OPTIONS http://xxx.com/index.html HTTp/1.1请求特定资源的可用特性,服务器会返回所支持的方法。
B.Allow:Allow首部列出了请求的URI所支持的方法列表。
eg:Allow:GET,HEAD,PUT/Allow:

四、缓存
1.命中
1)大部分缓存只有在客户端发起请求,且缓存过期时,才会对副本进行再验证。最常用的是
If-Modified-Since首部。
再验证命中
如果内容没有变化,服务器会返回一个小的304 Not Modified进行响应。
再验证未命中
如果内容已修改,服务器向客户端返回带有完整内容的HTTP 200 OK响应。
对象被删除
如果服务器对象已经被删除,返回404响应。
2)除了通常所说的文档命中率,还有字节命中率,例如有些文档只被命中了几次,但由于体积巨大,对整个数据
流量贡献极大,再一些按字节收费的服务商那里很重要。
提高文档命中率可以改善整体响应速度,提高字节命中率则可以节省网络带宽。
3)命中的检测
客户端可以通过定制的缓存代理头部判断是否是缓存命中的。
也可以使用Date首部来判断,将响应首部中的Date时间与当前时间进行判断。
2.过期日期
1)服务器用HTTP/1.0+的Expires首部或HTTP/1.1的Cache-Control:max-age首部来指定过期日期。
Expires指定的绝对日期,而Cache-Control指定的是相对秒数更加合理。
2)可以通过条件首部实现更高效的验证,包括If-Modified-Since:date和If-None-Match:etag.
3)HTTP/1.1支持弱验证器,如果只修改了一些不重要的内容,不希望所有缓存过期,允许服务器声明那是"足够好"的
等价副本。服务器会使用前缀"W/"来标识弱验证器。如:
ETag:W/"V2.7"
If-None-Match:W/"v2.7"
3.缓存控制头部
Cache-Control:no-store    禁止缓存响应,缓存在向客户端转发后立即删除,因为其可能含有敏感信息。
Cache-Control:no-cache    响应可以存储在本地缓存区中,只是在与原始服务器确认其新鲜度前,不能发送给客户端使用。
Pragma:no-cache是HTTP1.0的标准,而Cache-Control:no-cache是HTTP1.1的标准。
Cache-Control:max-age缓存秒数,如果设置为max-age=0,则不缓存,每次访问都刷新。
Expires指定绝对过期日期,受限于时钟同步。
Cache-Control:must-revalidate    在事先没有和原始服务器进行在验证的情况下,不能提供缓存副本;但如果在新鲜度内,
则可以提供。只是如果无法验证新鲜度,需要返回504Gateway Timeout。
Cache-Control:only-if-cached    只有当缓存中有副本存在时,客户端才会获取一份副本。
Cache-Control:max-stale=<s>    缓存可以随意提供过期的文件,如果指定了参数s,在这段时间内,一定不能过期。
Cache-Control:min-fresh=<s>    至少在s秒内保持新鲜。
4.设置缓存控制
为了使缓存控制更加灵活,而不仅仅依赖应用服务器的配置,HTML2.0定义了<META HTTP_EQUIV>标签,它可以定义
与文档有所关联的HTTP首部。
eg:<META HTTP-EQUIV="Cache-control" CONTENT="no-cache">

五、web网关、web隧道与中继
1.web网关
表示形式<客户端协议>/<服务器端协议>
服务器端网关 HTTP/*
客户端网关 */HTTP
安全加速网关 HTTPS/HTTP
通用网关接口(Common Gateway Interface,CGI),通过它可以将特定的请求转发到对应的处理模块上。
2.web隧道
这种方式可以通过HTTP连接发生非HTTP流量。
web隧道是用HTTP的CONNECT方法建立起来的,它可以请求隧道网关创建一条到达任意目的服务器的
TCP连接,并对客户端和服务器之间的后继数据进行盲转发。
客户端发送请求:
CONNECT xxx.com:443 HTTP/1.0
User-agent:Mozilla/4.0
网关响应:
HTTP/1.0 200 Connection Established
Proxy-agent:Netscape-Proxy/1.1
Web隧道可以穿过防火墙来传输加密的SSL流量。
3.中继
中继,可以实现简单的盲转发,由于无法正确处理connection首部,可能存在挂起keep-alive连接的问题

六、Web爬虫
1.避免环路
规范化URL链接,是避免环路的重要措施,例如:
将所有%xx替换为标准字符,对缺省端口加上:80,删除#标签等。
url文件系统中的连接符号也可能会造成无限循环,例如index.html中包含subdir/index.html的链接,
subdir指向/,index.html-->subdir/index.html-->subdir/subdir/index.html则会陷入无限循环。
动态创建的web链接页面,也可能会导致无限循环。
2.环路避免措施
规范化URL
广度优先爬行
节流(对同一个网站的采集速度)
URL大小长度
URL黑名单
模式检测
内容指纹摘要比较
人工监视
3.爬虫使用不当问题
失控,给被采集应用带来巨大负载。
失效的URL,给被采集应用带来大量404日志。
错误的URL,给被采集应用带来错误。
隐私URL,泄露隐私。
错误访问网关地址。
4.robots.txt 拒绝机器人访问标准
1)robots.txt说明了机器人可以访问服务器的哪些资源。
每个web站点仅有一个robots.txt文件.
为提高爬虫效率,降低被访问站点的压力,往往会对robots文件进行缓存,其更新可能不会立刻被爬虫知晓。
2)文件样例
User-Agent:baidu #指定爬虫名称
User-Agent:XXXX #指定爬虫名称
Disallow:/private #不允许访问
User-Agent:* #任意爬虫
Allow:/public #允许访问
5.robot-control元标签
1)robots.txt是整个站点层面的,而要单独控制某一页面,则需要配置相关的HTML META标签。
<META NAME="ROBOTS" CONTENT="INDEX/NOINDEX/FOLLOW/NOFOLLOW/NOARCHIVE//ALL/NONE">
INDEX允许爬虫对页面进行索引。
NOINDEX不允许爬虫对页面进行索引。
FOLLOW告诉机器人可以爬取页面上的任何外连接。
NOFOLLOW告诉机器人不可以爬取页面上的任何外连接。
NOARCHIVE告诉机器人不应该缓存页面的本地副本。
ALL等价于INDEX,FOLLOW。
NONE等价于NOINDEX,NOFOLLOW。
2)其他标签
DESCRIPTION 描述页面的摘要
KEYWORDS 逗号分隔的关键词
REVISIT-AFTER 告诉机器人几天后再重新访问。<meta name="REVISIT-AFTER" content="10 days">

第二部分、识别、认证与安全
一、cookie版本
1.cookie有两个版本,版本0(也称Netscape cookies)和版本1(RFC2965).
版本1对版本0进行了扩展,版本0用set-cookie标识,版本1用set-cookie2标识.
2.版本1改进了以下内容:
为每个cookie关联上解释性文本,对其目的进行解释。
允许在浏览器退出时,不考虑过期时间,将cookie强制销毁。
用相对秒数,而不是绝对日期来表示cookie的Max-Age.
通过URL端口号,而不仅仅是域和路径来控制cookie的能力。
通过cookie首部回送域、端口和路径过滤器。
为实现互操作性使用的版本号。
在cookie首部从名字中区分出附加关键字的$前缀。
3.版本0组成
NAME=VALUE
Domain 可选的,域。
Path 可选的,url子路径
Secure 可选的,只有在使用SSL安全连接时才发送cookie。
Expires 可选的,到期时间,如果没有指定,则在用户会话结束时过期。
4.版本1的组成
NAME=VALUE
Domain 可选的,域。
Path 可选的,url子路径
Secure 可选的,只有在使用SSL安全连接时才发送cookie。
Max-Age 可选的,cookie生存秒数,0表示立刻丢弃。
Version 强制的,cookie版本。
Comment 可选的,UTF-8编码的解释说明。
CommentURL 可选的,指向描述文档。
Discard 可选,在客户端程序终止时,指示客户端放弃这个cookie。
port 可选,端口号。
5.cookie缓存
对set-cookie头部的缓存应该十分小心,因为其含有用户敏感信息。
可以通过Cache-Control:no-cache="Set-Cookie"不缓存cookie;但这样就会丢失认证等cookie信息。
可以强制缓存与原始服务器重新验证每条请求,将set-cookie首部合并到缓存的文档上,响应给客户端。
二、基本认证机制
1.HTTP提供了一个原生的质询/响应框架,简化了对用户的认证过程。
其基本步骤:
请求:客户端发出请求。
质询:服务器返回401状态,要求客户端提供用户名和密码。在www-Authenticate首部描述保护区域和认证算法。
授权:客户端返回Authorization首部,用来说明认证算法、用户名和密码。
成功:服务器返回200状态,在Authorization-Info首部返回附加信息。如果认证失败返回401 UnAuthorized响应。
2.安全域
在www-Authenticate中可以指定保护范围,即安全域realm。
eg:HTTP/1.0 401 UnAuthorized
        www-Authenticate:Basic realm="XXXX"
3.HTTP基本认证将由冒号分隔的用户名和密码打包在一起,用Base-64进行编码,隐藏明文。
4.可以通过SSL方式建立连接,以提高基本认证的安全性。
三、摘要认证
1.工作原理
客户端发出请求
服务器通过www-Authenticate返回随机数(防止重放攻击),要求用户名和密码摘要。
客户端返回用户名和密码摘要。
服务器事先知道所有用户的密码,服务器进行相同运算,得出相同的摘要,进行验证。
2.摘要计算
可以通过散列函数、密码数据块A1和非保密数据块A2计算出摘要。密码和非保密数据间用:分隔。
A1由冒号连接起来的用户名、域及密码组成。
A2有两种策略,第一种策略只包含HTTP请求方法和URL。当qop="auth"时使用这种策略,这是默认情况。
第二种策略添加了报文实体的主体部分,提供报文完整性检测。当qop="auth-int"时使用这种策略。
3.预授权
摘要认证使用随机数来破坏重放攻击,每次请求都需要请求质询。
通过下述方式,客户端无需等待新的www-Authenticate质询,就可以获得正确的随机数:
a.服务器预先在Authentication-Info首部中发送下一个随机数。
b.服务器允许在一小段时间内使用同一个随机数。
c.客户端和服务器使用同步的、可预测的随机数生成算法。
4.安全风险
首部篡改/重放攻击/多重认证机制/词典攻击/恶意代理攻击和中间人攻击/选择明文攻击/密码存储
选择明文攻击:使用已知密钥来简化密码分析。例如:恶意代理拦截流量,向客户端提供随机数,通过返回
的摘要和已知的随机数推导密码。

第三部分、实体、编码和国际化
一、HTTP实体和编码
1.HTTP需要保证满足以下条件:
1)可以被正确地识别(通过Content_Type首部说明媒体格式,Content-Language首部说明语言),以便浏览器和
其他客户端能正确处理内容。
2)可以被正确地解包(通过Content-Length首部和Content-Encoding首部)。
3)是最新的(通过实体验证码和缓存过期控制)
4)符合用户的需要(基于Accept系列的内容协商首部)
5)在网络上可以快速有效地传输(通过范围请求、差异编码以及其他数据压缩方法)
6)完整到达、未被篡改(通过传输编码首部和Content-MD5校验和首部)
2.实体首部
HTTP/1.1定义了10个基本首部字段:
1)Content-Type:实体中所承载对象的类型。eg:Content-Type:text/html.
Content-Type首部还支持可选的参数。eg:Content-Type:text/html;charset=utf-8.
Content-Type也支持多部份主体multipart,通常只适用于下列两种情况:提交填写好的表格,或作为承载若干文档
片段的范围响应。boundary为主体不同部分分隔符。
多部分表格提交multipart/form-data;多部分范围响应multipart/byteranges.
eg:Content-Type:multipart/form-data;boundary=AaB03x
--AaB03x
Content-Disposition:form-data;name="commet"
file upload test
--AaB03x
Content-Disposition:form-data;name="files"
Content-Type:multipart/mixed;boundary=BbC04y
--BbC04y
Content-Disposition:file;filename="imageDes.txt"
Content-Type:text/plain
...file descptiption txt...
--BbC04y
Content-Disposition:file;filename="imageFile.gif"
Content-Type:image/gif
Content-Transfer-Encoding:binary
...picpicpicpic...
--BbC04y
--AaB03x
2)Content-Length:所传送实体主体的长度或大小。
        Content-Length指的是压缩后,实际传输的长度。
        Content-Length首部是为了检测因服务器崩溃等原因,导致的报文结尾。除非使用了分块编码,
    否则Content-Length首部不应省略,检测截尾是其主要功能。
        如果没有Content-Length,缓存服务器可能不会对其进行缓存,以避免缓存不完整结果。
        在持久化连接中,客户端依赖Content-Length首部判断连续报文的开始和结束位置。如果不使用Content-Length
    首部,可以通过分块编码的方式,进行发送,每块都有大小说明。
3)Content-Language:与所传送对象最匹配的人类语言。
4)Content-Encoding:对象数据所做的任意变换(比如,压缩)。
    客户端将自己支持的编码方式放在Accept-Encoding首部中,发送给服务器。如果没有包含Accept-Encoding
首部,服务器认为客户端可以接受一切编码,即Accept-Encoding:*。可以用q来说明编码的优先级。
    常用的内容编码有:gzip(实体采用GNU zip编码)、compress(实体采用Unix的文件压缩程序)、deflate(实体采用zlib
格式压缩)、identity(未对实体进行编码)
4-2)传输编码
Content-Encoding是对内容进行编码,http也支持传输编码。
HTTP协议只定义了下面两个首部来描述和控制传输编码。
    Transfer-Encoding 告知接收方为了可靠地传输报文,已经对其进行了何种编码。
    TE 用在请求首部中,告知服务器可以使用哪些传输编码扩展。
    eg:Transfer-Encoding:chunked
5)Content-Location:一个备用位置,请求时可通过它获得对象。
6)Content-Range:如果这是部分实体,这个首部说明它是整体的哪个部分。
    Range首部在点对点的文件共享客户端软件中得到广泛应用,它们从不同的对等实体同时下载文件的不同部分。
7)Content-MD5:实体主体内容的校验和。
8)Last-Modified:所传输内容在服务器上创建或最后修改的日期时间。
9)Expires:实体数据将要失效的日期时间。为了节省传输带宽,在到达失效时间时,可以向服务器查询内容是否有变化,
如果没有变化,不重新传输。
4种有条件请求HTTP首部:
If-Modified-Since Last-Modified变化就发送
If-Unmodified-Since Last-Modified没有变化就发送
If-Match ETag没有变化就发送
If-None-Match ETag不匹配就发送
10)Allow:该资源所允许的各种请求方法,如:GET和HEAD
11)ETag:这份文档特定实例的唯一验证码。ETag首部没有被正式定义,但较重要。
12)Cache-Control:如何缓存该文档,没有被正式定义。
3.实体主体
首部字段以一个空白的CRLF行结束,随后就是实体主体的原始内容。

二、国际化
1.HTTP对国际化的支持
服务器通过Content-Type首部中的charset参数和Content-Language首部告知客户端网页的字母表和语言。
客户端发送Accept-Charset首部和Accept-Language首部,告知服务器自己可以理解的字符集编码及优先顺序。
eg:Accept-Language:fr,en;q=0.8
     Accept-Charset:iso-8859-1,utf-8
2.如果Content-type首部没有指出对应的charset,客户端需要从文档中推断字符集。
eg:<META HTTP-EQUIV="Content-Type" CONTENT="text/html;charset=utf-8">
     <META LANG="jp">
3.URI的转义
URI中的一个字符转义为一组3字符序列,由%后跟两个16进制数字表示。这两个16进制数字,可以表示一个US-ASCII
字符的代码。

三、内容协商与转码
1.3种常见的内容协商技术
1)客户端驱动
原理:客户端发起请求,服务器发送可选项的列表,客户端选择。
优点:实现容易
缺点:至少要发两次请求,增加了延迟。
2)服务器驱动
原理:服务器检查客户端的请求首部集,并决定要提供的页面。
优点:减少了协商开销。
缺点:如果首部不全,服务器要做猜测。
3)透明
原理:某个中间设备(通常是缓存代理),代表客户端进行协商请求。
优点:速度快
缺点:没有正式的标准。
2.内容协商首部
Accept    协商Content-Type
Accept-Charset    协商Content-Type
Accept-Language    协商Content-Language
Accept-Encoding    协商Content-Encoding

第四部分、内容发布
一、主机托管
1.常用的4种虚拟主机托管技术:
通过URL路径进行托管
通过端口号进行托管
通过IP地址进行托管
通过Host首部识别虚拟站点
2.Host首部
HTTP(1.0+)中增加了Host首部,并在HTTP/1.1中称为正式标准。
Host首部包括主机和端口号 eg:Host: 127.0.0.1:8080
对于HTTP/1.1的服务器,需要用400状态码来响应缺少Host首部的请求报文。
如果url使用的是ip地址,Host首部也应该使用ip地址;
如果url使用的是域名,Host首部也应该使用域名;
host的地址应与url的保持一致。
如果客户端显示使用代理服务器,客户端就必须把原始服务器,而不是将代理服务器的名字和端口放在
Host首部中。
3.内容分发网络CDN
CDN中的节点可以是Web服务器、反向代理或缓存。
反向代理和镜像服务器之间的区别在于反向代理通常是需求驱动的,它们不会保存原始服务器的全部内容副本,
它们只保存客户端请求的那部分内容。
与反向代理不同,代理缓存能收到发往任何Web服务器的请求,不需要与原始服务器交互。
正向代理隐藏真实客户端,反向代理隐藏真实服务端。

二、重定向与负载均衡技术
1.常用的重定向方法包括
1)HTTP重定向
    a.各种方式:客户端先请求到第一台web服务器,web服务器返回重定向地址,客户端重新请求新地址。
    b.功能:支持多种算法,如轮转、最小延迟等。
    c.局限性:可能会很慢,多了重定向步骤,且第一台服务器负载较大。
    d.补充:服务器向客户端返回302状态码及连接地址,通知客户端重定向。
2)DNS重定向
    a.各种方式:DNS服务器决定返回多个ip中的哪一个。
    b.功能:支持多种算法,如轮转、最小延迟等。
    c.局限性:需要配置DNS服务器,DNS负责往往有缓存问题,因为很多客户端都会缓存DNS对应的ip信息,不能很好的实现ip负载变换。
3)任播寻址
    a.各种方式:几台服务器使用相同的IP地址。每台服务器都伪装成一个骨干路由器。
    b.功能:路由器有内建的最短路径路由功能。
    c.局限性:有地址冲突风险,如果路由变化,会导致连接不稳。
4)IP MAC转发
    a.各种方式:交换机或路由器根据分组的目的地址,将镜像服务器的mac地址赋予分组。
    b.功能:节省带宽,提高QoS,负载均衡。
    c.局限性:服务器或代理的跳距必须是1.
5)IP地址转发(NAT网络地址转换)
    a.各种方式:第四层交换机根据分组的目的端口,重定向分组的ip到镜像服务器。
    b.功能:节省带宽,提高QoS,负载均衡。
    c.局限性:服务器或代理可能看不到真正的客户端IP地址
    d.补充:将分组的源IP改成交换机的IP,称为完全NAT,服务器不知道客户端的IP地址。
                  不修改分组的源IP,称为半NAT,但需要对网络进行控制。
6)显式浏览器配置
    a.各种方式:配置web浏览器,使其将HTTP报文发送给附近的一个代理,通常是缓存。
    b.功能:节省带宽,提高QoS,负载均衡。
    c.局限性:需要配置浏览器
7)代理自动配置PAC
    a.各种方式:Web浏览器从配置服务器中解析出PAC文件,这个PAC文件告诉浏览器为每个URL使用什么代理。
    b.功能:节省带宽,提高QoS,负载均衡。
    c.局限性:需要配置浏览器,使其去查询配置服务器。
    d.补充:例如每次进入网站都会去后台通过js下载代理配置,对所有url用js进行处理,发送到代理服务器。
8)Web代理自动发现协议WPAD
    a.各种方式:Web浏览器从配置服务器中获取PAC文件地址,不局限于特定的配置服务器。例如从DHCP、
DNS等获取。
    c.局限性:只有部分浏览器支持
9)Web缓存重定向协议WCCP
    a.各种方式:路由器会评估一个分组的目的地址,并用代理或镜像服务器的ip地址将该分组封装起来,
这样不会丢失客户端IP地址。
    b.功能:节省带宽,提高QoS,负载均衡。
    c.局限性:必须使用支持WCCP的路由器。有些拓扑结构方面的限制。
    d.补充:WCCP由Cisco公司开发,可以使路由器将Web流量重定向到代理缓存中去。wccp负责路由器和
服务器之间的通信,路由器可以对缓存进行验证,在缓存间进行负载均衡。
    服务器组由一组支持wccp的路由器和缓存组成,它们之间可以交换wccp报文。服务器组的配置确定了分配规则。
    支持WCCP的路由器会用服务器的IP地址将HTTP分组封装起来(GRE通用路由器封装),将其重定向到特定的服务器
上。这样客户端的IP地址不会丢弃。
    WCCP路由器可以和服务器间交换心跳报文。
10)因特网缓存协议ICP
    a.各种方式:代理缓存会在一组兄弟代理缓存中查询所请求的内容,看看他们的缓存中是否有特定的URL。
还支持缓存的分层结构。
    b.功能:从兄弟缓存中获取内容比从原始服务器获取更快。
    c.局限性:请求内容时只使用了URL,所以会降低缓存命中率。
11)缓存阵列路由协议CARP
    a.各种方式:一种代理缓存散列协议,允许缓存将请求转发给一个父缓存,与ICP不同的是,高速缓存上的内容是
不相交的,这组缓存共同组成一个大型缓存。
    b.功能:从附近的对等高速缓存中获取内容比从原始服务器获取更快。
    c.局限性:CARP无法支持兄弟关系。所有的CARP客户端都必须在配置上达成一致;否则向错误的父代理发送uri会
降低命中率。
    d.ICP与CARP的区别在于,ICP中每个缓存服务器都是独立节点,进行冗余存储;而CARP将整个集群看成单一整体
缓存。
12)超文本缓存协议HTCP
    a.各种方式:代理缓存可以向一组兄弟缓存查询所请求的内容。ICP时基于http/0.9协议的,而HTCP可以支持
http1.0和http1.1首部,可以提高命中率。
    b.功能:从兄弟或父缓存中获取内容比从原始服务器获取更快。
2.其他方法
1)NECP(Network Element Control Protocol,网元控制协议)允许网元(NE,路由器和交换机等负责转发IP分组的设备)
与服务器元素(SE,Web服务器和缓存代理服务器)进行交互。
NECP提供了几种转发分组的方式:MAC转发、GRE封装、NAT等。

三、日志记录
1.常见的记录内容包括:
    HTTP方法
    客户端和服务器的HTTP版本
    所请求资源的URL
    响应的HTTP状态码
    请求和响应报文的尺寸
    时间戳
    Referer首部和User-Agent首部的值
2.常见的日志格式
标准的日志格式有助于日志分析。
remotehost
username
auth-username
timestamp
3.缓存的影响
缓存往往会对日记记录造成困难,常常对重要页面禁止缓存。
通过代理服务器等获取日志往往较为困难,需要命中率测量协议(meter首部)等的支持。

第五部分、补充
一、HTTPS
1.工作原理
    1.Client发起一个HTTPS(比如https://juejin.im/user/5a9a9cdcf265da238b7d771c)的请求,根据RFC2818的规定,Client知道需要连接Server的443(默认)端口。
    2.Server把事先配置好的公钥证书返回给客户端。
    3.Client验证公钥证书。
    4.Client使用伪随机数生成器生成加密所使用的对称密钥,然后用证书的公钥加密这个对称密钥,发给Server。
    5.Server使用自己的私钥解密这个消息,得到对称密钥。至此,Client和Server双方都持有了相同的对称密钥。
    6.Server使用对称密钥加密“明文内容A”,发送给Client。
    7.Client使用对称密钥解密响应的密文,得到“明文内容A”。
2.TLS与SSL
TLS(Transport Layer Security,传输层安全协议)是IETF(Internet Engineering Task Force,Internet工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本。
在TLS与SSL 3.0之间存在着显著的差别,主要是它们所支持的加密算法不同,所以TLS与SSL 3.0不能互操作。
TLS的版本1.0使用的版本号为SSLv3.1。
OpenSSL是SSL和TLS最常见的开源实现。
3.HTTPS代理
1)问题:a.如果客户端开始用服务器的公开密钥对发往服务器的数据进行加密,代理就再也不能读取HTTP首部了!
代理不能读取HTTP首部,就无法知道应该将请求转向何处了.
b.如果我们想在复用现有的HTTP proxy的传输方式来代理HTTPS流量,那么建立TLS连接需要证书。
但是代理没有,也不可能有网站的私钥证书,所以这么做会导致浏览器和代理之间的TLS无法建立,证书校验根本通不过。
2)一种常用的办法就是HTTPS SSL隧道协议。
使用HTTPS隧道协议,客户端首先要告知代理,它想要连接的安全主机和端口。这是在开始加密之前,以明文形式告知的,所以代理可以理解这条信息。
HTTP通过新的名为CONNECT的扩展方法来发送明文形式的端点信息。CONNECT方法会告诉代理,打开一条到所期望主机和端口号的连接。这项工作完成之后,直接在客户端
和服务器之间以隧道形式传输数据。
CONNECT方法就是一条单行的文本命令。host:port后面跟着一个空格和HTTP版本字符串,再后面是CRLF。
接下来是零个或多个HTTP请求首部行,后面跟着一个空行。空行之后,如果建立连接的握手过程成功完成,就可以开始传输SSL数据了。下面是一个例子:
CONNECT home.netscape.com:443 HTTP/1.0
User-agent: Mozilla/1.1N
<raw SSL-encrypted data would follow here...>
在请求中的空行之后,客户端会等待来自代理的响应。代理会对请求进行评估,确 保它是有效的,而且用户有权请求这样一条连接。如果一切正常,代理会建立一条
到目标服务器的连接。如果成功,就向客户端发送一条 200 Connection Established 响应。
HTTP/1.0 200 Connection established
Proxy-agent: Netscape-Proxy/1.1
3)HTTP tunnel的工作流程
普通的一次HTTP请求,header部分以连续两组CRLF(

)作为标记结束,如果后面还有内容,也就是content部分的话,
需要在header里面加入Content-Length头,值为content部分有多长,通信的对方(无论是服务器,还是接收服务器返回
结果时的客户端)会按照这个长度来读后面那么多个byte。对于CONNECT报文的请求,是没有content部分的,只有Request-Line
和header。Request-Line和header均为仅供代理服务器使用的,不能传给远端服务器。请求的header部分一旦结束(连续
的两组CRLF),后面所有的数据都被视为应该发给远端服务器(网站)的数据,代理需要把它们直接转发,而且不限长度,
直到从客户端的TCP读通道关闭。    对于CONNECT报文的返回值,代理服务器在和远端服务器成功建立连接后,可以向客户
端(浏览器)返回任意一个2xx状态码,此时表示含义是和远端服务器建立连接成功,这个2xx返回报文的header部分一旦结束
(连续的两组CRLF),后面所有的数据均为远端服务器返回的数据,同理代理会直接转发远端服务器的返回数据给客户端,直
到从远端服务器的TCP读通道关闭。

二、状态码
重定向
永久删除的资源 301 资源被移动到了新的位置,或被重新命名,有了新的URL。服务器告知客户端重定向获取。
临时删除的资源 303 See Other或307 Temporary Redirect 资源变动重定向是临时的,希望客户端不要对书签进行更新。
URL增强 303 See Other或307 Temporary 服务器对url进行包装增强后,通知客户端重定向到包装后的URL上。
负载均衡 303 See Other或307 Temporary。 304 状态没有变化
401 Unauthorized 访问前,需要先认证
403 Forbidden 请求被服务器拒绝
405 Method Not Allowed 服务器可以在响应中包含Allow首部,告知客户端自己所支持的方法

三、MIME
最早应用于电子邮件系统,但后来也应用到浏览器。浏览器根据MIME类型,调用对应格式的处理组件。
MIME由一个主媒体类型+斜线+子媒体类型组成。HTML的content-type属性指明了MIME类型。
.doc     application/msword
.docx   application/vnd.openxmlformats-officedocument.wordprocessingml.document
.rtf       application/rtf
.xls     application/vnd.ms-excel    application/x-excel
.xlsx    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
.ppt     application/vnd.ms-powerpoint
.pptx    application/vnd.openxmlformats-officedocument.presentationml.presentation
.pps     application/vnd.ms-powerpoint
.ppsx   application/vnd.openxmlformats-officedocument.presentationml.slideshow
.pdf     application/pdf
.swf    application/x-shockwave-flash
.dll      application/x-msdownload
.exe    application/octet-stream
.msi    application/octet-stream
.chm    application/octet-stream
.cab    application/octet-stream
.ocx    application/octet-stream
.rar     application/octet-stream
.tar     application/x-tar
.tgz    application/x-compressed
.zip    application/x-zip-compressed
.z       application/x-compress
.wav   audio/wav
.wma   audio/x-ms-wma
.wmv   video/x-ms-wmv
.mp3 .mp2 .mpe .mpeg .mpg     audio/mpeg
.rm     application/vnd.rn-realmedia
.mid .midi .rmi     audio/mid
.bmp     image/bmp
.gif     image/gif
.png    image/png
.tif .tiff    image/tiff
.jpe .jpeg .jpg     image/jpeg
.txt      text/plain
.xml     text/xml
.html     text/html
.css      text/css
.js        text/javascript
.mht .mhtml   message/rfc822

四、Base-64编码
1.原理
1)base64的字母表包括【A-Za-z0-9+-】共64个字母,另外有一个特殊字符【=】。
BASE64将原始二进制串拆散为6位的片段,每个6位片段代表base64字符表中的64个字符之一。
2)base64的长度为24的倍数(6和8的最小公倍数),不足的部分用0填充。如果6位都是0时对应特殊字符=。
3)base64用8位字符代表6位原始信息,所以字符串比原始值扩大了约33%。
4)示例:
a:aa 二进制8位序列为 01100001 00111010 01100001 01100001
           对应6位片段为 011000 010011 101001 100001 011000 01XXXX XXXXXX XXXXXX
           对应值为YTphYQ==
目的 BASE64可以避免特殊符号带来的传输问题,但base64中的+-号在url中仍然会被转义。

ISBN: 9787115281487

以上是 HTTP权威指南笔记 的全部内容, 来源链接: utcz.com/z/513124.html

回到顶部