http进阶

Telnet实例

由于Http使用的是TCP/IP传输协议,而且它是基于文本的,没有使用哪些难以理解的二进制格式,因此很容易直接1与Web服务器进行对话。

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

Web结构组件

  1. 代理:位于客户端和服务器之间的HTTP中间实体。
  2. 缓存:HTTP的仓库,是常用页面的副本可以存在离客户端更近的地方。
  3. 网关:连接应用程序的特殊Web服务器。
  4. 隧道:对HTTP通信报文进行盲转发的特殊代理。
  5. Agent代理:发起自动HTTP请求的半智能Web客户端。
代理

HTTP代理服务器是Web安全,应用集成以及性能优化的重要组成模块。

代理位于客户端与服务器之间,接收所有客户端的HTTP请求,并将这些请求转发给服务器(可能会对请求进行修改之后转发)。对用户来说,这些应用程序就是一个代理,代表用户访问服务器。

出于安全考虑,通常会将代理作为转发所有Web流量的可信任中间节点使用。代理还可以对请求和响应进行过滤。比如,在企业中对下载的应用程序进行病毒检测,或者对小学生屏蔽一些成人才能看的内容。

缓存

WEb缓存(Web cache)或代理缓存(proxy cache)是一种特殊的HTTP代理服务器,可以将经过代理传送的常用文档复制保存起来。下一个请求同一文档的客户端就可以享受缓存的私有副本所提供的服务了。

网关

网关(gateway)是一种特殊的服务器,作为其他服务器的中间实体使用,通常用于将HTTP流量转换成其他的协议。网关接受时就好像自己是咨议员的源端服务器一样。客户端可能并不知道自己正在与一个网关进行通信。

如:一个HTTP/FTP网关会通过HTTP请求接受对FTP URI的请求,但通过FTP协议来获取文档。得到的文档会被封装成一条HTTP报文发给客户端。

隧道

隧道(tunnel)是建立起来之后就会在两条连接之间对原始数据进行盲转发的HTTP应用程序。HTTP隧道通常用来在一条或多条HTTP连接上进行转发非HTTP数据,转发时不会窥探数据。

HTTP隧道的一种常见用途是通过HTTP连接承载加密的安全套接字层(SSL,Secure Socket Layout)流量,这样ssl流量就可以穿过只允许Web流量通过的防火墙了。

隧道

如:HTTP/SSL隧道收到一条HTTP请求,要求建立一条到目的的地址和端口的输出连接,然后在HTTP信道上通过隧道传输加密的SSL流量,这样就可以将其转发到目的服务器上。

Agent代理

用户代理是代表用户发起HTTP请求的客户端程序。所有发布Web请求的应用程序都是HTTP Agent代理。到目前为止,我们只提过一种HTTP Agent代理:WEb浏览器,但用户Agent代理还有很多类型。

如:有些自己会在Web上闲逛的自动用户Agent代理,可以在无人监视的情况下发布HTTP事务并获取内容。这些自动代理的名字很生动,比如“网络蜘蛛”或“web机器人”。网络蜘蛛会在WEb上闲逛,搜集信息以构建有效的Web内容档案,比如一个搜索引擎的数据库或者为比较购物机器人生成的产品目录。

image-20200430094207000

HTTP报文

请求报文格式

1
2
3
<method>     <request-URL>  <version>
<headers>
<entrity-body>

响应报文

1
2
3
<version>   <status>   <response-phrase>
<headers>
<entrity-body>
方法(method)

客户端希望服务器对资源执行的动作,是一个单独的词,比如GET,HEAD或POST.

方法 描述 是否包含主体
GET 从服务器获取一份文档
HEAD 只从服务器获取文档的首部
POST 向服务器发送需要处理的数据
PUT 将请求的主体部分存储在服务器上
TRACE 对可能经过代理服务器传送到服务器上去的报文进行追踪
OPTIONS 决定可以在服务器上执行哪些方法
DELETE 从服务器上删除一份文档

扩展方法:指的是没有在HTTP/1.1规范中定义的方法,服务器会为它所管理的资源实现一些二HTTP服务,这些方法为开发者提供了一种扩展这些HTTP服务能力的手段。

方法 描述
LOCK 允许用户“锁定”资源——比如,可以在编辑某个资源的时候将其锁定,以防别人对其进行修改。
MKCOL 允许用户创建资源
COPY 便于在服务器上复制资源
MOVE 在服务器上移动资源

