GZIP文件已损坏-但是为什么呢?

问题描述

我目前正在研究GZIP HTTP解压缩。

我的服务器接收到一些数据,并即时裁剪并将其保存为二进制模式。 我编写了一个小脚本,用于从stackoverflow下载gzip并将其保存到.gz文件中。 效果很好!

但是我从防御防火墙收到的“ gzip”最终被破坏了。

此处的工作文件已损坏:https://gofile.io/d/j520Nr

缓冲区是损坏的文件-我不确定为什么。 这两个文件都非常不同(至少在我看来是这样)-但是GZIP标头肯定存在!

有人可以比较这两个文件并告诉我为什么它们如此不同吗? 也许甚至告诉我如何解决

这就是两个文件的gzip html网址:What is the best way to parse html in C#?

我损坏的文件大约2KB!

对于朝正确方向迈出的每一步我都会感到高兴-也许这是可以真正轻松解决的事情!

以下代码应向您显示我的工作流程,“ ReadAll”的运行速度很慢,但会从流中读取所有内容。将会对其进行优化ofc(也许是gzip流错误的问题?)

    public static byte[] ReadAll(NetworkStream stream,int buffer)
    {
        byte[] data = new byte[buffer];
        using MemoryStream ms = new MemoryStream();
        int numBytesRead;
        while ((numBytesRead = stream.Read(data,data.Length)) > 0)
        {
            ms.Write(data,numBytesRead);
        }
        return ms.ToArray();
    }

    private bool Handled = false;

    /// <summary>
    /// Handles Client and passes matches to the parser for more investigation
    /// </summary>
    /// <param name="obj"></param>
    private void HandleClient(object obj)
    {
        TcpClient client = (TcpClient)obj;
        Out.Log(LogLevel.Verbose,$"Client {client.Client.RemoteEndPoint} connected");
        Data = null; // Resets data after each received stream
        // Get a stream object for reading and writing
        NetworkStream stream = client.GetStream();
        //MemoryStream memory = new MemoryStream();

        // Wait to receive all the data sent by the client.
        if (stream.CanRead)
        {

            Out.Log(LogLevel.Debug,"Can read stream");
            StringBuilder c_completeMessage = new StringBuilder();

            if (!Handled)
            {
                Out.Log(LogLevel.Warning,"Handling first and last client.");
                Handled = true;
                int breakPoint = 0;
                byte[] res = ReadAll(stream,1024);
                for (int i = 0; i < res.Length; i++)
                {
                    int xy = res[i];
                    int yy = res[i + 1];
                    if (res[i].Equals(31) && res[i + 1].Equals(139))
                    {
                        breakPoint = i;
                        Out.Log(LogLevel.Error,GZIP_MAGIC + $" found. Magic Number of GZIP at :{breakPoint}:");
                        break;
                    }
                    continue;
                }

                byte[] res2 = res.SubArray(breakPoint,res.Length - breakPoint - 7); // (7 for offset linebreaks,eol,etc)
                res2.WritetoFile(@"C:\Users\--\Temporary\Buffer_ReadFully_cropped.gz");

解决方法

如前所述,分块和缓冲区大小在这里起着重要作用。

请记住,ICAP使用分块,因此您必须使用CONTINUE响应先前的程序包,否则您将只从服务器收到前X个字节。