HTTP 协议解析

来源:互联网 发布:nginx 防ddos攻击 编辑:程序博客网 时间:2024/06/05 08:44

HTTP协议简介

超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是互联网上应用最为广泛的一种网络协议。设计HTTP最初的目的是为了

提供一种发布和接收HTML页面的方法。通过HTTP或者HTTPS协议请求的资源由统一资源标识符(Uniform Resource Identifiers,URI)来标识。

HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是基于TCP/IP的无连接,无状态的协议(每一个HTTP报文

不依赖于其前面的报文状态)。HTTP假定其下层协议提供可靠的传输。因此也就是其在TCP/IP协议族使用TCP作为其传输层。

如图为我们常说的tcp/ip协议栈。Internet四层网络模型(也叫TCP/IP四层模型)包括数据链路层(网络接口)、网络层、传输层和应用层。

                                   

 HTTP协议的主要特点可概括如下:

  简单:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的不同类型。
              由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。

 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。

 请求-响应模式:客户端每次向服务器发起一个请求时都建立一个连接, 服务器处理完客户的请求即断开连接。

 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能

                导致每次连接传送的数据量增大。

HTTP工作流程

HTTP,是符合C/S模型的,总是Client端来发起请求。

1、客户机(浏览器)主动向服务器(web   server)发出连接请求。 

2、服务器接受连接请求并建立起连接。 (1,2步即我们所熟知的TCP三次握手)

3、客户机通过此连接向服务器发出GET等http命令,(“HTTP请求报文”)。

4、服务器接到命令并根据命令向客户机传送相应的数据,(“HTTP响应报文”)。

5、客户机接收从服务器送过来的数据。

6、服务器发送完数据后,主动关闭此次连接。 (”TCP四次分手“)。

概况起来就是 客户/服务器传输过程可分为四个基本步骤:

  1) 浏览器与服务器建立连接; (TCP三次握手)

  2) 浏览器向服务器请求文档;

  3) 服务器响应浏览器请求;

  4) 断开连接。(”TCP四次分手“)

HTTP协议的URL,URI介绍

HTTP协议中的URL(URL是一种特殊类型的URI(Uniform Resource Identifier),包含了用于查找某个资源的足够的信息)

主要是用于定位服务器端资源的位置。我们来看下它的语法定义:

http://host[:port][path]

其中:

http:// 表示我们要使用HTTP协议;

host 表示一个可用的域名或IP地址;

port 为可选,表示要请求的端口号,缺省情况下为80

path 为可选,表示要请求的资源所在的路径(也叫URI),缺省情况下为/ ,如果URL中没有给出path,那么当它作为请求URI时,

必须以“/”的形式给出,比如浏览器中输入: www.abc.edu.cn 则浏览器自动换成 www.abc.edu.cn/ 。

HTTP协议结构

HTTP协议格式比较简单,格式如下:

                                            

由上图也可以看出来  HTTP 有两类报文:

请求报文——从客户向服务器发送请求报文。

响应报文——从服务器到客户的回答。

请求报文

请求报文 报文格式如下:

                                                    

空白行用CR LF对表示。CR LF对是回车(Carriage Return,CR)和换行(Line Feed,LF)字符的ASCII码,它表示报头组件的结束。

为了深入理解HTTP 协议请求报文,下面直接来一个例子:

GET /t5/style/css/module/base/home_frame.css?version=cc73de6cd25d6dbf HTTP/1.1/* 第一行叫做请求行(request),其他的各行都叫做头部行(header)请求行包括三个字段:方法字段、URI字段、HTTP版本字段 这个例子的请求行,是要做这样一件事:用HTTP协议1.1版本,使用GET方法,向服务端申请/t5/style/css/module/base/home_frame.css?version=cc73de6cd25d6dbf资源 *//* 下面都属于头部行 */Host: img.t.sinajs.cn/* Host用来指定要请求的服务器端主机为img.t.sinajs.cn,呵呵是新浪的*/User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:26.0) Gecko/20100101 Firefox/26.0 /* User-agent域则是用来指定当前这个请求报文是由谁产生的,通常来说,一般这里设置的是用户所使用的浏览器类型。*/Accept: text/css,*/*;q=0.1Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3 /* Accept-language域,客户端所能识别的语言 如果没有 则 采取默认语言 */Accept-Encoding: gzip, deflate/*客户端所能识别的编码压缩格式 gzip*/Referer: http://weibo.com/840450770/home=5&page=2&pre_page=1&end_id=3664048949921640&end_msign=-1Connection: keep-alive/* 这里有一个空行,而且是必须有这个空行。这是HTTP协议的硬性规定。 */
请求报文段就是下面这样,细细琢磨吧。

