mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-10-04 00:00:37 -04:00
Merge branch 'fix-hexdigest-on-compressed-bodies' into 'master'
aws sigv4support calculation of hexdigest on top of compressed bodies in correct way See merge request os85/httpx!355
This commit is contained in:
commit
8797434ae7
@ -89,7 +89,7 @@ module HTTPX
|
||||
sts = "#{algo_line}" \
|
||||
"\n#{datetime}" \
|
||||
"\n#{credential_scope}" \
|
||||
"\n#{hexdigest(creq)}"
|
||||
"\n#{OpenSSL::Digest.new(@algorithm).hexdigest(creq)}"
|
||||
|
||||
# signature
|
||||
k_date = hmac("#{upper_provider_prefix}#{@credentials.password}", date)
|
||||
@ -110,22 +110,38 @@ module HTTPX
|
||||
private
|
||||
|
||||
def hexdigest(value)
|
||||
if value.respond_to?(:to_path)
|
||||
# files, pathnames
|
||||
OpenSSL::Digest.new(@algorithm).file(value.to_path).hexdigest
|
||||
elsif value.respond_to?(:each)
|
||||
digest = OpenSSL::Digest.new(@algorithm)
|
||||
digest = OpenSSL::Digest.new(@algorithm)
|
||||
|
||||
mb_buffer = value.each.with_object("".b) do |chunk, buffer|
|
||||
buffer << chunk
|
||||
break if buffer.bytesize >= 1024 * 1024
|
||||
if value.respond_to?(:read)
|
||||
if value.respond_to?(:to_path)
|
||||
# files, pathnames
|
||||
digest.file(value.to_path).hexdigest
|
||||
else
|
||||
# gzipped request bodies
|
||||
raise Error, "request body must be rewindable" unless value.respond_to?(:rewind)
|
||||
|
||||
buffer = Tempfile.new("httpx", encoding: Encoding::BINARY, mode: File::RDWR)
|
||||
begin
|
||||
IO.copy_stream(value, buffer)
|
||||
buffer.flush
|
||||
|
||||
digest.file(buffer.to_path).hexdigest
|
||||
ensure
|
||||
value.rewind
|
||||
buffer.close
|
||||
buffer.unlink
|
||||
end
|
||||
end
|
||||
else
|
||||
# error on endless generators
|
||||
raise Error, "hexdigest for endless enumerators is not supported" if value.unbounded_body?
|
||||
|
||||
mb_buffer = value.each.with_object("".b) do |chunk, b|
|
||||
b << chunk
|
||||
break if b.bytesize >= 1024 * 1024
|
||||
end
|
||||
|
||||
digest.update(mb_buffer)
|
||||
value.rewind
|
||||
digest.hexdigest
|
||||
else
|
||||
OpenSSL::Digest.new(@algorithm).hexdigest(value)
|
||||
digest.hexdigest(mb_buffer)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "forwardable"
|
||||
require "uri"
|
||||
require "stringio"
|
||||
require "zlib"
|
||||
|
||||
module HTTPX
|
||||
|
@ -1,13 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "forwardable"
|
||||
require_relative "body_reader"
|
||||
|
||||
module HTTPX
|
||||
module Transcoder
|
||||
class Deflater
|
||||
extend Forwardable
|
||||
|
||||
attr_reader :content_type
|
||||
|
||||
def initialize(body)
|
||||
@ -51,6 +48,12 @@ module HTTPX
|
||||
@closed = true
|
||||
end
|
||||
|
||||
def rewind
|
||||
return unless @buffer
|
||||
|
||||
@buffer.rewind
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# rubocop:disable Naming/MemoizedInstanceVariableName
|
||||
|
@ -41,7 +41,7 @@ module HTTPX
|
||||
) -> untyped
|
||||
|
||||
|
||||
def hexdigest: (bodyIO value) -> String
|
||||
def hexdigest: (Request::Body value) -> String
|
||||
|
||||
def hmac: (String key, String value) -> String
|
||||
|
||||
|
@ -58,6 +58,23 @@ class HTTPXAwsSigv4Test < Minitest::Test
|
||||
assert request.headers["x-amz-content-sha256"] == Digest::SHA256.hexdigest("abcd")
|
||||
end
|
||||
|
||||
def test_plugin_aws_sigv4_x_amz_content_sha256_array
|
||||
request = sigv4_session.build_request("GET", "http://domain.com", body: %w[a b c d])
|
||||
assert request.headers["x-amz-content-sha256"] == Digest::SHA256.hexdigest("abcd")
|
||||
end
|
||||
|
||||
def test_plugin_aws_sigv4_x_amz_content_sha256_endless
|
||||
body = Enumerator.new do |y|
|
||||
loop do
|
||||
y << "a"
|
||||
end
|
||||
end
|
||||
ex = assert_raises(HTTPX::Error) do
|
||||
sigv4_session.build_request("GET", "http://domain.com", body: body)
|
||||
end
|
||||
assert ex.message.include?("hexdigest for endless enumerators is not supported")
|
||||
end
|
||||
|
||||
def test_plugin_aws_sigv4_x_amz_content_sha256_file
|
||||
body = Tempfile.new("httpx")
|
||||
body.write("abcd")
|
||||
@ -72,6 +89,21 @@ class HTTPXAwsSigv4Test < Minitest::Test
|
||||
end
|
||||
end
|
||||
|
||||
def test_plugin_aws_sigv4_x_amz_content_sha256_compressed_file
|
||||
body = Tempfile.new("httpx")
|
||||
body.write("abcd")
|
||||
body.flush
|
||||
|
||||
request = sigv4_session.build_request("GET", "http://domain.com", body: body, headers: { "content-encoding" => "gzip" })
|
||||
|
||||
assert request.headers["x-amz-content-sha256"] == Digest::SHA256.hexdigest(request.body.read)
|
||||
ensure
|
||||
if defined?(body)
|
||||
body.close
|
||||
body.unlink
|
||||
end
|
||||
end
|
||||
|
||||
def test_plugin_aws_sigv4_authorization_unsigned_headers
|
||||
request = sigv4_session(
|
||||
service: "SERVICE",
|
||||
|
Loading…
x
Reference in New Issue
Block a user