基于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完整代码

 

基于byte[]的HTTP协议头分析代码的更多相关文章

  1. capwap协议重点分析

    一.     CAPWAP概述 CAPWAP由两个部分组成:CAPWAP协议和无线BINDING协议. (1)CAPWAP协议是一个通用的隧道协议,完成AP发现AC等基本协议功能,和具体的无线接入技术 ...

  2. 基于Qt的A*算法可视化分析

    代码地址如下:http://www.demodashi.com/demo/13677.html 需求 之前做过一个无人车需要自主寻找最佳路径,所以研究了相关的寻路算法,最终选择A算法,因为其简单易懂, ...

  3. HTTP协议及其请求头分析

    HTTP协议及其请求头分析 HTTP协议及其请求头分析   众所周知,Internet的基本协议是TCP/IP协议,目前广泛采用的FTP.Archie Gopher等是建立在TCP/IP协议之上的应用 ...

  4. 基于虎书实现LALR(1)分析并生成GLSL编译器前端代码(C#)

    基于虎书实现LALR(1)分析并生成GLSL编译器前端代码(C#) 为了完美解析GLSL源码,获取其中的信息(都有哪些in/out/uniform等),我决定做个GLSL编译器的前端(以后简称编译器或 ...

  5. UNIX网络编程——分析一帧基于UDP的TFTP协议帧

    下图是UDP的段格式: 相比TCP段格式,UDP要简单得多,也没啥好说的,需要注意的是UDP数据长度指payload加上首部的长度. 下面分析一帧基于UDP的TFTP协议帧: 以太网首部 0000: ...

  6. 分析一帧基于UDP的TFTP协议帧

    下图是UDP的段格式: 相比TCP段格式,UDP要简单得多,也没啥好说的,需要注意的是UDP数据长度指payload加上首部的长度. 下面分析一帧基于UDP的TFTP协议帧: 以太网首部 0000: ...

  7. MySQL二进制日志分析-代码实现(FORMAT_DESCRIPTION_EVENT)

    如前文概述,MySQL Binlog v3以前版本, 二进制日志文件的第一个事件是START_EVENT_V3, 从v4版本开始第一个事件为FORMAT_DESCRIPTION_EVENT(以下简称F ...

  8. Fixed-Length Frames 谈谈网络编程中应用层(基于TCP/UDP)的协议设计

    http://blog.sina.com.cn/s/blog_48d4cf2d0101859x.html 谈谈网络编程中应用层(基于TCP/UDP)的协议设计 (2013-04-27 19:11:00 ...

  9. 苏宁基于Spark Streaming的实时日志分析系统实践 Spark Streaming 在数据平台日志解析功能的应用

    https://mp.weixin.qq.com/s/KPTM02-ICt72_7ZdRZIHBA 苏宁基于Spark Streaming的实时日志分析系统实践 原创: AI+落地实践 AI前线 20 ...

随机推荐

  1. 为代码减负之<二>存储过程(SQL)

    在上篇博客中介绍到了触发器的使用,而且当中也提到了触发器是个特殊的存储过程,那么什么是存储过程呢?他们 两个又究竟有什么差别呢? 事实上最基本的差别就是,触发器是当满足条件时系统自己主动运行的,而存储 ...

  2. 【剑指offer】堆栈推弹出序列

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/26077863 剑指offer上的第22题,九度OJ上AC. 题目描写叙述: 输入两个整数序 ...

  3. 第3章 抽象工厂模式(Abstract Factory)

    原文 第3章 抽象工厂模式(Abstract Factory) 场景我们的系统要同时支持两个数据库  SqlServer 跟Oracle数据库  并且不同的环境要进行随时切换. 看下面的代码: 1 2 ...

  4. Hard Parse&Soft Parse

    DDL每次运行将必须是难以解决. SQL 解析过程 Oracle对此SQL将进行几个步骤的处理过程: 1.语法检查(syntax check): 检查此sql的拼写是否语法. 2.语义检查(seman ...

  5. linux_vim_快捷键

    1.vim ~/.vimrc 进入配置文件 如果不知道vimrc文件在哪,可使用 :scriptnames 来查看 set nu #行号 set tabstop=4 #一个tab为4个空格长度 set ...

  6. 【转】Java 工程师成神之路

    一.基础篇 1.1 JVM 1.1.1. Java内存模型,Java内存管理,Java堆和栈,垃圾回收 http://www.jcp.org/en/jsr/detail?id=133 http://i ...

  7. Qunit 和 jsCoverage使用方法

    Qunit 和 jsCoverage使用方法(js单元测试) 近日在网上浏览过很多有关js单元测试相关的文档,工具,但是,针对Qunit 和 jsCoverage使用方法,缺少详细说明,对于初入前端的 ...

  8. Java NIO的多路复用及reactor

    (from:http://developer.51cto.com/art/201112/306489.htm) 以下描述,为了说明问题,就提提历史(类似的东西,网上一搜一大把,但是希望你能在这里止步, ...

  9. NHibernate构建一个ASP.NET MVC应用程序

    NHibernate构建一个ASP.NET MVC应用程序 什么是Nhibernate? NHibernate是一个面向.NET环境的对象/关系数据库映射工具.对象/关系数据库映射(object/re ...

  10. [C#]设置或取消开机启动(注册表形式)

    原文:[C#]设置或取消开机启动(注册表形式) 使用代码: 代码效果: