栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

你了解HTTP协议吗?(三)

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

你了解HTTP协议吗?(三)

1.写在前面

前面介绍完了HTTP协议的请求行、响应行,我们继续接下来的内容。

2.如何管理跨代理服务器的长短连接?

HTTP连接的常见的流程

  1. 浏览器解析出主机名
  2. 浏览器查询这个主机名的IP地址(DNS)
  3. 浏览器获得端口号(80)
  4. 浏览器发起到202.43.78.3端口80的连接
  5. 浏览器想服务器发送一条HTTP GET报文
  6. 浏览器从服务器读取HTTP响应报文
  7. 浏览器关闭连接

从TCP编程上看HTTP请求处理

短连接与长链接

Connection头部

  • Keep-Alive:长连接
    • 客户端请求长连接:Connection:Keep-Alive
    • 服务器表示支持长连接:Connection:Keep-Alive
    • 客户端复用连接
    • HTTP/1.1默认支持长连接 Connection:Keep-Alive无意义
  • Close:短连接
  • 对代理服务器的要求
    • 不转发Connection列出头部,该头部仅与当前连接相关

Connection仅针对当前连接有效

user agent 与 origin server 间有层层proxy代理

代理服务器对长连接的支持

  • 问题:各方间错误使用了长连接

    • 客户端发起长连接
    • 代理服务器陈旧,不能正确的处理请求的Connection头部,将客户端请求中的Connection:Keep-Alive原样转发给上游服务器
    • 上游服务器正确的处理了Connection头部,在发送响应后没有关闭连接,而试图保持、复用与不认长连接的代理服务器的连接
    • 代理服务器收到响应中Connection:Keep-Alive后不认,转发给客户端,同时等待服务器关闭短连接
    • 客户端收到了Connection:Keep-Alive,认为可以复用长连接,继续在该连接上发起请求
    • 代理服务器出错,因为短连接上不能发起两次请求
  • Proxy-Connection

    • 陈旧的代理服务器不识别该头部:退化为短连接

    • 新版本的代理服务器理解该头部 与客户端建立长连接 与服务器使用Connection替代Proxy-Connect头部

3.HTTP消息在服务器端的路由

Host头部

Host = uri-host[“:” port]

  • HTTP/1.1规范要求,不传递Host头部则返回400错误响应码
  • 为防止陈旧的代理服务器,发向正向代理的请求request-target必须以absolute-form形式出现
    • request-line = method SP request-target SP HTTP-version CRLF
    • Absolute-form = absolute-URI = scheme “:” hier-part[“?” query]

Host头部与消息的路由

  1. 建立TCP连接 确定服务器的IP地址
  2. 接收请求
  3. 寻找虚拟主机 匹配Host头部和域名
  4. 寻找URI的处理代码 匹配URI
  5. 执行处理请求的代码 访问资源
  6. 生成HTTP响应 各中间件基于PF架构串行修改响应
  7. 发送HTTP响应
  8. 记录访问日志

4.代理服务器转发消息时的相关头部

客户端与源服务器间存在多个代理

问题:如何传递IP地址?

  1. TCP连接四元组(src ip, src port, dst ip, dst port)
  2. HTTP 头部X-Forwarded-For用于传递IP
  3. HTTP 头部X-Real-IP用于传递用户IP
  4. 网络中存在许多反向代理**(前提)**

消息的转发

  • Max-Forwards头部 限制Proxy代理服务器的最大转发次数,仅对TRACE/OPTIONS方法有效 Max-Forwards = 1*DIGIT
  • Via头部 指明经过的代理服务器名称及版本
  • Cache-Control:no-transform 禁止代理服务器修改响应包体。
5.请求与响应的上下文

请求的上下文:User-Agent

指明客户端的类型信息,服务器可以据此对资源的表述做抉择

  • User-Agent = product * (RWS (product / comment))
  • product = token [“/” product-version]
  • RWS = 1 *(SP / HTAB)

请求的上下文:Referer

浏览器对来自某一页面的请求自动添加的头部

  • Referer = absolute-URI / partial-URI
  • Referer 不会被添加的场景
    • 来源页面采用的协议为表示本地文件的"file"或者"data" URI
    • 当前请求页面采用的是http协议,而来源页面采用的是https协议
  • 服务器端常用于统计分析、缓存优化、防盗链等功能

请求的上下文:From

主要用于网络爬虫,告诉服务器如何通过邮件联系到爬虫的负责人

响应的上下文:Server

