HTTP基础概念笔记

HTTP简述

URI

URI(统一资源标识符) 分为URL(统一资源定位符) 与URN(统一资源名)。

URL一般分为三个部分

  1. 方案,http:// 即访问资源使用的协议
  2. 服务器所在的Internet地址
  3. web服务器所在的某个资源

URN依旧处于实验阶段,现在几乎所有的URI都是URL,所以一般不区分URL与URI

事务

通过请求命令与响应结果,客户端获得想要的结果。

  1. 请求方法 GET,POST,PUT,DELETE,HEAD
  2. 状态码 1XX,2XX,3XX,4XX,5XX

报文

http报文是由一行一行的简单字符串组成的,而不是二进制数据,所以很方便程序员直接进行读写操作,http报文分为三个部分

起始行与首部字段都是纯文本类型,但是主体可以包含任何需要的数据,二进制数据或者文本都可以。HTTP 采用了MIME数据格式标签,使得能够传送多媒体内容。

  1. 起始行 请求报文中说明要做什么,响应报文中说明出现了什么情况
  2. 首部字段 键值对的形式
  3. 主体 包含所有需要的数据

连接

http是应用层协议,不需要考虑网络通信的具体细节。细节都有tcp协议进行处理。使用80端口进行http连接。

可以使用telnet来连接几乎所有的tcp服务器,包括http。只不过发送的数据需要符合http的格式。用来模拟http客户端

版本

  1. HTTP/0.9 只支持GET方法,只用于获取简单的HTML对象
  2. HTTP/1.0 添加了版本号,HTTP首部,多媒体等
  3. HTTP/1.1 重点在于校正HTTP设计中的结构性缺陷,明确语义,添加了基于口令基本认证的方法,得以支持访问控制
  4. HTTP/2.0 重点在于性能的大幅度提升

结构组件

  1. 代理 接收所有的请求或响应并转发
  2. 缓存
  3. 网关 通常用于将http协议与其他协议进行转换
  4. 隧道
  5. Agent代理 用户代理,web浏览器,爬虫等

URL与资源

URI 是统一资源标识符

URL通过描述资源位置来标识资源,而URN通过描述资源名字来标识资源

语法

URL语法:

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>

最重要的三个部分,scheme方案 host主机 path路径

需要说明的是,frag是在客户端部分进行处理的,服务器负责处理全局的对象

快捷方式

URL可以分为相对URL和绝对URL。

使用相对URL需要先设置一个baseURL,使得获取相对定位。在解析时还需要将相对URL解析成为绝对URL。

浏览器会将浏览过的历史记录下来,在需要的时候进行自动的url扩展,得以自动补全。

编码机制

通过编码,进行转义,使得在URL中表示各种不安全的字符。
通常使用的转义符号有

  • %
  • /
  • #
  • :
  • ;

常用方案

  • HTTP
  • HTTPS
  • FTP
  • mailto
  • file
  • news
  • telnet

缺点

URL是通过资源路径来定位资源的,如果服务器将该资源的路径进行了修改,会导致之前的URL失效,无法继续定位

HTTP报文

HTTP报文流动方向

报文流入源端服务器,工作完成后,流回Agent代理中
所有的报文都是下游流动

组成部分

HTTP报文由三个部分组成

  1. 对报文进行描述的起始行
  2. 包含属性的首部块
  3. 可选,包含数据的主体
起始行 HTTP/1.1 200 OK
首部 Content-type: text/plain
Content-length: 19
主体 Hi!

分类

所有的http报文可以分为两类,一是请求报文,二是响应报文。二者结构相同。

请求头

方法

客户端希望服务器执行的操作,GET,PUT,DELETE,POST,HEAD

请求URL

版本

状态码

原因短语

状态码

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

首部

一些键值对的列表,添加附加信息。

分类

通用首部

可以出现在请求报文和响应报文首部中的。例如Date

请求首部

提供更多请求信息

响应首部

提供更多响应内容

实体首部

描述主体长度内容,或者资源自身

扩展首部

规范中没有定义的部分

方法详解

安全方法

HTTP中定义了一系列安全方法。GET和HEAD被认为是一种安全方法,这意味着使用GET或者HEAD的请求不会产生什么动作。HTTP/1.1 要求服务器必须实现GET与HEAD方法。

常用方法,GET,POST,HEAD,
了解GET与POST之间的区别。

连接管理

HTTP协议是基于TCP连接的。确保连接中数据不会丢失损坏,失序

HTTPS是在HTTP的基础上添加了一层SSL/TSL封装

TCP是分组连接,一个发送的数据可能会被分成多个TCP数据包进行分组传送。

TCP通过4个参数建立唯一通道

<源地址,源端口,目的地址,目的端口>

