http权威指南阅读笔记
1 | 所有类型的内容来源都是资源。 |
HTTP 概述
Web 浏览器、服务器和相关的 Web 应用程序都是通过 HTTP 相互通信的。HTTP 是现代全球因特网中使用的公共语言。
Web 客户端和服务器
Web 内容都是存储在 Web 服务器上的。Web 服务器所使用的是 HTTP 协议,因此经常会被称为 HTTP 服务器。这些 HTTP 服务器存储了因特网中的数据,如果 HTTP 客户端发出请求的话,它们会提供数据。客户端向服务器发送 HTTP 请求,服务器会在 HTTP 响应中回送所请求的数据。HTTP 客户端和 HTTP 服务器共同构成了万维网的基本组件。
资源
Web 服务器是 Web 资源(Web resource)的宿主。Web 资源是 Web 内容的源头。最简单的 Web 资源就是 Web 服务器文件系统中的静态文件。这些文件可以包含任意内容:文本文件、 HTML 文件、微软的 Word 文件、 Adobe 的 Acrobat 文件、 JPEG 图片文件、 AVI 电影文件,或所有其他你能够想到的格式。但资源不一定非得是静态文件。资源还可以是根据需要生成内容的软件程序。
媒体类型
因特网上有数千种不同的数据类型,HTTP 仔细地给每种要通过 Web 传输的对象都打上了名为 MIME 类型(MIME type)的数据格式标签。最初设计 MIME (Multipurpose Internet Mail Extension,多用途因特网邮件扩展)是为了解决在不同的电子邮件系统之间搬移报文时存在的问题。MIME 在电子邮件系统中工作得非常好,因此 HTTP 也采纳了它,用它来描述并标记多媒体内容。存储在 Content-type 字段中
URI
每个 Web 服务器资源都有一个名字,这样客户端就可以说明它们感兴趣的资源是什么了。服务器资源名被称为统一资源标识符(Uniform Resource Identi?er,URI)。URI 就像因特网上的邮政地址一样,在世界范围内唯一标识并定位信息资源。这是 Joe 的五金商店的 Web 服务器上一个图片资源的 URI:http://www.joes-hardware.com/specials/saw-blade.gif
URL
统一资源定位符(URL)是资源标识符最常见的形式。URL 描述了一台特定服务器上某资源的特定位置。它们可以明确说明如何从一个精确、固定的位置获取资源。图 1-4 显示了 URL 如何精确地说明某资源的位置以及如何去访问它。
以密码保护的FTP 作为访问协议的lockingpliers.gif 图片文件的URL
1 | ftp://joe:tools4u@ftp.joes-hardware.com/lockingpliers.gif |
Yahoo! 的Web 站点标志URL
1 | http://www.yahoo.com/images/logo.gif |
URN
URI 的第二种形式就是统一资源名(URN)。URN 是作为特定内容的唯一名称使用的,与目前的资源所在地无关。使用这些与位置无关的 URN,就可以将资源四处搬移。通过 URN,还可以用同一个名字通过多种网络访问协议来访问资源。比如,不论因特网标准文档 RFC 2141 位于何处(甚至可以将其复制到多个地方),都可以用下列 URN 来命名它:
1 | urn:ietf:rfc:2141 |
URN 仍然处于试验阶段,还未大范围使用。
事务
我们来更仔细地看看客户端是怎样通过 HTTP 与 Web 服务器及其资源进行事务处理的。一个 HTTP 事务由一条(从客户端发往服务器的)请求命令和一个(从服务器发回客户端的)响应结果组成。这种通信是通过名为 HTTP 报文(HTTP message)的格式化数据块进行的
方法
HTTP 支持几种不同的请求命令,这些命令被称为 HTTP 方法(HTTP method)。每条 HTTP 请求报文都包含一个方法。这个方法会告诉服务器要执行什么动作(获取一个 Web 页面、运行一个网关程序、删除一个文件等)。常见的 get,post,put,delete,option…
状态码
每条 HTTP 响应报文返回时都会携带一个状态码。状态码是一个三位数字的代码,告知客户端请求是否成功,或者是否需要采取其他动作。常见的200,301,404,500…
报文
现在我们来快速浏览一下 HTTP 请求和响应报文的结构。第 3 章会深入研究 HTTP 报文。HTTP 报文是由一行一行的简单字符串组成的。HTTP 报文都是纯文本,不是二进制代码,所以人们可以很方便地对其进行读写 。
HTTP 报文包括以下三个部分。
起始行
报文的第一行就是起始行,在请求报文中用来说明要做些什么,在响应报文中说明出现了什么情况。
首部字段
起始行后面有零个或多个首部字段。每个首部字段都包含一个名字和一个值,为了便于解析,两者之间用冒号(:)来分隔。首部以一个空行结束。添加一个首部字段和添加新行一样简单。
主体
空行之后就是可选的报文主体了,其中包含了所有类型的数据。请求主体中包括了要发送给 Web 服务器的数据;响应主体中装载了要返回给客户端的数据。起始行和首部都是文本形式且都是结构化的,而主体则不同,主体中可以包含任意的二进制数据(比如图片、视频、音轨、软件程序)。当然,主体中也可以包含文本。
报文的发送,需要使用到 tcp/ip 、udp等报文传输协议。通过 ip:端口 建立连接通信
Web 的结构组件
在本章的概述中,我们重点介绍了两个 Web 应用程序(Web 浏览器和 Web 服务器)是如何相互发送报文来实现基本事务处理的。在因特网上,要与很多 Web 应用程序进行交互。在本节中,我们将列出其他一些比较重要的应用程序
代理
位于客户端和服务器之间的 HTTP 中间实体。这里主要指正向代理,代理客户端浏览器发送请求给服务器
出于安全考虑,通常会将代理作为转发所有 Web 流量的可信任中间节点使用。代理还可以对请求和响应进行过滤。比如,在企业中对下载的应用程序进行病毒检测,或者对小学生屏蔽一些成人才能看的内容。
缓存
Web 缓存(Web cache)或代理缓存(proxy cache)。代理缓存是指一个独立的服务器或设备,它作为中介存储用户请求的 Web 资源,并在后续的请求中直接返回缓存的资源,从而减轻源服务器的负担并提高访问速度。
浏览器缓存是指浏览器本身内置的缓存机制,用于存储从 Web 服务器获取的资源(如 HTML、CSS、JavaScript、图片等),以便下次访问同一资源时无需重新向服务器请求,从而提高访问速度。
网关
网关(gateway)是一种特殊的服务器,作为其他服务器的中间实体使用。通常用于将 HTTP 流量转换成其他的协议。网关接受请求时就好像自己是资源的源端服务器一样。客户端可能并不知道自己正在与一个网关进行通信。例如,一个 HTTP/FTP 网关会通过 HTTP 请求接收对 FTP URI 的请求,但通过 FTP 协议来获取文档。得到的文档会被封装成一条 HTTP 报文,发送给客户端。
隧道
隧道(tunnel)是建立起来之后,就会在两条连接之间对原始数据进行盲转发的 HTTP 应用程序。HTTP 隧道通常用来在一条或多条 HTTP 连接上转发非 HTTP 数据,转发时不会窥探数据。HTTP 隧道的一种常见用途是通过 HTTP 连接承载加密的安全套接字层(SSL, Secure Sockets Layer)流量,这样 SSL 流量就可以穿过只允许 Web 流量通过的防火墙了。如图所示,HTTP/SSL 隧道收到一条 HTTP 请求,要求建立一条到目的地址和端口的输出连接,然后在 HTTP 信道上通过隧道传输加密的 SSL 流量,这 样就可以将其盲转发到目的服务器上去了。
Agent代理
用户 Agent 代理(或者简称为 Agent 代理)是代表用户发起 HTTP 请求的客户端程序。所有发布 Web 请求的应用程序都是 HTTP Agent 代理。到目前为止,我们只提到过一种 HTTP Agent 代理:Web 浏览器,但用户 Agent 代理还有很多其他类型。比如,有些自己会在 Web 上闲逛的自动用户 Agent 代理,可以在无人监视的情况下发布 HTTP 事务并获取内容。这些自动代理的名字通常都很生动,比如“网络蜘蛛”(spiders)或者“Web 机器人”(Web robots)。网络蜘蛛会在 Web 上闲逛,搜集信息以构建有效的 Web 内容档案,比如一个搜索引擎的数据库或者为比较购物机器人生成的产品目录。
URL 与资源
URL可以通过HTTP之外的其他协议来访问资源。它们可以指向因特网上的任意资源,或者个人的email账户:
1 | mailto:president@whitehouse.gov |
或者通过其他协议(比如FTP协议)访问的各种文件:
1 | ftp://ftp.lots-o-books.com/pub/complete-price-list.xls |
或者从流视频服务器上下载电影:
1 | rtsp://www.joes-hardware.com:554/interview/cto_videoURL |
提供了一种统一的资源命名方式。大多数 URL 都有同样的:“方案 :// 服务器位置 / 路径”结构。因此,对网络上的每个资源以及获取这些资源的每种方式来说,命名资源的方法都只有一种,这样不管是谁都可以用名字来找到这个资源了。但是,事情并不是一开始就是这样的。
URL 的语法
URL 提供了一种定位因特网上任意资源的手段,但这些资源是可以通过各种不同的方案(比如 HTTP、FTP、SMTP)来访问的,因此 URL 语法会随方案的不同而有所不同。
大多数 URL 方案的 URL 语法都建立在这个由 9 部分构成的通用格式上:
1 | <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag> |
其中最重要的三个部分 scheme、host、path
scheme
使用什么协议,如http、https
host、port
主机与端口
user、password
用户名和密码
path
URL 的路径组件说明了资源位于服务器的什么地方。路径通常很像一个分级的文件系统路径。
params
参数,光靠路径无法满足时需要用到
1
http://www.joes-hardware.com/hammers;sale=false/index.html;graphics=true
query
查询字符串
1
http://www.joes-hardware.com/inventory-check.cgi?item=12731
frag
片段,url指向整个文档,frag 可以指向文档中某个片段
正常的url是绝对URL,如
1 | https://www.baidu.com/pageA.html |
相对 url,类似于缩写
1 | ./pageA.html |
但是它需要依赖 基础url
1 | https://www.baidu.com |
脑瓜子疼的字符
URL 是可移植的(portable)。它要统一地命名因特网上所有的资源,这也就意味着要通过各种不同的协议来传送这些资源。这些协议在传输数据时都会使用不同的机制,所以,设计 URL,使其可以通过任意因特网协议安全地传输是很重要的。安全传输意味着 URL 的传输不能丢失信息。有些协议,比如传输电子邮件的简单邮件传输协议(Simple Mail Transfer Protocol,SMTP),所使用的传输方法就会剥去一些特定的字符。为了避开这些问题,URL 只能使用一些相对较小的、通用的安全字母表中的字符。
URL字符集
使用的历史悠久的 US-ASCII 字符集,移植性好但是不支持一些其他语言的变体字符。认识到对完整性的需求之后,URL 的设计者就将转义序列集成了进去。通过转义序列,就可以用 US-ASCII 字符集的有限子集对任意字符值或数据进行编码了,这样就实现了可移植性和完整性。
编码机制
为了避开安全字符集表示法带来的限制,人们设计了一种编码机制,用来在 URL 中表示各种不安全的字符。这种编码机制就是通过一种“转义”表示法来表示不安全的字符,这种转义表示法包含一个百分号(%),后面跟着两个表示字符 ASCII 码的 十六进制数。
保留及受限的字符
%
保留作为编码字符的转义标志
/
保留作为路径组件中分隔路径段的定界符
.
保留在路径组件中使用
..
保留在路径组件中使用
保留作为分段定界符使用
?
保留作为查询字符串定界符使用
;
保留作为参数定界符使用
:
保留作为方案、用户/口令,以及主机/端口组件的定界符使用
$, +
保留
@ & =
在某些方案的上下文中有特殊的含义,保留
{ } | \ ^ ~ [ ] ‘
由于各种传输Agent代理,比如各种网关的不安全处理,使用受限
< > “
不安全;这些字符在URL范围之外通常是有意义的,比如在文档中对URL自身进行定界(比如http://www.joes-hardware.com ),所以应该对其进行编码
0x00-0x1F, 0x7F
受限,这些十六进制范围内的字符都在US-ASCII字符集的不可打印区间内
0x7F
受限,十六进制值在此范围内的字符都不在US-ASCII字符集的7比特范围内
HTTP 报文
报文流
HTTP 报文是在 HTTP 应用程序之间发送的数据块。这些数据块以一些文本形式的元信息(meta-information)开头,这些信息描述了报文的内容及含义,后面跟着可选的数据部分。这些报文在客户端、服务器和代理之间流动。术语“流入”、“流出”、“上游”及“下游”都是用来描述报文方向的。
报文流入源端服务器
HTTP 使用术语流入(inbound)和流出(outbound)来描述事务处理(transaction)的方向。报文流入源端服务器,工作完成之后,会流回用户的 Agent 代理中
报文组成部分
它们由三个部分组成:对报文进行描述的起始行(start line)、包含属性的首部(header)块,以及可选的、包含数据的主体(body)部分。
报文语法
报文又分为请求报文(request message)和响应报文(response message)
这是请求报文的格式:
1 | <method> <request-URL> <version> |
这是响应报文的格式(注意,只有起始行的语法有所不同):
1 | <version> <status> <reason-phrase> |
方法(method)
客户端希望服务器对资源执行的动作。是一个单独的词,比如 GET、HEAD 或 POST。
请求 URL(request-URL)
命名了所请求资源,或者 URL 路径组件的完整 URL。
版本(version)
报文所使用的 HTTP 版本
1
2// 其中主要版本号(major)和次要版本号(minor)都是整数。
HTTP/<major>.<minor>状态码 (status-code)
原因短语(reason-phrase)
只对人类有意义
首部(header)
可以有零个或多个首部,常见的
1
2
3
4
5
6
7
8
9
10
11
12// 服务器产生响应的日期
Date:Tue,3Oct 1997 02:16:03 GMT
// 实体的主体部分包含了15 040字节的数据
Content-length:15040
//实体的主体部分是一个GIF图片
Content-type:image/gif
//客户端可以接收GIF图片和JPEG图片以及HTML
Accept: image/gif, image/jpeg, text/html实体的主体部分(entity-body)
包含一个由任意数据组成的数据块,就是 HTTP 要传输的内容。
方法
安全方法
HTTP 定义了一组被称为安全方法的方法。GET 方法和 HEAD 方法都被认为是安全的,这就意味着使用 GET 或 HEAD 方法的 HTTP 请求都不会产生什么动作。
GET
请求服务器发送某个资源
POST
用来向服务器输入数据的
**HEAD **
HEAD 方法与 GET 方法的行为很类似,但服务器在响应中只返回首部。不会返回实体的主体部分。这就允许客户端在未获取实际资源的情况下,对资源的首部进行检查。使用 HEAD,可以:
在不获取资源的情况下了解资源的情况(比如,判断其类型);
通过查看响应中的状态码,看看某个对象是否存在;
通过查看首部,测试资源是否被修改了。
TRACE
这个请求可能要穿过防火墙、代理、网关或其他一些应用程序。每个中间节点都可能会修改原始的 HTTP 请求。TRACE 方法允许客户端在最终将请求发送给服务器时,看看它变成了什么样子。TRACE 方法主要用于诊断;也就是说,用于验证请求是否如愿穿过了请求 / 响应链。它也是一种很好的工具,可以用来查看代理和其他应用程序对用户请求所产生效果。
OPTIONS
OPTIONS 方法请求 Web 服务器告知其支持的各种功能。可以询问服务器通常支持哪些方法,或者对某些特殊资源支持哪些方法。
DELETE
DELETE 方法所做的事情就是请服务器删除请求 URL 所指定的资源。
首部
首部和方法配合工作,共同决定了客户端和服务器能做什么事情
通用首部
这些是客户端和服务器都可以使用的通用首部。可以在客户端、服务器和其他应用程序之间提供一些非常有用的通用功能。比如,Date 首部
1 | Date: Tue, 3 Oct 1974 02:16:00 GMT #日期 |
请求首部
请求报文中有意义的首部。用于说明是谁或什么在发送请求、请求源自何处,或者客户端的喜好及能力。
- Client-IP4 :提供了运行客户端的机器的IP地址
- From :提供了客户端用户的E-mail地址5
- Host :给出了接收请求的服务器的主机名和端口号
- Referer :提供了包含当前请求URI的文档的URL
- UA-Color :提供了与客户端显示器的显示颜色有关的信息
- UA-CPU6 :给出了客户端CPU的类型或制造商
- UA-Disp :提供了与客户端显示器(屏幕)能力有关的信息
- UA-OS :给出了运行在客户端机器上的操作系统名称及版本
- UA-Pixels :提供了客户端显示器的像素信息
- User-Agent :将发起请求的应用程序名称告知服务器
- Accept:将其喜好和能力告知服务器的方式,包括它们想要什么,可以使用什么,以及最重要的,它们不想要什么
- Expect :允许客户端列出某请求所要求的服务器行为
- Authorization:包含了客户端提供给服务器,以便对其自身进行认证的数据
- Cookie :客户端用它向服务器传送一个令牌
- Max-Forward:在通往源端服务器的路径上,将请求转发给其他代理或网关的最大次数
- Proxy-Authorization:与Authorization 首部相同,但这个首部是在与代理进行认证时使用的
- Proxy-Connection:与Connection 首部相同,但这个首部是在与代理建立连接时使用的
- …
响应首部
响应报文有自己的响应首部集。响应首部为客户端提供了一些额外信息,比如谁在发送响应、响应者的功能,甚至与响应相关的一些特殊指令。这些首部有助于客户端处理响应,并在将来发起更好的请求。
Age:(从最初创建开始)响应持续时间12
Public13:服务器为其资源支持的请求方法列表
Retry-After : 如果资源不可用的话,在此日期或时间重试
Server: 服务器应用程序软件的名称和版本
Title14: 对HTML文档来说,就是HTML文档的源端给出的标题
Warning :比原因短语中更详细一些的警告报文
Accept-Ranges:对此资源来说,服务器可接受的范围类型
Proxy-Authenticate: 来自代理的对客户端的质询列表
Set-Cookie : 不是真正的安全首部,但隐含有安全功能;可以在客户端设置一个令牌,以便服务器对客户端进行标识15
Set-Cookie2 : 与Set-Cookie 类似,RFC 2965 Cookie定义;
来自服务器的对客户端的质询列表WWW-Authenticate :来自服务器的对客户端的质询列表
实体部首
Allow :列出了可以对此实体执行的请求方法
Location :告知客户端实体实际上位于何处;用于将接收端定向到资源的
Content-Base16 :解析主体中的相对URL时使用的基础URL
Content-Encoding : 对主体执行的任意编码方式
Content-Language :理解主体时最适宜使用的自然语言
Content-Length :主体的长度或尺寸
Content-Location: 资源实际所处的位置
Content-MD5: 主体的MD5校验和
Content-Range: 在整个资源中此实体表示的字节范围
Content-Type: 这个主体的对象类型
ETag :与此实体相关的实体标记17
Expires :实体不再有效,要从原始的源端再次获取此实体的日期和时间
Last-Modified :这个实体最后一次被修改的日期和时间
连接管理
TCP 连接
世界上几乎所有的 HTTP 通信都是由 TCP/IP 承载的,TCP/IP 是全球计算机及网络设备都在使用的一种常用的分组交换网络分层协议集。客户端应用程序可以打开一条 TCP/IP 连接,连接到可能运行在世界任何地方的服务器应用程序。一旦连接建立起来了,在客户端和服务器的计算机之间交换的报文就永远不会丢失、受损或失序。
对 TCP 性能的考虑
HTTP 事务的时延有以下几种主要原因。
- DNS 解析
- 过多的 HTTP 事务
- Web 服务器 读取请求报文,并对请求进行处理。因特网传输请求报文,以及服务器处理请求报文都需要时间。
- Web 服务器会回送 HTTP 响应,这也需要花费时间。
性能聚焦区域
列出了一些会对 HTTP 程序员产生影响的、最常见的 TCP 相关时延,其中包括:
- TCP 连接建立握手;
- TCP 慢启动拥塞控制;
- 数据聚集的 Nagle 算法;
- 用于捎带确认的 TCP 延迟确认算法;
- TIME_WAIT 时延和端口耗尽。
HTTP 连接的处理
- 并行连接:通过多条 TCP 连接发起并发的 HTTP 请求。
- 持久连接:重用 TCP 连接,以消除连接及关闭时延。(默认 Keep-Alive,Connection: close 首部会关闭持久连接)
- 管道化连接:通过共享的 TCP 连接发起并发的 HTTP 请求。
- 复用的连接:交替传送请求和响应报文(实验阶段)。
- 本文作者: 王不留行
- 本文链接: https://wyf195075595.github.io/2022/06/17/computer/http/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!