Web安全实践(4)c#简单http编程示例

                                                                                                  作者:玄魂

前置知识:c# http协议

本系列导航http://www.cnblogs.com/xuanhun/archive/2008/10/25/1319523.html

安全技术区http://space.cnblogs.com/group/group_detail.aspx?gid=100566 

前言

   web安全实践系列主要是对《黑客大曝光——web应用安全机密与解决方案(第二版)》的内容做的实践研究和部分编程实现。所以如果您能完全理解那本书可以跳过本文章。

 

 

                                                                   正文

关于http编程我们可以采取套接字的方式遵循http协议来做。我采用的C#,对于http编程微软提供了已经封装好的类,WebRequest,WebResponse,HttpWebRequest,HttpWebResponse是常用的几个类,关于这些类的详细介绍请参考博客园内的其他文章,我只简单介绍我所用到的HttpWebRequest,HttpWebResponse类。抛砖引玉,因为做个好的http程序也是需要一定时间的,我这里给出的不是成型的工具,只是一个简单的例子,时间有限,望各位见谅。

HttpWebRequest

HttpWebRequest 类对 WebRequest 中定义的属性和方法提供支持,也对使用户能够直接与使用 HTTP 的服务器交互的附加属性和方法提供支持。

不要使用 HttpWebRequest 构造函数。使用 WebRequest.Create 方法初始化 HttpWebRequest 的一个新实例。如果 URI 的方案是 http:// https://,则 Create 将返回 HttpWebRequest 实例。

GetResponse 方法向 RequestUri 属性中指定的 Internet 资源发出同步请求并返回包含该响应的 HttpWebResponse 实例。可以使用 BeginGetResponse EndGetResponse 方法对 Internet 资源发出异步请求。

当要向 Internet 资源发送数据时,GetRequestStream 方法返回用于发送数据的Stream实例。BeginGetRequestStream EndGetRequestStream 方法提供对发送数据流的异步访问。

下面的示例为 URI http://www.contoso.com/ 创建 HttpWebRequest

HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("http://www.contoso.com/");

HttpWebResponse

此类包含对 WebResponse 类中的属性和方法的 HTTP 特定用法的支持。HttpWebResponse 类用于生成发送 HTTP 请求和接收 HTTP 响应的 HTTP 独立客户端应用程序。

注意:不要混淆 HttpWebResponse HttpResponse;后者用于 ASP.NET 应用程序,而且它的方法和属性是通过 ASP.NET 的内部 HttpResponse 对象公开的。

决不要直接创建 HttpWebResponse 类的实例。而应当使用通过调用 HttpWebRequest.GetResponse 所返回的实例。

通过调用 GetResponseStream 方法,以 Stream 的形式返回来自 Internet 资源的响应的内容。

下面的示例返回 HttpWebRequest HttpWebResponse

HttpWebRequest HttpWReq = (HttpWebRequest)WebRequest.Create("http://www.contoso.com");
HttpWebResponse HttpWResp = (HttpWebResponse)HttpWReq.GetResponse();
// Insert code that uses the response object.
HttpWResp.Close()

Uri

URI Internet 上可由应用程序使用的资源的简洁表示形式。Uri 类定义了属性和方法来处理 URI,包括分析、比较和组合。Uri 类属性是只读的,修改 Uri 实例需使用 UriBuilder 类。

Uri 类只存储绝对 URI(例如"http://www.contoso.com/index.htm")。相对 URI(例如"/new/index.htm")必须相对于基 URI 展开,这样才是绝对的。提供了 MakeRelative 方法在必要时将绝对 URI 转换为相对 URI

URI 由转义编码存储为规范化 URI,所有 ASCII 值大于 127 的字符都被替换为它们的等效十六进制数。为使 URI 具有规范化格式,Uri 构造函数执行以下步骤。

  • URI 方案转换为小写。
  • 将主机名转换为小写。
  • 移除默认端口号和空端口号。
  • 移除多余的段(如"/""/test"段)以简化 URI

使用 ToString 方法,可以将 Uri 类的内容从转义编码的 URI 引用转换为可读的 URI 引用。