TCP连接

TCP三次握手
socket连接编程

HTTP基于TCP连接,所以事务上的性能很大一部分取决于底层TCP通道的性能。往往HTTP时延是由tcp网络延时造成的。
首先是通过DNS解析网络IP地址,然后建立TCP连接。

HTTP性能聚焦

  • TCP连接建立握手
  • TCP慢启动拥塞控制
  • 数据聚焦Nagle算法
  • 捎带确认的TCP延迟确认算法
  • TIME_WAIT时延和端口耗尽

TCP连接建立握手

进行HTTP连接时需要先建立连接,这之间就存在握手时延。如果HTTP本身只传递少量数据的话,建立握手的时延就比较可观了。

延迟确认

TCP本身具有丢失重传机制来确保数据能够正确获得。如果发送者没有在指定时间内收到来自接收方的确认帧,则会认为该数据已经丢失,即开始重传。

大多数TCP采用延迟确认算法,在一定时间内的确认帧会放在缓冲区中,寻找能够携带的输出分组,如果一定时间内没有输出分组,则确认信息放在单独分组中传送。而由于HTTP本身的双峰特征,输出分组并没有很多,所以延迟算法一定程度上造成了时延。

TCP慢启动

TCP具有拥塞控制的功能,在一开始建立连接发送数据的时候,会限制本身的最大传送数据量,如果传输成功,则会逐渐提高传输速度。用于方式因特网的突然过载和拥塞。
例如先发送一个数据,然后两个,四个,逐步增加。
基于这种特性,已经进行过数据交换的连接传输速度比新连接要快一些。

Nagle算法和TCP_NODELAY

TCP本身有一个数据流接口,可以传送任意长度的数据。但是每个TCP的首部都有至少40字节的数据,所以如果大量发送少量数据,网络性能会严重下降。

所以Nagle算法会尽量将多个数据拼接在一起然后一起发送。这就造成了之前的数据会被延迟发送。特别是当剩余数据不足以达到算法的发送低值时,需要等到算法的设定时间后才会被发送。

可以配置禁用Nagle算法,但是同时应该确保发送的TCP分组中有大量数据。

TIME_WAIT累积与端口耗尽

当某个TCP端口关闭TCP连接的时候,会在内存中维护一个小的控制块,确保在一定时间内不会创建相同地址,端口的连接。在性能基准环境下,可能就会成为性能的限制。

每当客户端连接到80端口后,会获得一个新的端口,以实现连接的唯一性。但是由于可用源端口数量有限,在一定时间内可能会被限制不能再使用,就有可能遇到端口耗尽的问题。

即使没有端口耗尽的问题,也要考虑,大量连接处在打开状态,或处于等待状态,内存中分配了大量的控制块。会影响系统速度。

HTTP连接处理

Connection首部

###串行事务延时处理
如果只对连接进行简单管理,假设一个Web网页嵌入3个图片,则浏览器需要发起多个HTTP请求来显示页面。如果每个请求都串行建立新连接,则连接延时和慢启动就会叠加。

对此,可以采用并行连接,持久连接,管道化连接的方式处理

并行连接

浏览器开启多个TCP连接请求数据,但实际速度不一定更快。打开大量连接会消耗内存资源从而引发自身的性能问题。

持久连接

对于连到同一个站点的连接,浏览器可以通过一个TCP连接获取多个数据,这个方法在HTTP2.0中有所体现。

但是使用持久连接,需要注意,有可能出现大量空闲连接,消耗性能

持久连接有两种方案

HTTP/1.0 keep-alive

HTTP/1.1 persistent

Keep-Alive

Keep-Alive并不是默认开启的,需要有请求首部来显式要求

在代理中可能出现问题

persident

HTTP/1.1中默认开启

管道化连接

在响应到达前,可以先将多个请求放入队列中。可以减少网络环回时间。但是客户端需要做好随时断开连接,处理已发送尚未响应的请求。

关闭连接

Web服务器

Web服务器实现了HTTP和相关的TCP连接处理。负责管理Web服务器提供的资源,以及对Web服务器的配置、控制及扩展管理。

建立连接

处理新的连接,解析出IP地址,将连接加入Web服务器列表中。

接收请求报文

解析报文,读取内部控制字段和主体内容。

处理请求

对资源的映射和访问

构建响应

发送响应

记录日志

Web代理

Web代理服务器是网络的中间实体。位于客户端和服务器之间,在各端点间来回传送报文。

HTTP代理既是客户端又是服务器,需要同时处理请求和响应。

代理可以看到并接触所有流经的HTTP流量,所以代理可以监视和修改所有流量。

可以通过代理实现很多功能。

私有代理和公有代理

