通行证│用户名: 密码: 验证码: 验证码,看不清楚?请点击刷新验证码 爱心红客 电信网通铁通移动 在线
文章搜索:
热门搜索:红客 黑鹰 红客技术 安全动画 红客培训
首页 文章 软件 动画 资源 励志 论坛 邮箱 会员 军事 科技 博客 爱心红客 最近更新 800g资源
 业内新闻 漏洞公告 病毒公告 电脑知识 网络知识 菜鸟入门 攻防教程 黑客攻防 安全编程 工具使用 综合安全 个人安全 安全相关 Q Q安全 原创精华 红客人物 站内事件
您现在的位置: 爱国者安全网 > 文章类 > 技术文章 > 网络知识 > 文章正文
粗糙的C#版HTTP代理
责任编辑:酷酷の鱼   更新日期:2008-8-7
 

By;云舒

前些时候一个无锡人在我博客留言,说我读再多的书,也改变不了我是个程序员的本质。或许它觉得它是在鄙视我,不过我到觉得它是在赞扬我——我真的算不上是个程序员,写代码的能力实在是太烂了——不过我会努力的。

说说这段代码的问题吧。首先是字符串切割的问题,要将客户端提交过来的GET,POST等原始请求切割,分离出主机名,端口,URL等数据。这里用正则匹配是最好的,遗憾的是我不擅长此道,所以使用了手动切割的办法,很笨重繁琐,但是毕竟它工作得很好。第二个问题是Keep-Alive的问题,这里我没有处理好。最开始我在http proxy里面修改客户端请求,强行将keep-alive修改为close,但是发现在某些站点的时候会出错。于是使用了类似select的方法读取数据,直到超时关闭两端的连接。我猜测,这里如果解析content-length会更好,但是略微繁琐了点,还是等我仔细阅读下RFC再看怎么修改吧。第三个是CONNECT方法的问题,这个到很简单,转发数据就行了,因此是这个代码中写得最好的一部分,用来登陆QQ还是不错的。

