本文共 7244 字,大约阅读时间需要 24 分钟。
对于http协议,每个人都或多或少地会用到它,因为浏览器的地址栏就有,比如 http://www.baidu.com
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
首先由Client向Server发起请求,发送HTTP request。
Server收到请求后,进行响应,发送HTTP response。
整个过程可以归纳如下:
消息包括以下格式:请求行+请求头部+空行+请求数据,总共四个部分
举例:
请求行:
POST /examples HTTP/1.1\r\n //请求方式,请求路径和协议版本
请求头:
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */* //客户端向服务器端表示,我能支持什么类型的数据Referer: http://localhost:8080/examples/servlets/servlet/RequestParamExample //告诉服务器我是从哪一个页面链接过来的Accept-Language: zh-CN //支持语言格式User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E) //客户端信息Content-Type: application/x-www-form-urlencoded //提交的数据类型。经过urlencoding编码的form表单的数据Accept-Encoding: gzip, deflate //gzip, deflate为压缩算法 Host: localhost:8080 //服务器地址Content-Length: 31 //数据长度Connection: Keep-Alive //Keep-Alive保持连接Cache-Control: no-cache //对缓存的操作
请求体:
firstname=zhang&lastname=sansan //发送给服务器的数据
请求方式在请求头中的第一个字段
序号 | 方法 | 描述 |
---|---|---|
1 | GET(常用) | 请求指定的页面信息,并返回实体主体。 请求信息包含在URL中 |
2 | POST(常用) | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。请求数据被包含在请求体中。 |
3 | HEAD | 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头 |
4 | PUT | 从客户端向服务器传送的数据取代指定的文档的内容。 |
5 | DELETE | 请求服务器删除指定的页面。 |
6 | CONNECT | HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。 |
7 | OPTIONS | 允许客户端查看服务器的性能。 |
8 | TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
9 | PATCH | 是对 PUT 方法的补充,用来对已知资源进行局部更新 。 |
比如:
https://www.baidu.com/s?ie=UTF-8&wd=滴滴 //GET方式,数据包含在URL中
从上面的URL可以得到信息:
Server根据这些请求的数据,经过一定的程序逻辑,返回响应页面。
再次回顾网页访问的过程:
状态码用于告知Client当前的Server状态。
状态码分类与常见状态码:
1xx //信息提示 100 continue 继续发送2** //成功状态码 200 OK(请求成功)3** //重定向 301 永久重定向(搜索引擎会将排名等信息转移到新域名) 302 临时重定向(搜索引擎不会将排名等信息转移到新域名)4** //客户端错误 403 Forbidden(客户端没有权限访问此资源) 404 NotFound(资源不存在)5** //服务器错误 500 服务器内部出错(如Bug) 502 错误网关(网关向后端请求错误) 503 服务不可用(服务器无法处理请求,比如过载) 504 网关超时(网关向后端请求超时)
滴滴官网的404界面:
http响应头部和请求的头部类似:响应行+响应头+响应体
响应体为网页文件等资源
响应行:
HTTP/1.1 200 OK //协议版本,状态码,OK对应状态码
响应头:
Server: Apache-Coyote/1.1 //服务器类型,这里是TomcatContent-Type: text/html;charset=ISO-8859-1 //返回数据类型Content-Length: 673 //返回数据长度Date: Fri, 17 Feb 2017 02:53:02 GMT //响应时间
响应头 | 说明 |
---|---|
Allow | 服务器支持哪些请求方法(如GET、POST等)。 |
Content-Encoding | 文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,Servlet应该通过查看Accept-Encoding头(即request.getHeader(“Accept-Encoding”))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。 |
Content-Length | 表示内容长度。 |
Content-Type | 表示后面的文档属于什么类型。比如text/html。 |
Date | 当前的时间。 |
Expires | 文档过期时间,过期后浏览器可不再缓存 |
Last-Modified | 文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。 |
Location | 重定向后的位置。比如301永久重定向和302临时重定向 |
Refresh | 表示浏览器应该在多少时间之后刷新文档,以秒计。 |
Server | 服务器名字。 |
Set-Cookie | 设置和页面关联的Cookie。 |
(1) 媒体独立
所有类型的数据都可以通过http协议传输。传输的类型由Content-Type标明。
(2) http协议是无状态的
无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。
cookie和session技术让服务器有了记忆。
(3) http是无连接的
无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。
早期的服务器资源有限,采用无连接的方式以便腾出资源处理其他请求。
无连接产生的问题:
随着时间的推移,网页中嵌入了图片和其他元素,并且是以链接的方式嵌入。这就说明,客户端在请求完网页文件后,紧接着又会向服务器请求图片等静态资源。这样的话,无连接+多次请求就极大的浪费了带宽等资源(都浪费在TCP上了)。
如何解决?
在HTTP/1.0中,默认使用的是短连接。
从HTTP/1.1起,默认使用长连接。 使用长连接的HTTP协议,会在响应头有加入这行代码:Connection:keep-alive
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,一段时间后会断开。
比如:客户端和服务器之间会继续使用这个通道传输图片等资源。
服务器会和客户端保持一段空闲连接,在此期间他们可以无需连接即可传输数据。空闲时间到期后(默认2h),服务器会发送探测多个报文给客户端,如果都没有回应或回应断开连接的报文,则断开连接。
HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。
可以看到,长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。
新的二进制格式(Binary Format)
HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。
多路复用(MultiPlexing)
即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
header压缩
如上文中所言,对前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。
服务端推送(server push)
同SPDY一样,HTTP2.0也具有server push功能。
详细解释可以看这里:https://www.cnblogs.com/heluan/p/8620312.html
这是HTML5的协议
传统http只能由客户端请求,服务端回应。如果客户端定时请求,则会造成很大资源浪费。 Web Socket可以握手,实现真正的双向传输。这样有数据更新的时候服务端可以及时发送数据,也不会造成资源浪费。 详细介绍可是看这里:https://www.liaoxuefeng.com/wiki/1022910821149312/1103303693824096
Web Socket握手过程:
首先,WebSocket连接必须由浏览器发起,因为请求协议是一个标准的HTTP请求,格式如下:
GET ws://localhost:3000/ws/chat HTTP/1.1Host: localhostUpgrade: websocketConnection: UpgradeOrigin: http://localhost:3000Sec-WebSocket-Key: client-random-stringSec-WebSocket-Version: 13
解释:
GET请求的地址不是类似
请求头/path/
,而是以ws://
开头的地址;Upgrade: websocket
和Connection: Upgrade
表示这个连接将要被转换为WebSocket连接;Sec-WebSocket-Key
是用于标识这个连接,并非用于加密数据;Sec-WebSocket-Version
指定了WebSocket的协议版本。
服务端回应:
HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: server-random-string
由于长连接会占用大量资源,典型的就是出现大量的TIME_WAIT。
可以通过下面的命令查看TIME_WAIT等状态的数量:
netstat -ant|awk '/^tcp/ {++S[$NF]} END {for(a in S) print (a,S[a])}'
推荐配置:
vim /etc/sysctl.conf #TCP的配置 net.ipv4.tcp_syn_retries=2 #最多发起2次SYN请求(默认为5) net.ipv4.tcp_fin_timeout=30 #FIN_WAIT_2时间 net.ipv4.tcp_max_syn_backlog = 4096 #SYN队列长度(默认为1024),增加以容纳更多等待连接数 net.ipv4.tcp_tw_reuse = 1 #开启TIME-WAIT sockets重用机制(默认为0,即关闭),可重新用于新的TCP连接 net.ipv4.tcp_tw_recycle = 1 #开启TIME-WAIT sockets快速回收(默认为0,即关闭) net.ipv4.tcp_syncookies = 1 #当SYN等待队列溢出时,启用cookies来处理(默认为0,即关闭),可以防范少量SYN攻击 #http的keepalive长连接的配置 net.ipv4.tcp_keepalive_time=1200 #空连接可以保持1200s net.ipv4.tcp_keepalive_probes=5 #空连接结束后发送探测报文的个数(都未回应则断开连接) net.ipv4.tcp_keepalive_intvl=20 #每个探测包的间隔时间 #其他配置 net.core.netdev_max_backlog=3000 #每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目sysctl -p #加载内核文件
背景:
HTTPS就是在应用层和传输层中间加了一道验证的门槛以保证数据安全:
什么是SSL/TLS?
1996年 NetScape 公司发布 SSL v3.0;
1999年互联网标准化组织ISOC接替NetScape公司,发布了SSL的升级版TLS 1.0版。 2006年和2008年,TLS进行了两次升级,分别为TLS 1.1版和TLS 1.2版。 SSL 及其继任者 TLS 是为网络通信提供安全及数据完整性的一种安全协议。
(1) 客户端向服务器端索要并验证公钥。
(2) 双方协商生成"对话密钥"。 (3) 双方采用"对话密钥"进行加密通信。 前两步,又称为"握手阶段"。注意点:
背景知识:
问题1:为什么要使用对称加密?
问题2:为什么不直接使用对称秘钥?
问题3:公钥从哪里来,可否伪造?
问题4:HTTP不安全为什么还要用呢?