基于byte[]的HTTP协议头分析代码
基于byte[]的HTTP协议头分析代码
最近需要为组件实现一个HTTP的扩展包,所以简单地实现了HTTP协议分析。对于HTTP协议就不详细解说了网上的资料太丰富了,这里主要描述如何通过byte[]流分析出HTTP协议头信息。HTTP协议头有两个协议字符是比较重要的分别就是'\r\n'和':',前者要描述每个头信息的结束,而后则是属性名和属性值的分隔符号。
实现
由于并没有使用Stream来处理所以在分析的时候就不能使用ReadLine来的方便,只能通过分析byte来解决。估计有朋友会问直接把byte[]打包成Stream就方便了,其实主要是使用场问题,有可能一次过来的byte[]包括多个http请求。所以包装成stream用readline的方法成本高不划算。以下看下主体分析代码:
1 public bool Import(byte[] data, ref int offset, ref int count)
2 {
3 byte[] buffer = mBuffer;
4 while (count > 0)
5 {
6 buffer[mHeaderLength] = data[offset];
7 mHeaderLength++;
8 offset++;
9 count--;
10 if (mHeaderLength >= HEADER_BUFFER_LENGT)
11 throw new NetTcpException("header data too long!");
12 if (mBuffer[mHeaderLength - 1] == mWrap[1] && mBuffer[mHeaderLength - 2] == mWrap[0])
13 {
14 if (Action == null)
15 {
16 Action = Encoding.UTF8.GetString(buffer, mStartIndex, mHeaderLength - mStartIndex - 2);
17 mStartIndex = mHeaderLength;
18 }
19 else
20 {
21 if (mBuffer[mHeaderLength - 3] == mWrap[1] && mBuffer[mHeaderLength - 4] == mWrap[0])
22 {
23 if (mLastPropertyName != null)
24 {
25 this[mLastPropertyName] = Encoding.UTF8.GetString(buffer, mStartIndex, mHeaderLength - mStartIndex - 2);
26 }
27 return true;
28 }
29 else
30 {
31 if (mLastPropertyName != null)
32 {
33 this[mLastPropertyName] = Encoding.UTF8.GetString(buffer, mStartIndex, mHeaderLength - mStartIndex - 2);
34 mStartIndex = mHeaderLength;
35 mLastPropertyName = null;
36 }
37 }
38 }
39 }
40 else if (mBuffer[mHeaderLength - 1] == mNameEof[0] && mLastPropertyName == null)
41 {
42 mLastPropertyName = Encoding.UTF8.GetString(buffer, mStartIndex, mHeaderLength - mStartIndex - 1);
43 mStartIndex = mHeaderLength;
44 }
45
46 }
47 return false;
48
49 }代码比较简单,通过一次遍历buffer就把Http请求行为和相应用的头属性都分析出来的。由于一个byte[]有可能包括多个HTTP请求(特殊场景),所以参数上使用ref主要是通过外层这个byte[]是否有多个多header要处理。
单元测试
开发人员应该习惯写单元测试,好处是很明显就是实现的代码的可测性,如果可测性差那代码就要从设计上进行调整了。下面是针对以上代码的两种单元测试,主要测试分析代码在不同情况下是否可以良好地工作。
1 [TestMethod]
2 public void HeaderImport()
3 {
4 string header = "Post\r\nname:henry\r\nemail:\r\n\r\n";
5 byte[] data = Encoding.UTF8.GetBytes(header);
6 int offset = 0;
7 int count = data.Length;
8 byte[] buffer = new byte[1024 * 4];
9 HttpHeader hh = new HttpHeader(buffer);
10 if (hh.Import(data, ref offset, ref count))
11 {
12 Assert.AreEqual(hh.RequestType, "Post");
13 Assert.AreEqual(hh["name"], "henry");
14 Assert.AreEqual(hh["email"], "");
15 }
16
17 }
18
19 [TestMethod]
20 public void HeaderImport1()
21 {
22 string header = "Post\r\nname:henry\r\nemail:henryfan@msn.com\r\n\r\n";
23 byte[] data = Encoding.UTF8.GetBytes(header);
24 int offset = 0;
25 int count = data.Length;
26 byte[] buffer = new byte[1024 * 4];
27 HttpHeader hh = new HttpHeader(buffer);
28
29 if (hh.Import(data, ref offset, ref count))
30 {
31 Assert.AreEqual(hh.RequestType, "Post");
32 Assert.AreEqual(hh["name"], "henry");
33 Assert.AreEqual(hh["email"], "henryfan@msn.com");
34 hh = new HttpHeader(buffer);
35 }
36
37
38 header = "Get\r\nname:henry\r\n";
39 data = Encoding.UTF8.GetBytes(header);
40 offset = 0;
41 count = data.Length;
42 hh.Import(data, ref offset, ref count);
43
44
45 header = "email:henryfan@msn.com";
46 data = Encoding.UTF8.GetBytes(header);
47 offset = 0;
48 count = data.Length;
49 hh.Import(data, ref offset, ref count);
50
51 header = "\r";
52 data = Encoding.UTF8.GetBytes(header);
53 offset = 0;
54 count = data.Length;
55 hh.Import(data, ref offset, ref count);
56
57 header = "\n\r\n";
58 data = Encoding.UTF8.GetBytes(header);
59 offset = 0;
60 count = data.Length;
61
62 if (hh.Import(data, ref offset, ref count))
63 {
64 Assert.AreEqual(hh.RequestType, "Get");
65 Assert.AreEqual(hh["name"], "henry");
66 Assert.AreEqual(hh["email"], "henryfan@msn.com");
67 }
68
69 }
70 }
HttpHeader完整代码
开源多台平通讯组件
个性化网站信息收录和订阅平台
c#组件设计交流群:47164588
c# socket :136485198 微博http://weibo.com/ikende
基于byte[]的HTTP协议头分析代码的更多相关文章
- capwap协议重点分析
一. CAPWAP概述 CAPWAP由两个部分组成:CAPWAP协议和无线BINDING协议. (1)CAPWAP协议是一个通用的隧道协议,完成AP发现AC等基本协议功能,和具体的无线接入技术 ...
- 基于Qt的A*算法可视化分析
代码地址如下:http://www.demodashi.com/demo/13677.html 需求 之前做过一个无人车需要自主寻找最佳路径,所以研究了相关的寻路算法,最终选择A算法,因为其简单易懂, ...
- HTTP协议及其请求头分析
HTTP协议及其请求头分析 HTTP协议及其请求头分析 众所周知,Internet的基本协议是TCP/IP协议,目前广泛采用的FTP.Archie Gopher等是建立在TCP/IP协议之上的应用 ...
- 基于虎书实现LALR(1)分析并生成GLSL编译器前端代码(C#)
基于虎书实现LALR(1)分析并生成GLSL编译器前端代码(C#) 为了完美解析GLSL源码,获取其中的信息(都有哪些in/out/uniform等),我决定做个GLSL编译器的前端(以后简称编译器或 ...
- UNIX网络编程——分析一帧基于UDP的TFTP协议帧
下图是UDP的段格式: 相比TCP段格式,UDP要简单得多,也没啥好说的,需要注意的是UDP数据长度指payload加上首部的长度. 下面分析一帧基于UDP的TFTP协议帧: 以太网首部 0000: ...
- 分析一帧基于UDP的TFTP协议帧
下图是UDP的段格式: 相比TCP段格式,UDP要简单得多,也没啥好说的,需要注意的是UDP数据长度指payload加上首部的长度. 下面分析一帧基于UDP的TFTP协议帧: 以太网首部 0000: ...
- MySQL二进制日志分析-代码实现(FORMAT_DESCRIPTION_EVENT)
如前文概述,MySQL Binlog v3以前版本, 二进制日志文件的第一个事件是START_EVENT_V3, 从v4版本开始第一个事件为FORMAT_DESCRIPTION_EVENT(以下简称F ...
- Fixed-Length Frames 谈谈网络编程中应用层(基于TCP/UDP)的协议设计
http://blog.sina.com.cn/s/blog_48d4cf2d0101859x.html 谈谈网络编程中应用层(基于TCP/UDP)的协议设计 (2013-04-27 19:11:00 ...
- 苏宁基于Spark Streaming的实时日志分析系统实践 Spark Streaming 在数据平台日志解析功能的应用
https://mp.weixin.qq.com/s/KPTM02-ICt72_7ZdRZIHBA 苏宁基于Spark Streaming的实时日志分析系统实践 原创: AI+落地实践 AI前线 20 ...
随机推荐
- openstack 网络简史
openstack 网络简史 研究openstack有2个月的时间,这段时间从网上获取N多宝贵资料,对我的学习有非常大帮助,在加上我自己的研究,最终对openstack整个网络体系有了个浅显的认识,写 ...
- 设置韩澳大利亚sinox弄winxp清除字体和界面美观
澳大利亚开始与汉sinox一直以为接口暗淡,字体比较模糊,否winxp光明,导致眼比较辛苦的眼睛.比方说,可能不那么黯淡刺眼,有益眼睛,但我不能忍受字体模糊.即使调整分辨率,,但是字体模糊还是没有改观 ...
- CQRS模式实现
[.NET领域驱动设计实战系列]专题十:DDD扩展内容:全面剖析CQRS模式实现 一.引言 前面介绍的所有专题都是基于经典的领域驱动实现的,然而,领域驱动除了经典的实现外,还可以基于CQRS模式来进行 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(5)-前台JqueryEasyUI前台实现
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(5)-前台JqueryEasyUI前台实现 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框 ...
- CUMCM--总结
有些事情经历一次就好,一次的经历足以成长. 其实,对于数模真的没什么要说的,也没什么好写的.从9月11日,8点见到赛题,到今天早上8点的提交,短短的三天,度过寂静的黑夜,见到微曦的黎明.三天三夜,9个 ...
- hdu 2191 (多重背包+二进制优化)
Problem Description 急!灾区的食物依然短缺!为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品, ...
- Git批量删除
Git批量删除 git的改动都需要stage过程后才能commit.当git中有大量改动时就需要能够批量操作在方便.改动分三种: modify: 有文件修改 add: 有文件增加 rm: 有文件删除 ...
- Cloudera CDH 5集群搭建(yum 方式)
1 集群环境 主节点 master001 ~~ master006 从节点 slave001 ~~ slave064 2 安装CDH5的YUM源 rpm -Uvhhttp://ar ...
- C#操作Xml:XmlSerializer 对象的Xml序列化和反序列化
这篇随笔对应的.Net命名空间是System.Xml.Serialization:文中的示例代码需要引用这个命名空间. 为什么要做序列化和反序列化? .Net程序执行时,对象都驻留在内存中:内存中的对 ...
- windows编ffmpeg2.2.4和插件h265
0.前言 据说新出来了h265的视频,在迅雷看看上面看到的.网上查看了一下简单介绍,貌似h265的视频比h264的视频压缩率要高.并且能做4K的视频. 同一时候看到网上有人试过ffmpeg在编译的时候 ...
