HTTP协议请求消息与应答消息抓包详解

在讲解抓包实例之前,我们先来了解一点相关的基础知识。

 HTTP(HyperText Transfer Protocol)超文本传输协议。它是一种无状态的协议。也就是说,服务器在发送应答后,不会保留关于客户端的任何信息,因此也无法分辨来自于同一客户端的多个请求可能是相关的。

HTTP请求消息包括:请求行,请求首部,有时还有请求主体。

请求行以请求方法名开始,后面是资源标识符,以及浏览器所使用的协议版本。

如:GET/index.html   HTTP/1.1

最常用的请求方法叫做GET(GET请求用于从服务器上取得资源。它是默认的请示方法,所以,如果你在浏览器的地址栏里键入了一个URL,或单击了一个链接,那么你的请求将作为一个GET请求发送给服务器)

请求首部提供了服务器在处理请求的过程中可能需要的附加信息。消息主体只在某些类型的请求中才会出现,例如后面将要讲到的Post请求。

如:一个有效的HTTP请求消息示例:

GET/index.html    HTTP/1.1(请求行)

HOST(请求首部):www.gefionsoftware.com(附加消息)

User-Agent:MoZilla/4.5 [en] (winNT:(I)

Accept:p_w_picpath/gif,p_w_picpath/jpeg,p_w_picpath/pjpeg,p_w_picpath/png,*/*

Accep-Langeuage:en

Accept-Charset :iso-8859-1,*,UTF-8

(……请求主体)

请求行表示所使用的是GET方法,所请求的资源为/index.html,并通过HTTP/1.1版本的协议将其返回。各种请求首部都提供了附加信息。Host首部告诉服务器URL中所用到的主机名。User-Agent首部包含产生该请求的浏览器类型的信息。利用这个信息服务器便可以向不同类型的浏览器发送不同类型的应答。例如,如果服务器知道发送请求的服务器是Internet Explore还是NetScape Navigator,它就可以返回能利用每种服务器独有优点的应答。该项信息还能表示用户使用的是否为非HTML浏览器,例如,蜂窝电话或PDA设备上所用的WMLWireless Markup Language,无线标记语言)浏览器,并产生相应的应答。Accept首部提供了关于浏览器所能接受的语言和文件格式方面的信息。

 

WEB服务器收到请求时,它将看URI(统一资源标识符)并根据配置信息决定如何处理这个请求。它可以简单地从文件系统读入一个HTML文件来进行内部处理,也可以把请求转发给某个负责与該URI相对应的资源的组件。例如:这也许是一个使用数据库信息来动态产生相应应答的程序。对于浏览器来说,请求的处理方式无关紧要,它所关心的只是要得到一个应答。

应用消息与请求消息很相似。它也包括三个部分一:状态行,应答首部,还有可能出现的应答主体。

如:

HTTP/1.1  200 OK(状态行)

Last-Modified(应答首部) : Mon,20 Dec 2001 23 :26 :42 GMT

Date:Tue,11 Jan 2002 20:53:12 GMT

Status:200

Content-Type: Text/html

Servlet-Engine:

Content-Length:59

 

<html>(应答主体)

……

</html>

状态行以协议的名称开始,后面跟有状态代码。此处状态代码是200,表明请求已经被成功执行了。Last-Modified给出该资源最后一次修改的日期和时间,浏览器就可以让服务器只在资源自上次请求后又进行了更新时才返回该资源。Content-Type首部千知浏览器应答主体中包括了叧种类型的应答数据,Content_length首部则显示了数据的大小。首部和消息主体之间用一个空行分隔开。在这里,消息主体是一个简单的HTML页面.

   请求方法get,它用于从服务器上取得某种资源,而不引用服务器的任何其他行为。Post访求与get方法一样常用,该方法用于请求服务器执行某个处理过程,例如更新数据库或处理一份交易订单。

   请求参数:1.以查询字符串的形式附加在URI的后面。2作为请求消息主体一部分发送。查询字符串以一个问号(?)开始,由‘&’符号所分隔的名称/值对组成。语法:由&符号分隔的,经过URL编码的名称/值对。也就是说,像空格、问号,&符号以及其他所有不是字母和数字的特殊字母都需要经过编码,这样才不会和用来分隔名称/值对和URI其他部分的那些符号相混淆。空格会被编码成+符号,问号会被编码成为%3F.

    GetPost请求之间最明显的区别之一是参数的传递方式。GET请示通常使用查询字符串来发送参数值,而Post请示通常是把参数作为请求主体的一部分来发送的(另外,Post也可以用查询字符串的形式发送参数)

如果你在一个HTML页面中使用<a>元素插入了一个链接,那么单击这个链接就会服务器发出一个GET请求。由于GET请求使用查询字符串来传递参数,因此可以在URI链接里直接写入参数值:

如:

<a href=”/forecast.html?city=Bei+Jin&state=CA”>

……

</a>

当使用表单来把用户输入发送给服务器时,可以使用method属性来指定使用GET方法还是使用Post方法。

<form  action=”/forecast.html” method=”post”>

City:<input name=”city” type=”text”/>

State<input name=”State” type=”text”/>

<input type=”submit” />

</form>

如果用户在表单字体中输入了”Bei Jin””CA”,并单击了submit(提交)按钮,浏览器将向服务器发送如下请求消息:

Post/forecast.html HTTP/1.1

Host:www.sina.com

User-Agent:Mozilla/4.5[en] (winNT.I)

Accept-p_w_picpath/gif,p_w_picpath/JPEG,p_w_picpath/Pjpeg,*/*

Accept-language:en

Accept-Charset :iso-8939-1,*,UTF-8

 

  city=Bei+Jin&state=CA

 

由于GetPost请求在参数传递方式上的不同,以及它们在目的上的不同,因此浏览器将以不同的方式来处理请求。一个GET请求包括参数等,都可以很容易地作为书签保存下来,硬编码为一个固定的链接,而应答将被保存在浏览器的缓存中。而且,浏览器知道,如果它自动地重新发送一次GET请求的话(例如,如果用户单击了Reload按钮),将不会造成任何的破坏。另一方面,Post请求则无法很容易地被保存成书签,浏览器必须同时保存URI和请求消息主体。由于Post请求的目的是在服务器上执行某些不可逆的动作,所以每当浏览器要重新发送同一请求的时候,都必须询问用户是否确定。

实例分析:

这里客户机的IP172.16.10.107/24,web服务器IP172.16.10.4/24.用的是TomcatWEB容器解析。Test1为服务器主目录下的一个已发布了的工程。

GrapPost.htmlindex.jspTest1工程下的两个文档

文档内容分别为:

GrapPost.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">

<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>无标题文档</title>

</head>

<body>

<form  action="#" method="post">

<input type="submit" value="submit" />

<input type="text" name="text"/>

</form>

</body>

</html>

 

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>

<%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

    <base href="<%=basePath%>">   

    <title>My JSP 'index.jsp' starting page</title>

     <meta http-equiv="pragma" content="no-cache">

     <meta http-equiv="cache-control" content="no-cache">

     <meta http-equiv="expires" content="0">   

     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

     <meta http-equiv="description" content="This is my page">

     <!-- <link rel="stylesheet" type="text/css" href="styles.css">    -->

  </head> 

  <body>

    This is my JSP page. <br>

  </body>

</html>

使用Wireshark工具进行抓包的测试。

下图为客户机的浏览器中输入http://172.16.10.4:8080/test1/index.jsp后在Wireshark工具中截的主图与追踪TCP流得到子图。

 

 

下图为客户机的浏览器中输入http://172.16.10.4:8080/test1/GrapPost.html,然后在文本框中输入了123456后在Wireshark工具中截的图。

注意:我们可以发现第二个请求行GET后面的资源列表中含有请求页面提交的参数信息text=123456,因为是GET请求方式,所以在请求参数在请求行的URI后面。

下图为客户机的浏览器中输入http://172.16.10.4:8080/test1/ index.jsp后在Wireshark工具中截的图。

注意:我们可以发现第二个请求主体中含有请求页面提交的参数信息text=0000,因为是Post请求方式,所以在请求参数在请求主体中。