HTTP
HTTP 是应用层协议
HTTP 用于客户端和服务端之间进行通信
在应用 HTTP 协议时,必定是一端为客户端,一端为服务端。其中请求资源的一端称为客户端,提供资源响应的一端为服务端。一个 HTTP 链接必定是由客户端发起的。
HTTP 是无状态协议
HTTP 协议自身不对请求和响应之间的通信状态进行保存
HTTP 使用 URI 定位资源
资源请求的方式有两种:
GET http://abc.cn/index.html HTTP/1.1
或者是:
GET /index.html HTTP/1.1 Host: abc.cn
如果不是访问资源而是对服务器本身发起请求,可以使用 * 来代替 URI。下面是一个查询 HTTP 服务器支持的 HTTP 方法种类:
OPTIONS * HTTP/1.1
HTTP 方法
所谓 HTTP 方法,就是 客户端 在请求报文中用来告知服务器自己意图的方式。HTTP 拥有的方法如下:
方法 |
作用 |
解释 |
|---|---|---|
GET |
获取资源 |
用来请求指定 URI 所表示的资源 |
POST |
传输实体主体 |
用来向服务器发送数据 |
PUT |
传输文件 |
在请求报文中包含文件内容,并保存到 URI 代表的位置 |
HEAD |
获取报文受不 |
与 GET 类似,但是不获取报文主体,只获取报文头 |
DELETE |
删除文件 |
删除 URI 所代表的资源 |
OPTIONS |
询问支持的方法 |
向服务器查询针对 URI 所代表的资源的支持方法 |
TRACE |
跟在路径 |
让服务器将之前的请求通信环回给客户端 |
CONNECT |
要求用隧道协议廉洁代理 |
要求在于代理服务器通信时建立隧道 |
持久连接
在传统的 HTTP 连接中,每次发送资源都会建立一条新的 HTTP 连接。但是对于 HTML 这样包含很多资源的页面来说,重复地建立链接会导致效率低下,增加开销,因此,HTTP/1.1 提出了持久连接的概念
持久连接中,只要任意一端没有明确提出断开连接,就保持 TCP 连接状态。
持久连接使得一个 HTTP 连接可以发送多个资源,从而降低了创建和销毁 HTTP 连接的开销。
管线化
与 TCP 的滑动窗口类似,持久化连接允许一个 HTTP 连接中发送多个资源,而管线化则允许在没有得到相应时就发送下一个请求。这样就允许并发发送多个请求,而不是一个一个等待相应
状态管理
HTTP 是无状态的,服务器对于每条连接的处理方式都是一样的。但是通过让客户端在请求报文中携带一些数据来表明身份,服务器就可以对不同的客户端提供不同的服务
压缩传输和分块传输
HTTP 的实体部可以通过压缩再进行传输,这要求在首部指明压缩方式
Content-Encoding:gzip
压缩方式常用的有四种:gzip、compress、deflate(zlib)、identity(不进行编码)
在 HTTP 通信过程中,一次传输过程完成前数据是无法使用的,因此在传输大容量数据时,通过把数据进行分块,能够让浏览器逐步显示页面。这种把实体分块的功能称为 分块传输编码 ,其中每个小块被称为一个 Chunk
多类型数据的传输
MIME 拓展中使用了一种称为 多部分对象集合 的方法,用来在一次传输中容纳多份不同类型的数据。HTTP 也采用了此方法。
多对象集合包含对象如下:
MIME 类型 |
作用 |
multipart/form-data |
上传表单文件时使用 |
multipart/byteranges |
状态码 206 响应报文包含了多个范围的内容时使用 |
对于 multipart/form-data 来说,一个 POST 请求示例如下 1
POST /t2/upload.do HTTP/1.1
Content-Type:multipart/form-data; boundary=ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Host: w.sohu.com
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data; name="city"
Santa colo
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data;name="desc"
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
...
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data;name="pic"; filename="photo.jpg"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
... binary data of the jpg ...
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC--
其中 boundary 是自定义的分割符,而每次数据的形式为
<上个部分数据>
--分隔符
<首部字段>
<CRLF>
<data>
--分隔符
<下个部分数据>
--分隔符--
内容之间的分隔符形式为 –分隔符 ,结尾的分隔符为 –分隔符–
对于 multipart/byteranges 来说,一个响应报文的示例为
HTTP/1.1 206 Partial Content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Length: 1741
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES
--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 500-999/8000
...the first range...
--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 7000-7999/8000
...the second range
--THIS_STRING_SEPARATES--
范围请求
范围请求使得客户端能够指定只传输需要的实体部分字节流,这就实现了 HTTP 协议中的断点重传,在 HTTP 中,这种只传输指定范围字节的请求称谓 范围请求
一个使用范围请求的请求头例子为
GET /tip.jpg HTTP/1.1
Host www.abc.cn
Range: bytes =5001-10000
也可以传输 5001 之后全部的内容
Range: bytes=5001-
从起始到 3000 和 5000-7000 的多重范围
Range: bytes=-3000, 5000-7000
对于多重请求,相应状态码为 206。对于多重范围,相应报文的 MIME 格式为 multipart/byteranges。如果服务器无法响应范围请求,则会返回状态吗 200 OK 和完整报文
内容协商
服务器根据请求头可以返回合适的内容,例如根据请求头选择返回中文页面或者英文页面,这一过程称谓内容协商。内容协商需求的首部字段为:
Accept
Accept-Charset
Accept-Language
Content-Language
表单数据
表单中的 enctype 规定了以何种格式向服务器发送表单内容,有三种类型:
application/x-www-urlencoded
multipart/form-data
text-plain
其中 application/x-www-urlencoded 是默认类型
GET 请求只支持 ASCII 字符集,因此,如果要发送更大字符集的内容,应使用 POST 请求
一个使用 application/x-www-urlencoded 的示例为
POST / HTTP/1.1
Content-Type:application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Host: w.sohu.com
Content-Length: 21
Connection: Keep-Alive
Cache-Control: no-cache
txt1=hello&txt2=world
实际上就是把 GET 中的数据放到了 Body 中,与 GET 并无二致
HTTP 状态码
状态码代表了服务器对客户端请求的处理结果,写在了相应报文的首部。响应报文可以粗略地分为五类:
类别 |
原因 |
|
|---|---|---|
1xx |
Informational(信息性状态码) |
接受的请求正在处理 |
2xx |
Success(成功状态码) |
请求正常处理完毕 |
3xx |
Redirection(重定向状态码) |
需要进行附加操作以完成请求 |
4xx |
Client Error(客户端错误状态码) |
服务器无法处理请求 |
5xx |
Server Error(服务器错误状态码) |
服务器处理请求出错 |
除了 RFC 2616 记载的状态码外,WebDAV 所属的 RFC 4918 和 RFC 5842 等等也定义了大量状态码。只要遵循状态码类别的定义,即使改变 RFC 2616 定义的状态码,或者是自行创建状态码都是允许的。尽管如此,HTTP 常用的状态码只有 14 种:
状态码 |
含义 |
|---|---|
200 OK |
客户端发送的请求被正常处理了 |
204 No Content |
请求被正常处理,但是响应报文中不含实体的主体部分。一般发生在只需要从客户端发送信息的情况下 |
206 Partial Content |
客户端发送的范围请求被正确处理 |
301 Moved Permanently |
永久重定向。请求的资源被分配了新的 URI |
302 Found |
临时重定向。请求的资源被分配了新的 URI |
303 See Other |
与 302 类似。但是 303 要求客户端应当使用 GET 方法获取资源 |
304 Not Modified |
304 实际上和重定向无关。在未满足请求报文中的附带条件 2 时,响应报文不包含实体部 |
307 Temporary Redirect |
与 302 相同,但是要求不将 POST 变成 GET |
400 Bad Request |
请求报文中出现语法错误。此状态码在浏览器中视同 200 OK |
401 Unauthorized |
表示发送的请求需要有通过 HTTP 认证的认证信息。如果已经进行过一次认证,表明认证失败 |
403 Forbidden |
表示对请求资源的访问被服务器拒绝了。理由 可 写在实体部 |
404 Not Found |
服务器无法找到请求的资源。也可能是服务器拒绝请求并且不想说明理由 |
500 Internal Server Error |
服务器在执行请求时发生了错误。也可能是服务器的 Bug 或者某些临时故障 |
503 Service Unavailable |
服务器超负载或者正在停机维护,现在无法响应请求 |
备注
实际上,很多浏览器将 301、302 视同 303 进行处理,尽管 301、302 不允许将 POST 改为 GET
- 2
附带条件的请求指的是 GET 请求报文中包含了 If-Match, If-Modified-Since, If-None-Match, If-Range, If-Unmodified-Since 至少其中之一
协同技术
服务器还催生了一些其它技术。例如虚拟主机、代理、隧道等。
虚拟主机:将多个域名映射到一台主机上,然后服务器根据请求报文中的 Host 将请求转发给对应的网站处理。这样就可以使用一台主机搭建多个 Web 站点。
代理:代理服务器充当中间人,将客户端的请求发送给服务器,然后将服务器的响应报文发给客户端。如果在转发过程中没有更改报文,那么称为 透明代理 。如果代理会预缓存资源,那么称为 缓存代理
网关:网关与代理类似,但是网关能将使服务器提供非 HTTP 协议服务。例如在客户端和网关之间进行加密等。
隧道:隧道按要求建立一条与其它服务器的通信链路,从而保障通信的安全性
HTTPS
相比 HTTP 通过 TCP 发送报文而言,HTTPS 通过 SSL 发送报文。而 SSL 提供了双端加密。
提示
SSL 是应用层协议,而不是运输层协议。SSL 使用 TCP 作为运输层协议
在 SSL 的通信过程中。SSL 首先使用非对称加密来构建传输通道,然后双方约定对称加密密码,并使用对称密码来传输内容。之所以如此,是因为非对称加密安全性高但是加密解密慢,而对称加密安全性低,却加密解密快。
在 HTTPS 通信过程中,首先双方交换公钥,然后再进行 SSL 加密过程。
身份认证
CSRF
CSRF 即跨站请求伪造,是指利用受害者尚未失效的身份认证信息(cookie、会话等),诱骗其点击恶意链接或包含攻击代码的页面 3
以下哪个是可以执行的CSRF漏洞的修复方案(A)[#bcsrf]_
检测HTTP referer 字段同域
过滤单引号或尖括号
在每个请求里面都添加验证码校验
cookie 关键字段设置HttpOnly属性