mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-10-07 00:05:02 -04:00
simplified the compression API, sharing more across compressors
This commit is contained in:
parent
8b45c626ce
commit
6319d83b81
@ -44,10 +44,11 @@ module HTTPX
|
|||||||
class CompressEncoder
|
class CompressEncoder
|
||||||
attr_reader :content_type
|
attr_reader :content_type
|
||||||
|
|
||||||
def initialize(raw)
|
def initialize(raw, encoder)
|
||||||
@content_type = raw.content_type
|
@content_type = raw.content_type
|
||||||
@raw = raw.respond_to?(:read) ? raw : StringIO.new(raw.to_s)
|
@raw = raw.respond_to?(:read) ? raw : StringIO.new(raw.to_s)
|
||||||
@buffer = StringIO.new("".b, File::RDWR)
|
@buffer = StringIO.new("".b, File::RDWR)
|
||||||
|
@encoder = encoder
|
||||||
end
|
end
|
||||||
|
|
||||||
def each(&blk)
|
def each(&blk)
|
||||||
@ -56,7 +57,7 @@ module HTTPX
|
|||||||
@buffer.rewind
|
@buffer.rewind
|
||||||
return @buffer.each(&blk)
|
return @buffer.each(&blk)
|
||||||
end
|
end
|
||||||
compress(&blk)
|
@encoder.compress(@raw, @buffer, &blk)
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
@ -66,7 +67,7 @@ module HTTPX
|
|||||||
end
|
end
|
||||||
|
|
||||||
def bytesize
|
def bytesize
|
||||||
compress
|
@encoder.compress(@raw, @buffer)
|
||||||
@buffer.size
|
@buffer.size
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -22,18 +22,33 @@ module HTTPX
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module Encoder
|
||||||
|
module_function
|
||||||
|
|
||||||
|
def compress(raw, buffer, chunk_size: 16_384)
|
||||||
|
return unless buffer.size.zero?
|
||||||
|
raw.rewind
|
||||||
|
begin
|
||||||
|
while chunk = raw.read(chunk_size)
|
||||||
|
compressed = ::Brotli.deflate(chunk)
|
||||||
|
buffer << compressed
|
||||||
|
yield compressed if block_given?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
module BrotliTranscoder
|
module BrotliTranscoder
|
||||||
module_function
|
module_function
|
||||||
|
|
||||||
def encode(payload)
|
def encode(payload)
|
||||||
::Brotli.deflate(payload)
|
CompressEncoder.new(payload, Encoder)
|
||||||
end
|
end
|
||||||
|
|
||||||
def decode(io)
|
def decode(io)
|
||||||
::Brotli.inflate(io)
|
::Brotli.inflate(io)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
register_plugin :"compression/brotli", Compression::Brotli
|
register_plugin :"compression/brotli", Compression::Brotli
|
||||||
|
@ -15,24 +15,24 @@ module HTTPX
|
|||||||
end
|
end
|
||||||
|
|
||||||
module DeflateTranscoder
|
module DeflateTranscoder
|
||||||
class Encoder < CompressEncoder
|
module Encoder
|
||||||
private
|
module_function
|
||||||
|
|
||||||
def compress
|
def compress(raw, buffer, chunk_size: 16_384)
|
||||||
return unless @buffer.size.zero?
|
return unless buffer.size.zero?
|
||||||
@raw.rewind
|
raw.rewind
|
||||||
begin
|
begin
|
||||||
deflater = Zlib::Deflate.new(Zlib::BEST_COMPRESSION,
|
deflater = Zlib::Deflate.new(Zlib::BEST_COMPRESSION,
|
||||||
Zlib::MAX_WBITS,
|
Zlib::MAX_WBITS,
|
||||||
Zlib::MAX_MEM_LEVEL,
|
Zlib::MAX_MEM_LEVEL,
|
||||||
Zlib::HUFFMAN_ONLY)
|
Zlib::HUFFMAN_ONLY)
|
||||||
while chunk = @raw.read(16_384)
|
while chunk = raw.read(chunk_size)
|
||||||
compressed = deflater.deflate(chunk)
|
compressed = deflater.deflate(chunk)
|
||||||
@buffer << compressed
|
buffer << compressed
|
||||||
yield compressed if block_given?
|
yield compressed if block_given?
|
||||||
end
|
end
|
||||||
last = deflater.finish
|
last = deflater.finish
|
||||||
@buffer << last
|
buffer << last
|
||||||
yield last if block_given?
|
yield last if block_given?
|
||||||
ensure
|
ensure
|
||||||
deflater.close
|
deflater.close
|
||||||
@ -70,7 +70,7 @@ module HTTPX
|
|||||||
end
|
end
|
||||||
|
|
||||||
def encode(payload)
|
def encode(payload)
|
||||||
Encoder.new(payload)
|
CompressEncoder.new(payload, Encoder)
|
||||||
end
|
end
|
||||||
|
|
||||||
def decode(io)
|
def decode(io)
|
||||||
|
@ -14,43 +14,43 @@ module HTTPX
|
|||||||
end
|
end
|
||||||
|
|
||||||
module GZIPTranscoder
|
module GZIPTranscoder
|
||||||
class Encoder < CompressEncoder
|
class Encoder
|
||||||
def write(chunk)
|
def compress(raw, buffer, chunk_size: 16_384)
|
||||||
@compressed_chunk = chunk
|
return unless buffer.size.zero?
|
||||||
end
|
raw.rewind
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def compressed_chunk
|
|
||||||
compressed = @compressed_chunk
|
|
||||||
compressed
|
|
||||||
ensure
|
|
||||||
@compressed_chunk = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def compress
|
|
||||||
return unless @buffer.size.zero?
|
|
||||||
@raw.rewind
|
|
||||||
begin
|
begin
|
||||||
gzip = Zlib::GzipWriter.new(self)
|
gzip = Zlib::GzipWriter.new(self)
|
||||||
|
|
||||||
while chunk = @raw.read(16_384)
|
while chunk = raw.read(chunk_size)
|
||||||
gzip.write(chunk)
|
gzip.write(chunk)
|
||||||
gzip.flush
|
gzip.flush
|
||||||
compressed = compressed_chunk
|
compressed = compressed_chunk
|
||||||
@buffer << compressed
|
buffer << compressed
|
||||||
yield compressed if block_given?
|
yield compressed if block_given?
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
gzip.close
|
gzip.close
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def write(chunk)
|
||||||
|
@compressed_chunk = chunk
|
||||||
|
end
|
||||||
|
|
||||||
|
def compressed_chunk
|
||||||
|
compressed = @compressed_chunk
|
||||||
|
compressed
|
||||||
|
ensure
|
||||||
|
@compressed_chunk = nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module_function
|
module_function
|
||||||
|
|
||||||
def encode(payload)
|
def encode(payload)
|
||||||
Encoder.new(payload)
|
CompressEncoder.new(payload, Encoder.new)
|
||||||
end
|
end
|
||||||
|
|
||||||
def decode(io)
|
def decode(io)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user