众多客户端共享的代理是公有代理,而私有代理仅被一个客户端使用。

代理与网关的区别

代理连接的是两个或者多个使用相同协议的应用程序,而网关连接的则是两个或者多个使用不同协议的端点。网关负责进行协议的转换。

原理

  • 在客户端中设置代理。
  • 修改网络
  • 修改DNS
  • 修改Web服务器,使用重定向命令。

URI 代理需要对URI进行处理

在设置代理的情况下,客户端会发送完整URI。
在没有设置的情况下,客户端只会发送部分URI,因为默认接收方已经知晓地址和端口。

在虚拟主机的配置中,也会出现类似的问题。即缺少方案,缺少主机,缺少端口。

不过代理是通过显式要求报文中使用完整URI来解决这个问题,而虚拟主机是通过HOST字段来承载主机和端口信息。

在有不可见拦截代理的时,对主机的解析会有所不同。因为对于客户端而言,是没有代理的,代理需要有很强的健壮性,能够处理各种各样的情况

报文追踪

via首部字段可以用来列出报文途中路过的中间节点。请求VIA与对应的响应VIA基本上是相反的,因为二者共用一个TCP连接。

TRACE 用户可以用来追踪代理链传输的请求报文,观察代理是如何处理报文的

缓存

对于同一份文档,多次传输占用了网络带宽,降低传输速度,加重服务器负荷。

将物理位置上远距离的文件保存在附近的网络服务器中,可以显著降低传输时延。

命中与未命中

时间

需要通过HTTP再验证,来保证缓存的新鲜度,即确保缓存的数据与网络上的数据依旧是一致的。可以通过条件首部字段,IF-MODIFIED-SINCE ,来询问服务器该资源在是否在某时间后发生了改变。

如果发生改变,则服务器就将新的数据传送回来。

如果未改变,服务器返回304状态码,表示NOT Modified

如果资源已被删除,返回404 NOT FOUND,缓存也将其副本删除。

文件本身 ETag

通过IF-NONE-MATCH

发送文件的标志ETAG给服务器,来确认是否发生变化

服务器处理缓存步骤

  1. 接收
  2. 解析
  3. 查询
  4. 新鲜度检测
  5. 创建响应
  6. 发送
  7. 日志

控制缓存

通过首部字段Cache-Control可以来控制缓存相关设置。

no-store
在使用完数据后,马上将数据从客户端中删除

no-cache
在获取使用数据后,可以将其缓存,但是每次使用前必须先向服务器验证该缓存的新鲜度。

关于广告

广告的点击一般是靠点击量的,缓存的存在,使得点击量会减少。

此时可能需要由客户端记录点击次数,然后发送给服务端

网关

协议网关

转换来自双方的不同协议,进行不同协议之间的通信。

常见的如:

  • HTTP/FTP
  • HTTP/HTTPS

资源网关

API就是所谓的通用网关接口。

隧道

可以通过HTTP应用程序访问使用非HTTP协议的应用程序。

Web隧道允许用户通过HTTP连接发送非HTTP流量,在HTTP上捎带其他协议数据。这类流量可以穿过只允许Web流量通过的防火墙。

使用connect建立HTTP隧道

CONNECT方法请求隧道网关创建一条到达任意目的的服务器和端口的TCP连接,并对客户端和服务器之间的后继数据进行盲转发。

中继

简单HTTP代理

Web机器人

在无需人类干预的情况下,自动进行一系列的web事务处理软件。
从一个站点进入另一个站点,获取内容,跟踪链接,并对数据进行处理。

爬虫

从根集出发,开始爬取数据。

链接提取

对爬到的HTML进行解析,得到其中的URL,并将链接添加待爬队列中。

还需要将相对URL转为绝对URL

避免环路

避免循环爬取页面的情况出现。

对已经提取过的网页,爬虫需要记录,来进行查找以避免重复请求。

需要实现快速搜索。搜索树或者哈希表。

URL别名

默认端口,默认页面,IP地址等的存在,使得可能出现多个不同的URL指向同一个页面资源,此时爬虫需要进行区别。

URL规范化可以在一定程度下解决这个问题

文件系统环路

需要爬虫本身实现循环检测机制

可采取的方案

规范化URL

广度优先遍历

节流,限制一段时间内机器人可以从一个站点获取的页面数量

限制URL大小

URL站点黑名单 对已知的某些会产生环路,存在陷阱的站点加入黑名单,避开请求

模式检测 对环路请求的模式特征进行监控

内容指纹 类似消息摘要

人工

拒绝机器人访问

拒绝机器人访问标准,自愿遵守的一个守则,如果存在该守则,则爬虫默认不去爬取页面。进行自我约束。

搜索引擎

HTTP-NG

HTTP/1.1 提供了很多强大的功能,但目前也出现了局限性,复杂,性能,传输依赖。

Http2协议是一个二进制协议,二进制更易于frame(帧 数据包)的实现,Http2有十个不同frame定义,其中两个最基础的对应于HTTP 1.1的是Data数据和HEADE头部,其后将描述。

frame是包含几个部分:类型Type, 长度Length, 标记Flags, 流标识Stream和frame payload有效载荷。

流标识是描述二进制frame的格式,使得每个frame能够基于http2发送,与流标识联系的是一个流,每个流是一个逻辑联系,一个独立的双向的frame存在于客户端和服务器端之间的http2连接中。一个http2连接上可包含多个并发打开的流,这个并发流的数量能够由客户端设置,这些流可能是打散了通过物理连接传输。

关键之一就是在 应用层(HTTP/2)和传输层(TCP or UDP)之间增加一个二进制分帧层。

HTTP是一个无状态请求

但是有时候需要根据用户提供个性化网页,因此需要进行用户识别

  • 承载用户身份信息的HTTP首部
  • 客户端IP地址跟踪,通过IP地址识别用户
  • 用户登录,使用认证的方式
  • 胖URL,在URL中嵌入识别信息
  • cookie

HTTP首部

From 用户E-mail地址
User-Agent 用户的浏览器软件
Referer 用户通过这个页面跳转而来
Authorization 用户名和密码
Client-IP 客户端IP地址
X-Forwarded-For IP地址
Cookie 服务器产生的ID标签

From,User-Agent,Referer都不足以实现可靠的识别。

客户端IP地址

利用IP地址来区别用户

限制:

  1. IP地址描述的是客户端机器,而不是用户。如果多个用户共用一个机器,此时无法区分
  2. DHCP动态IP配置,使得每个客户端有可能出现不同的IP地址
  3. NAT网络地址转换,使得IP地址难以识别
  4. 代理和网关的存在,服务器会看见代理的IP,而不是用户的IP

用户登录

用户主动登录,来判断用户是谁

胖URL

利用URL中记录的信息,来区别用户,对URL进行一些扩展,添加一些状态信息。

由服务器为了跟踪,而产生的一段字符串

会话cookie

临时使用的,在浏览器退出后就会被删除

持久cookie

存储在硬盘上,过期时间比会话cookie长很多。

会话cookie和持久cookie的唯一区别就是二者的过期时间

如果设置了Discard,或者没有设置过期时间,则这个就是会话cookie

cookie设置

使用set-cookie 首部。

不同的站点使用不同的cookie,可以通过设置cookie的域属性和路径属性,来使同一站点的访问使用同一cookie
domain=”xxx.com”; path=/path1/

secure 是否只有在SSL连接时才发送这个cookie

expiration 过期时间

allh 域内所有主机都获取cookie,还是只有指定了名字的主机获取

当进行重定向转移的时候,之前cookie依旧会被添加进后续的请求中。

cookie与缓存

在使用cookie的时候,需要注意这些内容可能是用户个人定制的,在某些时候,应该禁止浏览器缓存相关的数据。

HTTP基本认证

HTTP原生提供了一种认证机制。

服务器返回401状态码,表示该需要通过认证才能访问

通过AUTHENTICATE 首部字段,来进行验证

使用时,可以通过BASE4编码,来混淆账号密码。

WWW-AUTHENTICATE中包含了realm域信息,来明确需要访问的是哪个安全域。

这种验证,因为并不是加密验证,其实也是一种明文的信息进行了数据传输,容易被中间人获取。并不安全

摘要认证

摘要认证避免明文在网络上传输

可以有选择的防止对报文内容的篡改

防止恶意用户捕获并重放认证的握手过程

MD5对密码进行摘要,然后传输

服务器可以添加一个随机数给客户端,将随机数附在密码后面进行加密。可以有效防止将摘要记录后作为重放进行验证。

安全HTTP

HTTPS

使用SSL或者TLS, 传输层级别的密码安全层

HTTPS先将未加密的报文发给安全层,由其进行数据加密,然后再发送。

一般来说,加密过程对于HTTPS的应用层是隐藏的,应用只需处理自己业务逻辑即可。

HTTPS使用443端口

https 三次握手。SSL交换密钥
端口443 。https就是在http的基础上添加了ssl加密协议,利用密钥交换协议进行了密钥交换
验证CA证书。
具体分析。。。

1
http://www.freebuf.com/articles/system/37900.html

HTTPS代理

对于代理而言,一旦HTTP数据加密,代理就看不到相关的HTTP头信息,无法进行数据的转发。

一般此时,需要客户端提前将端口与地址等告知代理。以明文的形式

之后建立隧道,直接以隧道的模式进行交流