如何模拟代理服务器的功能/操作,但不调用 HttpListener 或 TcpListener 等元素?如何从我的 C# 应用程序中生成它们?
我已经能够将实际数据流式传输回我的 C# 应用程序中的 WebBrowser 元素,但是在查看结果时,它给了我错误。原因是因为我正在查看 LITERAL 字符串,并且生成的 HTML 流中有 JS/CSS 组件通过相对 URI 引用对象。显然,我的解决方案认为它们是本地的,因此无法解决它们。
我缺少类似代理的功能,它应该只是将流传递回我的模拟浏览器并正确显示。但是,查看基于 C# 构建的示例代理服务器代码,它们都是使用侦听器构建为服务器的。我希望它是我可以在本地实例化而无需创建监听接口的东西。
现在,您可能想知道我为什么要这样做?嗯,有几个原因:
- 为了能够临时注入标头,以便我可以测试内部 Web 服务器
- 作为一个无头(无 GUI)组件运行,该组件可以从其他 .NET 组件获取 HTTP 或 HTTPS 流,并从其他 .NET 组件注入标头。
- 其他一些我认为可能但在我把它准备好之前不会知道的后端东西。
这是我到目前为止所拥有的:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using HtmlAgilityPack;
using System.Net;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
WebClient client = new WebClient();
var baseUrl = new Uri(textBox1.Text);
client.Headers.Add("Token1", textBox2.Text);
client.Headers.Add("Token2",textBox3.Text);
byte[] requestHTML = client.DownloadData(textBox1.Text);
string sourceHTML = new UTF8Encoding().GetString(requestHTML);
HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
htmlDoc.LoadHtml(sourceHTML);
//"//*[@background or @lowsrc or @src or @href]"
foreach (HtmlNode link in htmlDoc.DocumentNode.SelectNodes("//*[@href]"))
{
//Console.Out.WriteLine(link.ToString());
if (!string.IsNullOrEmpty(link.Attributes["href"].Value))
{
HtmlAttribute att = link.Attributes["href"];
Console.WriteLine("Before: " + att.Value);
//Console.Out.WriteLine(att.Value.ToString());
Console.WriteLine(new Uri(baseUrl, att.Value));
link.Attributes["href"].Value = new Uri(baseUrl, att.Value).ToString();
Console.WriteLine("After: " + link.Attributes["href"].Value);
//att.Value = this.AbsoluteUrlByRelative(att.Value);
}
}
foreach (HtmlNode link2 in htmlDoc.DocumentNode.SelectNodes("//*[@src]"))
{
//Console.Out.WriteLine(link.ToString());
if (!string.IsNullOrEmpty(link2.Attributes["src"].Value))
{
HtmlAttribute att = link2.Attributes["src"];
Console.WriteLine("Before: " + att.Value);
// //Console.Out.WriteLine(att.Value.ToString());
Console.WriteLine(new Uri(baseUrl, att.Value));
if (!att.Value.Contains("/WS"))
{
Console.WriteLine("HIT ME!");
var output = "/WS/" + att.Value;
link2.Attributes["src"].Value = new Uri(baseUrl, output).ToString();
Console.WriteLine("After HIT: " + link2.Attributes["src"].Value);
}
else
{
link2.Attributes["src"].Value = new Uri(baseUrl, att.Value).ToString();
Console.WriteLine("After: " + link2.Attributes["src"].Value);
}
// //att.Value = this.AbsoluteUrlByRelative(att.Value);
}
}
Console.WriteLine(htmlDoc.DocumentNode.OuterHtml);
Console.WriteLine("+========================+");
webBrowser1.DocumentText = htmlDoc.DocumentNode.OuterHtml;
}
}
}
同样,这只是原型代码,所以请原谅古怪的间距和注释。最后,它会更正式。现在,这只猴子正在杀死我。