说实话,我不喜欢HTTP这种太宽松的协议,感觉灵活得让我难以把握。直接看代码吧,我加了很多debug信息,真的要用就去掉好了。调用这个类很简单,看main函数的实现就好了。为了方便贴代码,我写的时候就把三个类写到一个文件里面去了。顺便要说的是,虽然有类,但是没有任何面向对象的东西——这也再次证明,其实我算不上一个程序员,最多是个代码爱好者。


 using System;
 
 using System.Net;
 
 using System.Net.Sockets;
 
 using System.Text;
 
 using System.IO;
 
 using System.Threading;
 
 using System.Collections;
 
 
 
 namespace HttpProxy
 
 {
 
 public class HttpProxy
 
 {
 
 int ProxyPort;
 
 
 
 /// <summary>
 
 /// 代理服务器入口类构造函数
 
 /// </summary>
 
 /// <param name="Port">Http Proxy监听的端口</param>
 
 public HttpProxy( int Port)
 
 {
 
 ProxyPort = Port;
 
 }
 
 
 
 /// <summary>
 
 /// 启动Http代理服务
 
 /// </summary>
 
 public void Start( )
 
 {
 
 TcpListener tcplistener = null;
 
 try
 
 {
 
 // 开始监听端口
 
 tcplistener = new TcpListener(Dns.GetHostAddresses(Dns.GetHostName())[0], ProxyPort);
 
 tcplistener.Start();
 
 Console.WriteLine("侦听端口号: " + ProxyPort.ToString());
 
 }
 
 catch (Exception e)
 
 {
 
 Console.WriteLine("启动代理服务器失败: " + e.Message);
 
 }
 
 
 
 while (true)
 
 {
 
 try
 
 {
 
 // 接受客户端连接
 
 Socket socket = tcplistener.AcceptSocket();
 
 
 
 HttpSession Session = new HttpSession(socket);
 
 
 
 // 启动新线程,处理连接
 
 Thread thread = new Thread(new ThreadStart(Session.Start));
 
 thread.Start();
 
 }
 
 catch( Exception e )
 
 {
 
 Console.WriteLine("接受客户端连接异常: " + e.Message );
 
 }
 
 }
 
 
 
 }
 
 }
 
 
 
 public class HttpSession
 
 {
 
 // 客户端socket
 
 Socket ClientSocket;
 
 
 
 // 设定编码
 
 Encoding ASCII = Encoding.ASCII;
 
 
 
 /// <summary>
 
 /// 构造函数
 
 /// </summary>
 
 /// <param name="socket">客户端socket</param>
 
 public HttpSession(Socket socket)
 
 {
 
 this.ClientSocket = socket;
 
 }
 
 
 
 public void Start()
 
 {
 
 // 客户端缓冲区,读取客户端命令
 
 Byte[] ReadBuff = new byte[1024 * 10];
 
 
 
 try
 
 {
 
 int Length = ClientSocket.Receive(ReadBuff);
 
 
 
 // 没有读到数据
 
 if (0 == Length)
 
 {
 
 Console.WriteLine("从客户端读取命令错误");
 
 ClientSocket.Shutdown(SocketShutdown.Both);
 
 ClientSocket.Close();
 
 
 
 return;
 
 }
 
 }
 
 // 读取出现异常
 
 catch (Exception e)
 
 {
 
 Console.WriteLine("读取客户端异常: " + e.Message);
 
 }
 
 
 
 // 来自客户端的HTTP请求字符串
 
 string ClientMsg = ASCII.GetString(ReadBuff);
 
 
 
 // 根据rnrn截取请求行
 
 string Line = ClientMsg.Substring(0, ClientMsg.IndexOf("rn"));
 
 string[] CmdArray = Line.Split(' ');
 
 
 
 // GET http://www.test.com:80/index.php HTTP/1
 
 // CONNECT www.test.com:443 HTTP/1
 
 string Cmd = CmdArray[0];
 
 string RawUrl = CmdArray[1];
 
 
 
 Console.WriteLine("原始请求: ", Line);
 
 
 
 // CONNECT请求
 
 if (Cmd == "CONNECT")
 
 {
 
 DoConnect(RawUrl);
 
 }
 
 // GET,POST和其他
 
 else
 
 {
 
 DoOther(RawUrl, ClientMsg);
 
 }
 
 }
 
 
 
 /// <summary>
 
 /// 处理CONNECT命令,此处作用是支持QQ,MSN,以及多级代理串联等
 
 /// </summary>
 
 /// <param name="RawUrl"></param>
 
 private void DoConnect( string RawUrl )
 
 {
 
 string[] Args = RawUrl.Split( ':' );
 
 
 
 string Host = Args[0];
 
 int Port = int.Parse(Args[1]);
 
 
 
 Socket ServerSocket = null;
 
 try
 
 {
 
 IPAddress[] IpList = Dns.GetHostEntry(Host).AddressList;
 
 Console.WriteLine("尝试连接:", IpList[0], Port);
 
 
 
 ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 
 ServerSocket.Connect(IpList[0], Port);
 
 }
 
 catch (Exception e)
 
 {
 
 Console.WriteLine("连接真实服务器异常: " + e.Message);
 
 }
 
 
 
 // 连接真实服务器成功
 
 if (ServerSocket.Connected)
 
 {
 
 ClientSocket.Send( ASCII.GetBytes("HTTP/0 200 Connection establishedrnrn") );
 
 }
 
 else
 
 {
 
 ClientSocket.Shutdown(SocketShutdown.Both);
 
 ClientSocket.Close();
 
 }
 
 
 
 // 开始转发数据
 
 ForwardTcpData(ClientSocket, ServerSocket);
 
 }
 
 
 
 /// <summary>
 
 /// 处理GET,POST等命令。使用了POLL,在代理服务器中强制去掉了Keep-Alive能力
 
 /// </summary>
 
 /// <param name="RawUrl"></param>
 
 /// <param name="ClientMsg"></param>
 
 public void DoOther(string RawUrl, string ClientMsg)
 
 {
 
 RawUrl = RawUrl.Substring(0 + "http://".Length);
 
 
 
 int Port;
 
 string Host;
 
 string Url;
 
 
 
 // 下面是分割处理请求,此处应该用正则匹配,不过我不擅长,因此手动切割,—_—!
 
 int index1 = RawUrl.IndexOf(':');
 
 // 没有端口
 
 if (index1 == -1)
 
 {
 
 Port = 80;
 
 
 
 int index2 = RawUrl.IndexOf('/');
 
 // 没有目录
 
 if (index2 == -1)
 
 {
 
 Host = RawUrl;
 
 Url = "/";
 
 }
 
 else
 
 {
 
 Host = RawUrl.Substring(0, index2);
 
 Url = RawUrl.Substring(index2);
 
 }
 
 }
 
 else
 
 {
 
 int index2 = RawUrl.IndexOf('/');
 
 // 没有目录
 
 if (index2 == -1)
 
 {
 
 Host = RawUrl.Substring(0, index1);
 
 Port = IntParse(RawUrl.Substring(index1 + 1));
 
 Url = "/";
 
 }
 
 else
 
 {
 
 // /出现在:之前,则说明:后面的不是端口
 
 if (index2 < index1)
 
 {
 
 Host = RawUrl.Substring(0, index2);
 
 Port = 80;
 
 }
 
 else
 
 {
 
 Host = RawUrl.Substring(0, index1);
 
 Port = IntParse(RawUrl.Substring(index1 + 1, index2 - index1 - 1));
 
 }
 
 Url = RawUrl.Substring(index2);
 
 }
 
 }
 
 
 
 Console.WriteLine("Host is:, Port is:, Url is:", Host, Port, Url);
 
 
 
 IPAddress[] address = null;
 
 try
 
 {
 
 IPHostEntry IPHost = Dns.GetHostEntry(Host);
 
 address = IPHost.AddressList;
 
 
 
 Console.WriteLine("Web服务器IP地址: " + address[0]);
 
 }
 
 catch( Exception e )
 
 {
 
 Console.WriteLine( "解析服务器地址异常: " + e.Message );
 
 }
 
 
 
 Socket IPsocket = null;
 
 try
 
 {
 
 // 连接到真实WEB服务

[1] [2] 下一页

  • 上一篇文章:
  • 下一篇文章: 没有了
  • 最近更新
    固顶文章 黑鹰的奥运激情
    普通文章 客发虚拟奥运信息诱使用户点击中毒
    普通文章 企业安全堪忧 07年89%安全事件未报告
    普通文章 美国运输安全管理局丢3万旅客信息
    普通文章 美规模最大信用卡盗窃案公诉
    普通文章 齐向东:瑞星心态不对唯利是图
    普通文章 McAfee:音乐、科技有关检索更多染毒网页
    普通文章 卡巴斯基:Twitter--网络犯罪新温床
    普通文章 近两年网络安全消费85亿美元
    普通文章 检测你的Web系统有多少安全漏洞
    热门文章
    普通文章“爆破作文网”全部网页被删
    推荐文章瑞星公司07月30日发布 每日计算机病毒及木马播报
    普通文章检测注册表中的ProgID信息
    普通文章安全精彩:走出误区 真正黑客是门艺术
    普通文章服务器隐藏自己的方法
    普通文章阿根廷黑客又发布集合攻击工具
    普通文章英黑客入侵美军系统找外星人 面临60年监禁
    普通文章"新木马"专门盗窃企业用户的商业数据
    普通文章解百纳英文域名水涨船高 网上兜售喊价1万
    普通文章人肉搜索的新时代 绝不仅仅是网络暴力
    精彩专题