Sha256: 28bcdce3383bfc33df7e10c876fe341fbba76c3083336c7792b447e419d85d6c

Contents?: true

Size: 1.67 KB

Versions: 1

Compression:

Stored size: 1.67 KB

Contents

require "set"

class HTTP::Session
  module Features
    class AutoInflate < HTTP::Feature
      def initialize(br: false)
        load_dependencies if br

        @supported_encoding = Set.new(%w[deflate gzip x-gzip])
        @supported_encoding.add("br") if br
        @supported_encoding.freeze
      end

      def wrap_response(response)
        content_encoding = response.headers.get(HTTP::Headers::CONTENT_ENCODING).first
        return response unless content_encoding && @supported_encoding.include?(content_encoding)

        content =
          case content_encoding
          when "br" then brotli_inflate(response.body)
          else inflate(response.body)
          end
        response.headers.delete(HTTP::Headers::CONTENT_ENCODING)
        response.headers[HTTP::Headers::CONTENT_LENGTH] = content.length

        options = {
          status: response.status,
          version: response.version,
          headers: response.headers,
          proxy_headers: response.proxy_headers,
          body: HTTP::Session::Response::StringBody.new(content),
          request: response.request
        }
        HTTP::Response.new(options)
      end

      private

      def load_dependencies
        require "brotli"
      rescue LoadError
        raise LoadError,
          "Specified 'brotli' for inflate, but the gem is not loaded. Add `gem 'brotli'` to your Gemfile."
      end

      def brotli_inflate(body)
        Brotli.inflate(body)
      end

      def inflate(body)
        zstream = Zlib::Inflate.new(32 + Zlib::MAX_WBITS)
        zstream.inflate(body)
      ensure
        zstream.close
      end

      HTTP::Options.register_feature(:hsf_auto_inflate, self)
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
ruby-http-session-1.0.1 lib/http/session/features/auto_inflate.rb