制作一个“;Web代理”-循序渐进

本文关键字:Web 代理 循序渐进 一个 | 更新日期: 2023-09-27 18:26:45

有什么方法可以在您的页面中显示另一个页面吗?我不能使用框架,因为框架会直接打开那个页面,我想复制整个页面并将其保存到新文件中,然后向用户显示我的新文件。我认为最好使用简单的URL加密,因为我不喜欢显示真实的页面地址。例如,我想使用以下URL而不是yahoo.com:www.myDomain.com/Open.aspx?url=zipp_dpn。。。我知道如何读取、加密和解密URL,但我的问题是我不知道如何将该页面复制到新页面以及如何显示。

编辑:我不知道如何开始研究,甚至我不知道我应该寻找什么。这就是我在这里向专家提问的原因。我需要一个关键词来开始研究!

制作一个“;Web代理”-循序渐进

听起来像是在尝试设置代理。

您可以执行以下操作:

  • 使用HTTP处理程序侦听请求。这可以是MVC控制器、web表单(ASPX)、IHttpHandler的实例,甚至是原始TCP服务器。

  • 使用加密的URL来确定目标网站。

  • 从您的网站向其他网站提出请求。在.Net中有多种方法可以做到这一点,包括HttpClient类。

  • 将响应转换为字符串。

  • (可选)解析内容中的链接以指向您的代理网站地址,而不是真实地址。

  • 将字符串作为响应的主体返回给调用者。据他们的浏览器所知,这就是他们请求的页面

免责声明:虽然代理是常用的,但在不同的URL下呈现他人的内容可能会产生潜在的影响(超出我的非法律知识和建议)。此外,绕过过滤后的内容可能还有其他(可能是严重的)后果。即使修改了URL,代理内容仍然可能触发过滤器。

好吧,我终于开始创建一个web代理了。

我决定在这里解释我的工作有两个原因:1) 适合所有想开始类似项目的人。2) 这些代码的大部分都是从Stack页面复制的,我刚刚收集了它们。)

我需要专家来纠正我的错误,并帮助我继续前进。

以下是我所做的:


ASP(Default.aspx):

我放了一个名为"txtURL"的文本框,按用户输入网址。

我放置了一个名为"btnRun"的按钮来开始处理。

目前,这些组件就足够了!


C#:

单击"btnRun",页面重定向到:"www.domain.com/default.aspx?URL=(xxx)"-xxx将被一个函数加密的网页地址所取代。

这是btnRun_Click:的代码