惯例:对所发送的内容要求严一点,对接收的内容宽容一些处理扩展方法。

  1. 请求URL(request-URL)

    命名了所有请求资源,或者URL路径组件的完整URL。如果直接与服务器进行对话,只要URL的路径组件是资源的绝对路径,通常就不会有什么问题——服务器可以假定自己是URL的主机/端口。

  2. 版本(version)

  3. 状态码(status-code)

    这三位数字描述了请求过程中所发生的情况。每个状态码的第一位数字都用于描述状态的一般类型(“成功”、“出错”)。

    状态码分类

    整体范围 已定义范围 分类
    100-199 100-101 信息提示
    200-299 200-206 成功
    300-399 300-305 重定向
    400-499 400-415 客户端错误
    500-599 500-505 服务器错误

    常见状态码

    状态码 原因短语 含义
    200 OK 成功。请求的所有数据都在响应主体中。
    401 Unauthorized(未授权) 需要输入用户名和密码
    404 Not Found(未找到) 服务器无法找到所请求URL对应的资源
    501 Not Implemented(无法实现)

    信息性状态码

    状态码 原因短语 含义
    100 Continue 说明受到了请求的初始部分,请客户端继续,发送了这个状态码后,服务器在收到请求后必须进行响应。
    101 Switching Protocols 说明服务器正在根据客户端的指定,将协议切换成Update’首部所列的协议。

    100 Continue是一种优化,客户端应用程序只有在避免向服务器发送一个服务器无法处理或使用的大实体时才会使用100 Continue。当服务端超时一定时间后,客户端直接将实体发出去。

    成功状态码

    状态码 原因短语 原因短语
    200 请求没问题,实体的主体部分包含了所请求的资源 OK
    201 用于创建对象的请求(PUT)。响应的主体部分包含各种已创建资源的URL,location首部包含则是最具体的引用。 Created
    202 请求已被接受,但服务器还未对其执行任何动作,不能保证服务器会完成这个请求。 Accepted
    203 实体部分包含的资源不是来自源服务器,而是来自资源的一份副本。如果中间节点上有一份资源副本,但无法对它所发送的与资源有关的元信息(首部)进行验证,就会出现这种情况。 Non-Authoritative-Information
    204 响应报文中包含若干首部和一个状态行,但没有实体部分,主要用于在浏览器不转为显示新文档的情况下,对其将进行更新(如刷新一个表单页面) No Content
    205 另一个主要用于浏览器的代码,负责告诉浏览器清除当前页面中所有HTML表单元素。 Reset Content
    206 成功执行一部分请求。稍后会看到,客户端可以通过一些特殊的首部来获取部分或某个范围内的文档——这个状态码就说明请求成功了。 Partial Content

    重定向状态码

    状态码 原因短语 描述
    300 Multiple Choices 客户端请求一个实际指向多个资源的URL时会返回这个状态码,比如服务器上有某个HTML文档的英语和法语版本。返回这个代码时会带有一个选项列表,这样用户就可以选择他希望使用的那一项了。有多个版本1可用时,客户端需要沟通解决。
    301 Moved Permananently 在请求的URL已被移除时使用。响应的Location首部中应该包含资源现在所处的URL。
    302 Found 与301状态码相似,但是客户端应该使用Location首部给出的URL来临时定位资源。将来的请求仍应使用老的URL。
    303 See Other 告知客户端应该用另一个URL来获取资源。新的URL位于响应报文的Location首部。其主要目的是允许POST请求的响应将客户端定向到某个资源上去。
    304 Not Modified 客户端可以通过所包含的请求首部,使其请求变成有条件的。如果客户端发起一个GET请求,而最近资源未被修改,就可用这个状态码来说明资源未被修改,带有这个状态吗的响应不应该包含实体的主体部分。
    305 Use Proxy 用来说明必须通过一个代理来访问资源,代理的位置由Location首部给出。很重要一点是,客户端是相对某个特定资源来解析这个响应的,不能假定所有请求,甚至所有对持有所请求资源的服务器的请求都通过这个代理进行。如果客户端错误的让代理介入了某条请求,可能会引发破环性的行为,而且会造成安全漏洞。
    306 (未使用) 当前未使用
    307 Temporary Redirect 与301状态码相似,但是客户端应该使用Location首部给出的URL来临时定位资源。将来的请求仍应使用老的URL。

    客户端错误

    状态码 原因短语 描述
    400 Bad Request 用于告诉客户端他发送了一个错误的请求
    401 Unauthorized 与适当的首部一同返回,在这些首部中请求客户端在获取对资源的访问权之前,对自己进行认证。
    402 Payment Required 现在这个状态码还未使用,但已经被保留,以作未来之用。
    403 Forbidden 用以说明请求被服务器拒绝了,如果服务器想说明为什么拒绝请求,可以包含实体的主体部分来对原因进行描述。但这个状态通常是在服务器不想说明拒绝原因的时候使用的。
    404 Not Found 用于说明服务器无法找到所请求的URL。通常会包含一个实体以便客户端应用程序显示给用户看。
    405 Method Not Allowed 发起的请求中带所请求的URL不支持的方法时,使用此状态码。应该在响应中包含Allow首部,以告知客户端对请求的资源可以使用哪些方法。
    406 Not Acceptable 客户端可以指定参数来说明他们愿意接受什么类型的实体。服务器没有与客户端可接受的URL相匹配的资源时,使用此代码。通常,服务器会包含一些首部以便客户端弄清楚为什么请求无法满足。
    407 Proxy Authentication Required 与401状态码类似,但用于要求对资源进行认证的代理服务器。
    408 Request Timeout 如果客户端完成请求所花的时间太长,服务器可以回送此状态码,并关闭连接。超时时长随服务器的不同而不同,但通常对所有合法请求来说都是够长的。
    409 Conflict 用于说明请求可能在资源上引发的一些冲突,服务器担心请求会引发冲突时可发送此状态码。响应中应该包含描述冲突的主体。
    410 Gone 与404相似,只要服务曾经拥有过此资源。主要用于Web站点的维护,这样服务器的管理者就可以在资源被移除的情况下通知客户端了。
    411 Length Required 服务器要求在请求报文中包含Content-Length首部时使用。
    412 Precondition Failed 客户端发起了条件请求且其中一个条件失败时使用。
    413 Request Entrity Too Large 客户端发送实体主体部分比服务器能够或希望处理的要大时发送此状态码。
    414 Request URL Too Long 客户端发送请求中的URL比服务器希望处理的要大时发送此状态码。
    415 Unsupported Media Type 服务器无法理解或无法支持客户端所发送实体的内容类型时
    416 Unsupported Media Type 请求报文所请求的是指定资源的某个范围,而此范围无效或无法满足时使用此状态码。
    417 Expectation Failed 请求的Expect请求首部包含了一个期望,但服务器无法满足此期望时,使用此状态码。如果代理或其他中间应用程序与确切证据说明源端服务器会为某请求产生一个失败的期望就可发送此状态码。

    服务器错误

    状态码 原因短语 含义
    500 Internal Server Error 服务器遇到一个妨碍它为请求提供服务的错误时使用此状态码。
    501 Not Implemented 客户端发起的请求超出服务器的能力范围。
    502 Bad Gateway 作为代理或网关使用的服务器从请求响应链的下一条链路上收到了一条伪响应(如,他无法链接到其父网关时)。
    503 Service Unavailable 用来说明服务器现在不能为请求提供服务,但将来可以。如果服务器知道什么时候资源会变为可用的,可在响应中包含一个Retry-After首部。
    504 Gateway Timeout 与状态码408相似,只是这里的响应来自一个网关或代理,他们在等待另一服务器对其请求进行响应时超时了。
    505 HTTP Version Not Supported 服务器收到的请求使用了它无法或不愿支持的协议版本。有些服务器应用程序会选择不支持协议的早期版本。
  1. 原因短语(reason-phrase)

    数字状态码的可读版本,包含行终止序列的所有文本。

  2. 首部(header)

    可以有零个或多个首部,每个首部都包含一个名字,后面跟着一个冒号,然后是一个可选的空格,接着是一个值,最后是一个CRLF。首部是由一个空行结束的,表示了首部列表的结束和实体主体部分的开始。

    首部分类

    • 通用首部:既可以出现在请求报文中,又可以出现在响应报文中。
    • 请求首部:提供更多有关请求的信息。
    • 响应首部:提供更多有关响应的信息。
    • 实体首部:描述主体的长度和内容,或者资源自身。
    • 扩展首部:规范中没有定义的新首部。

    常见首部实例

    首部实例 描述
    Date:Tue,3 Oct 1997 02:16:03 GMT 服务器产生响应的日期
    Content-length:15040 实体的主体部分包含了
    Content-type:image/gif 实体的主体部分是一个GIF图片
    Accept:image/gif, image/jpeg, text/html 客户端可以接收
    Connection 允许客户端和服务器指定与请求或响应连接有关的选项。
    MIME-Version 给定发送端使用的MIME版本。
    Trailer 如果报文采用了分块传输编码(chunked transfer encoding)方式就可以用这个首部列出位于报文拖挂(trailer)部分的首部集合。
    Transfer-Encoding 告知接收端为了保证报文可靠传输,对报文采取什么编码方式。
    Update 给出了发送端可能想要“升级”使用的新版本或协议。
    Via 显示了报文经过的中间节点(代理,网关)
  3. 实体的主体部分(entrity-body)

    实体的主体部分包含一个由任意数据组成的数据块。并不是所有的报文都包含实体的主体部分。

