HTTP权威指南笔记

2020-03-25  本文已影响0人  93张先生

HTTP : Web 的基础

第一章 HTTP概述

Web客户端和服务器

客户端请求服务器内容
http-link-server

资源

媒体类型

MIME 类 型(MIME type)
Multipurpose Internet Mail Extension,多用途因特网邮件扩展

选区_103

URI

统一资源标识符(Uniform Resource Identifier,URI)

URL

统一资源定位符(URL)是资源标识符最常见的形式。URL描述了一台特定服务器上某资源的特定位置。


选区_104

大部分 URL 都遵循一种标准格式,这种格式包含三个部分。

URN

统一资源名(URN)。URN 是作为特定内容的唯一名称使用
的,与目前的资源所在地无关。使用这些与位置无关的 URN,就可以将资源四处搬移。通过 URN,还可以用同一个名字通过多种网络访问协议来访问资源。
URN 仍然处于试验阶段,还未大范围使用。

事务

一个 HTTP 事务由一条(从客户端发往服务器的)请求命令和一个(从服务器发回客户端的)响应结果组成。


选区_108
方法
选区_109
状态码
选区_109

复合 Web 页面要为每个嵌入式资源使用一个单独的 HTTP 事务

报文

选区_111 选区_112

链接

(Transmission Control Protocol,TCP)
HTTP 是个应用层协议。HTTP无需操心网络通信的具体细节;它把联网的细节都交给了通用、可靠的因特网传输协议 TCP/IP。
TCP 提供了:

选区_113 选区_114

Telnet 的实例

Telnet 程序可以将键盘连接到某个目标 TCP 端口,并将此 TCP 端口的输出回送到显示屏上。Telnet常用于远程终端会话,但它几乎可以连接所有的 TCP 服务器,包括 HTTP 服务器。

协议版本

HTTP/1.1

Web的结构组件

第二章 URL与资源

URL语法

URL http://www.joes-hardware.com/seasonal/index-fall.html

通用格式

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>

几乎没有哪个 URL 中包含了所有这些组件。URL 最重要的 3 个部分是方案(scheme)、主机(host)和路径(path)。表 2-1 对各种组件进行了总结。

选区_116

绝对 URL

相对 URL

解析相对URL
选区_117

第三章 HTTP报文

报文流

HTTP 报文是在 HTTP应用程序之间发送的数据块。
这些数据块以一些文本形式的元信息(meta-information)开头。

报文流动

选区_118

报文的组成部分

选区_120

起始行和首部就是由行分隔的 ASCII 文本

方法

状态码

选区_125

首部

第四章 连接管理

TCP链接(传输控制协议)

TCP 的可靠数据管道

TCP 流是分段的、由 IP 分组传送

选区_137.png

用 TCP 套接字编程

选区_138.png 选区_139.png

对TCP性能的考虑

HTTP 事务的时延
选区_140.png

性能聚焦区域

TCP 连接的握手时延

选区_141.png

延迟确认

TCP 实现了自己的确认机制来确保数据的成功传输。
延迟确认算法会在一个特定的窗口时间(通常是 100 ~ 200 毫秒)内将输出确认存放在缓冲区中,以寻找能够捎带它的输出数据分组。如果在那个时间段内没有输出数据分组,就将确认信息放在单独的分组中传送。

TCP 慢启动

TCP 数据传输的性能还取决于 TCP 连接的使用期(age)。TCP 连接会随着时间进行自我“调谐”,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度。

Nagle 算法与 TCP_NODELAY

Nagle 算法(根据其发明者 John Nagle 命名)试图在发送一个分组之前,将大量TCP 数据绑定在一起,以提高网络效率。
Nagle 算法鼓励发送全尺寸(LAN 上最大尺寸的分组大约是 1500 字节,在因特网上是几百字节)的段。
延迟确认算法延迟 100 ~ 200 毫秒。
HTTP 应用程序常常会在自己的栈中设置参数 TCP_NODELAY,禁用 Nagle 算法,提高性能。如果要这么做的话,一定要确保会向 TCP 写入大块的数据,这样就不会产生一堆小分组了。

TIME_WAIT 累积与端口耗尽

当某个 TCP 端点关闭 TCP 连接时,会在内存中维护一个小的控制块,用来记录最近所关闭连接的 IP 地址和端口号。这类信息只会维持一小段时间,通常是所估计的最大分段使用期的两倍(称为 2MSL,通常为 2 分钟 8 )左右,以确保在这段时间内不会创建具有相同地址和端口号的新连接。

客户端每次连接到服务器上去时,都会获得一个新的源端口,以实现连接的唯一性。但由于可用源端口的数量有限(比如,60 000 个),而且在 2MSL 秒(比如,120秒)内连接是无法重用的,连接率就被限制在了 60 000/120=500 次 / 秒。如果再不断进行优化,并且服务器的连接率不高于 500 次 / 秒,就可确保不会遇到 TIME_WAIT 端口耗尽问题。

HTTP连接的处理

常被误解的 Connection 首部

并行连接

选区_143.png 选区_142.png

持久连接

HTTP/1.1(以及 HTTP/1.0 的各种增强版本) 允许 HTTP 设备在事务处理结束之后将 TCP 连接保持在打开状态,以便为未来的 HTTP 请求重用现存的连接。在事务处理结束之后仍然保持在打开状态的 TCP 连接被称为持久连接。

持久以及并行连接
HTTP/1.0+ keep-alive 连接
选区_144.png
HTTP/1.1 持久连接

HTTP/1.1 逐 渐 停 止 了 对 keep-alive 连 接 的 支 持, 用 一 种 名 为持 久 连 接(persistent connection)的改进型设计取代了它。持久连接的目的与 keep-alive 连接的目的相同,但工作机制更优一些。

管道化连接

在响应到达之前,可以将多条请求放入队列。当第一条请求通过网络流向地球另一端的服务器时,第二条和第三条请求也可以开始发送了。在高时延网络条件下,这样做可以降低网络的环回时间,提高性能。

必须按照与请求相同的顺序回送 HTTP 响应。
HTTP 客户端不应该用管道化的方式发送会产生副作用的请求(比如 POST )。

选区_145.png

关闭连接的奥秘

链接类型(MDN web docs)

选区_146.png