protected void btnRun_Click(object sender, EventArgs e)
    {
        if (txtURL.Text.Length == 0) return;
        if (!(txtURL.Text.ToLower().StartsWith("http://") || txtURL.Text.ToLower().StartsWith("https://")))
            txtURL.Text = "http://" + txtURL.Text;
        try
        {
            Response.Redirect("Default.aspx?URL=(" + Encrypt(txtURL.Text, mainKey) + ")", false);
        }
        catch (Exception ex)
        {
            ShowPopUpMsg(ex.Message);
        }

稍后我将解释"Encrypt"answers"ShowPopUpMsg"函数。

点击"btnRun",此页面将被刷新,加密的URL将包含在地址中。

现在,在"Page_Load"中,我们应该读取加密的URL(也是检测回发的条件):

protected void Page_Load(object sender, EventArgs e)
    {
        string url = Regex.Match(HttpContext.Current.Request.Url.AbsoluteUri, @"'(([^)]*)')").Groups[1].Value;
        if (url.Length == 0 || Page.IsPostBack) return;

从现在起,每个代码都会一个接一个地添加到"Page_Load"中。

解密URL并读取远程网页源代码:

try
        {
            txtURL.Text = Server.UrlDecode(Decrypt(url, mainKey));
            string TheUrl = txtURL.Text;
            string response = GetHtmlPage(TheUrl);

稍后我将解释"解密"answers"GetHtmlPage"。

现在,我们有了"response"中的源代码。

下一步是在此源代码中查找链接。链接的开头是"href="xxx"",xxx就是链接。我们必须通过代理将它们替换为我们的链接:

            response = response.Replace("href =", "href=");
            response = response.Replace("href'n=", "href=");
            response = response.Replace("href't=", "href=");
            HtmlWeb hw = new HtmlWeb();
            HtmlDocument doc = hw.Load(txtURL.Text);
            foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]"))
            {
                char[] c = { ' ', ''"' };
                string s = link.OuterHtml;
                int from = s.IndexOf("href=");
                int to = SearchString(s, from, ''"');
                s = s.Substring(from + 5, to - from - 5);
                s.TrimStart(c);
                if (s.StartsWith("'"")) s = s.Remove(0, 1);

"SearchString"是一个返回"href"的右引号的函数。我稍后再解释。

有两种链接:

  1. 指向另一个域名的链接。这些链接以"http://"或"https://"开头。我们会找到它们并替换地址:

                string corrected = "href='"" + "Default.aspx?URL=(" + Encrypt(s, mainKey) + ")" + "'"";
                if ((s.ToLower().StartsWith("http://") || s.ToLower().StartsWith("https://")))
                    response = response.Replace("href='"" + s + "'"", corrected);
    
  2. 引用当前域名的链接。这些链接以"/"开头。要替换它们,我们应该首先找到域名,然后找到整个地址:

                else
                {
                    var uri = new Uri(txtURL.Text);
                    string domain = uri.GetComponents(UriComponents.Host, UriFormat.SafeUnescaped);
                    corrected = "href='"" + "Default.aspx?URL=(";
                    if (txtURL.Text.ToLower().StartsWith("http://")) corrected += Encrypt("http://" + domain + s, mainKey);
                    if (txtURL.Text.ToLower().StartsWith("https://")) corrected += Encrypt("https://" + domain + s, mainKey);
                    corrected += ")" + "'"";
                    response = response.Replace("href='"" + s + "'"", corrected);
                }
    

现在,一切都完成了(参考我目前的知识),我们应该显示带有新链接的页面,并完成"page_Load":

            }
            Response.Write(response);                
        }
        catch (Exception ex)
        {
            ShowPopUpMsg(ex.Message);
        }
    }

在字符串中搜索的函数:

private int SearchString(string mainString, int startLocation, char charToFind)
    {
        if (startLocation < 0) return -1;
        bool next = false;
        for (int i = startLocation; i < mainString.Length; i++)
            if (mainString.Substring(i, 1) == charToFind.ToString() && next)
                return i;
            else
            {
                if (mainString.Substring(i, 1) == charToFind.ToString()) next = true;
                continue;
            }
        return -1;
    }

读取源代码的功能:

private string GetHtmlPage(string URL)
        {
            String strResult;
            WebResponse objResponse;
            WebRequest objRequest = HttpWebRequest.Create(URL);
            objResponse = objRequest.GetResponse();
            using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
            {
                strResult = sr.ReadToEnd();
                sr.Close();
            }
            return strResult;
        }

显示弹出消息的功能:

private void ShowPopUpMsg(string msg)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("alert('");
            sb.Append(msg.Replace("'n", "''n").Replace("'r", "").Replace("'", "'''"));
            sb.Append("');");
            ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "showalert", sb.ToString(), true);
        }

解密字符串的函数:

private string Decrypt(string s, string key)
        {
            try
            {
                byte[] keyArray; byte[] toEncryptArray = Convert.FromBase64String(s);
                System.Configuration.AppSettingsReader settingsReader = new System.Configuration.AppSettingsReader();
                MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
                keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); hashmd5.Clear();
                TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
                tdes.Key = keyArray; tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.PKCS7;
                ICryptoTransform cTransform = tdes.CreateDecryptor();
                byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
                tdes.Clear(); return UTF8Encoding.UTF8.GetString(resultArray);
            }
            catch { return null; }
        }

加密字符串的函数:

private string Encrypt(string s, string key)
    {
        try
        {
            byte[] keyArray; byte[] encryptArray = UTF8Encoding.UTF8.GetBytes(s);
            System.Configuration.AppSettingsReader SettingReader = new System.Configuration.AppSettingsReader();
            MD5CryptoServiceProvider Hashmd5 = new MD5CryptoServiceProvider();
            keyArray = Hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); Hashmd5.Clear();
            TripleDESCryptoServiceProvider Tdes = new TripleDESCryptoServiceProvider();
            Tdes.Key = keyArray; Tdes.Mode = CipherMode.ECB; Tdes.Padding = PaddingMode.PKCS7;
            ICryptoTransform Ctransform = Tdes.CreateEncryptor();
            byte[] resultarray = Ctransform.TransformFinalBlock(encryptArray, 0, encryptArray.Length);
            Tdes.Clear(); return Convert.ToBase64String(resultarray, 0, resultarray.Length);
        }
        catch { return null; }
    }