七、《图解HTTP》- HTTP首部和HTTP协作服务器(三)

简介: 七、《图解HTTP》- HTTP首部和HTTP协作服务器(三)

#tjhttp 七、《图解HTTP》- HTTP首部和HTTP协作服务器(三)

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第二十天,点击查看活动详情

#知识点

  1. 请求头部字段分类比较多,本章介绍了下面的首部,内容非常多,熟悉常见的请求首部即可。
  1. 首部字段介绍
  2. 非HTTP1.1 首部字段
  3. 通用首部
  4. 请求首部
  5. 响应首部
  6. 负载首部(实体首部)
  7. 其他首部字段
  1. 协作服务器指的是为了HTTP加速访问而架设的一些中间件介绍,内容介绍比较匮乏,个人也没有补充,简单浏览即可

7.5 负载首部字段

因为HTTP2.0新协议的缘故,这里更想要称之为负载首部,实体首部的概念已经被废弃。负载首部表明了实体内容的请求头部信息,可以认为是快递上面快递单的货物信息。

image.png

7.5.1 Allow(Allow: GET, HEAD)

通知客户端指定资源所有的HTTP方法。如果不支持会返回405响应。

405Method Not Allowed:服务器已接收并识别请求,但拒绝了特定的请求方法。该响应必须返回一个Allow 头信息用以表示出当前资源能够接受的请求方法的列表。 对于一些修改服务器资源数据的请求方法比如PUT和DELETE通常不被允许。

7.5.2 Content-Encoding(Content-Encoding: gzip)

表明服务器使用的负载的主体部分的内容编码方式,并且在不丢失内容的前提下进行压缩。

主要支持的编码方式如下:

  • gzip
  • compress
  • deflate
  • identity

7.5.3 Content-Language(Content-Language: zh-CN)

告知客户端服务器使用的语言主体。

7.5.4 Content-Length(Content-Length: 15000)

告知实体主体部分大小(单位字节),但是一旦使用内容编码方式传输则不能使用此字段。

可参考 tools.ietf.org/html/rfc723… 的 4.4了解编码格式的内容长度计算。

