mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-08-10 00:01:27 -04:00
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:
parent
72b90c3f17
commit
dcd90b706a
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user