From b444edf8e55ddf7e4bb5ab967cdd8ad9c9c9ec29 Mon Sep 17 00:00:00 2001 From: Hakim Lahlou <30755392+HDLahlou@users.noreply.github.com> Date: Tue, 14 Sep 2021 17:47:03 -0400 Subject: [PATCH] Hdl 285 paypal sdk header: Fixing Case Sensitivity (#11) * Config Encoder and Client to enforce lowercase Content Types and Unit tests * Updated version, changelog, and license Co-authored-by: Hakim --- CHANGELOG.md | 6 ++++ LICENSE | 2 +- lib/paypalhttp/encoder.rb | 1 + lib/paypalhttp/http_client.rb | 8 ++++- lib/paypalhttp/version.rb | 2 +- spec/paypalhttp/encoder_spec.rb | 27 +++++++++++++++ spec/paypalhttp/http_client_spec.rb | 51 +++++++++++++++++++++++++++++ 7 files changed, 94 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db6bd33..f5e48fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.0.1 +* Fix Case Sensitivity of Content Type for deserialization process + +## 1.0.0 +* Fix Case Sensitivity of Acessing Headers by formatting beforehand + ## 0.5.0 * Add support for multipart/form-data file uploads with JSON content FormParts. diff --git a/LICENSE b/LICENSE index 9e671b2..1c8dec7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009-2019 PayPal, Inc. +Copyright (c) 2009-2021 PayPal, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/lib/paypalhttp/encoder.rb b/lib/paypalhttp/encoder.rb index 5c67606..5c694d1 100644 --- a/lib/paypalhttp/encoder.rb +++ b/lib/paypalhttp/encoder.rb @@ -41,6 +41,7 @@ def deserialize_response(resp, headers) raise UnsupportedEncodingError.new('HttpResponse did not have Content-Type header set') unless headers && (headers['content-type']) content_type = _extract_header(headers, 'content-type') + content_type.downcase! enc = _encoder(content_type) raise UnsupportedEncodingError.new("Unable to deserialize response with Content-Type #{content_type}. Supported decodings are #{supported_encodings}") unless enc diff --git a/lib/paypalhttp/http_client.rb b/lib/paypalhttp/http_client.rb index a518141..3d35673 100644 --- a/lib/paypalhttp/http_client.rb +++ b/lib/paypalhttp/http_client.rb @@ -28,7 +28,13 @@ def has_body(request) def format_headers(headers) formatted_headers = {} headers.each do |key, value| - formatted_headers[key.downcase] = value + # TODO: Since header is treated as a hash, val is in an array. + # Will this cause an issue when accessing and modifying val + # Ensure this is the case and will not propegate access issues/errors + if key.casecmp("content-type") == 0 + value[0].downcase! + end + formatted_headers[key.downcase] = value end formatted_headers end diff --git a/lib/paypalhttp/version.rb b/lib/paypalhttp/version.rb index 3277f64..50b5ea9 100644 --- a/lib/paypalhttp/version.rb +++ b/lib/paypalhttp/version.rb @@ -1 +1 @@ -VERSION = "1.0.0" +VERSION = "1.0.1" diff --git a/spec/paypalhttp/encoder_spec.rb b/spec/paypalhttp/encoder_spec.rb index 97315c1..ba60bd4 100644 --- a/spec/paypalhttp/encoder_spec.rb +++ b/spec/paypalhttp/encoder_spec.rb @@ -205,6 +205,26 @@ expect(deserialized).to eq(expected) end + it 'deserializes the response when content-type == application/json: case insensitive' do + expected = { + "string" => "value", + "number" => 1.23, + "bool" => true, + "array" => ["one", "two", "three"], + "nested" => { + "nested_string" => "nested_value", + "nested_array" => [1,2,3] + } + } + + headers = {"content-type" => ["application/JSON; charset=utf8"]} + body = '{"string":"value","number":1.23,"bool":true,"array":["one","two","three"],"nested":{"nested_string":"nested_value","nested_array":[1,2,3]}}' + + deserialized = Encoder.new.deserialize_response(body, headers) + + expect(deserialized).to eq(expected) + end + it 'deserializes the response when content-type == text/*' do headers = {"content-type" => ["text/plain; charset=utf8"]} body = 'some text' @@ -212,6 +232,13 @@ expect(Encoder.new.deserialize_response(body, headers)).to eq('some text') end + it 'deserializes the response when content-type == text/*: case insensitive' do + headers = {"content-type" => ["TEXT/plain; charset=utf8"]} + body = 'some text' + + expect(Encoder.new.deserialize_response(body, headers)).to eq('some text') + end + it 'throws when attempting to deserialize multipart/*' do headers = {"content-type" => ["multipart/form-data"]} body = 'some multipart encoded data here' diff --git a/spec/paypalhttp/http_client_spec.rb b/spec/paypalhttp/http_client_spec.rb index 97a202a..d8653f8 100644 --- a/spec/paypalhttp/http_client_spec.rb +++ b/spec/paypalhttp/http_client_spec.rb @@ -226,6 +226,57 @@ def _inj(req) expect(resp.result).to eq(return_data) end + it 'handles json array result: case insensitive' do + WebMock.enable! + + return_data = ["one", "two"] + + http_client = HttpClient.new(@environment) + + stub_request(:get, @environment.base_url + "/v1/api") + .to_return(body: JSON.generate(return_data), status: 200, headers: {"Content-Type" => "application/JSON"}) + + req = OpenStruct.new({:verb => "GET", :path => "/v1/api"}) + + resp = http_client.execute(req) + + expect(resp.result).to eq(return_data) + end + + it 'handles plain text result' do + WebMock.enable! + + return_data = "value" + + http_client = HttpClient.new(@environment) + + stub_request(:get, @environment.base_url + "/v1/api") + .to_return(body: return_data, status: 200, headers: {"Content-Type" => "text/plain; charset=utf8"}) + + req = OpenStruct.new({:verb => "GET", :path => "/v1/api"}) + + resp = http_client.execute(req) + + expect(resp.result).to eq(return_data) + end + + it 'handles plain text result: case insensitive' do + WebMock.enable! + + return_data = "value" + + http_client = HttpClient.new(@environment) + + stub_request(:get, @environment.base_url + "/v1/api") + .to_return(body: return_data, status: 200, headers: {"Content-Type" => "TEXT/plain; charset=utf8"}) + + req = OpenStruct.new({:verb => "GET", :path => "/v1/api"}) + + resp = http_client.execute(req) + + expect(resp.result).to eq(return_data) + end + it 'deserializes nested response object into nested openstruct response' do WebMock.enable!