C# - GZipStream的魔数不正确?

3

所以,我正在尝试制作一个程序,将计算机变成一个代理 使用这个。一切都很顺利,除了gzip/deflate页面。

每当我尝试解压缩时,我会收到一个InvalidDataException,指出GzipHeader中的幻数不正确。

我使用这个函数:

private byte[] GZipUncompress(byte[] data)
{
    using (var input = new MemoryStream(data))
    {
        input.Seek(0, SeekOrigin.Begin);

        using (var gzip = new GZipStream(input, CompressionMode.Decompress))
        using (var output = new MemoryStream())
        {
            output.Seek(0, SeekOrigin.Begin);
            gzip.CopyTo(output);

            return output.ToArray();
        }
    }
}

解压数据。错误信息:

error
(来源:gyazo.com)

任何帮助将不胜感激。

编辑:我似乎有所进展!

如usr建议的那样,我应该编写一个HTTP解析器来获取主体并对其进行解压缩。

在解析之前:http://pastebin.com/Cb0E8WtT

解析后:http://pastebin.com/k9e8wMvr

这是我用来获取主体的方法:

    private byte[] HTTParse(byte[] data)
    {
        string http = ascii.GetString(data);
        char[] lineBreak = crlf.ToCharArray();
        string[] parts = http.Split(lineBreak);

        List<byte> res = new List<byte>();

        for (int i = 1; i < parts.Length; i++)
        {
            if (i % 2 == 0)
            {
                Regex r = new Regex(@"(.)*: (.)*");
                Regex htt = new Regex(@"HTT(.)*/(.)*.(.)* d{1,50} (.)*");
                if (!r.IsMatch(parts[i]) && !htt.IsMatch(parts[i]))
                {
                    //Console.WriteLine("[TEST] " + parts[i]);
                    res.AddRange(ascii.GetBytes(parts[i]));
                    res.AddRange(ascii.GetBytes("\r\n"));
                }
                
            }
        }
        return res.ToArray();
    }

然而,我仍然收到一个错误,说“GZip头中的魔数不正确。确保您传递了一个GZip流。”
编辑(2):从此处复制答案后,我已经成功地解压缩了正文。
新问题:Firefox。 error (来源:gyazo.com
现在我不确定是否需要解压缩gzip页面。
我现在做错了什么?

1
可能数据没有被压缩。看一下字节。它们长什么样子? - usr
顺便提一下:您不需要“倒带”一个新的MemoryStreamSeek(0, SeekOrigin.Begin)是多余的。 - Max Yakimets
@usr:http://pastebin.com/Cb0E8WtT 这是whatismyip.org的请求,看起来我需要将响应与头部分离。你有什么想法吗? - Adam M
1
使用标准的HTTP库下载响应。使用AutomaticDecompression。 - usr
@usr:我想保持这种方式,因为这样可以更容易地实现SOCKS。 - Adam M
显示剩余9条评论
2个回答

3

你说,你使用这段代码来进行gzip/deflate压缩。但是deflate和gzip不同,尤其是它没有像gzip那样的magic header。Deflate在RFC1951中定义,gzip在RC1952中定义。此外,像Firefox和Chrome这样的浏览器(但不包括Internet Explorer)还根据RFC1950接受“原始deflate”。

因此,在对body进行解压缩之前,您必须首先根据“Content-Encoding”头检查使用了哪种压缩方式。


1
原来我甚至不需要解压缩数据。
然而,按照解决方案:
我使用this分离了正文,并尝试解压缩。但我没有意识到我发送了大约500个空白字节,导致请求失败(其中包含压缩数据的html),所以我无法解压缩。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接