What can be controlled by HTTP

Here is a list of common features controllable with HTTP.

To prevent snooping and other privacy invasions, Web browsers enforce strict separation between Web sites. Only pages from the same origin can access all the information of a Web page. Though such constraint is a burden to the server, HTTP headers can relax this strict separation on the server side, allowing a document to become a patchwork of information sourced from different domains; there could even be security-related reasons to do so.

Some pages may be protected so that only specific users can access them. Basic authentication may be provided by HTTP, either using the WWW-Authenticate and similar headers, or by setting a specific session using HTTP cookies.

Servers or clients are often located on intranets and hide their true IP address from other computers. HTTP requests then go through proxies to cross this network barrier. Not all proxies are HTTP proxies. The SOCKS protocol, for example, operates at a lower level. Other protocols, like ftp, can be handled by these proxies.

Using HTTP cookies allows you to link requests with the state of the server. This creates sessions, despite basic HTTP being a state-less protocol. This is useful not only for e-commerce shopping baskets, but also for any site allowing user configuration of the output.

Web服务器

各种形状和尺寸的 Web 服务器

“Web 服务器”可以用来表示 Web 服务器的软件,也可以用来表示提供 Web 页面的特定设备或计算机。

Web 服务器的实现

Web 服务器实现了 HTTP 和相关的 TCP 连接处理。负责管理 Web 服务器提供的资源,以及对 Web 服务器的配置、控制及扩展方面的管理。

通用软件 Web 服务器
Web 服务器设备
嵌入式 Web 服务器
最小的 Perl Web 服务器

实际的 Web 服务器会做些什么

(1) 建立连接——接受一个客户端连接,或者如果不希望与这个客户端建立连接,就将其关闭。
(2) 接收请求——从网络中读取一条 HTTP 请求报文。
(3) 处理请求——对请求报文进行解释,并采取行动。
(4) 访问资源——访问报文中指定的资源。
(5) 构建响应——创建带有正确首部的 HTTP 响应报文。
(6) 发送响应——将响应回送给客户端。
(7) 记录事务处理过程——将与已完成事务有关的内容记录在一个日志文件中。

image.png
第一步——接受客户端连接

如果客户端已经打开了一条到服务器的持久连接,可以使用那条连接来发送它的
请求。否则,客户端需要打开一条新的到服务器的连接。

第二步——接收请求报文

连接上有数据到达时,Web 服务器会从网络连接中读取数据,并将请求报文中的内容解析出来(参见图 5-5)。
解析请求报文时,Web 服务器会:

image.png

解析请求报文时,Web 服务器会不定期地从网络上接收输入数据。网络连接可能随
时都会出现延迟。Web 服务器需要从网络中读取数据,将部分报文数据临时存储在
内存中,直到收到足以进行解析的数据并理解其意义为止。

报文的内部表示法

有些 Web 服务器还会用便于进行报文操作的内部数据结构来存储请求报文。


image.png
连接的输入 / 输出处理结构

第三步——处理请求

第四步——对资源的映射及访问

docroot
image.png

在配置文件 httpd.conf 中添加一个 DocumentRoot 行就可以为 Apache Web 服务器
设置文档的根目录了:

DocumentRoot /usr/local/httpd/files
虚拟托管的 docroot

虚拟托管的 Web 服务器会在同一台 Web 服务器上提供多个 Web 站点,每个站点在
服务器上都有自己独有的文档根目录。

图 5-9 中的服务器托管了两个站点:www.joes-hardware.comwww.marys-antiques.
com。服务器可以通过 HTTP 的 Host 首部,或根据不同的 IP 地址来区分不同的Web 站点。

image.png

Apache Web 服务器虚拟主机的 docroot 配置

<VirtualHost www.joes-hardware.com>
ServerName www.joes-hardware.com
DocumentRoot /docs/joe
TransferLog /logs/joe.access_log
ErrorLog /logs/joe.error_log
</VirtualHost>
<VirtualHost www.marys-antiques.com>
ServerName www.marys-antiques.com
DocumentRoot /docs/mary
TransferLog /logs/mary.access_log
ErrorLog /logs/mary.error_log
</VirtualHost>
...
用户的主目录 docroot

Docroot 的另一种常见应用是在 Web 服务器上为人们提供私有的 Web 站点。通常会把那些以斜杠和波浪号( /~ )开始,后面跟着用户名的 URI 映射为此用户的私有文档根目录。


image.png

第五步——构建响应

一旦 Web 服务器识别出了资源,就执行请求方法中描述的动作,并返回响应报文。响应报文中包含有响应状态码、响应首部,如果生成了响应主体的话,还包括响应主体。

响应实体
MIME 类型

Web 服务器要负责确定响应主体的 MIME 类型。


image.png

重定向

第六步——发送响应

第七步——记录日志

代理

6.1 Web 的中间实体

6.1.1 私有和共享代理

6.1.2 代理与网关的对比

代理连接的是两个或多个使用相同协议的应用程序,而网关连接的则是两个或多个使用不同协议的端点。网关扮演的是“协议转换器”的角色,即使客户端和服务器使用的是不同的协议,客户端也可以通过它完成与服务器之间的事务处理。


image.png

6.2 为什么使用代理

6.3 代理会去往何处

6.3.1 代理服务器的部署

6.3.2 代理的层次结构

image.png

6.3.3 代理是如何获取流量的

6.4 客户端的代理设置

6.5 与代理请求有关的一些棘手问题

...

6.6 追踪报文

6.6.1 Via 首部

Via 首部字段列出了与报文途经的每个中间节点(代理或网关)有关的信息。报文每经过一个节点,都必须将这个中间节点添加到 Via 列表的末尾。

Via: 1.1 proxy-62.irenes-isp.net, 1.0 cache.joes-hardware.com
image.png
Via 的请求和响应路径
image.png

Via 与网关

有些代理会为使用非 HTTP 协议的服务器提供网关的功能。 Via 首部记录了这些协议转换,这样, HTTP 应用程序就会了解代理链上各点的协议处理能力以及所做的协议转换了。图 6-22 显示了一个通过 HTTP/FTP 网关请求某个 FTP URI 的 HTTP
客户端。


image.png
Via 的隐私和安全问题

我们并不希望在 Via 字符串中使用确切的主机名。

