如何在控制台应用程序中模拟Internet Explorer URL编码 [英] How do I emulate Internet Explorer url encoding in a console app

查看:105
本文介绍了如何在控制台应用程序中模拟Internet Explorer URL编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标:

使控制台应用程序以正确的方式发送简单的获取请求。

Make a console app that send a simple get request - in exactly the right way.

问题:

我有这样的网址:
http://myhost/somepage.do?Search01 =コード番号= 123456& Search02 =改订番号= 2

当我将其复制并粘贴到IE 11或更低版本时,我要返回的页面正确地。
当我将其复制并粘贴到IE Edge,chrome,firefox中时,它返回一个错误,提示它无法正确识别参数。

When I copy and past this into IE 11 or lower, the page I want returns correctly. When I copy and past this into IE Edge, chrome, firefox, it returns an error saying it does not properly recognize the parameters.

我对此进行了调查Wireshark,我可以很清楚地看到ol'IE正在使用某种不同的编码发送网址:

I investigated this with Wireshark, and I can see quite clearly that ol' IE is sending the url with some kind of different encoding:

Chrome会提供更理想的编码:

Whereas Chrome does a more expected encoding:

我不完全了解发生在这里,但似乎我正在向其发送邮件的服务器针对IE的url编码方式有些混乱-因为它只是在响应混乱的请求。

I don't fully understand what is happening here, but it seems that this server I am sending the message to, is somewhat TAILORED towards ol' IE's messed up way of encoding the url - because it is only replying to the messed up requests.

我检查了其他内容,例如useragent e tc-没什么区别。该服务器运行的服务非常旧(可能使用ASP)。

I have checked other things like the useragent etc - it makes no difference. This server is running a service which is very old (maybe using ASP).

因此,我的目标是在控制台应用程序中模拟这种混乱的编码。我该怎么做?

So, my objective is to emulate this messed up encoding in a console app. How do I do it?

推荐答案

因此,在了解可能发生的情况的帮助下,可以通过以下方式进行操作:
此stackoverflow问题

So, with some help from understanding what might be happening via: This stackoverflow question

我开始意识到我的url是如何编码的。

I came to realize how my url is being encoded.

我的计算机是日语的,因此默认代码页是932。
之后弄弄一个示例控制台应用程序,看着Wireshark中的数据包,我意识到无论做什么,默认的 HttpClient 无论我使用哪种编码,WebClient 始终都会正确地对我的URL进行网址编码

My computer is Japanese, so the default codepage is 932. After much messing around with a sample console app, and watching the packets in Wireshark, I realized that no matter what I did, the default HttpClient and WebClient will always UrlEncode my URL correctly regardless of what encoding I used. This is not how ol' IE encodes it's URLs.

我深入研究发现在源中用于 HttpClient (和 WebClient ),它使用类 Uri ,其构造函数的参数为​​: DontEscape 我以为 Eurika!但是事实证明,此构造函数已过时,并且在使用 HttpClient WebClient 时,没有办法不使URL自动转义。 code> 。

I dug deeper and found that in the source for HttpClient (and WebClient) it uses the class Uri, which has a constructor with parameter : DontEscape which I thought, "Eurika!" but it turns out this constructor is Obsolete, and there is no way to not make URL's automatically escape themselves when using HttpClient or WebClient.

所以我不得不使用 TcpClient 来提出自己的请求。哪个我从这里偷来的:

So I had to use TcpClient and make my own request instead. Which I stole from here:

    /// <summary>
    /// The initial request to search only works if the url is encoded using Shift-JIS, which means we cannot use any client library and must use a custom TCP message.
    /// </summary>
    /// <param name="serveripaddress"></param>
    /// <param name="restoftheurl"></param>
    /// <returns></returns>
    private async Task<string> HttpRequestAsync(string serveripaddress, string restoftheurl)
    {
        Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
        string result = string.Empty;

        using (var tcp = new TcpClient(serveripaddress, 80))
        using (var stream = tcp.GetStream())
        {
            tcp.SendTimeout = 500;
            tcp.ReceiveTimeout = 1000;
            Console.WriteLine("URL rest:" + restoftheurl);
            // Send request headers
            var builder = new StringBuilder();
            builder.AppendLine("GET " + restoftheurl + " HTTP/1.1");
            builder.AppendLine("Host: " + serveripaddress);
            //builder.AppendLine("Content-Length: " + data.Length);   // only for POST request
            builder.AppendLine("Accept: text/html, application/xhtml+xml, */*");
            builder.AppendLine("Accept-Language: ja-JP");
            builder.AppendLine("User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
            builder.AppendLine("Accept-Encoding: gzip, deflate");
            builder.AppendLine("Connection: Close");
            builder.AppendLine();
            Console.WriteLine("Sending message:" + builder.ToString());
            var header = Encoding.GetEncoding(932).GetBytes(builder.ToString());
            await stream.WriteAsync(header, 0, header.Length);

            // Send payload data if you are POST request
            //await stream.WriteAsync(data, 0, data.Length);

            // receive data
            using (var memory = new MemoryStream())
            {
                await stream.CopyToAsync(memory);
                memory.Position = 0;
                var data = memory.ToArray();

                var index = BinaryMatch(data, Encoding.ASCII.GetBytes("\r\n\r\n")) + 4;
                var headers = Encoding.ASCII.GetString(data, 0, index);
                memory.Position = index;

                if (headers.IndexOf("Content-Encoding: gzip") > 0)
                {
                    using (GZipStream decompressionStream = new GZipStream(memory, CompressionMode.Decompress))
                    using (var decompressedMemory = new MemoryStream())
                    {
                        decompressionStream.CopyTo(decompressedMemory);
                        decompressedMemory.Position = 0;
                        result = Encoding.UTF8.GetString(decompressedMemory.ToArray());
                    }
                }
                else
                {
                    result = Encoding.UTF8.GetString(data, index, data.Length - index);
                    //result = Encoding.GetEncoding("gbk").GetString(data, index, data.Length - index);
                }
            }

            //Debug.WriteLine(result);
            return result;
        }
    }

    private int BinaryMatch(byte[] input, byte[] pattern)
    {
        int sLen = input.Length - pattern.Length + 1;
        for (int i = 0; i < sLen; ++i)
        {
            bool match = true;
            for (int j = 0; j < pattern.Length; ++j)
            {
                if (input[i + j] != pattern[j])
                {
                    match = false;
                    break;
                }
            }
            if (match)
            {
                return i;
            }
        }
        return -1;
    }

}

此代码的关键部分是:

var header = Encoding.GetEncoding(932).GetBytes(builder.ToString());

var header = Encoding.GetEncoding(932).GetBytes(builder.ToString());

这会强制在我的代码页中对字符串进行编码,这要求注册代码页提供程序,因此在顶部:
Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);

This forces the string to be encoded in my codepage, which required that the codepage provider was registered, so at the top: Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);

用法很简单:

await HttpRequestAsync( 123.456.789.123, /somepage.do?Search01=コード番号= 123456& Search02 =改订番号= 2);

这篇关于如何在控制台应用程序中模拟Internet Explorer URL编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