blob: 722ecfe24d52ba652aa201edf4096f36de011096 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
require 'puppet/network/http'
module Puppet::Network::HTTP::Compression
# this module function allows to use the right underlying
# methods depending on zlib presence
def module
return Active if Puppet.features.zlib?
return None
end
module_function :module
module Active
require 'zlib'
require 'stringio'
# return an uncompressed body if the response has been
# compressed
def uncompress_body(response)
case response['content-encoding']
when 'gzip'
return Zlib::GzipReader.new(StringIO.new(response.body)).read
when 'deflate'
return Zlib::Inflate.new().inflate(response.body)
when nil, 'identity'
return response.body
else
raise Net::HTTPError.new("Unknown content encoding - #{response['content-encoding']}", response)
end
end
def uncompress(response)
raise Net::HTTPError.new("No block passed") unless block_given?
case response['content-encoding']
when 'gzip','deflate'
uncompressor = ZlibAdapter.new
when nil, 'identity'
uncompressor = IdentityAdapter.new
else
raise Net::HTTPError.new("Unknown content encoding - #{response['content-encoding']}", response)
end
yield uncompressor
uncompressor.close
end
def add_accept_encoding(headers={})
headers['accept-encoding'] = 'gzip; q=1.0, deflate; q=1.0; identity' if Puppet.settings[:http_compression]
headers
end
# This adapters knows how to uncompress both 'zlib' stream (the deflate algorithm from Content-Encoding)
# and GZip streams.
class ZlibAdapter
def initialize
# Create an inflater that knows to parse GZip streams and zlib streams.
# This uses a property of the C Zlib library, documented as follow:
# windowBits can also be greater than 15 for optional gzip decoding. Add
# 32 to windowBits to enable zlib and gzip decoding with automatic header
# detection, or add 16 to decode only the gzip format (the zlib format will
# return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
# a crc32 instead of an adler32.
@uncompressor = Zlib::Inflate.new(15 + 32)
@first = true
end
def uncompress(chunk)
out = @uncompressor.inflate(chunk)
@first = false
return out
rescue Zlib::DataError => z
# it can happen that we receive a raw deflate stream
# which might make our inflate throw a data error.
# in this case, we try with a verbatim (no header)
# deflater.
@uncompressor = Zlib::Inflate.new
retry if @first
raise
end
def close
@uncompressor.finish
@uncompressor.close
end
end
end
module None
def uncompress_body(response)
response.body
end
def add_accept_encoding(headers)
headers
end
def uncompress(response)
yield IdentityAdapter.new
end
end
class IdentityAdapter
def uncompress(chunk)
chunk
end
def close
end
end
end
|