深度解密HTTP通信细节

本文深入剖析HTTP通信的细节,通过工具抓取HTTP报文,从三次握手到请求响应,详细解读HTTP协议的各个组成部分,包括报文格式、状态码、编码、代理、缓存、Cookie等,旨在提升读者对HTTP协议的理解。
摘要由CSDN通过智能技术生成


上一篇 文章中,我们学会了用wireshark和tcpdump来分析TCP的“三次握手,四次挥手”,非常好用。这哥俩就是传说中的 锤子,拿着 锤子,看什么都像 钉子!在这篇文章中,我对准了 HTTP这颗钉子砸下去,咳咳。

为了对网络数据包的“流转”有更加深刻的理解,我在docker(远程)上部署一个服务,支持http方式调用。从客户端(本地)用http方式请求其中的一个接口,并得到响应数据。同时本地通过wireshark抓包,远程用tcpdump抓包,然后分析过程中的所有通信细节。悲剧是把美好的东西撕碎给人看,而我则是把复杂的东西撕碎了给人看。

文章稍长,请在看本文时保持耐心。我先通过工具获取HTTP通信的数据包,再来抽丝剥茧,深入二进制的天地里,解密HTTP所有的通信细节。分析过程中,由点到面,将相关知识串接起来。保证全篇读完之后,你对HTTP的理解会上升一个台阶!

HTTP报文截获

背景介绍

我手头现在有一个地理几何相关的服务,它提供一组接口对外使用。其中有一个接口是Fence2Area. 使用方传入一个围栏(由点的列表组成,点由<经度,纬度>表示)、点的坐标系类型(谷歌地图用的是wgs84, 国内腾讯、高德用的是soso, 而百度用的是另一套自己的坐标系),接口输出的则是围栏的面积。

我请求服务的“Fence2Area”接口,输入围栏(fence)顶点(lng, lat)坐标、坐标系类型(coordtype),输出的则是多边形的面积(area).

一次正常的请求示例url, 这个大家都不陌生(我用docker_ip代替真实的ip):

http://docker_ip:7080/data?cmd=Fence2Area&meta={
   "caller":"test","TraceId":"test"}&request={
   "fence":[{
   "lng":10.2,"lat":10.2}, {
   "lng":10.2,"lat":8.2}, {
   "lng":8.2,"lat":8.2}, {
   "lng":8.2,"lat":10.2}],"coordtype":2}

请求发出后,服务器进行处理,之后,客户端收到返回的数据如下:

{
   
    "data": {
   
        "area": 48764135597.842606
    },
    "errstr": ""
}

area字段表示面积,errstr表示出错信息,空说明没有出错。

抓包

在真正发送请求之前,需要进行抓包前的设置。在本地mac,我用wireshark; 而在远程docker上,我用tcpdump工具。

mac本地

设置wireshark包过滤器,监控本地主机和远程docker之间的通信。

ip.addr eq docker_ip

点击开始捕获。

远程docker

该服务通过7080端口对外提供,使用如下命令捕获网络包:

tcpdump -w /tmp/testHttp.cap port 7080 -s0

请求 && 分析

准备工作做完,我选了一个神圣的时刻,在本地通过浏览器访问如下url:

http://docker_ip:7080/data?cmd=Fence2Area&meta={
   "caller":"test","TraceId":"test"}&request={
   "fence":[{
   "lng":10.2,"lat":10.2}, {
   "lng":10.2,"lat":8.2}, {
   "lng":8.2,"lat":8.2}, {
   "lng":8.2,"lat":10.2}],"coordtype":2}

这样本地的wireshark和远程的tcpdump都能抓取到HTTP网络数据包。

关闭服务进程

正式请求之前,我们先看一下几种特殊的情形。

首先,关闭gcs服务进程,请求直接返回RST报文。

rst

如上图,我在请求的时候,访问服务端的另一个端口5010, 这个端口没有服务监听,和关闭gcs服务进程是同样的效果。可以看到,客户端发送SYN报文,但直接被远程docker RST掉了。因为服务端操作系统找不到监听此端口的进程。

关闭docker

关闭docker, 由于发送的SYN报文段得不到响应,因此会进行重试,mac下重试的次数为10次。

