class Chef::HTTP::Decompressor

Middleware-ish class for handling compression in HTTP responses.

Constants

CONTENT_ENCODING
DEFLATE
GZIP
IDENTITY

Public Class Methods

new(opts = {}) click to toggle source
# File lib/chef/http/decompressor.rb, line 53
def initialize(opts = {})
  @disable_gzip = false
  handle_options(opts)
end

Public Instance Methods

decompress_body(response) click to toggle source
# File lib/chef/http/decompressor.rb, line 77
def decompress_body(response)
  if gzip_disabled? || response.body.nil?
    response.body
  else
    case response[CONTENT_ENCODING]
    when GZIP
      Chef::Log.trace "Decompressing gzip response"
      Zlib::Inflate.new(Zlib::MAX_WBITS + 16).inflate(response.body)
    when DEFLATE
      Chef::Log.trace "Decompressing deflate response"
      Zlib::Inflate.inflate(response.body)
    else
      response.body
    end
  end
end
gzip_disabled?() click to toggle source

gzip is disabled using the disable_gzip => true option in the constructor. When gzip is disabled, no 'Accept-Encoding' header will be set, and the response will not be decompressed, no matter what the Content-Encoding header of the response is. The intended use case for this is to work around situations where you request file.tar.gz, but the server responds with a content type of tar and a content encoding of gzip, tricking the client into decompressing the response so you end up with a tar archive (no gzip) named file.tar.gz

# File lib/chef/http/decompressor.rb, line 126
def gzip_disabled?
  @disable_gzip
end
handle_request(method, url, headers = {}, data = false) click to toggle source
# File lib/chef/http/decompressor.rb, line 58
def handle_request(method, url, headers = {}, data = false)
  headers[HTTPRequest::ACCEPT_ENCODING] = HTTPRequest::ENCODING_GZIP_DEFLATE unless gzip_disabled?
  [method, url, headers, data]
end
handle_response(http_response, rest_request, return_value) click to toggle source
# File lib/chef/http/decompressor.rb, line 63
def handle_response(http_response, rest_request, return_value)
  # temporary hack, skip processing if return_value is false
  # needed to keep conditional get stuff working correctly.
  return [http_response, rest_request, return_value] if return_value == false

  response_body = decompress_body(http_response)
  http_response.body.replace(response_body) if http_response.body.respond_to?(:replace)
  [http_response, rest_request, return_value]
end
handle_stream_complete(http_response, rest_request, return_value) click to toggle source
# File lib/chef/http/decompressor.rb, line 73
def handle_stream_complete(http_response, rest_request, return_value)
  [http_response, rest_request, return_value]
end
stream_response_handler(response) click to toggle source

This isn't used when this class is used as middleware; it returns an object you can use to unzip/inflate a streaming response.

# File lib/chef/http/decompressor.rb, line 96
def stream_response_handler(response)
  if gzip_disabled?
    Chef::Log.trace "disable_gzip is set. \
      Not using #{response[CONTENT_ENCODING]} \
      and initializing noop stream deflator."
    NoopInflater.new
  else
    case response[CONTENT_ENCODING]
    when GZIP
      Chef::Log.trace "Initializing gzip stream deflator"
      GzipInflater.new
    when DEFLATE
      Chef::Log.trace "Initializing deflate stream deflator"
      DeflateInflater.new
    else
      Chef::Log.trace "content_encoding = '#{response[CONTENT_ENCODING]}' \
        initializing noop stream deflator."
      NoopInflater.new
    end
  end
end

Private Instance Methods

handle_options(opts) click to toggle source
# File lib/chef/http/decompressor.rb, line 132
def handle_options(opts)
  opts.each do |name, value|
    case name.to_s
    when "disable_gzip"
      @disable_gzip = value
    end
  end
end