当前位置 博文首页 > 纽西兰牛小扒的博客:浅析HTTP协议

    纽西兰牛小扒的博客:浅析HTTP协议

    作者:[db:作者] 时间:2021-09-19 10:18

    以下内容是本人阅读《图解HTTP》后的个人笔记和总结

    一、HTTP入门

    1、HTTP是一个属于应用层的面向对象的协议,它是基于TCP协议的可靠传输,采用客户端/服务器端模式,由客户端发起请求,服务端进行响应。

    2、HTTP是一种无状态协议,即不保存状态,它不对之前发生过的请求和响应的状态进行管理。每当有新的请求发送时,就会有对应的新响应产生,协议本身并不保留之前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性而设计的。但同时也带来了一些不便,比如,用户登录到一家购物网站,即使他跳转到该网站的其他页面,也需要能继续保持登录状态,为了实现期望的保持状态功能,于是就引入了Cookie技术。(Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端的状态。Cookie会根据从服务器端发送的响应报文内的一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie,当客户端下次再往服务器端发送请求时,客户端会自动在请求报文中加入Cookie值后发送出去。服务器端发现客户端发送过来的Cookie后,会去检和比对服务器上的记录,最后得到之前的状态信息。)

    3、URL(Uniform Resource Locator,统一资源定位符)是我们使用Web浏览器等访问Web页面时需要输入的网页地址,比如http://www.baidu.com。URI(Uniform Resource Identifier,统一资源标识符)是由某个协议方案表示的资源的定位标识符,协议方案是指访问资源所使用的协议类型名称。URI用字符串标识某一互联网资源,而URL表示资源的地址,可见URL是URI的子集。

    二、HTTP中的方法

    HTTP/1.1中可使用的方法(方法名区分大小写):
    (1)GET:获取资源
    GET方法用来请求访问已被URI识别的资源,指定的资源经服务器端解析后返回响应内容。
    (2)POST:传输实体主体
    POST方法用来传输实体的主体。虽然GET方法也可以传输,但一般不用GET方法进行传输。虽说POST的功能与GET很相似,但POST的主要目的并不是获取响应的主体内容。
    (3)HEAD:获得报文首部
    HEAD方法和GET方法一样,只是不返回报文主体部分。用于确认URI的有效性和资源更新的日期时间等。
    (4)PUT:传输文件
    PUT方法用来传输文件,就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求URI指定的位置。但是由于HTTP/1.1的PUT方法自身不带验证机制,任何人都可以上传文件,存在安全性问题,所以一般不使用该方法。
    (5)DELETE:删除文件
    DELETE方法用来删除文件。DELETE方法按请求URI删除指定的资源。但是和PUT一样不带验证机制,所以一般也不是用该方法。
    (6)OPTIONS:询问支持的方法
    OPTIONS方法用来查询针对请求URI指定的资源支持的方法。
    (7)TRACE:追踪路径
    TRACE方法时让Web服务器端将之前的请求通信环回给客户端的方法。
    (8)CONNECT:要求用隧道协议连接代理
    CONNECT方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL(Secure Sockets Layer,安全套接层)和TLS(Transport Layer Security,传输安全层)协议把通信内容加密后经网络隧道传输。

    三、HTTP报文概要

    用于HTTP协议交互的信息被称为HTTP报文。请求端的HTTP报文叫做请求报文,响应端的叫做响应报文。HTTP报文由报文首部、空行和报文主体三部分组成,通常,并不一定要有报文主体。请求报文和响应报文的结构如下图:

    这里写图片描述这里写图片描述
    请求报文和响应报文的首部内容由以下数据组成:

    • 请求行:包含用于请求的方法、请求URI和HTTP版本。
    • 状态行:包含表明响应结果的状态码,原因短语和HTTP版本。
    • 首部字段:包含表示请求和响应的各种条件和属性的各类首部。
    • 其他:可能包含HTTP的RFC里未定义的首部(Cookie等)。

    四、HTTP状态码

    状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。状态码的类别有以下5种:

    类别原因短语
    1xx信息性状态码接收的请求正在处理
    2xx成功状态码请求正常处理完毕
    3xx重定向状态码需要进行附加操作以完成请求
    4xx客户端错误状态码服务器无法处理请求
    5xx服务端错误状态码服务器处理请求出错

    常见的状态码如下:
    2xx 成功

    • 200 OK:表示从客户端发来的请求在服务器端被正常处理了。
    • 204 No Content:该状态码代表服务器接收的请求已经成功处理,但在返回的响应报文中不含实体的主体部分。
    • 206 Partial Content:该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的请求。响应报文中包含由Content-Range指定范围的实体内容。

    3xx 重定向

    • 301 Moved Permanently:永久性重定向。该状态码表示请求的资源已被分配了新的URI,以后应该使用现在资源所指的URI。
    • 302 Found:临时性重定向。该状态码表示请求的资源已被分配了新的URI,希望用户本次能使用新的URI访问。
    • 303 See Other:该状态码表示由于请求对应的资源存在着另外一个URI,应使用GET方法定向获取请求的资源。
    • 304 Not Modified:该状态码表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但因发生请求未满足条件的情况后直接返回304。304状态码返回时,不包含任何响应的主体部分。304虽然被划分在3XX类别中,但是和重定向没有关系。(附带条件的请求时指采用GET方法的请求报文中包含If-Match、If-Modified-Since、If-Range等任一首部)
    • 307 Temporary Redirect:临时重定向。该状态码与302 Found有着相同的含义。

    4xx 客户端错误

    • 400 Bad Request:该状态码表示请求报文中存在语法错误。

    • 401 Unauthorized:该状态码表示发送的请求需要有通过HTTP认证(BASIC认证、DIGEST认证)的认证信息。另外若之前已进行过1次请求,则表示用户认证失败。

    • 403 Forbidden:该状态码表明对请求资源的访问被服务器拒绝了。未获得文件系统的访问授权,访问权限出现某些问题等情况都可能发生403。

    • 404 Not Found:该状态码表明服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。

    5xx 服务器错误

    • 500 Internal Server Error:该状态码表明服务器端在执行请求时发生了错误,也有可能是Web应用存在的Bug或某些临时的故障。

    • 503 Service Unavailable:该状态码表明服务器暂时处于超负荷或正在进行停机维护,现在无法处理请求。

    五、HTTP报文首部详解

    HTTP请求报文由方法、URI、HTTP版本、HTTP首部字段等部分构成。
    HTTP响应报文由HTTP版本、状态码、HTTP首部字段三部分组成。
    HTTP首部字段是构成HTTP报文的要素之一,无论是请求还是响应都会使用首部字段,它能起到传递额外信息的重要作用。
    HTTP首部字段根据实际用途被分为以下4种类型:

    • 通用首部字段:请求报文和响应报文都会使用的首部。
    • 请求首部字段:客户端向服务器端发送请求报文时使用的首部。
    • 响应首部字段:服务器端向客户端返回响应报文时使用的首部。
    • 实体首部字段:针对请求报文和响应报文的实体部分使用的首部。

    1、通用首部字段

    (1)Cache-Control
    通过指定首部字段Cache-Control的指令,就能控制缓存的行为。例如:Cache-Control: private, max-age=0, no-cache
    缓存请求指令:

    指令参数说明
    no-cache强制向源服务器再次验证,客户端不会接收缓存过的响应
    no-store不缓存请求或响应的任何内容
    max-age = [秒]必需 响应的最大时间值(会使Expires字段失效)
    max-stale( = [秒])可省略即使过期,只要处于指定时间内,也照常接收资源
    min-fresh = [秒]必需要求返回至少还未过指定时间的缓存资源
    no-transform代理不可更改媒体类型
    only-if-cached仅从缓存获取资源,如果无响应则返回504 Gateway Timeout
    cache-extension 新指令标记,可以扩展Cache-Control首部字段内的指令

    缓存响应指令:

    指令参数说明
    public 可向任意方提供响应的缓存
    private可省略仅向特定用户返回响应
    no-cache可省略缓存前必须先确认其有效性,不缓存过期的资源
    no-store不缓存请求或响应的任何内容(这个才是真正的不进行缓存)
    no-transform要求代理不可更改媒体类型,可防止缓存或代理压缩图片等类似操作
    must-revalidate代理会向源服务器再次验证即将返回的响应缓存是否仍然有效(会使max-stable失效)
    proxy-revalidate 要求中间缓存服务器对缓存的响应有效性再进行确认
    max-age = [秒]必需 响应的最大时间值(会使Expires字段失效)
    s-maxage = [秒]必需公共缓存服务器响应的最大时间值(会使Expires字段失效)
    cache-extension 新指令标记,可以扩展Cache-Control首部字段内的指令

    (2)Connection
    Connection字段用来控制不再转发给代理的首部字段和管理持久连接。HTTP/1.1版本的默认连接都是持久连接,当服务端想断开连接时,可以指定Connection首部字段的值为Close。HTTP/1.1之前的版本默认都是非持久化连接,如果想维持持续连接,则需要指定Connection的值为Keep-Alive。
    (3)Date
    首部字段Date表明创建HTTP报文的日期和时间。
    (4)Pragma
    这个字段是HTTP/1.1之前的版本遗留下来的,仅作为向后兼容而定义的。它只用在客户端发送的请求中,要求中间服务器不返回缓存的资源(no-cache)。
    (5)Trailer
    首部字段Trailer会事先说明在报文主体后记录了哪些首部字段,该首部字段可应用在HTTP/1.1版本分块传输编码时。
    (6)Transfer-Encoding
    首部字段Transfer-Encoding规定了传输报文主体时采用的编码方式。
    (7)Upgrade
    首部字段Upgrade用于检测HTTP协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议。
    (8)Via
    使用首部字段Via是为了追踪客户端与服务器之间的请求和响应报文的传输路径,还可以避免请求回环的发生。报文经过代理或网关时,会先在首部字段Via中附加该服务器的信息,然后再进行转发。
    (9)Warning
    首部字段Warning会告知用户一些与缓存相关的问题的警告。

    2、请求首部字段

    (1)Accept
    Accept首部字段可通知服务器用户代理能够处理的媒体类型及媒体类型的相对优先级。比如,如果浏览器不支持gif图片的显示,那Accept就不指定image/gif,而可以指定image/png和image/jpeg等类型。当有多种类型时,可以使用q来表示权重,范围为0~1,不指定权重时,默认为1.0。比如下面,表示给我HTML格式的啊,没有的话text格式也行:

    Accept: text/plain; q=0.3, text/htm

    (2)Accept-Charset
    Accept-Charset首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。比如:

    Accept-Charset: iso-8859-5, unicode-1-1; q=0.8

    (3)Accept-Encoding
    Accept-Encoding首部字段用来告知服务器用户代理支持的内容编码及内容编码的优先级顺序。比如:

    Accept-Encoding: gzip, deflate

    (4)Accept-Language
    Accept-Language首部字段用来告知服务器用户代理能够处理的自然语言集,以及自然语言集的相对优先级。比如,表示的意思是有中文版的给我中文版的,没有的话英文也行。

    Accept-Language: zh-cn,zh; q=0.7, en-us,en; q=0.3

    (5)Authorization
    Authorization首部字段是用来告知服务器用户代理的认证信息。
    (6)Expect
    客户端使用Expect来告知服务器,期望出现的某种特定行为。如果服务器无法理解客户端的期望而发生错误时,会返回417 Expectation Failed。
    (7)Form
    Form首部字段用来告知服务器使用用户代理的用户的电子邮件地址。
    (8)Host
    首部字段Host会告知服务器,请求的资源所处的互联网主机名和端口号。它是唯一一个必须被包含在请求内的首部字段。当相同的IP地址下部署运行着多个域名,就需要使用首部字段Host来指出请求的主机名。比如:

    Host: sp0.baidu.com

    (9)If-xxx
    If-Match、If-None-Match、If-Modified-Since、If-Unmodified-Since、If-Ranged都为条件请求,服务器接收到附带条件的请求后,只有判定指定条件为真时才会执行请求。
    (10)Max-Forwards
    通过TRACE或OPTIONS方法发送包含首部字段Max-Forwards的请求时,指定了可经过的服务器最大数目。当服务器接收到Max-Forward值为0的请求时,则不再进行转发,而是直接返回响应。比如:

    Max-Forwards: 6

    (11)Proxy-Authorization
    接收到从代理服务器发来的认证质询时,客户端会发送包含首部字段Proxy-Authorization的请求,以告知服务器认证所需要的信息。
    (12)Range
    对于只需获取部分资源的范围请求,包含首部字段Range即可告知服务器资源的指定范围。格式如下,表示请求获取5001字节到10000字节的资源:

    Range: bytes=5001-10000

    (13)Referer
    首部字段Referer会告知服务器请求的原始资源的URI。
    (14)TE
    首部字段TE会告知服务器客户端能够处理响应的传输编码方式及相对优先级。比如:

    TE: gzip, deflate; q=0.5

    (15)User-Agent
    首部字段User-Agent会将创建请求的浏览器和用户代理名称等信息传达给服务器。比如,已经暴露了我正在使用chrome浏览器:

    User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36

    3、响应首部字段

    (1)Accept-Ranges
    首部字段Accept-Ranges是用来告知客户端服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。当可处理范围请求时其值为bytes,否则会none。比如:

    Accept-Ranges: bytes

    (2)Age
    首部字段Age能告知客户端,源服务器在多久前创立了响应,单位为秒。若创建该响应的服务器是缓存服务器,Age值是指缓存后的响应再次发起认证到认证完成的时间值。比如:

    Age: 300

    (3)ETag
    首部字段ETag能告知客户端实体标识。它是一种可将资源以字符串形式做唯一标识的方式,服务器会为每份资源分配对应的ETag值。
    (4)Location
    使用首部字段Location可以将响应接收方引导至某个与请求URI位置不同的资源。基本上,该字段会配合3xx Redirection的响应,提供重定向的URI。比如,当我们访问https://www.baidu.com/sample.html时,它会把我们重定向到如下URI:

    Location:https://www.baidu.com/search/error.html

    (5)Proxy-Authenticate
    首部字段Proxy-Authenticate会把由代理服务器所要求的认证信息发送给客户端。
    (6)Retry-After
    首部字段Retry-After告知客户端应该在多久之后再次发送请求,主要配合状态码503 Service Unavailable响应或3xx Redirect响应一起使用。字段值可以是具体日期,也可以是秒数,比如:

    Retry-After: 120

    (7)Server
    首部字段Server告知客户端当前服务器上安装的HTTP服务器应用程序的信息。比如:

    Server: Apache

    (8)Vary
    首部字段Vary可对缓存进行控制。源服务器会向代理服务器传达关于本地缓存使用方法的命令。
    (9)WWW-Authenticate
    首部字段WWW-Authenticate用于HTTP访问认证。它会告知客户端适用于访问请求URI所指定资源的认证方案和带参数提示的质询。

    4、实体首部字段

    (1)Content-Encoding
    首部字段Content-Encoding会告知客户端服务器对实体的主体部分选用的内容编码方式。内容编码食指在不丢失实体信息的前提下所进行的压缩。比如:

    Content-Encoding: gzip

    (2)Content-Language
    首部字段Content-Language会告知客户端,实体主体使用的自然语言。比如:

    Content-Language: zh-CN

    (3)Content-Length
    首部字段Content-Length表明了实体主体部分的大小(字节)。比如:

    Content-Length: 15000

    (4)Content-Location
    首部字段Content-Length给出与报文主体部分相对应的URI。和首部字段Location不同,Content-Location表示的是报文主体返回资源对应的URI。
    (5)Content-MD5
    首部字段Content-MD5是一串由MD5算法生成的值,其目的在于检查报文主体在传输过程中是否保持完成,以及确认传输到达。
    (6)Content-Range
    针对范围请求,返回响应时使用的首部字段,能告知客户端作为响应返回的实体的哪个部分符合范围请求。比如下面,表示一共10000字节,返回第5001-10000字节:

    Content-Range: bytes 5001-10000/100000

    (7)Content-Type
    首部字段Conteng-Type说明了实体主体内对象的媒体类型,和首部字段Accept一样,字段值用type/subtype形式赋值。
    (8)Expires
    首部字段Expires会将资源失效的日期告知客户端,缓存服务器在接收到含有首部字段Expires的响应后,会以缓存来应答请求,在Expires字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送来时,会转向源服务器请求资源。
    (9)Last-Modified
    首部字段Last-Modified指明资源最终修改的时间。

    5、其他首部字段

    (1)X-Frame-Options
    首部字段X-Frame-Options属于HTTP响应首部,用于控制网站内容在其他Web网站的Frame标签内的显示问题。其主要目的是为了防止点击劫持攻击。此字段有两个字段值,分别为DENY和SAMEORIGN。
    (2)X-XSS-Protection
    首部字段X-XSS-Protection属于HTTP响应首部,它是针对跨站脚本攻击的一种对策,用于控制浏览器跨站脚本攻击防护机制的开关。此字段有两个字段值,分别为0和1,对应关和开。
    (3)DNT
    首部字段DNT属于HTTP请求首部,其中DNT是Do Not Track的简称,意为拒绝个人信息被收集,是表示拒绝被精准广告追踪的一种方法。此字段有两个字段值,分别为0和1,对应同意被追踪和拒绝被追踪。
    (4)P3P
    首部字段P3P属于HTTP响应首部,通过利用P3P技术,可以让Web网站上的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的目的。

    六、HTTP的安全性

    1、HTTP的不足

    到目前为止,我们看到了HTTP的许多优点,但是它也有不足之处,例如:
    (1)通信使用明文,内容可能会被窃听
    由于HTTP本身不具备加密的功能,所以也无法做到对通信整体进行加密。同时,TCP/IP是可能被窃听的网络,即使报文经过加密,也只是可能让人无法破解而已,加密后的内容还是能被窥视到。
    目前最为普及的加密技术的对象有:

    • 通信的加密:
        HTTP协议中没有加密机制,但可以通过和SSL(Secure Socket Layer,安全套接层)和TLS(Transport Layer Security,安全传输层协议)的组合使用,加密HTTP的通信内容。
    • 内容的加密:
        另一种是将参与通信的内容本身加密的方式。由于HTTP协议中没有加密机制,那么就对HTTP协议传输的内容本身加密。

    (2)不验证通信方的身份,因此有可能遭遇伪装
    在HTTP协议通信时,由于不存在确认通信方的步骤,任何人都可以发起请求,服务器不管对方是谁都会进行响应,因此会存在一些隐患:

    • 无法确定请求发送至目标的Web服务器是否是按真实意图返回响应的那台服务器。即我发送给A服务器的请求,被一台伪装成A的服务器给接收了。
    • 无法确定响应返回到的客户端是否是按真实意图接收响应的那个客户端。即服务器想发送给我的东西,被一个伪装成我的人给拿走了。
    • 无法确定正在通信的对方是否具备访问权限。因为某些Web服务器上保存着重要的信息,只想发给特定用户通信的权限。
    • 无法判定请求是来自何方,出自谁手。
    • 即使是无意义的请求也会照单全收,无法阻止海量请求下的DoS攻击。

    虽然使用HTTP协议无法确定通信方,但是如果使用SSL则可以。SSL不仅提供加密处理,还是用了一种被称为证书的手段,可用户确定方,可以减少个人信息泄露的危险性。
    (3)无法验证报文的完整性,所以有可能已遭篡改
    由于HTTP协议无法证明通信的报文完整性,因此在请求或响应的传输的过程中,即使内容遭到篡改也无法获悉。比如,有可能你从服务器请求一张正常的图片,结果在传输过程中被人改成了一张限制级的图片,结果你就被查水表了。

    2、HTTPS

    为了统一解决上述问题,需要在HTTP上再加入加密处理和认证等机制,最后就诞生了HTTPS了。最常出现HTTPS的地方应该是在购物结算或银行网站等着一些地方。HTTPS并非是应用层的一种新协议,它只是HTTP通信接口部分用SSL和TSL协议代替而已。简而言之,HTTPS就是身披SSL协议的HTTP了。在采用SSL后,HTTP就拥有了HTTPS的加密、证书和完整性保护这些功能。
    那么问题来了,既然HTTPS安全可靠,为什么Web网站不一直使用呢?原因其一就是加密通信会消耗更多的CPU及内存资源,因此只有涉及到重要信息的数据才使用HTTPS。除此之外,购买证书也是要花钱的。

    cs
    下一篇:没有了