通用首部

通用缓存首部:HTTP/1.0引入了第一个允许HTTP应用程序缓存对象本地副本的首部,这样就不需要总是直接从源端服务器获取了。

首部 描述
Cache-Control 用于随报文传送缓存指示。
Pragma 另一种随报文传送指示的方式,但并不专用于缓存。

请求首部:是只在请求报文中有意义的首部,用于说明是谁或什么在发送请求,请求源自何处,或者客户端的喜好和能力。服务器可以根据请求首部给出的客户端信息,试着为客户端提供更好的响应。

image-20200502215359440

Accept首部为客户端提供一种将其喜好和能力告知服务器的方式,包括它们想要什么,可以使用什么,以及最重要的,他们不想要什么,这样,服务器可以根据这些额外的信息,对要发送的内容做出更明智的决定。Accept首部会使连接的两端都受益。客户端会得到它们想要的内容,服务器则不会浪费时间和带宽来发送客户端无法使用的东西。

image-20200502220337984

条件请求首部:有时客户端希望为请求加上某些限制。比如,如果客户端已经有了一份文件副本就希望只在服务器上的文档与客户端拥有的副本有所区别时才请求服务器传输文档。通过条件请求首部,客户端就可以为请求加上这种限制,要求服务器在对请求进行响应前,确保某个条件为真。