指明服务器上所用软件的信息,用于帮助客户端定位问题或者统计数据

  • Server = product *(RWS (product / comment))
  • product = token [“/” product-version]

响应的上下文:Allow与Accept-Ranges

Allow:告诉客户端,服务器上该URI对应的资源允许哪些方法的执行

  • Allow = #method

Accept-Ranges:告诉客户端服务器上该资源是否允许range请求

  • Accept-Ranges = acceptable-ranges
6.内容协商和资源表述

内容协商

每个URI指向的资源可以是任何事物,可以有多种不同的表述,例如一份文档可以有不同语言的翻译、不同的媒体格式、可以针对不同的浏览器提供不同的压缩编码等。

内容协商的两种方式

  • Proactive 主动式内容协商:指由客户端在请求头部中提出需要的表述形式,而服务器根据这些请求头部提供特定的representation表述

  • Reactive 响应式内容协商:指服务器返回300 Multiple Choices 或者 406 Not Acceptable,由客户端选择一种表述URI使用

常见的协商要素

  • 质量因子q:内容的质量、可接受类型的优先级
  • 媒体资源的MIME类型及质量因子。
  • 字符编码:由于UTF-8格式广为使用,Accept-Charset已被废弃
  • 内容编码:主要指压缩算法 Accept-Encoding:gizp, deflate,br
  • 表述语言:Accept-Language

国际化与本地化

  • Internationalization (i18n,i和n间有18个字符)
    • 指设计软件时,在不同的国家、地区可以不做逻辑实现页面的修改便能够以不同的语言显示
  • localization (l10n,l和n间有10个字符)
    • 指内容协商时,根据请求中的语言及区域信息,选择特定的语言作为资源表述

资源表述的元数据头部

  • 媒体类型、编码 content-type
  • 内容编码 content-encoding
  • 语言 content-language
7.HTTP包体的传输方式

HTTP包体:承载的消息内容

  • 请求或响应都可以携带包体

    • HTTP-message = start-line * (header-field CRLF) CRLF [message-body]
    • message-body = *OCTET:二进制字节流
  • 以下消息不能含有包体

    • HEAD方法请求对应的响应
    • 1xx、204、304对应的响应
    • CONNECT方法对应的2xx响应

两种传输HTTP包体的方式

  • 发送HTTP消息时已能够确定包体的全部长度

    • 使用Content-Length头部明确指明包体长度 Content-Length = 1*DIGIT 用10进制表示包体中的字节个数,且必须与实际传输的包体长度一致。
    • 如果包体的长度小于实际的长度,这个时候再TCP协议的层面是发送实际的长度,但是在HTTP协议层实际上只发送了包体的长度。
    • 如果包体的长度大于实际的长度,这个时候浏览器会直接无法解析
  • 优点:接收端处理更简单

  • 发送HTTP消息时不能确定包体的全部长度

    • 使用Transfer-Encoding头部指明使用Chunk传输方式
    • 含Transfer-Encoding头部后Content-Length头部应被忽略
  • 优点

    • 基于长连接持续推送动态内容
    • 压缩体积较大的包体时,不必完全压缩完(计算出头部)再发送,可以边发边压缩
    • 传递必须在包体传输完才能计算出的Trailer头部

不定长包体的chunk传输方式

  • Transfer-Encoding头部
    • transfer-coding = “chunked” / “compress” / “deflate” / “gzip” / transfer-extension
    • chunked transfer encoding 分块传输编码:Transfer-Encoding:chunked
    • chunked-body = *chunk last-chunk trailer-part CRLF
    • chunk = chunk-size [chunk-ext] CRLF chunk-data CRLF chunk-size = 1*HEXDIG chunk-data = 1*OCTET
    • last-chunk = 1*(“0”)[chunk-ext] CRLF
    • trailer-part = *(header-field CRLF)

Trailer头部的传输

  • TE头部:客户端在请求在声明是否接受Trailer头部
    • TE:trailers
  • Trailer头部:服务器告知接下来chunk包体后传输哪些Trailer头部
    • Trailer:Date
  • 以下头部不允许出现在Trailer值中:
    • 用于信息分帧的首部(例如 Transfer-Encoding 和 Content-Length)
    • 用于路由用途的首部 (例如Host)
    • 请求修饰首部(例如控制类和条件类的,如Cache-Control Max-Forwards 或者TE)
    • 身份验证首部(例如Authorization 或者 Set-Cookie)
    • Content-Encoding Content-Type Content-Range,以及Trailer自身

MIME

MIME(Multipurpose Internet Mail Extensions)

