Skip to content

Commit

Permalink
Fix regarding AWS signatures #32 (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrkamel authored Sep 27, 2022
1 parent f665fd7 commit be037ba
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@

# CHANGELOG

## v3.7.2

* Fix wrong AWS signatures by generating the json before passing it to http-rb

## v3.7.1

* Fix thread-safety issue of http-rb
Expand Down
1 change: 0 additions & 1 deletion lib/search_flip/aws_sigv4_plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ def call(request, method, uri, options = {})
}

signature_request[:body] = options[:body] if options.key?(:body)
signature_request[:body] = options[:json].respond_to?(:to_str) ? options[:json] : JSON.generate(options[:json]) if options[:json]

signature = signer.sign_request(signature_request)

Expand Down
17 changes: 15 additions & 2 deletions lib/search_flip/http_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,22 @@ class << self
private

def execute(method, uri, options = {})
final_request = plugins.inject(self) { |res, cur| cur.call(res, method, uri, options) }
opts = options.dup
final_request = self

if opts[:json]
# Manually generate and pass the json body to http-rb to guarantee that
# we have the same json which is used for aws signatures and to
# guarantee that json is always generated as stated in the config

opts[:body] = JSON.generate(opts.delete(:json))
final_request = final_request.headers(content_type: "application/json")
end

final_request = plugins.inject(final_request) { |res, cur| cur.call(res, method, uri, opts) }
final_request = final_request.headers({}) # Prevent thread-safety issue of http-rb: https://github.com/httprb/http/issues/558
response = final_request.request.send(method, uri, options)

response = final_request.request.send(method, uri, opts)

raise SearchFlip::ResponseError.new(code: response.code, body: response.body.to_s) unless response.status.success?

Expand Down
2 changes: 1 addition & 1 deletion lib/search_flip/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module SearchFlip
VERSION = "3.7.1"
VERSION = "3.7.2"
end
6 changes: 4 additions & 2 deletions spec/search_flip/aws_sigv4_plugin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,17 @@
end

it "feeds the http method, full url and body to the signer" do
body = JSON.generate(key: "value")

signing_request = {
http_method: "GET",
url: "http://localhost/index?param=value",
body: JSON.generate(key: "value")
body: body
}

expect(plugin.signer).to receive(:sign_request).with(signing_request).and_call_original

plugin.call(client, :get, "http://localhost/index", params: { param: "value" }, json: { key: "value" })
plugin.call(client, :get, "http://localhost/index", params: { param: "value" }, body: body)
end
end
end
6 changes: 6 additions & 0 deletions spec/search_flip/http_client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ def initialize

expect(SearchFlip::HTTPClient.new.send(method, "http://localhost/path", body: "body", params: { key: "value" }).body.to_s).to eq("success")
end

it "generates json, passes it as body and sets the content type when the json option is used" do
stub_request(method, "http://localhost/path").with(body: '{"key":"value"}', headers: { "Content-Type" => "application/json" }).to_return(body: "success")

expect(SearchFlip::HTTPClient.new.send(method, "http://localhost/path", json: { "key" => "value" }).body.to_s).to eq("success")
end
end
end

Expand Down

0 comments on commit be037ba

Please sign in to comment.