image-20200502220845355

安全请求首部

HTTP本身就支持一种简单的机制,可以对请求进行质询/响应认证。这种机制要求客户端在获取特定资源之前,先对自身进行认证,这样就可以使事务稍微安全一些。

image-20200502221420633

代理请求首部

image-20200502221552479

响应报文

响应报文有自己的响应首部集。响应首部为客户端提供了一些额外信息,比如谁发送响应,响应者的功能,甚至与响应相关的一些特殊指令,这些首部有助于客户端处理响应,并在将来发起更好的请求。

image-20200503080735091

协商首部

如果资源有多种表示方法——如,若服务器上有某文档的法语和德语译稿,HTTP/1.1可以为服务器和客户端提供对资源进行协商的能力。

image-20200503082210004

安全响应首部

首部 描述
Proxy-Authenticate 来自代理的对客户端的质询列表
Set-Cookie 不是真正的安全首部,但隐含有安全功能,可以在客户端设置一个令牌,以便服务器对客户端进行标识。
Set-Cookie2 与Set-Cookie类似
www-Authenticate 来自服务器的对客户端的质询列表
HTTP事务产生时延的原因
  1. 客户端首先需要根据URI确定Web服务器的IP地址和端口号。如果最近没有对URI中的主机名进行访问,通过DNS解析系统将URI中的主机名转换成一个IP地址可能要花费数十秒的时间。
  2. 接下来,客户端会向服务器发送一条TCP连接请求,并等待服务器回送一个请求经接受应答。每条新的TCP连接都会有连接建立时延。这个值通常最多只有一两秒钟,但如果有数百个HTTP事务的话,这个值就会快速叠加上去。
  3. 一旦连接建立起来,客户端就会通过新建立的TCP管道来发送HTTP请求。数据到达时,Web服务器会从TCP链接中读取请求报文,并对请求进行处理。因特网传输请求报文,以及服务器请求报文都需要时间。
  4. 然后,Web服务器会回送HTTP响应,这也需要花费时间。