7.5.5 Content-Location(Content-Location: www.hackr.jp/index-ja.ht…

给出与报文负载部分相对应的 URI,这个字段表示的是报文负载返回资源对应URI。

比如出现在Accept-Language字段实际的URI和返回的URI可能会不一样,则需要在此字段中标记。

7.5.6 Content-MD5(Content-MD5: OGFkZDUwNGVhNGY3N2MxMDIwZmQ4NTBmY2IyTY==)

客户端对于接受的报文负载内容进行MD5加密,目的是保证报文传输的时候保持完整性。

但是需要注意对于报文负载MD5加密之后还需要进行Base64加密,这是因为HTTP首部不能记录二进制的内容,当报文被接受之后同样使用MD5算法解密,并且对于负载内容校验完整 。

但是需要注意的是这个字段在校验完整性的同时是无法校验MD5加密是否被篡改的,所以安全性保证不佳。

7.5.7 Content-Range(Content-Range: bytes 5001-10000/10000)

告知客户端作为响应返回的负载哪个部分符合范围请求,告知哪一部分符合请求,字段值的单位为字节,表示当前发送部分以及整个实体大小。

7.5.8 Content-Type(Content-Type: text/html; charset=UTF-8)

说明了负载主体内对象的媒体类型,和首部字段 Accept一样,字段值用 type/subtype 形式赋值。

参数 charset 使用 iso-8859-1euc-jp 等字符集进行赋值。

7.5.9 Expires

首部字段 Expires 会将资源失效的日期告知客户端。如果不希望资源被缓存,则在首部字段里面和首部字段Date相同。

需要注意在Cache-Control指定max-age的指令时候,比起首部字段Expires,会优先处理max-age处理

7.5.10 Last-Modified(Last-Modified: Wed, 23 May 2012 09:59:55 GMT)

Last-Modified 指明资源最终修改的时间, 实际通过Request-URI 指定资源被修改的时间。实际案例是在使用CGI进行动态数据处理的时候有可能改变这个时间。

7.6 Cookie服务的首部字段

Cookie虽然并不是HTTP1.1的规范,但是由于在WEB领域应用广泛。Cookie的基本作用是保存用户的访问信息以及状态管理,同时把一些数据写入到客户端可以在下一次访问的时候简化用户操作同时可以减少服务端的一些压力。

7.6.1 Cookie(Cookie: status=enable)

这个首部字段会告知服务器想要获得HTTP状态支持管理,这时候请求的时候会包含多个Cookie同时可以按照Cookie发送。

对于正规发布的Cookie而言,由于可以校验有效期、发送方的域名和路径、协议信息等,所以不会受到外来攻击比较安全。

这里顺带说说Cookie的历史,Cookie最初是由于网景公司开发并且制定标准的,但是在后续发展中出现了下面的协议规格:

  • 网景标准(实际标准)
    1994年前后发布,目前普及的标准基本为这个时候的范本,网景的标准是由一个24岁的大神写的5页纸决定的,目前无法找到任何有关的规范链接,可以参考RFC6265看到一些最初的端倪。
  • RFC2109(搞事小弟1号)比较意外这是W3C 发布的一项标准,本意是想要和网景制定的标准兼容(实则想要取代),但是因为标准过于严苛,同时很多服务实现方错误的实现这个标准,所以后来依然改回了网景的标准。
  • RFC2965(搞事小弟2号)
    RFC2965 定义了 Cookie2,并试图解决 RFC2109 关于 Cookie1的缺点。RFC2965 目标在取代 RFC2109。
    发送 RFC2965 Cookie 的服务器除了使用 Set-Cookie 标头外,还将使用 Set-Cookie2 标头。注意RFC2965 Cookie 对端口非常敏感。
    RFC2965 可在 www.w3.org/Protocols/r…,但是实际上属于W3C黑历史被删除,
    最后通过:RFC 2965 - HTTP State Management Mechanism (ietf.org) 可以阅读了解
    然而不幸的是W3C还是没成功,因为基本没用多少服务器投入使用。
  • RFC6265:W3C最后放弃了争夺标准,RFC6265是按照网景的标准重新定义标准的产物,最终为业界事实标准。(继承大哥,统合一切)
    但是结果依然是没有采用RFC任何一个协议,网景公司的标准。
    从结果来看我们可以认为RFC6265是一个先实现后补写设计文档的一种标准,RFC6265虽然并不是实际采用的标准,但是却是白皮书公开认可的标准规范,也就是从原本大家口头协商变成了白纸黑字的标准的区别。
    RFC 6265 - HTTP State Management Mechanism (ietf.org)

吐槽:所以符合市场的标准才能被大众接受,哪怕是W3C这样庞大的组织也无法撼动一个被认可的标准。

最后特别感谢一下IETF,可以说是互联网的图书馆,也可以说是互联网发展的基石。另外RFC一些被W3C掩盖的黑历史也被找到了,哈哈。

IETF是由网民自发组织,自我管理的,任何人都可以参加的,完全民主平等的,无投票机制的,充分体现了自由、开放、合作、共享的精神)里成立了特别工作小组。

Cookie的首部字段样式如下:

image.png

7.6.2 Set-Cookie

基本的格式如下,在开始使用Cookie之前的一些准备操作:

Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31

基本的字段属性如下:

image.png

expires 属性:发送Cookie的有效期,默认为会话为Seesion级别,也就是一次浏览器访问。另外需要注意Cookie一旦创建服务端就没办法随便删除,只能覆盖的方式改写客户端的Cookie信息。

path属性:限制指定Cookie的发送范围目录,但是实际上有办法绕过这个限制,所以这个属性不是一个安全属性。

domain属性:通过domain校验结尾匹配,实际上不指定这个属性更加安全,因为这个属性类似白名单允许多个domain访问。

secure 属性(Set-Cookie: name=value; secure):限制仅在HTTPS连接才发送Cookie,是一种比较安全的属性,意味着当同样的域名在使用HTTPS的情况下会发送Cookie,但是转为HTTP则不会覆盖客户端的Cookie。另一方面不指定这个属性意味着不会发生回收行为。

7.6.3 HttpOnly 属性

介绍:属于Cookie本身的扩展功能,作用是防止JS脚本窃取Cookie信息,也就是防止XSS攻击。

声明方式:

Set-Cookie: name=value; HttpOnly

通过这样的声明之后,JavaScriptdocument.cookie 就无法读取附加 HttpOnly Cookie 的内容了。

实际上HttpOnly 这个扩展本意并不是为了防止XSS攻击发明的,但是后来作为缓解XSS攻击的一项重要手段被广泛采用。