content:=“Content-Type”“:”“type”/“subtype*(”;"parameter)

  • type := discrete-type / composite-type

  • discrete-type := “text”/“image”/“audio”/“video”/“application”/extension-token

  • composite-type := “message” / “multipart” /extension-token

  • subtype := extension-token / iana-token

  • parameter := attribute “=” value

大小写不敏感,但通常是小写

Content-Disposition头部

  • disposition-type = “inline” | “attachment” | disp-ext-type
    • inline:指定包体是以inline内联的方式,作为页面的一部分展示
    • attachment:指定浏览器将包体以附件的方式下载
    • 在multipart/form-data类型应答中,可以用于子消息体部分
8.HTML form 表单提交时的协议格式

HTML FORM表单

HTML:HyperText Markup Language,结构化的标记语言 浏览器可以将HTML文件渲染为可视化网页

FORM表单:HTML中的元素,提供了交互控制元件用来向服务器通过HTTP协议提交信息,常见控件有:

  • Text Input Controls:文本输入控件
  • Checkboxes Controls:复选框控件
  • Radio Box Controls:单选框按钮控件
  • Select Box Controls:下拉列表控件
  • File Select boxes:选取文件控件
  • Clickable Buttons:可点击的按钮控件
  • Submit and Reset Button:提交或者重置按钮控件

HTML FORM 表单提交请求时的关键属性

action:提交时发起HTTP请求的URI

method:提交时发起HTTP请求的http方法

  • GET:通过URI,将表单数据以URI参数的方式提交
  • POST:将表单数据放在请求包体中提交

enctype : 在POST方法下,对表单内容在请求包体中的编码方式

  • application/x-www-form-urlencoded 数据被编码成以’&'分隔的键-值对,字符以URL编码方式编码
  • multipart/form-data
    • boundary 分隔符
    • 每部分表述皆有HTTP头部描述子包体,例如Content-Type
    • last boundary 结尾

multipart: 一个包体中多个资源表述

  • Content-type 头部指明这是一个多表述包体
    • Content-type: multipart/form-data
  • Boundary 分隔符的格式
    • boundary := 0*69 bcharsnospace
      • bchars := bcharsnospce /“”
      • bcharsnospace := DIGIT / ALPHA / “'” / “(” /“)” / “+” /“_” /“,” / “-” /“.” /“/” /“:” / “=” /“?”

Multipart包体格式

multipart-body = preamble 1*encapsulation close-delimiter epilogue

  • premble := discard-text
  • epilogue := discard-text
    • discard-text := *(*text CRLF)
  • 每部分包体格式:encapsulation = delimiter body-part CRLF
    • delimiter = “–” boundary CRLF
    • body-part = fields *(CRLF * text)
      • field = field-name “:” [field-value] CRLF
  • close-delimiter = “–” boundary “–” CRLF
9.断点续传与多线程下载如何做到?

多线程、断点续传、随机点播等场景的步骤

  1. 客户端明确任务:从哪开始下载
    • 本地是否已有部分文件
      • 文件已下载部分在服务端发生改变?
    • 使用多个线程并发下载
  2. 下载文件的指定部分内容
  3. 下载完毕后拼装成统一的文件

HTTP Range规范

  • 允许服务器基于客户端的请求只发送响应包体的一部分给到客户端,而客户端自动将多个片断的包体组合成完整的体积更大的包体
    • 支持断点续传
    • 支持多线程下载
    • 支持视频播放器实时拖动
  • 服务器通过Accept-Range头部表示是否支持Range请求
    • Accept-Ranges:bytes 支持
    • Accept-Ranges:none 不支持

Range请求范围的单位

基于字节,设包体总长度为10000

  • 第1个500字节:bytes=0~499
  • 第2个500字节:bytes = 500~999 bytes = 500600,601999 bytes = 500700,601999
  • 最后一个500字节:bytes = -500 bytes = 9500-
  • 仅要第1个和最后1个字节:bytes = 0-0,-1

通过Range头部传递请求范围。

Range条件请求

  • 如果客户端已经得到了Range响应的一部分,并想在这部分响应为过期的情况下,获取其他部分的响应
    • 常与If-Unmodified-Since或者If-Match头部共同使用
  • If-Range = entity- tag / HTTP-date
    • 可以使用Etag或者Last-Modified

服务器响应

206Partial Content

  • Content-Range头部:显示当前片断在完整包体中的位置
  • Content-Range = byte-conent-range /other-content-range
    • Byte-content-range = bytes-unit SP (byte-range-resp / unsatisfied-range)
      • Byte-range-resp = byte-range “/” (complete-length / “*”)
      • Complete-length = 1*DIGIT 完整资源的大小,如果未知则用*号替代
      • Byte-range = first-byte-pos “-” last-byte-pos

416Range Not Satisfiable

  • 请求范围不满足实际资源的大小,其中Content-Range中的complete-length 显示完整响应的长度。

200 OK

  • 服务器不支持Range请求时,则以200返回完整的响应包体

多重范围与multipart

  • 请求
    • Range:bytes = 050,100150
  • 响应
    • Content-Type: multipart/byteranges;boundary=…
10.Cookie的格式与约束

Cookie是什么?

保存在客户端、由浏览器维护、表示应用状态的HTTP头部

  • 存在在内存或者磁盘中

  • 服务端生成Cookie在想用中通过Set-Cookie头部告知客户端(允许多个Set-Cookie头部传递多个值)

  • 客户端得到Cookie后,后续请求都会自动将Cookie头部携带至请求中

Cookie与Set-Cookie头部的定义

  • Cookie头部中可以存放多个name/value名值对
    • Cookie-header = "Cookie: " OWS cookie-string OWS
    • Cookie-string = cookie-pair * (“;” SP cookie-pair)
    • Cookie-pair = cookie-name “=” cookie-value
  • Set-Cookie 头部一次只能传递1个name/value名值对,响应中可以含多个头部
    • Set-cookie-header = “Set-Cookie:” SP set-cookie-string
    • Set-cookie-string = cookie-pair * (“;” SP cookie-av)
    • Cookie-pair = cookie-name “=” cookie-value
    • Cookie-av: 描述Cookie-pair的可选属性

Set-Cookie中描述cookie-pair的属性

Cookie-av = expires-av /max-age-av / domain-av / path-av / secure-av / httponly-av / extension-av

  • expies-av = “Expires=” sane-cookie-date cookie到日期sane-cookie-date后失效
  • max-age-av = “Max-Age=” non-zero-digit *DIGIT cookie经过*秒后失效。max-age优先级高于expires
  • domain-av = “Domain” = domain-value 指定cookie可用于哪些域名,默认可以访问当前域名
  • path-av = “Path=” path-value 指定Path路径下才能使用cookie
  • secure-av = “Secure” 只有使用TLS/SSL协议(https)时才能使用cookie
  • Httponly-av = “HttpOnly” 不能使用JavaScript(Document.cookie 、XMLHttpRequest、Request APIs)访问到cookie

Cookie使用的限制

RFC规范对浏览器使用Cookie的要求

  • 每条Cookie的长度至少要支持达到4KB
  • 每个域名下至少支持50Cookie
  • 至少要支持3000个Cookie

代理服务器传递Cookie时会有限制

Cookie在协议设计上的问题

Cookie会被附加在每个HTTP请求中,所以无形中增加了流量

由于在HTTP请求中的Cookie是明文传递的,所以安全性成问题(除非用HTTPS)

Cookie的大小不应超过4KB,故对于复杂的存储需求来说是不够用的

11.Session的工作的原理

常见的登录的场景下的Cookie与Session的常见用法

无状态的REST架构VS状态管理

应用状态与资源状态

  • 应用状态:应由客户端管理,不应由服务器管理

    • 如浏览器目前在哪一页
    • REST架构要求服务器不应保存应用的状态
  • 资源状态:应有服务器管理,不应由客户端管理

    • 如数据库中存放的数据状态,例如用户的登录信息。
  • HTTP请求的状态

    • 有状态的请求:服务端保存请求的相关的信息,每个请求可以使用一起保留的请求相关信息
      • 服务器session机制使服务器保存请求的相关信息
      • cookie使请求可以携带查询信息,与session配合完成有状态的请求
    • 无状态的请求:服务器能够处理的所有信息都来自当前请求所携带的信息
      • 服务器不会保存session信息
      • 请求可以通过cookie携带

第三方Cookie

浏览器允许对于不安全域下的资源(如广告图片)响应中的set-Cookie保存,并在后续访问该域时自动使用Cookie

  • 用户踪迹信息的搜索
12.写在最后

本节博客主要介绍了代理服务器的长短连接,HTTP消息在服务器端的路由,代理服务器转发消息时的相关头部,请求与响应的上下文,内容协商和资源表述,HTTP包体的传输方式,HTML form 表单提交时的协议格式,断点续传与多线程下载如何做到,Cookie的格式与约束,Session的工作的原理。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/939836.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号