Http协议网关分类、断点续传和内容协商

目录

一、长连接和短连接

长连接和短连接的使用环境区分

二、HTTP代理服务

三、HTTP网关的分类

1、HTTP/*:服务器端Web网关

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

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

4、资源网关

(1)CGI

(2)服务器扩展API

四、HTTP断点续传和多线程下载

1、HTTP 断点续传示例

增强校验

2、多线程下载示例

3、断点续传关联header字段

检测服务器是否支持断点续传

五、HTTP内容协商机制

(1)客户端驱动

(2)服务器驱动——常用  

(3)透明协商


一、长连接和短连接

HTTP的长连接和短连接实质上是TCP的长连接和短连接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。

在HTTP/1.0 中,默认使用短连接。 就是说:浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。

从 HTTP/1.1 起,默认使用长连接保持连接持续性。 一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的的网页, 会继续使用这一条已经建立好的连接。

注:Keep-Alive不会永久保持连接,它有一个保持的时间,可以在不同服务器软件中设定这个时间(Apache)。 要实现长连接,客户端、服务器端首先得支持。

短连接步骤:

建立连接 – 数据传输 – 关闭连接  ——

长连接步骤:

建立连接 – 数据传输 –(保持连接)– 数据传输 – 数据传输 – 关闭连接  ——

长连接和短连接的使用环境区分

长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况,每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。

例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。

而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源

如果用长连接而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。

总结:

长连接省去了较多的TCP建立、关闭操作,减少了浪费,节约时间。对于频繁请求资源的客户来说,适合用长连接。 

短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但如果客户请求频繁,将在TCP的建立和关闭操作上浪费时间和带宽。

二、HTTP代理服务

HTTP代理服务(proxy server) 器就是客户端也是服务端,是一个事务处理的中间人,如图所示:

代理服务器的作用有很多,例如:儿童过滤器、文档访问控制、安全防火墙、web缓存等等。

三、HTTP网关的分类

网关概念

网关(Gateway)又称网间连接器、协议转换。网关在网络层以上实现网络互连,是复杂的网络互连设备,仅用于两个高层协议不同的网络互连。网关是一种充当转换重任的计算机系统或设备。使用在不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间,网关是一个翻译器。          ——百度百科

1、HTTP/*:服务器端Web网关

请求流入原始服务器时,服务器端Web网关会将客户度的HTTP请求转换成其他协议,如图:

在图8-5中,网关收到了一条对FTP资源的HTTP请求:

ftp://ftp.irs.gov/pub/00-index.txt

网关会打开一条道原始服务器FTP端口(端口21)的FTP连接,通过FTP协议获取对象。网关会做下列事情:

(1)发送USER和PASS命令登录到服务器上去;

(2)发布CWD命令,转移到服务器上合适的目录中去;

(3)将下载类型设置为ASCII;

(4)用MDTM获取文档的最后修改时间;

(5)用PASV告诉服务器将有被动数据获取请求到达;

(6)用RETR请求进行对象获取;

(7)打开到FTP服务器的数据连接,服务器端口由控制信道返回;一旦数据通信打开了就将对象内容回送给网关

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

一个组织可以通过网关对所有的输入Web请求加密,以提供额外的隐私和安全性保护。客户端可以用普通的HTTP浏览Web内容,但网关会自动加密用户的对话(参见图8-6)

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

将HTTPS/HTTP网关作为安全加速器使用的情况是越来越多了。这些HTTPS/HTTP网关位于Web服务器之前,通常作为不可见的拦截网关或反向代理使用。它们接收安全的HTTPS流量,对安全流量进行解密,并向Web服务器发送普通的http请求(见图8-7)

这些网关中通常包含专用的解密硬件,以比原始服务器有效得多的方式来解密安全流量,以减轻原始服务器的负荷。这些网关在网关和原始服务器之间发送的是未加密的流量,所以,要谨慎使用,确保网关和原始服务器之间的网络是安全的。

4、资源网关

前面我们一直说的是通过网络连接客户端和服务器的网关。但最常见的网关,应用程序服务器会将目标服务器与网关结合在一个服务器中实现。应用程序服务器是服务器端网关,与客户端通过HTTP进行通信,并与服务器端的应用程序相连(参见图8-8)

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

(1)收到客户端A的请求,根据URL将其通过API发送给一个数码摄像机应用程序。将得到的图片绑定到一条HTTP响应报文中,再回送给客户端,在客户端的浏览器中显示。

(2)客户端B的URL请求的是一个电子商务应用程序。客户端B的请求是通过服务器网关API发送给电子商务软件的,结果会被回送给浏览器。电子商务软件与客户端进行交互,应道用户通过一系列HTML页面来完成购物的。

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

请求需要使用网关的资源时,服务器会请辅助应用程序来处理请求。服务器会将辅助应用程序所需的数据传送给它。通常就是整条请求,或者用户想在数据库上运行的请求(来自URL的请求字符串)之类的东西。

然后它会向服务器返回一条响应或响应数据,服务器会将其转发给客户端。服务器和网关是相互独立的应用程序,因此,它们的责任是分得很清楚的。图8-9显示了服务器与网关应用程序之间交互的基本运行机制。

(1)CGI

CGI是第一个得到最广泛应用的服务器扩展。在Web上广泛用于动态HTML、信用卡处理以及数据库查询等任务。

CGI应用程序是独立于服务器的,所以,几乎可以用任意语言来实现。CGI很简单,几乎所有的HTTP服务器都支持它。

CGI的处理对用户来说是不可见的。从客户端的角度来看,就像发起一个普通请求一样。它完全不清楚服务器和CGI应用程序之间的转接过程。URL中出现字符CGI和可能出现的“?”是客户端发现使用了CGI应用程序的唯一线索。

(2)服务器扩展API

CGI协议外部翻译器与现有的HTTP服务器提供了一种简洁的接口方式,但如果想要改变服务器自身的行为,或者只是想提升从服务器上获得的性能呢?服务器开发者为这两种需求提供了几种服务器扩展API,为Web开发者提供了强大的接口,以便他们将自己的模块与HTTP服务器直接连接。扩展API允许程序员将自己的代码嫁接到服务器上,或者用自己的代码将服务器的一个组件完整的替换出来。

四、HTTP断点续传和多线程下载

断点续传就是从文件上次中断的地方开始重新下载或上传,当下载或上传文件的时候,如果没有实现断点续传功能,那么每次出现异常或者用户主动的暂停,都会去重头下载,这样很浪费时间。所以断点续传的功能就应运而生了。要实现断点续传的功能,需要客户端记录下当前的下载或上传进度,并在需要续传的时候通知服务端本次需要下载或上传的内容片段。

1、HTTP 断点续传示例

其实断点续传的原理很简单,就是在Http的请求上多定义了断点续传相关的HTTP头RangeContent-Range字段而已,例如:

(1)浏览器请求服务器上的一个文件名为test.zip时,请求内容只展示了一些与本文有关的信息

GET /test.zip HTTP/1.1

Accept-Language: zh-cn

Accept-Encoding: gzip, deflate

Connection: Keep-Alive

(2)服务器收到请求后,按要求寻找请求的文件,提取文件的信息,然后返回给浏览器,返回信息如下:

200

Content-Length=66667777

Accept-Ranges=bytes

Content-Type=application/octet-stream

(3)为了实现从文件已经下载的地方开始继续下载。所以在客户端传给服务器的时候要多加一条信息--从哪里开始。下面是客户端请求时的请求信息,要求从44445555字节开始。

GET /test.zip HTTP/1.0

User-Agent: NetFox

RANGE: bytes=44445555-

(4)上面的请求信息多了一个新的字段RANGE RANGE:bytes=44445555-,这段话的意思就是告诉服务器test.zip这个文件从44445555字节开始传,前面的字节不用传了。服务器收到这个请求以后,返回的信息如下:

206

Content-Length=66667777

Content-Range=bytes 44445555-66667777

Content-Type=application/octet-stream

和第一次服务器返回的信息相比,增加了一行:Content-Range=bytes 44445555-66667777,返回的代码也改为206了,而不再是200了。

增强校验

但是在实际场景中,会出现一种情况,即在终端发起续传请求时,URL对应的文件内容在服务端已经发生变化,此时续传的数据肯定是错误的。如何解决这个问题了?显然此时我们需要有一个标识文件唯一性的方法。在RFC2616中也有相应的定义,比如实现Last-Modified来标识文件的最后修改时间,这样即可判断出续传文件时是否已经发生过改动。同时RFC2616中还定义有一个ETag的头,可以使用ETag头来放置文件的唯一标识,比如文件的MD5值。
终端在发起续传请求时应该在HTTP头中申明If-Match 或者If-Modified-Since 字段,帮助服务端判别文件变化。 

另外RFC2616中同时定义有一个If-Range头,终端如果在续传是使用If-Range。If-Range中的内容可以为最初收到的ETag头或者是Last-Modfied中的最后修改时间。服务端在收到续传请求时,通过If-Range中的内容进行校验,校验一致时返回206的续传回应,不一致时服务端则返回200回应,回应的内容为新的文件的全部数据。

2、多线程下载示例

假设你要开发一个多线程下载工具,你会自然的想到把文件分割成多个部分,比如4个部分,然后创建4个线程,每个线程负责下载一个部分,如果文件大小为403个byte,那么你的分割方式可以为:0-99 (前100个字节),100-199(第二个100字节),200-299(第三个100字节),300-402(最后103个字节)。
分割完成,每个线程都明白自己的任务,比如线程3的任务是负责下载200-299这部分文件,现在的问题是:线程3发送一个什么样的请求报文,才能够保证只请求文件的200-299字节,而不会干扰其他线程的任务。这时,我们可以使用HTTP1.1的Range头。Range头域可以请求实体的一个或者多个子范围,Range的值为0表示第一个字节,也就是Range计算字节数是从0开始的

  • 表示头500个字节:Range: bytes=0-499
  • 表示第二个500字节:Range: bytes=500-999
  • 表示最后500个字节:Range: bytes=-500
  • 表示500字节以后的范围:Range: bytes=500-
  • 第一个和最后一个字节:Range: bytes=0-0,-1
  • 同时指定几个范围:Range: bytes=500-600,601-999

所以,线程3发送的请求报文必须有这一行:

Range: bytes=200-299

服务器接收到线程3的请求报文,发现这是一个带有Range头的GET请求,如果一切正常,服务器的响应报文会有下面这行:

HTTP/1.1 206 OK

表示处理请求成功,响应报文还有这一行:

Content-Range: bytes 200-299/403

斜杠后面的403表示文件的大小。通常Content-Range的用法为:

.The first 500 bytes:

 Content-Range: bytes 0-499/1234

.The second 500 bytes:

 Content-Range: bytes 500-999/1234
 
.All except for the first 500 bytes:

 Content-Range: bytes 500-1233/1234

.The last 500 bytes:

 Content-Range: bytes 734-1233/1234

3、断点续传关联header字段

HTTP 1.1默认支持断点续传。关联header字段如下:

If-Modified-SinceLast-Modified:If-Modified-Since,和 Last-Modified 一样都是用于记录页面最后修改时间的 HTTP 头信息,只是 Last-Modified 是由服务器往客户端发送的 HTTP 头,而 If-Modified-Since 则是由客户端往服务器发送的头。

当再次请求本地存在的 cache 页面时,客户端会通过 If-Modified-Since 头将先前服务器端发过来的 Last-Modified 最后修改时间戳发送回去,这是为了让服务器端进行验证,通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回新的内容,如果是最新的,则返回 304 告诉客户端其本地 cache 的页面是最新的,于是客户端就可以直接从本地加载页面了,这样在网络上传输的数据就会大大减少,同时也减轻了服务器的负担。

Etag:Etag(Entity Tags)主要为了解决 Last-Modified 无法解决的一些问题

  1. 一些文件也许会周期性的更改,但是内容并不改变(仅改变修改时间),这时候我们并不希望客户端认为这个文件被修改了,而重新 GET。
  2. 某些文件修改非常频繁,例如:在秒以下的时间内进行修改(1s 内修改了 N 次),If-Modified-Since 能检查到的粒度是 s 级的,这种修改无法判断(或者说 UNIX 记录 MTIME 只能精确到秒)。
  3. 某些服务器不能精确的得到文件的最后修改时间。

为此,HTTP/1.1 引入了 Etag。Etag 仅仅是一个和文件相关的标记,可以是一个版本标记,例如:v1.0.0;或者说 “627-4d648041f6b80” 这么一串看起来很神秘的编码。但是 HTTP/1.1 标准并没有规定 Etag 的内容是什么或者说要怎么实现,唯一规定的是 Etag 需要放在 “” 内。

Range:用于客户端到服务端的请求,可以通过改字段指定下载文件的某一段大小及其单位,字节偏移从0开始。典型格式:

  • Ranges:    (unit=first byte pos)-[last byte pos]
  • Ranges:    bytes=4000- 下载从第4000字节开始到文件结束部分
  • Ranges:    bytes=0~N 下载第0-N字节范围的内容
  • Ranges:    bytes=M-N 下载第M-N字节范围的内容
  • Ranges:    bytes=-N 下载最后N字节内容

If-Range:用于客户端到服务端的请求,用于判断实体是否发生改变。若实体未被修改,则响应所缺少的那部分;否则,响应整个新的实体。一般格式为:

If-Range: Etag | HTTP-Date

也就是说,If-Range 可以使用 Etag 或者 Last-Modified 返回的值。当没有 ETage 却有 Last-modified 时,可以把 Last-modified 作为 If-Range 字段的值。例如:

If-Range: “627-4d648041f6b80” 
If-Range: Fri, 22 Feb 2013 03:45:02 GMT

If-Range 必须与 Range 配套使用。如果请求报文中没有 Range,那么 If-Range 就会被忽略。如果服务器不支持 If-Range,那么 Range 也会被忽略。

如果请求报文中的 Etag 与服务器目标内容的 Etag 相等,即没有发生变化,那么应答报文的状态码为 206。如果服务器目标内容发生了变化,那么应答报文的状态码为 200。

用于校验的其他 HTTP 头信息:If-Match/If-None-Match、If-Modified-Since/If-Unmodified-Since

工作原理

Etag 由服务器端生成,客户端通过 If-Range 条件判断请求来验证资源是否修改。请求一个文件的流程如下:

第一次请求:

  1. 客户端发起 HTTP GET 请求一个文件。
  2. 服务器处理请求,返回文件内容以及相应的 Header,其中包括 Etag(例如:627-4d648041f6b80)(假设服务器支持 Etag 生成并已开启了 Etag)状态码为 200。

第二次请求(断点续传):

  1. 客户端发起 HTTP GET 请求一个文件,同时发送 If-Range(该头的内容就是第一次请求时服务器返回的 Etag:627-4d648041f6b80)。
  2. 服务器判断接收到的 Etag 和计算出来的 Etag 是否匹配,如果匹配,那么响应的状态码为 206;否则,状态码为 200。

Accept-Ranges:用于服务端到客户端的应答,client通过该字段判断server是否支持断点续传。

  • Accept-Ranges:bytes    表示支持以bytes为单位进行传输。
  • Accept-Ranges:none     表示不支持断点续传

Content-Ranges:用于服务端到客户端的应答,与Accept-Ranges在同一个报文内,通过该字段指定了返回的文件资源的字节范围。格式如下:

  • Content-Ranges:bytes M-N/size 大小为size的文件的第M-N字节范围的内容

断点续传响应码206:断点续传,如果返回文件的一部分,则使用HTTP 206状态码;如果返回整个文件,则使用HTTP 200响应码。

  • HTTP/1.1 200 OK(不使用断点续传)
  • HTTP/1.1 206 Partial Content(使用断点续传)

检测服务器是否支持断点续传

CURL 实现检测:

[root@localhost ~]# curl -i --range 0-9 http://www.baidu.com/img/bdlogo.gif
HTTP/1.1 206 Partial Content
Date: Mon, 21 Nov 2016 05:26:29 GMT
Server: Apache
P3P: CP=" OTI DSP COR IVA OUR IND COM "
Set-Cookie: BAIDUID=0CD0E23B4D4F739954DFEDB92BE6CE03:FG=1; expires=Tue, 21-Nov-17 05:26:29 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1
Last-Modified: Fri, 22 Feb 2013 03:45:02 GMT
ETag: "627-4d648041f6b80"
Accept-Ranges: bytes
Content-Length: 10
Cache-Control: max-age=315360000
Expires: Thu, 19 Nov 2026 05:26:29 GMT
Content-Range: bytes 0-9/1575
Connection: Keep-Alive
Content-Type: image/gif

GIF89a[root@localhost ~]#

能够找到 Content-Range,则表明服务器支持断点续传。有些服务器还会返回 Accept-Ranges,输出结果 Accept-Ranges: bytes ,说明服务器支持按字节下载。

五、HTTP内容协商机制

HTTP协议的内容协商概念:某一资源,服务器有多个版本,客户端告知服务器自己的偏好,服务器根据偏好选择合适的版本响应客户端的请求。

 共有3种不同的方法可以决定服务器上哪个页面最适合客户端:让客户端来选择、服务器自动判定、让中间代理来选。这3种技术分别称为客户端驱动的协商、服务器驱动的协商以及透明协商。

(1)客户端驱动

客户端发起请求,服务器发送可选项列表,客户端作出选择后在发送第二次请求。
优点:比较容易实现;
缺点:增加了时延,至少要发送两次请求,第一次请求获取资源列表,第二次获取选择的副本;

(2)服务器驱动——常用  

服务器检查客户端的请求首部集并决定提供哪个版本的页面。
优点:比客户端驱动的协商要快。HTTP提供了q机制,允许服务器近似匹配,还提供了vary首部供服务器告知下游的设备(如代理服务器)如何对请求估值;
缺点:首部集不匹配,服务器要做猜测;

(3)透明协商

某个中间设备(通常是缓存代理)代表客户端进行协商。
优点:免除了web服务器的协商开销,比客户端驱动的协商要快;
缺点:HTTP并没有提供相应的规范;

其中,服务器驱动的解决方案应用的较为广泛。

关于内容协商:https://www.cnblogs.com/hellohuman/p/3989904.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

swadian2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值