XSS攻击类似下面的脚本:

http://example.jp/login?ID="> <script>var+f=document.getElementById("login");+f.action="h </script><span+s=" 对请求时对应的HTML源代码(摘录)

7.6.4 Cookie(Cookie: status=enable)

首部字段 Cookie 会告知服务器,当客户端想获得 HTTP 状态管理支持时,就会在请求中包含从服务器接收到的 Cookie。Cookie可以发送多个。

7.7 其他首部字段

其他首部字段也是HTTP对于开放扩展的支持,这些字段并不符合WEB的标准,需要交由实现方决定,但是使用频率并不低。

7.7.1 X-Frame-Options

此字段为响应首部的内容,主要作用是控制Frame标签显示内容,主要为了防止点击劫持的攻击方式。

可选内容有下面两项

  • DENY:拒绝
  • SAMEORIGIN:同源页面匹配许可。

主流浏览器基本已经支持这个字段,下面为Apach的一个参考:

<IfModule mod_headers.c>
Header append X-FRAME-OPTIONS "SAMEORIGIN"
</IfModule>

7.7.2 X-XSS-Protection(X-XSS-Protection: 1)

首部字段 X-XSS-Protection 属于 HTTP 响应首部,主要作用是用于控制浏览器 XSS 防护机制的开关。

语法:

X-XSS-Protection: 0
X-XSS-Protection: 1
X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; report=<reporting-uri>

标识解释:

  • 0:禁止 XSS 过滤。
  • 1:启用 XSS 过滤(通常浏览器是默认的)。 如果检测到跨站脚本攻击,浏览器将清除页面(删除不安全的部分)。
  • 1;mode=block,启用 XSS 过滤。 如果检测到攻击,浏览器将不会清除页面,而是阻止页面加载。
  • 1; report=<reporting-URI> (Chromium only),启用 XSS 过滤。 如果检测到跨站脚本攻击,浏览器将清除页面并使用 CSP report-uri (en-US)指令的功能发送违规报告。

7.7.2 DNT

DNT 属于 HTTP 请求首部,是 Do Not Track 的简 称,主要用于防止广告抓取个人信息。

首部字段 DNT 可指定的字段值如下。

  • 0 :同意被追踪
  • 1 :拒绝被追踪

这里介绍一个好用的谷歌插件**“Ublock origin”**,图标类似一个小红色盾牌。

最大特点可以利用html元素直接抹掉页面的广告信息过滤元素,非常好用。

7.7.3 P3P

P3P(The Platform for Privacy Preferences,在线隐私偏好平台)技术,通过这个首部可以把隐私信息变为仅应用程序识别的方式处理。

创建P3P的步骤如下:

步骤 1:创建 P3P 隐私。

步骤 2:创建 P3P 隐私对照文件后,保存命名在 /w3c/p3p.xml。

步骤 3:从 P3P 隐私中新建 Compact policies 后,输出到 HTTP 响应中。

关于P3P可以继续阅读下面的内容:

The Platform for Privacy Preferences 1.0(P3P1.0)Specification www.w3.org/TR/P3P/

X-前缀废弃:通过这个前缀来排查掉非标准参数,并且依次作为非标准参数的扩展,但是实际使用发现这样不仅导致命名混乱,还可能影响正常的通信,所以在后续的“RFC 6648 - Deprecating the "X-" Prefix and Similar Constructs in Application Protocols”废弃此用法。

7-2. HTTP协作服务器

7.1 单台虚拟机多域名

HTTP1.1支持服务器搭建多个站点,提供WEB托管服务, 而针对域名和IP的映射以及查找工作涉及到DNS,域名需要通过DNS解析之后才能进行访问,当请求发送到服务器的时候使用的已经是IP的方式了。

7.2 通信转发程序

通信转发存在几个专业术语:代理、网关、隧道,下面一一区分他们的概念。

代理:代理扮演了服务端和客户端的“中间商”,代理服务器的基本行为就是接收客户端发送的请求后转发给其他服务器。代理的作用通常是加快目标站点的访问加速或者作为跳板使用。

网关:专门负责转发其他服务器的通信数据的服务器,对于自己的位置类似传话筒,负责把一个服务器的“话”传给另一个服务器,所以发送请求的服务器本身也会被当作被转发的服务器。

隧道:保证距离很远的客户端和服务器中转的应用程序。

7.2.1 代理

代理主要的变动信息在Via 首部信息,每次代理转发都需要在Via首部加入转发信息,具体添加信息如下:

image.png

对于代理按照是否修改报文和是否缓存数据,分为透明代理缓存代理

  • 透明代理:透明代理指的是不对请求报文做任何加工的代理方式。
  • 缓存代理:缓存代理通常存在于缓存服务器,代理转发响应之前先把数据缓存到缓存服务器,然后再进行返回到客户端。

7.2.2 缓存服务器

缓存服务器的作用是减轻服务器的负担,利用缓存可以避免同样的资源反复从源服务器进行返回,而可以直接从缓存服务器获取资源。这部分内容在《网络是怎么样连接的》这本书中有详细介绍。

7.2.3 隧道

隧道可按要求建立起一条与其他服务器的通信线路,届时使用 SSL 等 加密手段进行通信。

HTTP 之前出现的协议

  • FTP:比 TCP/IP 协议族的出现还要早,虽然被HTTP超越,但是目前还是还是广泛用于文件上传。
  • NNTP(Network News Transfer Protocol):用于 NetNews 电子会议室内传送消息的协议。
  • Archie:搜索 anonymous FTP 公开的文件信息的协议。
  • WAIS(Wide Area Information Servers):通过关键词检索多个数据库使用的协议。
  • Gopher:查找与互联网连接的计算机内信息的协议。
相关实践学习
基于函数计算快速搭建Hexo博客系统
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
|
1天前
|
JavaScript
http-server实现本地服务器
使用Node.js的http-server模块创建本地服务器:先确保安装Node.js和npm,然后在命令行中安装http-server模块,运行`npm install http-server -g`。接着,切换到目标文件夹并启动服务器,输入`http-server`或带端口号的`http-server -p 3000`。最后,通过`http://localhost:8080`(或指定端口)访问服务器。
|
2天前
|
PHP Android开发
android通过http上传文件,服务器端用php写(原创)
android通过http上传文件,服务器端用php写(原创)
14 4
|
11天前
|
中间件 Go
【Go语言专栏】使用Go语言编写HTTP服务器
【4月更文挑战第30天】本文介绍了如何使用Go语言创建基本的HTTP服务器,包括设置路由、处理请求和响应。首先确保安装了Go环境,然后引入`net/http`包,定义路由和处理器函数。处理器函数接收`http.ResponseWriter`和`*http.Request`参数,用于发送响应和处理请求。使用`http.ListenAndServe`启动服务器,并可通过中间件增强功能。文章还提及了处理复杂请求、查询参数和POST数据的方法,以及使用第三方库如Gin和Echo扩展功能。通过本文,读者可掌握Go语言编写HTTP服务器的基础知识。
|
12天前
|
弹性计算 监控 Shell
监控HTTP 服务器的状态
【4月更文挑战第29天】
10 0
|
存储 Web App开发 监控
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
我们以前使用过的对hbase和hdfs进行健康检查,及剩余hdfs容量告警,简单易用 1.针对hadoop2的脚本: #/bin/bashbin=`dirname $0`bin=`cd $bin;pwd`STATE_OK=...
1016 0
|
SQL Web App开发 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
在运行一个group by的sql时,抛出以下错误信息: Task with the most failures(4):  -----Task ID:  task_201411191723_723592_m_000004URL:  http://DDS0204.
922 0
|
Web App开发 存储 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
      前段时间公司hadoop集群宕机,发现是namenode磁盘满了, 清理出部分空间后,重启集群时,重启失败。 又发现集群Secondary namenode 服务也恰恰坏掉,导致所有的操作log持续写入edits.new 文件,等集群宕机的时候文件大小已经达到了丧心病狂的70G+..重启集群报错 加载edits文件失败。
856 0
|
Web App开发 前端开发 Android开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
使用MAT分析内存泄露 对于大型服务端应用程序来说,有些内存泄露问题很难在测试阶段发现,此时就需要分析JVM Heap Dump文件来找出问题。
746 0
|
Web App开发 监控 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
Hbase依赖的datanode日志中如果出现如下报错信息:DataXceiverjava.io.EOFException: INFO org.apache.hadoop.hdfs.server.datanode.DataNode: Exception in receiveBlock for block  解决办法:Hbase侧配置的dfs.socket.timeout值过小,与DataNode侧配置的 dfs.socket.timeout的配置不一致,将hbase和datanode的该配置调成大并一致。
767 0