GET /t5/style/css/module/base/home_frame.css?version=cc73de6cd25d6dbf HTTP/1.1
Host: img.t.sinajs.cn
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:26.0) Gecko/20100101 Firefox/26.0
Accept: text/css,*/*;q=0.1
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://weibo.com/840450770/home?wvr=5&page=2&pre_page=1&end_id=3664048949921640&end_msign=-1
Connection: keep-alive

HTTP 请求方法概述:

                         

客户程序向服务器发送的请求可以有不同的类型,这样服务器可以根据不同的请求类型进行不同的处理。

响应报文

响应报文格式如下:

                                      

  一般情况下,服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息。HTTP的响应消息也是由三个部分组成,

分别是:状态行、消息报头、响应正文。

应用举例:

 /* 第一行是状态行,包括三个字段:版本字段、状态码字段、原因短语字段 */HTTP/1.1 200 OK/* 本例中,HTTP协议的响应报文想表达的意思是服务器使用的是HTTP协议1.1版本,   而且找到了客户端所要的资源,且会将响应报文发给客户端,整个过程都很正常 */Expires: Wed, 22 Jan 2014 02:51:09 GMT/*给出响应过期的日期和时间。为了让代理服务器或浏览器在一段时间以后更新缓存中(再次访问曾访问过的页面时,直接从缓存中加载,缩短响应时间和降低服务器负载)的页面,我们可以使用Expires指定页面过期的时间)*/Date: Tue, 07 Jan 2014 02:51:09 GMT/* 这里记录了这个响应报文被发送出去的时间点 */Server: nginx/1.4.2/* Server域表明这个响应报文是nginx服务器发出的,且nginx的版本是1.4.2 */Content-Type: text/css/* 指出所包含的数据是txt/css文本内容 */Last-Modified: Mon, 06 Jan 2014 07:50:31 GMT/* 用于记录本响应报文中所存的数据的最后修改时间 */Transfer-Encoding: chunked/*服务端向客户端传输数据所采用的传输模式(仅在HTTP1.1中出现)*/Cache-Control: max-age=1296000/*服务端要求中间代理及客户端如何缓存自己响应的数据*/Content-Encoding: gzip/*用于记录文档的压缩方法 gzip*/Age: 1X-Via: 1.1 whjyw137:3 (Cdn Cache Server V2.0)Connection: keep-alive/* 服务器端会保持住这个连接*/ /* 看这里,还得看这里,和请求报文类似,这里也有一个空行 */  (实际数据 …………)
响应报文,原报文如下:

HTTP/1.1 200 OK
Expires: Wed, 22 Jan 2014 02:51:09 GMT
Date: Tue, 07 Jan 2014 02:51:09 GMT
Server: nginx/1.4.2
Content-Type: text/css
Last-Modified: Mon, 06 Jan 2014 07:50:31 GMT
Transfer-Encoding: chunked
Cache-Control: max-age=1296000
Content-Encoding: gzip
Age: 1
X-Via: 1.1 whjyw137:3 (Cdn Cache Server V2.0)
Connection: keep-alive

835a
?

HTTP状态码

状态码都是三位数字 ,第一位表示状态类别,共分五种,如下图:

                                       

其实常用的状态码并不多,我们把常见的列举在此:
    200 OK:客户端请求成功了,客户端要的东西就在响应报文里了;

    301 Moved Permanently:客户端啊,你要请求的资源已经永久的搬家了,我把他的新地址放到了Location头部域中了;

    302 Moved Temporarily:客户端啊,你要请求的资源临时有事去别的地方了,我把他的位置放到了Location头部域中了,

            你可以先去那里找他,不过他应该是会回到他自己的家的;

    304 Not Modified:客户端啊,你要请求的资源自从上次你请求之后,就再也没有改动过,我想你是应该早就有这个资源了,

             所以在响应报文的数据部分我也没有再放这个资源。

    400 Bad Request:客户端发来的请求报文里有语法错误,服务器端实在看不懂了;

    401 Unauthorized:客户端发来的请求不是合法来源的请求,也就是这个客户端是没有被授权的;

    403 Forbidden:服务器端顺利收到了客户端的请求,但是因为某些理由,服务器端拒绝为他提供服务;

    404 Not Found:客户端要请求的资源不存在,八成是资源地址写错了;

    500 Internal Server Error:很遗憾,服务器不能给你提供服务了,服务器内部出现了不可预知的问题了;

    502 Bad Gateway:客户端你好,我是请求报文的代理服务器,持有资源的那个服务器在给我发送资源时出问题了;

    503 Server Unavailable:服务器现在可能是太忙了,暂时不能给你这个客户端提供服务了,或许稍后会恢复。

HTTP常见问题

HTTP协议是无状态的和Connection: keep-alive的区别

  无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。从另一方面讲,打开一个服务器上的网页和你之前打开这个服务器上的

  网页之间没有任何联系。HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。

 从HTTP/1.1起,默认都开启了Keep-Alive,保持连接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,

 如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件

(如Apache)中设定这个时间。

更多知识请参考 相关RFC文档。

参考资料:

http://www.rfc-editor.org/info/rfc2616

http://blog.csdn.net/daniel_ustc/article/details/12043469

http://my.oschina.net/johnsony/blog/113090

http://my.oschina.net/aiguozhe/blog/41313

http://roclinux.cn/?p=3450#more-3450





15 0