对那些有着非常强烈的隐私要求,需要隐藏内部网络设计和拓扑结构的组织来说,代理应该将一个(接收协议值相同的)有序 Via 路标条目序列合并成一个联合条目。比如,可以将:
Via: 1.0 foo, 1.1 devirus.company.com, 1.1 access-logger.company.com
压缩成:
Via: 1.0 foo, 1.1 concealed-stuff

6.6.2 TRACE 方法

通过 HTTP/1.1 的 TRACE 方法,用户可以跟踪经代理链传输的请求报文,观察报文经过了哪些代理,以及每个代理是如何对请求报文进行修改的。


image.png

如果 Max-Forwards 的值为零( Max-Forwards:0 ),那么即使接收者不是原始服务器,它也必须将 TRACE 报文回送给客户端,而不应该继续转发。


image.png

6.7 代理认证

代 理 可 以 作 为 访 问 控 制 设 备 使 用。HTTP 定 义 了 一 种 名 为 代 理 认 证(proxyauthentication)的机制,这种机制可以阻止对内容的请求,直到用户向代理提供了
有效的访问权限证书为止。


image.png

6.8 代理的互操作性

6.8.1 处理代理不支持的首部和方法

6.8.2 OPTIONS :发现对可选特性的支持

image.png

如果 OPTIONS 请求的 URI 是个星号( * ),请求的就是整个服务器所支持的功能。比如:
OPTIONS * HTTP/1.1
如果 URI 是个实际资源地址,OPTIONS 请求就是在查询那个特定资源的可用特性:
OPTIONS http://www.joes-hardware.com/index.html HTTP/1.1

6.8.3 Allow首部

Allow 实体首部字段列出了请求 URI 标识的资源所支持的方法列表,如果请求 URI为 * 的话,列出的就是整个服务器所支持的方法列表。
Allow: GET, HEAD, PUT
可以将 Allow 首部作为请求首部,建议在新的资源上支持某些方法。并不要求服务器支持这些方法,但应该在相应的响应中包含一个 Allow 首部,列出它实际支持的方法。

缓存

冗余的数据传输

带宽瓶颈

image.png

瞬间拥塞

选区_148.png

距离时延

每台网络路由器都会增加因特网流量的时延。即使客户端和服务器之间没有太多的路由器,光速自身也会造成显著的时延。
波士顿到旧金山的直线距离大约有2700英里。在最好的情况下,以光速传输(186000英里/秒)的信号可以在大约15毫秒内从波士顿传送到旧金山,并在30毫秒内完成一个往返。

命中和未命中的

再验证(新鲜度检测)revalidation

原始服务器的内容可能会发生变化,缓存要不时对其进行检测,看看它们保存的副本是否仍是服务器上最新的副本。


image.png
命中率

文档命中率
40% 的命中率是很合理的

字节命中率

缓存的拓扑结构

私有缓存
公有代理缓存
image.png
代理缓存的层次结构
image.png
网状缓存

有些网络结构会构建复杂的网状缓存(cache mesh),而不是简单的缓存层次结构。

内容路由

代理缓存会决定选择何种路由对内容进行访问、管理和传送,因此可将其称为内容路由器(content router)

对等缓存

缓存之间这些更为复杂的关系允许不同的组织互为对等(peer)实体,将它们的缓存连接起来以实现共赢。提供可选的对等支持的缓存被称为兄弟缓存(siblingcache)

image.png

缓存的处理步骤

(1) 接收——缓存从网络中读取抵达的请求报文。
(2) 解析——缓存对报文进行解析,提取出 URL 和各种首部。
(3) 查询——缓存查看是否有本地副本可用,如果没有,就获取一份副本(并将其保存在本地)。
(4) 新鲜度检测——缓存查看已缓存副本是否足够新鲜,如果不是,就询问服务器是否有任何更新。
(5) 创建响应——缓存会用新的首部和已缓存的主体来构建一条响应报文。
(6) 发送——缓存通过网络将响应发回给客户端。
(7) 日志——缓存可选地创建一个日志文件条目来描述这个事务。


image.png
新鲜度检测

缓存可以在不联系服务器的情况下,直接提供该文档。但一旦已缓存副本停留的时间太长,超过了文档的新鲜度限值(freshness limit),就认为对象“过时”了,在提供该文档之前,缓存要再次与服务器进行确认,以查看文档是否发生了变化。客户端发送给缓存的所有请求首部自身都可以强制缓存进行再验证,或者完全避免验证,这使得事情变得更加复杂了。

保持副本的新鲜

文档会随着时间发生变化。
HTTP 有一些简单的机制可以在不要求服务器记住有哪些缓存拥有其文档副本的情况下,保持已缓存数据与服务器数据之间充分一致。HTTP 将这些简单的机制称为文档过期(document expiration)和服务器再验证(server revalidation)。


image.png
文档过期

HTTP Cache-Control 首部 和 Expires 首部


image.png
image.png
服务器再验证

• 如果再验证显示内容 发生了变化,缓存会获取一份新的文档副本,并将其存储在旧文档的位置上,然后将文档发送给客户端。
• 如果再验证显示内容 没有发生变化,缓存只需要获取新的首部,包括一个新的过期日期,并对缓存中的首部进行更新就行了。

缓存并不一定要为每条请求验证文档的有效性——只有在文档过期时它才需要与服务器进行再验证。这样不会提供陈旧的内容,还可以节省服务器的流量,并拥有更好的用户响应时间。

用条件方法进行再验证

HTTP 的条件方法可以高效地实现再验证。HTTP 允许缓存向原始服务器发送一个“条件 GET”,请求服务器只有在文档与缓存中现有的副本不同时,才回送对象主体。

image.png
If-Modified-Since:Date 再验证

If-Modified-Since 再验证请求通常被称为 IMS 请求。只有自某个日期之后资源发生了变化的时候,IMS 请求才会指示服务器执行请求:

If-Modified-Since 首部可以与 Last-Modified 服务器响应首部配合工作。原始服务器会将最后的修改日期附加到所提供的文档上去。当缓存要对已缓存文档进行再验证时,就会包含一个 If-Modified-Since 首部,其中携带有最后修改已缓存副本的日期:
If-Modified-Since: <cached last-modified date>

