removed the compression modules from the transcoders, using them directly in the plugin, rewrote the encoder to be more interchangeable

This commit is contained in:
HoneyryderChuck 2018-01-14 22:46:28 +00:00
parent 72b90c3f17
commit dcd90b706a
4 changed files with 127 additions and 125 deletions

View File

@ -15,17 +15,28 @@ module HTTPX
end
end
module RequestBodyMethods
def initialize(*)
super
return if @body.nil?
@headers.get("content-encoding").each do |encoding|
@body = Encoder.new(@body, Compression.registry(encoding).encoder)
end
@headers["content-length"] = @body.bytesize unless chunked?
end
end
module ResponseBodyMethods
def initialize(*)
super
@_decoders = @headers.get("content-encoding").map do |encoding|
Transcoder.registry(encoding).decoder
Compression.registry(encoding).decoder
end
@_compressed_length = if @headers.key?("content-length")
@headers["content-length"].to_i
else
Float::INFINITY
end
@headers["content-length"].to_i
else
Float::INFINITY
end
end
def write(chunk)
@ -49,7 +60,48 @@ module HTTPX
buffer
end
end
class Encoder
def initialize(body, deflater)
@body = body.respond_to?(:read) ? body : StringIO.new(body.to_s)
@buffer = StringIO.new("".b, File::RDWR)
@deflater = deflater
end
def each(&blk)
return enum_for(__method__) unless block_given?
unless @buffer.size.zero?
@buffer.rewind
return @buffer.each(&blk)
end
deflate(&blk)
end
def bytesize
deflate
@buffer.size
end
def to_s
deflate
@buffer.rewind
@buffer.read
end
def close
@buffer.close
@body.close
end
private
def deflate(&blk)
return unless @buffer.size.zero?
@body.rewind
@deflater.deflate(@body, @buffer, chunk_size: 16_384, &blk)
end
end
class Decoder
extend Forwardable
@ -65,41 +117,6 @@ module HTTPX
@inflater.inflate(chunk)
end
end
class CompressEncoder
attr_reader :content_type
def initialize(raw, encoder)
@content_type = raw.content_type
@raw = raw.respond_to?(:read) ? raw : StringIO.new(raw.to_s)
@buffer = StringIO.new("".b, File::RDWR)
@encoder = encoder
end
def each(&blk)
return enum_for(__method__) unless block_given?
unless @buffer.size.zero?
@buffer.rewind
return @buffer.each(&blk)
end
@encoder.compress(@raw, @buffer, chunk_size: 16_384, &blk)
end
def to_s
compress
@buffer.rewind
@buffer.read
end
def bytesize
@encoder.compress(@raw, @buffer, chunk_size: 16_384)
@buffer.size
end
def close
# @buffer.close
end
end
end
register_plugin :compression, Compression
end

View File

@ -11,16 +11,13 @@ module HTTPX
end
def self.configure(*)
Transcoder.register "br", BrotliTranscoder
Compression.register "br", self
end
module Encoder
module_function
def compress(raw, buffer, chunk_size: )
return unless buffer.size.zero?
raw.rewind
def deflate(raw, buffer, chunk_size: )
begin
while chunk = raw.read(chunk_size)
compressed = ::Brotli.deflate(chunk)
@ -43,16 +40,14 @@ module HTTPX
end
end
module BrotliTranscoder
module_function
def encode(payload)
CompressEncoder.new(payload, Encoder)
end
def decoder
Decoder.new(BrotliWrapper)
end
module_function
def encoder
Encoder
end
def decoder
Decoder.new(BrotliWrapper)
end
end
end

View File

@ -10,45 +10,40 @@ module HTTPX
end
def self.configure(*)
Transcoder.register "deflate", DeflateTranscoder
Compression.register "deflate", self
end
module DeflateTranscoder
module Encoder
module_function
def compress(raw, buffer, chunk_size: )
return unless buffer.size.zero?
raw.rewind
begin
deflater = Zlib::Deflate.new(Zlib::BEST_COMPRESSION,
Zlib::MAX_WBITS,
Zlib::MAX_MEM_LEVEL,
Zlib::HUFFMAN_ONLY)
while chunk = raw.read(chunk_size)
compressed = deflater.deflate(chunk)
buffer << compressed
yield compressed if block_given?
end
last = deflater.finish
buffer << last
yield last if block_given?
ensure
deflater.close
end
end
end
module Encoder
module_function
def encode(payload)
CompressEncoder.new(payload, Encoder)
def deflate(raw, buffer, chunk_size: )
begin
deflater = Zlib::Deflate.new(Zlib::BEST_COMPRESSION,
Zlib::MAX_WBITS,
Zlib::MAX_MEM_LEVEL,
Zlib::HUFFMAN_ONLY)
while chunk = raw.read(chunk_size)
compressed = deflater.deflate(chunk)
buffer << compressed
yield compressed if block_given?
end
last = deflater.finish
buffer << last
yield last if block_given?
ensure
deflater.close
end
end
end
def decoder
Decoder.new(Zlib::Inflate.new(32 + Zlib::MAX_WBITS))
end
module_function
def encoder
Encoder
end
def decoder
Decoder.new(Zlib::Inflate.new(32 + Zlib::MAX_WBITS))
end
end
end

View File

@ -11,54 +11,49 @@ module HTTPX
end
def self.configure(*)
Transcoder.register "gzip", GZIPTranscoder
Compression.register "gzip", self
end
module GZIPTranscoder
class Encoder
def compress(raw, buffer, chunk_size: )
return unless buffer.size.zero?
raw.rewind
begin
gzip = Zlib::GzipWriter.new(self)
class Encoder
def deflate(raw, buffer, chunk_size: )
begin
gzip = Zlib::GzipWriter.new(self)
while chunk = raw.read(chunk_size)
gzip.write(chunk)
gzip.flush
compressed = compressed_chunk
buffer << compressed
yield compressed if block_given?
end
ensure
gzip.close
while chunk = raw.read(chunk_size)
gzip.write(chunk)
gzip.flush
compressed = compressed_chunk
buffer << compressed
yield compressed if block_given?
end
end
private
def write(chunk)
@compressed_chunk = chunk
end
def compressed_chunk
compressed = @compressed_chunk
compressed
ensure
@compressed_chunk = nil
gzip.close
end
end
module_function
def encode(payload)
CompressEncoder.new(payload, Encoder.new)
end
def decoder
Decoder.new(Zlib::Inflate.new(32 + Zlib::MAX_WBITS))
private
def write(chunk)
@compressed_chunk = chunk
end
def compressed_chunk
compressed = @compressed_chunk
compressed
ensure
@compressed_chunk = nil
end
end
module_function
def encoder
Encoder.new
end
def decoder
Decoder.new(Zlib::Inflate.new(32 + Zlib::MAX_WBITS))
end
end
end