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--
1

深入解析 multipart/form-data

范围请求

范围请求使得客户端能够指定只传输需要的实体部分字节流,这就实现了 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 4918RFC 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]_

  1. 检测HTTP referer 字段同域

  2. 过滤单引号或尖括号

  3. 在每个请求里面都添加验证码校验

  4. cookie 关键字段设置HttpOnly属性

3

CSRF跨站请求伪造漏洞修复方案

4

以下哪个是可以执行的CSRF漏洞的修复方案