假设今天是美国东部标准时间(EST,Eastern Standard Time)2002 年 6 月 29 日上午 9 ∶ 30 , Joe 的五金商店正在准备进行 7 月 4 日(美国国庆日)特卖(只剩 5 天了)。 Joe 想在他的 Web 服务器上放置一个特殊的 Web 页面,并将其设置为 2002 年7 月 5 日晚上的 EST 午夜时间过期。如果 Joe 的服务器使用的是老式的 Expires 首部,服务器响应报文(参见图 7-13a)中可能就会包含这个首部:
Expires: Fri, 05 Jul 2002, 05:00:00 GMT

如果 Joe 的服务器使用了较新的 Cache-Control: max-age 首部,服务器响应报文
(参见图 7-13b)中可能就会包含这个首部:Cache-Control: max-age=484200如果这还不够明确的话,可以这样来看,当前时间,EST 时间 2002 年 6 月 29 日早上9∶30,到售卖结束时间 2002 年 7 月 5 日午夜之间有 484 200 秒。到售卖结束之前还有 134.5 小时(大约 5 天)。每小时有 3600 秒,这样到售卖结束之前还有 484 200 秒。

例如,如图 7-14 所示,如果你的缓存在 7 月 3 日对 Joe 的五金商店的 7 月 4 日特卖声明进行再验证,就会收到一条 Not Modified 响应(参见图 7-14a)。但如果你的缓存在 7 月 5 日午夜售卖结束后对文档进行再验证,缓存就会收到一个新文档,因为服务器内容已经发生了变化(参见图 7-14b)。


image.png
If-None-Match:实体标签再验证

有些情况下仅使用最后修改日期进行再验证是不够的。

为了解决这些问题, HTTP 允许用户对被称为实体标签( ETag )的“版本标识符”
进行比较。


image.png

如果服务器上的实体标签已经发生了变化(可能变成了 v3.0 ),服务器会在一个 200
OK 响应中返回新的内容以及相应的新 Etag 。

强弱验证器

服务器希望在对文档进行一些非实质性或不重要的修改时,不要使所有的已缓存副本都失效。HTTP/1.1 支持“弱验证器”,如果只对内容进行了少量修改,就允许服务器声明那是“足够好”的等价体。

只要内容发生了变化,强验证器就会变化。弱验证器允许对一些内容进行修改,但内容的主要含义发生变化时,通常它还是会变化的。有些操作不能用弱验证器来实现(比如有条件地获取部分内容),所以,服务器会用前缀“W/”来标识弱验证器。

ETag: W/"v2.6"
If-None-Match: W/"v2.6
什么时候应该使用实体标签和最近修改日期

如果服务器回送了一个实体标签,HTTP/1.1 客户端就必须使用实体标签验证器。如果服务器只回送了一个 Last-Modified 值,客户端就可以使用 If-Modified-Since验证。如果实体标签和最后修改日期都提供了,客户端就应该使用这两种再验证方案,这样HTTP/1.0 和 HTTP/1.1 缓存就都可以正确响应了。

控制缓存的能力

Pragma: no-cache
Cache-Control: no-store
Cache-Control: no-cache

标识为 no-store 的响应会禁止缓存对响应进行复制。缓存通常会像非缓存代理服务器一样,向客户端转发一条 no-store 响应,然后删除对象。
标识为 no-cache 的响应实际上是可以存储在本地缓存区中的。只是在与原始服务器进行新鲜度再验证之前,缓存不能将其提供给客户端使用。

Cache-Control: must-revalidate

Cache-Control: must-revalidate 响应首部告诉缓存,在事先没有跟原始服务器进行再验证的情况下,不能提供这个对象的陈旧副本。

Cache-Control: max-age=3600
Cache-Control: s-maxage=3600
Expires: Fri, 05 Jul 2002, 05:00:00 GMT

试探性过期

如果响应中没有 Cache-Control: max-age 首部,也没有 Expires 首部,缓存可以计算出一个试探性最大使用期

LM-Factor 算法是一种很常用的试探性过期算法,如果文档中包含了最后修改日期,就可以使用这种算法。LM-Factor 算法将最后修改日期作为依据,来估计文档有多么易变。算法的逻辑如下所示。

image.png

客户端的新鲜度限制

image.png

设置缓存控制

控制 Apache 的 HTTP 首部
<Files *.html>
Header set Cache-control no-cache
</Files>
ExpiresDefault A3600
ExpiresDefault M86400
ExpiresDefault "access plus 1 week"
ExpiresByType text/html "modification plus 2 days 6 hours 12 minutes"
通过 HTTP-EQUIV 控制 HTML 缓存
<HTML>
<HEAD>
<TITLE>My Document</TITLE>
<META HTTP-EQUIV="Cache-control" CONTENT="no-cache">
</HEAD>
...

总之,< META HTTP-EQUIV > 标签并不是控制文档缓存特性的好方法。通过配置正确的服务器发出 HTTP 首部,是传送文档缓存控制请求的唯一可靠的方法。


image.png

详细算法

缓存和广告

Freshness (新鲜度)

As HTTP is a client-server protocol, servers can't contact caches and clients when a resource changes; they have to communicate an expiration time for the resource. Before this expiration time, the resource is fresh; after the expiration time, the resource is stale.
Here is an example of this process with a shared cache proxy:


image.png

第八章 集成点:网关、隧道及中继

Web 浏览器这样的 HTTP 应用程序为用户提供了一种统一的方式来访问因特网上的内容。
HTTP 也已成为应用程序开发者的一种基本构造模块,开发者们可以在 HTTP 上捎回其他的协议内容(比如,可以将其他协议的流量包裹在 HTTP 中,用 HTTP 通过隧道或中继方式将这些流量传过公司的防火墙)。Web 上所有的资源都可以使用 HTTP 协议,而且其他应用程序和应用程序协议也可以利用 HTTP 来完成它们的任务。
本章简要介绍了一些开发者用 HTTP 访问不同资源的方法,展示了开发者如何将HTTP 作为框架启动其他协议和应用程序通信。

8.1 网关

HTTP 扩展和接口的发展是由用户需求驱动的。要在 Web 上发布更复杂资源的需求出现时,人们很快就明确了一点:单个应用程序无法处理所有这些能想到的资源。