一些 URI 包括段标识符或查询。段标识符是 URI 中跟在数字符号 (#) 后的任何文本,存储在 Fragment 属性中。查询信息是 URI 中跟在问号 (?) 后的任何文本,存储在 Query 属性中。

注意:URI 类支持使用以下格式的 IP 地址:四组表示法的 IPv4 协议和冒号分隔的十六进制 IPv6 协议。请记住在 IPv6 地址两边括上方括号,如 http://[::1]

下面的示例创建 Uri 类的实例,并用它来创建 WebRequest

Uri siteUri = new Uri("http://www.contoso.com/");
WebRequest wr = WebRequest.Create(siteUri);

 

程序示例说明

在界面设计上,用一个textbox控件来输入地址,三个combobox控件提供请求方式和编码方式,连续发送次数的选择,因为不同的服务器可能支持不同的请求方式,不同的页面也可能是不同的编码方式。

另外两个textbox控件分别用来显示头信息和内容信息。

(1)信息处理类ProcessInfo。我们把用户输入的各种参数传给该类,由它负责发送请求和接收响应。下面给出的主要的函数,结合代码做说明。

/// <summary>

/// 发送请求接受响应

/// </summary>

/// <param name="tb">显示头信息的TextBox</param>

/// <param name="ta">显示内容信息的TextBox</param>

/// <param name="method">请求方式</param>

/// <param name="codemethod">编码方式</param>

public void SendInfo( TextBox tb,TextBox ta,string method,string codemethod)

{

//首先我们创建HttpWebRequest的实例,用来发送请求。

hwr = (HttpWebRequest)WebRequest.Create(uri);

//然后设置它的请求方式。

hwr.Method = method;

CodingMethod = codemethod;

try

{

//创建HttpWebResponse的实例

response = (HttpWebResponse)hwr.GetResponse();

//因为response.Headers包含了我们想要的头信息,而它是WebHeaderCollection类型

//所以我们创建WebHeaderCollection实例myheaders,然后把它转化成字符串。

WebHeaderCollection myheaders = response.Headers;

f1.AddInfo(myheaders.ToString(), ta);

// GetResponseStream()方法,获取的信息是返回的内容信息。

Stream resStream = response.GetResponseStream();

int count = resStream.Read(buf, 0, buf.Length);

f1.AddInfo(getString(buf), tb);

hwr.Abort();

resStream.Close();

response.Close();

}

catch(Exception e)

{

MessageBox.Show(e.ToString());

}

finally

{

Thread.CurrentThread.Abort();

}

}

(2)form1的主要函数。

这是点击button按钮的事件处理函数,获得用户设置的各种参数,然后启动单独的线程调用信息处理类ProcessInfo的相关方法

private void button_send_Click(object sender, EventArgs e)

{

// 部分代码省略

for (int i = 0; i < Int32.Parse(this.comboBox_sendtiems.SelectedItem.ToString()); i++)

{

Thread t = new Thread(new ThreadStart(GetInfo));

t.Start();

}

}

/// <summary>

/// 把参数传入ProcessInfo类的处理函数

/// </summary>

private void GetInfo()

{

 

ProcessInfo pi = new ProcessInfo(textBox_uri.Text,this);

pi.SendInfo(textBox_content, textBox_head, combox1, combox2);

}

/// <summary>

/// 用于异步调用向textbox中添加响应信息

/// </summary>

/// <param name="info"></param>

/// <param name="myt"></param>

public void AddInfo(string info,TextBox myt)

{

//判断是否为跨线程调用

if (myt.InvokeRequired)

{

SetInfoCallback sic = new SetInfoCallback(AddInfo);

this.Invoke(sic, new object[] { info,myt });

}

else

{

myt.Text += info;

}

}

 

好了,这个简单的例子可能不能给你太多的启示,但是我的这个系列还得继续向前走。更多的编程实践,如果你做了,一定要分享哦,独乐乐不如众乐乐吗!

下面把源代码附上:https://files.cnblogs.com/xuanhun/源代码.rar

posted @ 2008-10-28 10:53  玄魂  阅读(5902)  评论(5编辑  收藏  举报