连接管理
- HTTPS比HTTP多了一层TSL或者SSL的安全层
- 位于HTTP和TCP之间
- TCP连接通过源IP,源端口号,目的IP,目的端口号确定唯一连接
- 并行连接
- 一个HTML页面可能包含多个资源(文字,图片,视频等)
- 如果收到一个资源才请求下一个则太慢,我们可以并行请求
- 浏览器端同时开启多个http connection的方式从服务端获取数据资源
- 缺陷
- 但是如果网络带宽太小,并行请求都去竞争有限的带宽,则每个对象都会加载很慢
- 并且大量的连接会消耗很多内存资源,特别会对服务器造成压力
- 所以一般浏览器只会少量并行(4个左右)
- 所以一般浏览器只会少量并行(4个左右)
- 持久连接
-
好处
- 一次传输完成后不断开TCP连接,避免了建立和关闭连接的消耗和延迟
- 例如程序和数据库的连接应该用长连接
- 一次传输完成后不断开TCP连接,避免了建立和关闭连接的消耗和延迟
-
缺陷
- 一不小心可能会积累大量空闲连接,消耗服务器和客户端资源
- 像WEB网站这样可能存在成千上万客户端的连接的服务,用短连接会更省一些资源
- 并发量大,但每个用户无需频繁操作情况下需用短连好
- 一不小心可能会积累大量空闲连接,消耗服务器和客户端资源
-
HTTP1.1默认为持久连接(Connection:Keep-Alive)
-
- 哑代理
- 代理服务器可能不支持keep-alive连接,但是他仍然会直接转发客户端的持久连接请求首部到服务器。
- 如果服务器同意持久连接并告知给客户端,客户端会以为该连接保持打开而不会执行关闭连接操作
- 当客户端在同一连接上发送下一个请求时,代理却忽略了该请求
- 此时浏览器一直阻塞,直到连接超时
- 因此实际上代理服务器不会转发HTTP1.0的Connection首部
- 管道化连接(pipeline)
- HTTP1.1在持久连接的基础上支持管道连接
- 可以不用等第一条消息返回响应就发送下一条消息
- 在理想情况下,所有资源的获取仅仅需要一个RTT时长(Round Trip Time)
- 而非pipeline的情况下,所有资源获取需要N个RTT时长(N表示资源个数)
- 只有幂等的方法才能使用pipeline
- 例如POST是非幂等的,因此不能使用pipeline
- 队头阻塞
- client端可以不必等待上一个response返回即可发送下一个request,但在server端必须根据收到的request的顺序来返回response
- 因为HTTP是一个无状态的协议,每条request无法知道哪条response是返回给他的
- 如果server端来处理pipeline请求的时候出现问题,那么排在后面的request都会被block
- 一些产品使用pipeline后产生的问题:Safari使用pipeline后发生了图片互换问题,AFNetworking在下载文件时遇到的问题
- 所以主流浏览器上默认下该功能都是关闭状态
- client端可以不必等待上一个response返回即可发送下一个request,但在server端必须根据收到的request的顺序来返回response
代理
-
代理和网关的区别
- 代理连接的是使用相同协议的端点
- 网关连接的可能是使用不同协议的端点
- 网关扮演协议转换器的角色,可以使非HTTP协议的服务器为客户端提供HTTP服务
- 实际上代理和网关的边界很模糊
-
代理的优点
- 过滤内容
- 访问控制
- 可设置服务器只接受来自特定代理服务器的访问请求(反向代理)
- 可禁止客户端访问某些网站,或者记录访问(正向代理)
- 防火墙
- 缓存
- 转码器
- 降低饱和度使得能在电视上观看
- 重新排版使得能在手机上显示
- 匿名代理
-
客户端的代理配置
- PAC文件(proxy auto-configuration)
- javascript程序,自动判断URL是否需要重定向到代理服务器
-
代理URI和服务器URI的不同
- 原始的请求行不包含服务器地址和端口部分
- 由于代理需要知道目标服务器的名称才能转发,于是基于代理的请求发送完整的URI
- 现在一个WEB物理主机上可能会有多个服务器,也就是同一个IP地址对应多个网址
- 与上面的处理方式不同,虚拟web服务器通过Host首部来承载主机和端口信息
-
浏览器对URL的解析
- 没有代理时,会尝试自动扩展,例如加入www前缀
- 有显式代理时,不自动拓展
缓存
- 优点
- 减少冗余数据传输
- 缓解带宽瓶颈
- 互联网带宽远小于以太网带宽
- 避免瞬间拥堵
- 突发事件如爆炸性新闻可能导致许多人访问同一个网页造成瞬间拥堵
- 减少距离时延
- 客户端和服务器之间的地理距离造成延迟
- 缓存的处理步骤
- 接受请求报文
- 解析处URL和各种首部
- 查询本地缓存
- 新鲜度检测
- 创建响应报文
- 发送回客户端
- 记录日志
- 缓存过期
- 原始服务器可以通过cache-control或者expires首部告知客户端缓存过期时间
- 服务器再验证
- 缓存过期不意味着缓存的内容被更改了
- 客户端可以向服务器验证缓存是否被修改了,如果没有,仍然可以直接返回缓存
- 验证首部
- If-Modified-Since
- If-None-Match
- 如果没有修改,服务器就返回304 Not Modified
- 缓存与广告
- 缓存会减少向原始服务器的访问次数,从而减少了广告商(如Google)的收益
- 所以广告商会添加Cache-Control:no-cache避免缓存
隧道
- 隧道允许用户通过HTTP连接发送非HTTP流量
- 使用隧道的常见原因就是在HTTP连接中嵌入非HTTP流量
- 在SSL加密后,客户端发送的消息都要通过公钥加密,网关无法解密,无法识别HTTP首部,于是不知道将流量发往何处
- 因此需要先告知网关要连接的主机和端口,然后建立隧道
- 通过Connect方法与Proxy Server建立好HTTP Tunnel后,直接转发协议流量
- 隧道建立起来后,数据可以在任何时间流量任何方向,直到连接断开
- 隧道建立起来后,数据可以在任何时间流量任何方向,直到连接断开
- 通过HTTP中的CONNECT方法创建
- 为了避免通过建立的隧道传输恶意信息,可以对客户端进行代理认证
WEB爬虫
- 为了避免重复访问某一页面甚至产生环路,爬虫需要记录所访问的页面
- 树或散列表
- URL转换为定长数字的位图
- 不同的URL可能指向同一个资源
- 例如省略了80端口或者省略了默认的index.html页面
- 因此爬虫需要自动规范化URL再判断
- 避免循环的方式
- 规范化URL
- 广度优先的爬行
- 限制爬虫从一个web站点获得网页的数量
- 拒绝爬虫访问
- 网站管理员可以通过
robots.txt
文件告知爬虫哪些页面不允许被访问- 这一标准并无强制约束力
- 网站管理员可以通过
客户端识别方法
- HTTP首部
User-Agent
Authorization
From
- 一般是由爬虫发送,告诉服务器如何通过邮件联系到爬虫的负责人
X-Real-IP
用于传递用户公网IP
- 胖URL
- 在URL开始或者结束的地方添加用户状态信息
- 存在的问题
- 丑陋
- 可能泄露信息
- 不小心包URL发送给其他人
- 不能缓存
- 服务器需要重写HTML,增加了负载
cookie
- 种类
- 会话cookie
- 临时的,退出浏览器即被删除
- 持久cookie
- 储存在硬盘上
- 一般用来记录配置文件和登录信息
- 唯一区别在于过期时间
- 会话cookie
- cookie由服务器发送,客户端储存
- 带有cookie首部的请求不应该被缓存
- cookie跨域问题
- 由于域名不同,用户向系统A登录后,系统A返回给浏览器的Cookie,用户再请求系统B的时候不会将系统A的Cookie带过去
- 这就导致如果一个服务涉及多个域名,则无法共享用户信息和状态
- Set-Cookie属性
Expires
- 定义实际生存期
Domain
- 只向特定域名的服务器发送cookie
- 例如只向amazon.com发送
Path
- 为服务器的特定文档(路径)分配
Secure
- 只在HTTPS时发送cookie
Max-Age
- 生存时间
- 生存时间
认证
- 步骤
- HTTP基本认证
- 用冒号分割用户名和密码,然后用base-64编码
- base-64编码虽然使得密码不再是明文,但是很容器解码
- 并且第三方可以在传输过程中捕获密码
- 可以和SSL结合使用
HTTPS
-
使用RSA算法的非对称加密虽然安全到但是计算很慢
- 现在一般采取混合加密系统
- 即用非对称加密传递对称密钥,然后通过对称密钥通信
-
数字证书
- 用于身份认证
- 大多数证书采用X509的标准格式
- HTTPS
- 默认端口为443
- 默认端口为443
- HTTPS还可以防止运营商劫持HTTP
- 即在原来的页面上嵌入广告
- 利用session简化SSL握手过程
- SSL握手验证服务端证书和协商对称秘钥的过程十分耗时,且在一些场景下(例如频繁的建立连接过程)传递服务端证书也是件比较消耗流量的事情
- 当用户第一次访问https服务器并完成证书验证和秘钥协商后,服务端会发送一个Session Ticket给用户
- 在下一次客户发起的ClientHello中会带上这个Session Ticket,当服务端验证有效后会省去中间的证书验证和秘钥协商过程,可以直接进行通信。如果验证失败,则重新开始证书验证和秘钥协商过程
- 也就是利用session机制后,只需要SSL握手一次即可,后面的连接都可以复用
重定向
- 重定向常见原因
- 站点从 HTTP 迁移到 HTTPS
- 站点部分 URI 发生了变化,但搜索引擎或者流量入口站点只收录了老的 URI
- 站点正在维护中,需要给用户展示不一样的内容
- 站点更换了新域名
- HTTP重定向
- 返回302状态码
- 增加了时延
- DNS重定向
- 一个域名可以对应多个IP
- DNS服务器可以将域名每次都解析到负载最轻的IP
断点续传
- HTTP/1.1允许服务器基于客户端的请求只发送响应包体的一部分给到客户端,而客户端自动将多个片断的包体组合成完整的体积更大的包体
- 功能
- 支持断点续传
- 支持多线程下载
- 支持视频播放器实时拖动
- 客户端通过
Range : bytes= 100-150, 1234-5678
来请求部分数据- 支持多重跳跃范围
- 如果服务器支持部分传输
- 服务端返回状态码
206 Partial Content
- 并在首部添加
Accept-Ranges: bytes
表示支持部分传输 - 添加
Content-Range=1234-5678/12345678
头部表示当前片断包体在完整包体中的位置以及完整资源大小- 如果未知则用*号替代
- 服务端返回状态码
- 如果服务器不支持 Range 请求,则以
200
返回完整的响应包体
HTTP劫持
- 现象
- 在网页的一脚有时候会出现一些小广告,有时候这些广告,不是访问的站点为了盈利而投放的广告,而是第三方的运营商提供的
- 劫持方式
- 在TCP连接中,找出应用层采用了HTTP协议的连接,进行标识
- 篡改HTTP响应体
- 可以通过网关来获取数据包进行内容的篡改
- 篡改方式:插入静态脚本或者是HTML Content,或者是将整体替换成Iframe,然后再在顶层的Iframe上进行内容的植入
- 抢先回包,将篡改后的数据包抢先正常站点返回的数据包先到达用户侧
- 这样后面正常的数据包在到达之后会被直接丢弃
- 这样后面正常的数据包在到达之后会被直接丢弃
- 检查方式
- 可以通过抓包来看是否有两个回包以及通过与正常的回报时间进行对比可以得出是否被HTTP劫持的结论
- 防范手段
- 使用HTTPS连接代替HTTP连接
- 很大一部分HTTP劫持,主要的原因就是在传输数据时都是明文的
- 必须要全站使用HTTPS,否则只要有一个地方没有使用HTTPS,明文传输就很有可能会被HTTP劫持了
- 由于运营商可能会使用DNS劫持,在DNS劫持之下,HTTPS的服务完全用不了了,所以会导致白屏
- 使用加密代理
- 可以在代理服务器与web服务之间使用HTTP请求,只需确认代理与web服务之间不会被HTTP劫持就可以避开HTTP劫持
- 拆分HTTP请求数据包
- 在HTTP劫持的步骤中,第一步是标记TCP连接,因此只要躲过了标识,那么后续的运营商篡改就不会存在了
- 通过浏览器Api,根据若干规则去匹配DOM中的节点,对匹配到的节点作拦截和隐藏
- 使用HTTPS连接代替HTTP连接