Statistics
| Branch: | Revision:

root / trunk / hammock / src / net35 / Hammock.Silverlight / Compat / GzipHttpWebResponse.cs @ 0eea575a

History | View | Annotate | Download (3.5 kB)

1
using System;
2
using System.IO;
3
using System.Net;
4
using System.Text;
5
using ICSharpCode.SharpZipLib.Silverlight.GZip;
6
using ICSharpCode.SharpZipLib.Silverlight.Zip;
7

    
8
namespace Hammock.Silverlight.Compat
9
{
10
    public class GzipHttpWebResponse : HttpWebResponse
11
    {
12
        private const int ChunkSize = 2048;
13
       
14
        private readonly HttpWebResponse _response;
15

    
16
        public override string Method
17
        {
18
            get { return _response.Method; }
19
        }
20

    
21
        public override HttpStatusCode StatusCode
22
        {
23
            get { return _response.StatusCode; }
24
        }
25

    
26
        public override string StatusDescription
27
        {
28
            get { return _response.StatusDescription; }
29
        }
30

    
31
        public GzipHttpWebResponse(HttpWebResponse response)
32
        {
33
            _response = response;
34
        }
35

    
36
        public override void Close()
37
        {
38
            _response.Close();
39
        }
40

    
41
        public override Stream GetResponseStream()
42
        {
43
            Stream compressed = null;
44

    
45
            var responseStream = _response.GetResponseStream();
46

    
47
#if !WindowsPhone
48
            var contentEncoding = _response.Headers["Content-Encoding"];
49
            if (contentEncoding != null && contentEncoding.Contains("gzip"))
50
            {
51
                compressed = new GZipInputStream(responseStream);
52
            }
53
            else if (contentEncoding != null && contentEncoding.Contains("deflate"))
54
            {
55
                compressed = new ZipInputStream(responseStream);
56
            }
57
#else
58
            byte[] marker;
59
            responseStream = ReadIntoMemoryStream(responseStream, out marker);
60
            if (marker.Length > 2 && (marker[0] == 31 && marker[1] == 139))
61
            {
62
                compressed = new GZipInputStream(responseStream);
63
            }
64
#endif
65
            if (compressed != null)
66
            {
67
                var decompressed = new MemoryStream();
68
                var size = ChunkSize;
69
                var buffer = new byte[ChunkSize];
70
                while (true)
71
                {
72
                    size = compressed.Read(buffer, 0, size);
73
                    if (size > 0)
74
                    {
75
                        decompressed.Write(buffer, 0, size);
76
                    }
77
                    else
78
                    {
79
                        break;
80
                    }
81
                }
82
                decompressed.Seek(0, SeekOrigin.Begin);
83
                return decompressed;
84
            }
85

    
86
            return responseStream;
87
        }
88

    
89
        // [DC]: We have to read the entire stream in as HTTP response streams are read-once
90
        private static MemoryStream ReadIntoMemoryStream(Stream stream, out byte[] marker)
91
        {
92
            var buffer = new byte[8192];
93
            var ms = new MemoryStream();
94

    
95
            int read;
96
            while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
97
            {
98
                ms.Write(buffer, 0, read);
99
            }
100

    
101
            ms.Position = 0;
102
            marker = new byte[2];
103
            ms.Read(marker, 0, 2);
104
            ms.Position = 0;
105

    
106
            return ms;
107
        }
108

    
109
        public override long ContentLength
110
        {
111
            get { return _response.ContentLength; }
112
        }
113

    
114
        public override string ContentType
115
        {
116
            get { return _response.ContentType; }
117
        }
118

    
119
        public override WebHeaderCollection Headers
120
        {
121
            get { return _response.Headers; }
122
        }
123

    
124
        public override System.Uri ResponseUri
125
        {
126
            get { return _response.ResponseUri; }
127
        }
128
    }
129
}