注:大多数HTTP客户端都有一个小的DNS缓存,用来保存近期所访问站点的IP地址。如果已经在本地“缓存”了IP地址,查询就可立即完成,因为大多数Web浏览器浏览的是少数常用站点,所以通常可以很快将主机名解析出来。

TCP网络时延的大小取决于硬件速度,网络和服务器的负载,请求和响应报文的尺寸,以及客户端和服务器之间的距离。

TCP连接握手步骤
  1. 请求新的TCP连接时,客户端要向服务器发送一个小的TCP分组(通常是40-60字节)。这个分组中设置了一个特殊的SYN标记,说明这是一个连接请求。
  2. 如果服务器接受了连接,就会对连接参数进行计算,并向客户端回送一个TCP分组,这个分组中的SYN和ACK标记都被置位,说明连接请求已被接受。
  3. 最后,客户端向服务器回送一条确认消息,通知他连接已成功建立,现代的TCP栈都允许客户端在这个确认分组中发送消息。

小的HTTP事务可能会在TCP建立上花费50%,或更多的时间

延迟确认

由于因特网自身无法确保可靠的分组传输(因特网路由器超负荷的话,可以随意丢弃分组),所以TCP实现了自己的确认机制来确保数据的成功传输。

每个TCP段都有一个序列号和数据完整性校验和。每个段的接收者收到完好的段时,都会向发送者回送小的确认分组。如果发送者,欸有在指定的窗口时间内收到确认信息,发送者就会认为分组已被破环或损毁,并重发数据。

由于u企鹅人保温很小,所以TCP允许在发往相同方向的输出数据分组中对其进行“捎带”。TCP将将返回的确认信息与输出的数据分组结合在一起,可以更有效利用网络。为了增加确认报文找到同向传输数据分组的可能性,很多TCP栈都实现了一种延迟确认算法。延迟确认算法会在一个特定的窗口时间内将输出确认缓存放在缓存区中,以寻找能够捎带他的输出数据分组。如果在那个时间段内没有输出数据分组,就将确认信息放在单独的分组中传送。

但是,HTTP具有双峰特征的请求——应答行为就降低了捎带信息的可能。当希望有相反方向回传分组的时候,偏偏没有那么多。通常,延迟确认算法会引起相当大的时延。根据所使用的操作系统的不同,可以调整或禁止延迟确认算法。

在对TCP栈的任何参数进行修改之前,一定要对袭击在做什么会有清晰的了解。TCP中引入这些算法的目的是为了防止设计欠佳的应用程序对因特网造成破环。对TCP配置进行任意修改都要绝对确保应用程序不会引发这些i算法所要避免的问题。

TCP慢启动

TCP数据传输的性能还取决于TCP连接的使用期。TCP连接会随着时间进行自我“调谐”,起初还会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度,这种调谐被称为TCP慢启动,用于防止因特网的突然过载和拥塞。

TCP慢启动限制了一个TCP端点在任意时刻可以传输的分组数。简单来讲是每成功接收一个分组,发送端就有了发送另外两个分组的权限。如果某个HTTP事务有大量的数据要发送,是不能依次将所有分组都发送出去的,必须发送一个分组,确认后才可以再发。这种方式是”打开拥塞窗口“。

由于存在这种拥塞控制特性,所以新连接的传输速度会比已经交换过一定数据量的,“已调谐”连接慢一些。由于已调谐连接要更快一些,所以HTTP中有一些可以重用现存连接的工具。即HTTP“持久连接”。

提高HTTP连接性能的四类方法
  1. 并行连接
  2. 持久连接
  3. 管道化连接
  4. 复用连接
文章目录
  1. 1. Telnet实例
  • Web结构组件
    1. 1. 代理
    2. 2. 缓存
    3. 3. 网关
    4. 4. 隧道
    5. 5. Agent代理
  • HTTP报文
    1. 1. 方法(method)
    2. 2. 通用首部
    3. 3. 响应报文
    4. 4. HTTP事务产生时延的原因
    5. 5. TCP连接握手步骤
    6. 6. 延迟确认
    7. 7. TCP慢启动
    8. 8. 提高HTTP连接性能的四类方法
  • |