diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4e0ab676..6231875b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
+* Made a new option `body_hash_enabled` which defaults to true to maintain backward compatibility with prior releases. Setting to `false` disables generation of a `oauth_body_hash` component as part of the signature computation.
### Fixed
diff --git a/lib/oauth/client/net_http.rb b/lib/oauth/client/net_http.rb
index 7a56b982..8b00f5f7 100644
--- a/lib/oauth/client/net_http.rb
+++ b/lib/oauth/client/net_http.rb
@@ -18,7 +18,7 @@ class HTTPGenericRequest
# * consumer - OAuth::Consumer instance
# * token - OAuth::Token instance
# * options - Request-specific options (e.g. +request_uri+, +consumer+, +token+, +scheme+,
- # +signature_method+, +nonce+, +timestamp+)
+ # +signature_method+, +nonce+, +timestamp+, +body_hash+)
#
# This method also modifies the User-Agent header to add the OAuth gem version.
#
@@ -29,7 +29,7 @@ def oauth!(http, consumer = nil, token = nil, options = {})
helper_options = oauth_helper_options(http, consumer, token, options)
@oauth_helper = OAuth::Client::Helper.new(self, helper_options)
@oauth_helper.amend_user_agent_header(self)
- @oauth_helper.hash_body if oauth_body_hash_required?
+ @oauth_helper.hash_body if oauth_body_hash_required?(helper_options)
send("set_oauth_#{helper_options[:scheme]}")
end
@@ -51,7 +51,7 @@ def oauth!(http, consumer = nil, token = nil, options = {})
def signature_base_string(http, consumer = nil, token = nil, options = {})
helper_options = oauth_helper_options(http, consumer, token, options)
@oauth_helper = OAuth::Client::Helper.new(self, helper_options)
- @oauth_helper.hash_body if oauth_body_hash_required?
+ @oauth_helper.hash_body if oauth_body_hash_required?(helper_options)
@oauth_helper.signature_base_string
end
@@ -64,7 +64,8 @@ def oauth_helper_options(http, consumer, token, options)
scheme: "header",
signature_method: nil,
nonce: nil,
- timestamp: nil }.merge(options)
+ timestamp: nil,
+ body_hash_enabled: true }.merge(options)
end
def oauth_full_request_uri(http, options)
@@ -87,8 +88,8 @@ def oauth_full_request_uri(http, options)
uri.to_s
end
- def oauth_body_hash_required?
- !@oauth_helper.token_request? && request_body_permitted? && !content_type.to_s.downcase.start_with?("application/x-www-form-urlencoded")
+ def oauth_body_hash_required?(options)
+ !@oauth_helper.token_request? && request_body_permitted? && !content_type.to_s.downcase.start_with?("application/x-www-form-urlencoded") && options[:body_hash_enabled]
end
def set_oauth_header
diff --git a/lib/oauth/consumer.rb b/lib/oauth/consumer.rb
index e916d54b..6787242e 100644
--- a/lib/oauth/consumer.rb
+++ b/lib/oauth/consumer.rb
@@ -64,6 +64,11 @@ class Consumer
# some_value - uses some_value
debug_output: nil,
+ # Defaults to producing a body_hash as part of the signature but
+ # can be disabled since it's not officially part of the OAuth 1.0
+ # spec. Possible values are true and false
+ body_hash_enabled: true,
+
oauth_version: "1.0"
}
@@ -78,7 +83,8 @@ class Consumer
# :http_method => :post,
# :request_token_path => "/oauth/example/request_token.php",
# :access_token_path => "/oauth/example/access_token.php",
- # :authorize_path => "/oauth/example/authorize.php"
+ # :authorize_path => "/oauth/example/authorize.php",
+ # :body_hash_enabled => false
# })
#
# Start the process by requesting a token
diff --git a/test/units/test_net_http_client.rb b/test/units/test_net_http_client.rb
index 111d156d..f92f4377 100644
--- a/test/units/test_net_http_client.rb
+++ b/test/units/test_net_http_client.rb
@@ -310,6 +310,16 @@ def test_that_post_bodies_signed_if_other_content_type
signature_base_string
end
+ def test_that_post_bodies_not_signed_if_body_hash_disabled
+ request = Net::HTTP::Post.new(@request_uri.path)
+ request.body = "baz"
+ request["Content-Type"] = "application/xml"
+ signature_base_string = request.signature_base_string(@http, @consumer, nil,
+ { nonce: @nonce, timestamp: @timestamp, body_hash_enabled: false })
+ assert_equal "POST&http%3A%2F%2Fexample.com%2Ftest&oauth_consumer_key%3Dconsumer_key_86cad9%26oauth_nonce%3D225579211881198842005988698334675835446%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1199645624%26oauth_version%3D1.0",
+ signature_base_string
+ end
+
def test_that_site_address_is_not_modified_in_place
options = { site: "http://twitter.com", request_endpoint: "http://api.twitter.com" }
request = Net::HTTP::Get.new("#{@request_uri.path}?#{request_parameters_to_s}")