A class for compressing and decompressing GZIP streams.

Like the GZipStream in the .NET Base Class Library, the Ionic.Zlib.GZipStream can compress while writing, or decompress while reading, but not vice versa.

A GZipStream can be used for Read() or Write(), and thus decompression or compression, but not both.

If you wish to use the GZipStream to compress (deflate) data, you must wrap it around a write-able stream. As you call Write() on the GZipStream, the data will be compressed into the GZIP (IETF RFC 1952) format.

If you want to decompress (inflate) data, you must wrap the GZipStream around a readable stream that contains an IETF RFC 1952-compliant stream. The data will be decompressed as you call Read() on the GZipStream.

Though the GZIP format allows data from multiple files to be concatenated together, this stream handles only a single segment of GZIP format, typically representing a single file.

For more information on GZIP, see IETF RFC 1952, "GZIP file format specification version 4.3".

This class is similar to ZlibStream and DeflateStream. ZlibStream handles RFC1950-compliant streams. DeflateStream handles RFC1951-compliant streams. And this class handles RFC1952-compliant streams.

Inheritance: System.IO.Stream
Example #1
0
        public void ReadFromStream(Stream inputStream, Stream bodyStream)
        {
            progress = 0;

            if (inputStream == null) {
                throw new HTTPException ("Cannot read from server, server probably dropped the connection.");
            }
            var top = Protocol.ReadLine (inputStream).Split (' ');

            status = -1;
            int _status = -1;
            if (!(top.Length > 0 && int.TryParse (top [1], out _status))) {
                throw new HTTPException ("Bad Status Code, server probably dropped the connection.");
            }
            status = _status;
            message = string.Join (" ", top, 2, top.Length - 2);
            protocol = top[0];
            Protocol.CollectHeaders (inputStream, headers);

            if (status == 101) {
                progress = 1;
                return;
            }

            if (status == 204) {
                progress = 1;
                return;
            }

            if (status == 304) {
                progress = 1;
                return;
            }

            var chunked = headers.Get ("Transfer-Encoding").ToLower() == "chunked";

            /*
            //This code would break requests coming from HTTP/1.0

            if(!chunked && !headers.Contains("Content-Length")) {
                progress = 1;
                return;
            }
            */

            if(this.request.method.ToLower() == "head") {
                progress = 1;
                return;
            }

            Stream output = (Stream)bodyStream;
            if(output == null) {
                output = new MemoryStream();
            }

            if (chunked) {
                Protocol.ReadChunks (inputStream, output, ref progress);
                Protocol.CollectHeaders (inputStream, headers); //Trailers
            } else {
                Protocol.ReadBody (inputStream, output, headers, false, ref progress);
            }

            if(bodyStream == null) {
                output.Seek (0, SeekOrigin.Begin);
                Stream outputStream = output;

                var zipped = headers.Get ("Content-Encoding").ToLower() == "gzip";
                if(zipped) {
                    outputStream = new GZipStream (output, CompressionMode.Decompress);
                } else {
                    outputStream = output;
                }

                bytes = new byte[0];
                var buffer = new byte[1024];
                var count = -1;
                while (count != 0) {
                    count = outputStream.Read (buffer, 0, buffer.Length);
                    var offset = bytes.Length;
                    Array.Resize<byte> (ref bytes, offset + count);
                    Array.Copy (buffer, 0, bytes, offset, count);
                }
                outputStream.Dispose();
            }
        }