基于HTTP报文分析HTTP协议

关于HTTP

HTTP(HyperText Transfer Protocol, 缩写:HTTP),是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是基于文本的协议,也就是说我们可以很直观的看到每个HTTP报文的相关内容,基于此前提,本文通过分析对应的HTTP报文来了解HTTP协议的相关信息。

关于URI

在了解HTTP协议之前,有必要先了解一下URI,毕竟HTTP协议是基于URI来实现的。

URI定义

每个Web服务器资源都有一个名字,被成为URI (Uniform Resource Identifier),用于在世界范围内标识并定位信息资源。

关于URL

URL (Uniform Resource Locator)是URI最常见的一种形式,用于描述一台特定服务器上某资源的特定位置,它可以明确的说明如何从一个精确、固定的位置获取资源。

URL的标准格式

大多数URL方案的URL语法都建立在由以下9部分构成的通用格式上:

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

其中:

组件 描述 默认值
schema 访问服务器获取资源时要使用哪种协议
user 某些方案访问时所需要的用户名 匿名
password 某些方案访问时所需要的密码
host 资源服务器的主机名或这IP
port 资源服务器所监听的端口号 与协议相关
path 资源在服务器上的路径,使用/与前面组件隔开
params 某些方案使用此组件来输入参数,参数为名/值对;可以包含多个参数字段,相互之间及与路径使用”;”隔开
query 某些方案使用此组件来传递参数,用”?”将其与URL的其余部分分隔
frag 用来标识资源的某个片段,用”#”将其与URL的其余部分分隔


事实上,几乎没有哪个URL中包含了以上所有组件;其中最为重要的是schema、host、path。

例如:

https://twitter.com/Jiasheng_Lee
http://ljsalm089.github.io/git/2015/11/10/Android项目版本管理.html

URL encode

因一些协议在实现传输的过程中,会剥去一些特定的字符;且在使用URL的过程中,一些字符因有特殊的意义而被保留。为了避开这两种限制,人们设计了一种编码机制,通过“转义”来表示对应的非安全字符及关键字符。

这种转义表示法包含一个”%”,后面跟随两个标识字符ASCII码的十六进制数。

下表列出了保留及受限的字符:

字符 保留/受限
% 保留作为编码字符的转义标志
/ 保留作为路径组件中分隔路径的定界符
. 保留在路径组件中使用
.. 保留在路径组件中使用
# 保留作为分段定界符使用
? 保留作为查询字符串定界符使用
; 保留作为参数定界符使用
: 保留作为协议、用户/密码,以及主机/端口组件的定界符使用
$, + 保留
@&= 在某些方案的上下文中有特殊的含义,保留
{}\|\^~[]’ 由于各种传输Agent代理,比如各种网关的不安全处理,使用受限
<>” 不安全,这些字符在URL范围之外通常是有意义的
0x00-0x1F, 0x7F 受限,这些十六进制范围内的字符都在US-ASCII字符集的不可打印区间内
>0x7F 受限,十六进制值在此范围内的字符都不在US-ASCII字符集的二进制范围内


URL转义Demo:

http://ljsalm089.github.io/git/2015/11/10/Android项目版本管理.html ——> http://ljsalm089.github.io/git/2015/11/10/Android%E9%A1%B9%E7%9B%AE%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86.html

HTTP报文

所有的HTTP报文都可以分为两类:请求报文和**响应报文。

HTTP报文Demo

HTTP请求报文:



HTTP响应报文:



HTTP报文是简单的格式化数据块,它们由三部分组成:

  • 对报文进行描述的起始行
  • 包含属性的首部(header)
  • 可选的、包含数据的主体(body)部分

起始行和首部是有行分隔的ASCII文本,每行都以一个CRLF(回车换行)作为结束;报文的主体是一个可选的数据块,可包含文本或者二进制数据,也可为空。HTTP报文的首部以一行空行结束,即使没有头部和实体也应如此。

HTTP报文语法

请求报文

以下是请求报文的格式:


  • method: 请求的方式,一个单词,例如:GET、HEAD或POST。具体方式参看文章末尾对应表格。
  • request-url: 所请求的资源的路径
  • version: 报文所使用的HTTP版本,格式如:HTTP/<主版本号>.<次版本号>
  • header: 可以有0或多个首部,每个首部都包含一个名字,后面跟着”:”,然后是一个可选的空格,接着是一个值,最后使用CRLF来作为一行的结束。首部是由一个CRLF来结束的。
  • entity-body: 实体的主体部分包含一个由任意数据组成的数据块。并非所有的报文都包含实体,有时报文只是以一个CRLF结束
响应报文

以下是响应报文的格式:


  • status-code: 响应状态码,用来描述请求请求过程中发生的情况。对应状态码解析参看文章末尾对应表格。
  • reason-phrase: 状态码的可读描述。
  • header: 同请求报文。
  • entity-body: 同请求报文。

关于HTTP报文格式的说明,则止于以上。而HTTP协议,则是基于此报文格式来进行实现并扩展的,而其中涉及到连接、代理、缓存、网关、隧道等,都是基于HTTP报文的header或者实体进行展开处理。

常用HTTP请求方法:

方法 描述 是否包含主体
GET 从服务器获取一份文档 N
HEAD 只从服务器获取文档的header N
POST 向服务器发送需要处理的数据 Y
PUT 将请求的body存储在服务器上 Y
TRACE 对可能经过代理服务器传送到服务器上的报文进行追踪 N
OPTIONS 决定可以在服务器上执行哪些方法 N
DELETE 从服务器上删除一份文档 N

状态码分类

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

常用状态码

状态码 原因短语 含义
200 OK 成功
401 Unauthorized(未授权) 需要输入用户名和密码
404 Not Found(未找到) 服务器无法找到所请求的URL对应的资源

未完待续