为了解决这个问题,开发者提出了网关(gateway)的概念,网关可以作为某种翻译器使用,它抽象出了一种能够到达资源的方法。网关是资源和应用程序之间的粘合剂。应用程序可以(通过 HTTP 或其他已定义的接口)请求网关来处理某条请求,网关可以提供一条响应。网关可以向数据库发送查询语句,或者生成动态的内容,就像一个门一样:进去一条请求,出来一个响应。

图 8-1 显示的是一种资源网关。在这里,Joe 的五金商店服务器就是作为连接数据库内容的网关使用的——注意,客户端只是在通过 HTTP 请求资源,而 Joe 的五金商店的服务器在与网关进行交互以获取资源。


image.png

图 8-2 显示了三个网关的示例。

客户端和服务器端网关

可以用一个斜杠来分隔客户端和服务器端协议,并以此对网关进行描述:
< 客户端协议 >/< 服务器端协议 >

我们用术语服务器端网关和客户端网关来说明对话是在网关的哪一侧进行的。

8.2 协议网关

图 8-3 显示了配置浏览器使用服务器端 FTP 网关的对话框。在图中显示的配置中,配置浏览器将 gw1.joes-hardware.com 作为所有 FTP URL 的 HTTP/FTP 网关。浏览器没有将 FTP 命令发送给 FTP 服务器,而是将 HTTP 命令发送给端口 8080 上的HTTP/FTP 网关 gw1.joes-hardware.com。

image.png image.png

