深入http协议一

HTTP协议概念

HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传输协议。

HTTP是一个客户端终端(用户)和服务器端(网站)请求和应答的标准(TCP)。
通过使用Web浏览器、网络爬虫或者其它的工具,客户端发起一个HTTP请求到服务器上指定端口(默认端口为80)。我们称这个客户端为用户代理程序(user agent)。
应答的服务器上存储着一些资源,比如HTML文件和图像。我们称这个应答服务器为源服务器(origin server)。
在用户代理和源服务器中间可能存在多个“中间层”,比如代理、网关或者隧道(tunnel)。

HTTP在TCP/IP协议栈中的位置:

HTTP在TCP/IP协议栈中的位置

HTTP协议通常承载于TCP协议之上,有时也承载于TLS或SSL协议层之上,这个时候,就成了我们常说的HTTPS。

默认HTTP的端口号为80,HTTPS的端口号为443。

HTTP协议特点

  • 支持客户/服务器模式。
  • 简单快速,客户向服务器请求服务,只需传送请求方法和路径。
  • 灵活,允许传输任意类型的数据对象。
  • 无连接,每次连接只处理一个请求。
  • 无状态,HTTP 协议是无状态协议。

HTTP 使用的是可靠的数据传输协议,因此即使数据来自地球的另一端,它也能够确保数据在传输的过程中不会被损坏或产生混乱。

HTTP请求流程

访问一个网址http://www.codewhere.cn/index.php时,发生了些什么?

  1. 用户在浏览器中输入网址
  2. 浏览器拿到网址后通过DNS 查询它的ip地址
  3. DNS服务器根据网址返回ip地址 114.113.144.74
  4. 浏览器得到地址后,和该地址建立一条通道(TCP连接)
  5. 浏览器向服务器发出一个请求,包括 URL,协议版本号(http 1.0等),协议头(请求的方法get,客户端cookie,agent信息等等),协议内容等等
  6. 服务器拿到请求后,根据请求中的内容找相应的数据,如果不能正常拿到,返回一个错误码(例如404),如果能正常拿到,返回一坨内容(包括正常的状态码,header头,例如是否压缩,是否分段传输等等.返回实体内容,例如页面的内容)
  7. 断开连接吗?一般情况下,服务器就关闭了tcp连接,但是如果有Connection:keep-alive,则不会关闭tcp,下次有请求的时候还是用同一个连接了(http/1.1)
  8. 浏览器拿到返回的数据后,开始渲染html数据并展示给用户了.

所有能够提供Web 内容的东西都是Web 资源

HTTP协议之URL

HTTP URL (URL 是一种特殊类型的URI,包含了用于查找某个资源的足够的信息)的格式如下:http://host[":"port][abs_path]

  • http 表示要通过HTTP 协议来定位网络资源;
  • host 表示合法的Internet 主机域名或者IP 地址;
  • port 指定一个端口号,为空则使用缺省端口80;
  • abs_path 指定请求资源的URI;如果URL 中没有给出abs_path,那么当它作为请求URI 时,必须以“/”的形式给出,通常这个工作浏览器自动帮我们完成。

URL编码

RFC3986文档规定,Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符。
保留字符
保留字符

其他字符均需要经过编码之后才能出现在Url中。
关于url中的汉字的编码参考这里:
http://www.ruanyifeng.com/blog/2010/02/url_encoding.html

HTTP请求

http 请求由三部分组成:请求行、消息报头、请求正文
请求行以一个方法符号开头,以空格分开,后面跟着请求的URI 和协议的版本,格式如下:
Method Request-URI HTTP-Version CRLF

  • Method 表示请求方法;
  • Request-URI 是一个统一资源标识符;
  • HTTP-Version 表示请求的HTTP 协议版本;
  • CRLF 表示回车和换行(除了作为结尾的CRLF 外,不允许出现单独的CR 或LF 字符)。

下面是访问百度时的请求头:
请求头

请求方法

  • GET    请求获取Request-URI 所标识的资源
  • POST   在Request-URI 所标识的资源后附加新的数据
  • HEAD   请求获取由Request-URI 所标识的资源的响应消息报头
  • PUT    请求服务器存储一个资源,并用Request-URI 作为其标识
  • DELETE  请求服务器删除Request-URI 所标识的资源
  • TRACE   请求服务器回送收到的请求信息,主要用于测试或诊断
  • CONNECT  保留将来使用
  • OPTIONS  请求查询服务器的性能,或者查询与资源相关的选项和需求

HTTP响应

在接收请求消息后,服务器返回一个HTTP 响应消息。
HTTP 响应也是由三个部分组成:状态行、消息报头、响应正文
状态行格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF

  • HTTP-Version 表示服务器HTTP 协议的版本
  • Status-Code 表示服务器发回的响应状态代码
  • Reason-Phrase 表示状态代码的文本描述

eg:HTTP/1.1 200 OK (CRLF)

下图是访问百度的http response
请求头

响应状态码

  • 1xx:指示信息–表示请求已接收,继续处理
  • 2xx:成功–表示请求已被成功接收、理解、接受
  • 3xx:重定向–要完成请求必须进行更进一步的操作
  • 4xx:客户端错误–请求有语法错误或请求无法实现
  • 5xx:服务器端错误–服务器未能实现合法的请求

常见状态代码

  • 200 (成功) 服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。
  • 301 (永久移动) 请求的网页已永久移动到新位置。服务器返回此响应(对 GET 或 HEAD + 请求的响应)时,会自动将请求者转到新位置。
  • 302 (临时移动)服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
  • 304 (未修改) 自从上次请求后,请求的网页未修改过。服务器不会返回网页内容。
  • 403 (禁止) 服务器拒绝请求。
  • 404 (未找到) 服务器找不到请求的网页。
  • 500 (服务器内部错误) 服务器遇到错误,无法完成请求。
  • 502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
  • 504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。

  (请求|响应)正文

报头和正文之间是一个空行,这个行非常重要,它表示报头已经结束,接下来的是正文。
请求正文中可以包含客户提交的查询字符串信息:
username=jinqiao&password=1234
响应正文就是要传输的内容。内容可以是二进制的、压缩的、未压缩的、英语、中文等等任何允许的资源类型。

报文就是箱子,正文就是货物。

消息报头(首部)

HTTP 消息报头包括普通报头、请求报头、响应报头、实体报头、扩展报头。

每一个报头域都是由名字+冒号+可选的空格+值组成,消息报头域的名字是大小写无关的。

利用telnet观察http协议的通讯过程

打开telnet
cmd -> telnet

打开telnet回显功能
set localecho

连接服务器并发送请求
open www.baidu.com 80 ##注意端口号不能省略,telnet默认是23

发送http请求
HEAD / HTTP/1.1
Host: www.baidu.com