mac retry

先每隔1秒重试了5次,再用“指数退避”的时间间隔重试,2s, 4s, 8s, 16s, 32s. 最后结束。

重启docker

先进行一次正常的访问,随后重启docker。并再次在本地访问以上url, 浏览器这时还是用的上一次的端口,访问到服务端后,因为它已经重启了,所以服务端已经没有这个连接的消息了。因此会返回一个RST报文。

正常请求

服务正常启动,正常发送请求,这次请求成功,那是当然的,嘿嘿!

normal_req_wireshark

这是在mac上用wireshark捕获的数据包,共7个包,前三个包为3次握手的包,第四个包为HTTP层发送的请求数据,第五个包为服务端的TCP 确认报文,第六个包为服务端在HTTP层发送的响应数据,第七个包为mac对第六个包的确认报文。

重点来关注后面几个包,先看第四个包,

0x0000:  4500 0295 0000 4000 3606 623b ac17 ccdc
0x0010:  0a60 5cd4 db9b 1ba8 a59a 46ce 6d03 e87d
0x0020:  8018 1015 0ee7 0000 0101 080a 2e4c b2ef
0x0030:  0f20 3acf 4745 5420 2f64 6174 613f 636d
0x0040:  643d 4665 6e63 6532 4172 6561 266d 6574
0x0050:  613d 7b25 3232 6361 6c6c 6572 2532 323a
0x0060:  2532 3274 6573 7425 3232 2c25 3232 5472
0x0070:  6163 6549 6425 3232 3a25 3232 7465 7374
0x0080:  2532 327d 2672 6571 7565 7374 3d7b 2532
0x0090:  3266 656e 6365 2532 323a 5b7b 2532 326c
0x00a0:  6e67 2532 323a 3130 2e32 2c25 3232 6c61
0x00b0:  7425 3232 3a31 302e 327d 2c25 3230 7b25
0x00c0:  3232 6c6e 6725 3232 3a31 302e 322c 2532
0x00d0:  326c 6174 2532 323a 382e 327d 2c25 3230
0x00e0:  7b25 3232 6c6e 6725 3232 3a38 2e32 2c25
0x00f0:  3232 6c61 7425 3232 3a38 2e32 7d2c 2532
0x0100:  307b 2532 326c 6e67 2532 323a 382e 322c
0x0110:  2532 326c 6174 2532 323a 3130 2e32 7d5d
0x0120:  2c25 3232 636f 6f72 6474 7970 6525 3232
0x0130:  3a32 7d20 4854 5450 2f31 2e31 0d0a 486f
0x0140:  7374 3a20 3130 2e39 362e 3932 2e32 3132
0x0150:  3a37 3038 300d 0a55 7067 7261 6465 2d49
0x0160:  6e73 6563 7572 652d 5265 7175 6573 7473
0x0170:  3a20 310d 0a41 6363 6570 743a 2074 6578
0x0180:  742f 6874 6d6c 2c61 7070 6c69 6361 7469
0x0190:  6f6e 2f78 6874 6d6c 2b78 6d6c 2c61 7070
0x01a0:  6c69 6361 7469 6f6e 2f78 6d6c 3b71 3d30
0x01b0:  2e39 2c2a 2f2a 3b71 3d30 2e38 0d0a 5573
0x01c0:  6572 2d41 6765 6e74 3a20 4d6f 7a69 6c6c
0x01d0:  612f 352e 3020 284d 6163 696e 746f 7368
0x01e0:  3b20 496e 7465 6c20 4d61 6320 4f53 2058
0x01f0:  2031 305f 3133 5f36 2920 4170 706c 6557
0x0200:  6562 4b69 742f 3630 352e 312e 3135 2028
0x0210:  4b48 544d 4c2c 206c 696b 6520 4765 636b
0x0220:  6f29 2056 6572 7369 6f6e 2f31 322e 302e
0x0230:  3220 5361 6661 7269 2f36 3035 2e31 2e31
0x0240:  350d 0a41 6363 6570 742d 4c61 6e67 7561
0x0250:  6765 3a20 7a68 2d63 6e0d 0a41 6363 6570
0x0260:  742d 4
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值