8.2.1 HTTP/* :服务器端 Web 网关

请求流入原始服务器时,服务器端 Web 网关会将客户端 HTTP 请求转换为其他协议。


image.png

在图 8-5 中,网关收到了一条对 FTP 资源的 HTTP 请求:
ftp://ftp.irs.gov/pub/00-index.txt
网关会打开一条到原始服务器 FTP 端口(端口 21)的 FTP 连接,通过 FTP 协议获
取对象。

8.2.2 HTTP/HTTPS :服务器端安全网关

image.png

8.2.3 HTTPS/HTTP 客户端安全加速器网关

image.png

这些网关中通常都包含专用的解密硬件,以比原始服务器有效得多的方式来解密安全流量,以减轻原始服务器的负荷。

8.3 资源网关

应用程序服务器,会将目标服务器与网关结合在一个服务器中实现。应用程序服务器是服务器端网关,与客户端通过 HTTP 进行通信,并与服务器端的应用程序相连。


image.png

两 个 客 户 端 是 通 过 HTTP 连 接 到 应 用 程 序 服 务 器 的。 但 应 用 程 序服 务 器 并 没 有 回 送 文 件, 而 是 将 请 求 通 过 一 个 网 关 应 用 编 程 接 口(ApplicationProgramming Interface,API)发送给运行在服务器上的应用程序。

第一个流行的应用程序网关 API 就是通用网关接口(Common Gateway Interface,
CGI)。CGI 是 一 个 标 准 接 口 集,Web 服 务 器 可 以 用 它 来 装 载 程 序 以 响 应 对 特 定URL 的 HTTP 请求,并收集程序的输出数据,将其放在 HTTP 响应中回送。

8.3.1 CGI

CGI 是第一个,可能仍然是得到最广泛使用的服务器扩展。在 Web 上广泛用于动态HTML 、信用卡处理以及数据库查询等任务。
它在服务器和众多的资源类型之间提供了一种简单的、函数形式的粘合方式,用来处理各种需要的转换。这个接口还能很好地保护服务器,防止一些糟糕的扩展对它造成的破坏。

8.3.2 服务器扩展 API

扩展 API 允许程序员将自己的代码嫁接到服务器上,或者用自己的代码将服务器的一个组件完整地替换出来。

8.4 应用程序接口和 Web 服务

将资源网关作为 Web 服务器与应用程序的通信方式使用。
随着 Web 应用程序提供的服务类型越来越多,有一点变得越来越清晰了:HTTP 可以作为一种连接应用程序的基础软件来使用。
因特网委员会开发了一组允许 Web 应用程序之间相互通信的标准和协议。尽管 Web
服务(Web service)可以用来表示独立的 Web 应用程序(构造模块),这里我们还是宽松地用这个术语来表示这些标准。

8.5 隧道

Web 隧道允许用户通过 HTTP 连接发送非 HTTP 流量,这样就可以在 HTTP 上捎带其他协议数据了。使用 Web 隧道最常见的原因就是要在 HTTP 连接中嵌入非 HTTP
流量,这样,这类流量就可以穿过只允许 Web 流量通过的防火墙了。

8.5.1 用 CONNECT 建立 HTTP 隧道

CONNECT 方法请求隧道网关创建一条到达任意目的服务器和端口的 TCP 连接,并对客户端和服务器之间的后继数据进行盲转发。

image.png

8.5.2 数据隧道、定时及连接管理

8.5.3 SSL 隧道

Web 隧道是为了通过防火墙来传输加密的 SSL 流量。很多组织都会将所有流量通过分组过滤路由器和代理服务器以隧道方式传输,以提升安全性。但有些协议,比如加密 SSL,其信息是加密的,无法通过传统的代理服务器转发。隧道会通过一条 HTTP 连接来传输 SSL 流量,以穿过端口 80 的 HTTP 防火墙(参见图 8-11)。


image.png

8.5.4 SSL 隧道与 HTTP/HTTPS 网关的对比

image.png

缺点:

8.5.5 隧道认证

将代理的认证支持与隧道配合使用,对客户端使用隧道的权利进行认证(参见图 8-13)。


image.png

8.5.6 隧道的安全性考虑

为了降低对隧道的滥用,网关应该只为特定的知名端口,比如 HTTPS 的端口 443,打开隧道。

8.6 中继

HTTP 中继(relay)是没有完全遵循 HTTP 规范的简单 HTTP 代理。中继负责处HTTP 中建立连接的部分,然后对字节进行盲转发。


image.png

第九章 Web 机器人

9.6 搜索引擎

image.png

9.6.3 全文索引

全文索引就是一个数据库,给它一个单词,它可以立即提供包含那个单词的所有文档。创建了索引之后,就不需要对文档自身进行扫描了。


image.png

第十章 HTTP-NG

image.png

第三部分 识别、认证与安全

第十一章 客户端识别与 cookie 机制

Web 服务器可能会同时与数千个不同的客户端进行对话。这些服务器通常要记录下它们在与谁交谈,而不会认为所有的请求都来自匿名的客户端。本章讨论了一些服务器可以用来识别其交谈对象的技巧。

11.1 个性化接触

HTTP 最初是一个匿名、无状态的请求 / 响应协议。服务器处理来自客户端的请求,然后向客户端回送一条响应。

用户识别机制

11.6 cookie

cookie 是当前识别用户,实现持久会话的最好方式。

11.6.1 cookie 的类型

11.6.2 cookie 是如何工作的

cookie 就像服务器给用户贴的“嗨,我叫”的贴纸一样。用户访问一个 Web 站点时,这个 Web 站点就可以读取那个服务器贴在用户身上的所有贴纸。

cookie 中包含了一个由名字 = 值(name=value)这样的信息构成的任意列表,并通过 Set-Cookie 或 Set-Cookie2 HTTP 响应(扩展)首部将其贴到用户身上去。


image.png

11.6.3 cookie 罐:客户端的状态

cookie 的基本思想就是让浏览器积累一组服务器特有的信息,每次访问服务器时都将这些信息提供给它。

  1. 网景的 Navigator 的 cookie


    image.png
  2. 微软 Internet Explorer 的 cookie


    image.png
11.6.4 不同站点使用不同的 cookie
  1. cookie 的域属性
    产生 cookie 的服务器可以向 Set-Cookie 响应首部添加一个 Domain 属性来控制哪些站点可以看到那个 cookie。
    Set-cookie: user="mary17"; domain="airtravelbargains.com"
    如果用户访问的是 www.airtravelbargains.comspecials.airtravelbargains.com 或意
    以 .airtravelbargains.com 结尾的站点,下列 Cookie 首部都会被发布出去:
    Cookie: user="mary17"
  2. cookie 路径属性
    cookie 规范甚至允许用户将 cookie 与部分 Web 站点关联起来。可以通过 Path 属性来实现这一功能,在这个属性列出的 URL 路径前缀下所有 cookie 都是有效的。
11.6.5 cookie 成分

cookies 版本 0(有时被称为 Netscapecookies) 和 cookies 版 本 1(RFC 2965)。cookies 版 本 1 是 对 cookies 版 本 0 的 扩展,应用不如后者广泛。

11.6.6 cookies 版本 0 ( Netscape )
Set-Cookie: name=value [; expires=date] [; path=path] [; domain=domain]
[; secure]
Cookie: name1=value1 [; name2=value2] ...
11.6.7 cookies 版本 1 ( RFC 2965 )

RFC 2965 cookie 标准比原始的网景公司的标准略微复杂一些,还未得到完全的支持。RFC 2965 cookie 的主要改动包括下列内容。

  1. 版本 1 的 Set-Cookie2 首部
  2. 版本 1 的 Cookie 首部
  3. 版本 1 的 Cookie2 首部和版本协商
11.6.8 cookie 与会话跟踪
image.png
11.6.9 cookie 与缓存

cookie 和缓存的规则并没有很好地建立起来。下面是处理缓存时的一些指导性规则。

11.6.10 cookie 、安全性和隐私

cookie 是可以禁止的,而且可以通过日志分析或其他方式来实现大部分跟踪记录,所以 cookie 自身并不是很大的安全隐患。

第十二章 基本认证机制

12.1 认证

12.2 基本认证

12.1.1 HTTP 的质询 / 响应认证框架

image.png

12.1.2 认证协议与首部

HTTP 通过一组可定制的控制首部,为不同的认证协议提供了一个可扩展框架。
HTTP 定义了两个官方的认证协议:基本认证和摘要认证。

image.png
image.png
image.png

12.1.3 安全域

HTTP/1.0 401 Unauthorized
WWW-Authenticate: Basic realm="Corporate Financials"
image.png

12.2 基本认证

基本认证是最流行的 HTTP 认证协议。几乎每个主要的客户端和服务器都实现了
基本认证机制。

12.2.1 基本认证实例

12.2.2 Base-64 用户名 / 密码编码

image.png

12.2.3 代理认证

image.png

12.3 基本认证的安全缺陷

(1) 基本认证会通过网络发送用户名和密码,这些用户名和密码都是以一种很容易解码的形式表示的。实际上,密码是以明文形式传输的,任何人都可以读取并将其捕获。虽然 Base-64 编码通过隐藏用户名和密码,致使友好的用户不太可能在进行网络观测时无意中看到密码,但 Base-64 编码的用户名和密码可以很轻易地通过反向编码过程进行解码。

第13章 摘要认证

基本认证便捷灵活,但极不安全。用户名和密码都是以明文形式传送的, 也没有采取任何措施防止对报文的篡改。安全使用基本认证的唯一方式就是将其与 SSL 配合使用。
摘要认证与基本认证兼容,但却更为安全。

13.1 摘要认证的改进

13.1.1 用摘要保护密码

摘要认证遵循的箴言是“绝不通过网络发送密码”。客户端不会发送密码,而是会发送一个“指纹”或密码的“摘要”,这是密码的不可逆扰码。

image.png

13.1.2 单向摘要

摘要是“对信息主体的浓缩”。 6 摘要是一种单向函数,主要用于将无限的输入值转换为有限的浓缩输出值。
最重要的是如果不知道密码的话,要想正确地猜出发送给服务器的摘要将是非常困难的。同样,如果有摘要,想要判断出它是由无数输入值中的哪一个产生的,也是非常困难的。

摘要算法

MD5 安全散列算法(Secure Hash AlgorithmSHA)

13.1.3 用随机数防止重放攻击

隐藏密码并不能避免危险,因为即便不知道密码,别有用心的人也可以截获摘要,并一遍遍地重放给服务器。摘要和密码一样好用。

为防止此类重放攻击的发生,服务器可以向客户端发送一个称为随机数(nonce) 的特殊令牌,这个数会经常发生变化(可能是每毫秒,或者是每次认证都变化)。客户端在计算摘要之前要先将这个随机数令牌附加到密码上去。

13.1.4 摘要认证的握手机制

基本认证和摘要认证对比
image.png

qop quality of protection
nonce 随机数

简化的摘要认证三步握手机制

13.2 摘要的计算 (todo)

摘要认证的核心就是对公共信息、保密信息和有时限的随机值这个组合的单向摘要。

13.2.1 摘要算法的输入数据

摘要是根据以下三个组件计算出来的。

13.2.2 算法 H(d ) 和 KD(s,d )

摘要认证支持对各种摘要算法的选择。RFC 2617 建议的两种算法为 MD5 和 MD5-sess(“sess”表示会话),如果没有指定其他算法,默认算法为 MD5。

函数 H 来计算数据的 MD5,用摘要函数 KD 来计算以冒号连接的密码和非保密数据的MD5。例如:
H(<data>) = MD5(<data>)
KD(<secret>,<data>) = H(concatenate(<secret>:<data>))

13.2.3 与安全性相关的数据( A1 )

被称为 A1 的数据块是密码和受保护信息的产物,它包含有用户名、密码、保护域和随机数等内容。A1 只涉及安全信息,与底层报文自身无关。A1 会与 H、KD 和A2 一同用于摘要计算。
RFC 2617 根据选择的算法定义了两种计算 A1 的方式。

13.2.4 与报文有关的数据( A2 )

数据块 A2 表示的是与报文自身有关的信息,比如 URL、请求方法和报文实体的主体部分。 A2 有助于防止方法、资源或报文被篡改。 A2 会与 H 、 KD 和 A1 一起用于摘要的计算。
RFC 2617 根据所选择的保护质量( qop ),为 A2 定义了两种策略。

13.2.5 摘要算法总述

RFC 2617 定义了两种给定了 H 、 KD 、 A1 和 A2 之后,计算摘要的方式。

表 13-4 给出了得到的摘要函数定义。注意得到的摘要使用了 H、KD、A1 和 A2。


image.png

这些派生封装层很容易把人弄晕。这也是有些读者觉得 RFC 2617 难懂的原因之一。
为了简化,表 13-5 扩展了 H 和 KD 的定义,用 A1 和 A2 来表示摘要。


image.png

13.2.6 摘要认证会话

客户端响应对保护空间的 WWW-Authenticate 质询时,会启动一个此保护空间的认证会话。
在 客 户 端 收 到 另 一 条 来 自 保 护 空 间 的 任 意 一 台 服 务 器 的 WWW-Authenticate 质询之前,认证会话会一直持续。

13.2.7 预授权

在普通的认证方式中,事务结束之前,每条请求都要有一次请求 / 质询的循环。
如果客户端事先知道下一个随机数是什么,就可以取消这个请求 / 质询循环,这样客户端就可以在服务器发出请求之前,生成正确的 Authorization 首部了。


image.png
预授权方式

13.2.8 随机数的选择

RFC 2617 建议采用这个假想的随机数公式:
BASE64(time-stamp H(time-stamp ":" ETag ":" private-key))

13.2.9 对称认证

RFC 2617 扩展了摘要认证机制,允许客户端对服务器进行认证。这是通过提供客户端随机值来实现的,服务器会根据它对共享保密信息的正确了解生成正确的响应摘要。然后,服务器在 Authorization-Info 首部中将此摘要返回给客户端。


cnonce 值 和 nc 值 必 须 是 本 报 文 所 响 应 的 客 户 端 请 求 中 的 相 应 值。 如 果 指 定 了qop="auth" 或 qop="auth-int" ,就必须提供响应 auth 、 cnonce 和 nonce 计数指令。

13.3 增强保护质量

可以在三种摘要首部中提供 qop 字段: WWW-Authenticate 、 Authorization 和
Authentication-Info 。

13.3.1 报文完整性保护

如果使用了完整性保护( qop="auth-int" ),H(实体的主体部分)就是对实体主体部分,而不是报文主体部分的散列。

13.3.2 摘要认证首部

image.png

13.4 应该考虑的实际问题

13.4.1 多重质询

13.4.2 差错处理

13.4.3 保护空间

13.4.4 重写 URI

13.4.5 缓存

13.5 安全性考虑

13.5.1 首部篡改

13.5.2 重放攻击

13.5.3 多重认证机制

13.5.4 词典攻击

13.5.5 恶意代理攻击和中间人攻击

13.5.6 选择明文攻击

13.5.7 存储密码

第14章 安全 HTTP

保护HTTP安全

HTTP 的安全版本要高效、可移植且易于管理,不但能够适应不断变化的情况而且还应该能满足社会和政府的各项要求。我们需要一种能够提供下列功能的 HTTP 安全术。

HTTPS

HTTPS 是最流行的 HTTP 安全形式。它是由网景公司首创的,所有主要的浏览器和服务器都支持此协议。
使用 HTTPS 时,所有的 HTTP 请求和响应数据在发送到网络之前,都要进行加密。
HTTPS 在 HTTP 下面提供了一个传输级的密码安全层。


image.png

14.2 数字加密

14.2.1 密码编制的机制与技巧

14.2.2 密码

image.png

14.2.3 密码机

14.2.4 使用了密钥的密码

编码算法和编码机都可能会落入敌人的手中,所以大部分机器上都有一些号盘,可以将其设置为大量不同的值以改变密码的工作方式。即使机器被盗,没有正确的号盘设置(密钥值),解码器也无法工作。 这些密码参数被称为密钥(key)。


image.png

14.2.5 数字密码

image.png

14.3 对称密钥加密技术

很多数字加密算法都被称为对称密钥(symmetric-key)加密技术,这是因为它们在编码时使用的密钥值和解码时一样(e=d)。我们就将其统称为密钥 k。

流行的对称密钥加密算法包括:DES、Triple-DES、RC2 和 RC4。

14.3.1 密钥长度与枚举攻击

image.png

14.3.2 建立共享密钥

对称密钥加密技术的缺点之一就是发送者和接收者在互相对话之前,一定要有一个
共享的保密密钥。

14.4 公开密钥加密技术

公开密钥加密技术没有为每对主机使用单独的加密 / 解密密钥,而是使用了两个非对称密钥:一个用来对主机报文编码,另一个用来对主机报文解码。编码密钥是众所周知的。但只有主机才知道私有的解密密钥。这样,每个人都能找到某个特定主机的公开密钥,密钥的建立变得更加简单。但解码密钥是保密的,因此只有接收端才能对发送给它的报文进行解码。


image.png

14.4.1 RSA

所有公开密钥非对称加密系统所面临的共同挑战是,要确保即便有人拥有了下面所有的线索,也无法计算出保密的私有密钥:

RSA 算法就是一个满足了所有这些条件的流行的公开密钥加密系统,它是在 MIT发明的,后来由 RSA 数据安全公司将其商业化。

14.4.2 混合加密系统和会话密钥

但公开密钥加密算法的计算可能会很慢。实际上它混合使用了对称和非对称策略。比如,比较常见的做法是在两节点间通过便捷的公开密钥加密技术建立起安全通信,然后再用那条安全的通道产生并发送临时的随机对称密钥,通过更快的对称加密技术对其余的数据进行加密。

14.5 数字签名

除了加 / 解密报文之外,还可以用加密系统对报文进行签名(sign),以说明是谁编写的报文,同时证明报文未被篡改过。这种技术被称为数字签名(digital signing)。

签名是加了密的校验和

数字签名是附加在报文上的特殊加密校验码。使用数字签名有以下两个好处。

数字签名通常是用非对称公开密钥技术产生的。因为只有所有者才知道其私有密钥,所以可以将作者的私有密钥当作一种“指纹”使用。
图 14-10 显示了一个例子,说明了节点 A 是如何向节点 B 发送一条报文,并对其进行签名的。


image.png

14.6 数字证书

本节将介绍因特网上的“ID 卡”——数字证书。数字证书(通常被称作“certs”,有点像 certs 牌薄荷糖)中包含了由某个受信任组织担保的用户或公司的相关信息。
我们每个人都有很多形式的身份证明。有些 ID,比如护照和驾照,都足以在很多场合证明某人的身份。

14.6.1 证书的主要内容

14.6.2 X.509 v3 证书

不过好消息就是现在使用的大多数证书都以一种标准格式——X.509 v3,来存储它们信息。X.509 v3证书提供了一种标准的方式,将证书信息规范至一些可解析字段中。不同类型的证书有不同的字段值,但大部分都遵循 X.509 v3 结构。


image.png
image.png

14.6.3 用证书对服务器进行认证

通过 HTTPS 建立了一个安全 Web 事务之后,现代的浏览器都会自动获取所连接服务器的数字证书。如果服务器没有证书,安全连接就会失败。服务器证书中包含很多字段,其中包括:

14.7 HTTPS ——细节介绍

HTTPS 将 HTTP 协议与一组强大的对称、非对称和基于证书的加密技术结合在一起,使得 HTTPS 不仅很安全,而且很灵活,很容易在处于无序状态的、分散的全球互联网上进行管理。

14.7.1 HTTPS 概述

HTTPS 就 是 在 安 全 的 传 输 层 上 发 送 的 HTTP。HTTPS 没 有 将 未 加 密 的HTTP 报文发送给 TCP,并通过世界范围内的因特网进行传输(参见图 14-13a),它在将
HTTP 报文发送给 TCP 之前,先将其发送给了一个安全层,对其进行加密(参见图 14-13b)。


image.png

14.7.2 HTTPS 方案

请求一个客户端(比如 Web 浏览器)对某 Web 资源执行某事务时,它会去检查URL 的方案。

14.7.3 建立安全传输

在未加密 HTTP 中,客户端会打开一条到 Web 服务器端口 80 的 TCP 连接,发送一条请求报文,接收一条响应报文,关闭连接。图 14-15a 对此序列进行了说明。
由于 SSL 安全层的存在,HTTPS 中这个过程会略微复杂一些。在 HTTPS 中,客户端首先打开一条到 Web 服务器端口 443(安全 HTTP 的默认端口)的连接。一旦建立了 TCP 连接,客户端和服务器就会初始化 SSL 层,对加密参数进行沟通,并交换密钥。握手完成之后, SSL 初始化就完成了,客户端就可以将请求报文发送给安全层了。在将这些报文发送给 TCP 之前,要先对其进行加密。图 14-15b 对此过程进行了说明。


image.png

14.7.4 SSL 握手

在发送已加密的 HTTP 报文之前,客户端和服务器要进行一次 SSL 握手,在这个握手过程中,它们要完成以下工作:

在通过网络传输任何已加密的 HTTP 数据之前,SSL 已经发送了一组握手数据来建立通信连接了。图 14-16 显示了 SSL 握手的基本思想。


image.png

14.7.5 服务器证书

SSL 支持双向认证,将服务器证书承载回客户端,再将客户端的证书回送给服务器。而现在,浏览时并不经常使用客户端证书。大部分用户甚至都没有自己的客户端证书。服务器可以要求使用客户端证书,但实际中很少出现这种情况。
安全 HTTPS 事务总是要求使用服务器证书的。


image.png

14.7.6 站点证书的有效性

14.7.7 虚拟主机与证书

对虚拟主机(一台服务器上有多个主机名)站点上安全流量的处理有时是很棘手的。有些流行的 Web 服务器程序只支持一个证书。如果用户请求的是虚拟主机名,与证书名称并不严格匹配,浏览器就会显示警告框。

14.8 HTTPS 客户端实例

14.8.1 OpenSSL

14.8.2 简单的 HTTPS 客户端

14.8.3 执行 OpenSSL 客户端

14.9 通过代理以隧道形式传输安全流量

客户端通常会用 Web 代理服务器(参见第 6 章)代表它们来访问 Web 服务器。比如,很多公司都会在公司网络和公共因特网的安全边界上放置一个代理(参见图14-19)。代理是防火墙路由器唯一允许进行 HTTP 流量交换的设备,它可能会进行病毒检测或其他的内容控制工作。


image.png

但只要客户端开始用服务器的公开密钥对发往服务器的数据进行加密,代理就再也
不能读取 HTTP 首部了!代理不能读取 HTTP 首部,就无法知道应该将请求转向何
处了(参见图 14-20)。


image.png

为了使 HTTPS 与代理配合工作,要进行几处修改以告知代理连接到何处。一种常用的技术就是 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

终于到一个段落了,后面还有几章,不太重要了,这次就写到这里了啊!

上一篇下一篇

猜你喜欢

热点阅读