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/");
此类包含对 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 是 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
作者:玄魂
出处:http://www.cnblogs.com/xuanhun/
原文链接:http://www.cnblogs.com/xuanhun/
更多内容,请访问我的个人站点 对编程,安全感兴趣的,加qq群:hacking-1群:303242737,hacking-2群:147098303,nw.js,electron交流群 313717550。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
关注我: