Skip to content

Commit a5ae5bf

Browse files
committed
fix: ensure non utf-8 characters in the webook response do not cause an error in the Pact Broker response body
1 parent 273078b commit a5ae5bf

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

lib/pact_broker/domain/webhook_request.rb

+25-8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
require 'pact_broker/api/pact_broker_urls'
99
require 'pact_broker/build_http_options'
1010
require 'cgi'
11+
require 'delegate'
1112

1213
module PactBroker
1314

@@ -22,6 +23,24 @@ def initialize message, response
2223

2324
end
2425

26+
class WebhookResponseWithUtf8SafeBody < SimpleDelegator
27+
def body
28+
if unsafe_body
29+
unsafe_body.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')
30+
else
31+
unsafe_body
32+
end
33+
end
34+
35+
def unsafe_body
36+
__getobj__().body
37+
end
38+
39+
def unsafe_body?
40+
unsafe_body != body
41+
end
42+
end
43+
2544
class WebhookRequest
2645

2746
include PactBroker::Logging
@@ -110,9 +129,10 @@ def build_request uri, pact, verification, execution_logger
110129
def do_request uri, req
111130
logger.info "Making webhook #{uuid} request #{to_s}"
112131
options = PactBroker::BuildHttpOptions.call(uri)
113-
Net::HTTP.start(uri.hostname, uri.port, :ENV, options) do |http|
132+
response = Net::HTTP.start(uri.hostname, uri.port, :ENV, options) do |http|
114133
http.request req
115134
end
135+
WebhookResponseWithUtf8SafeBody.new(response)
116136
end
117137

118138
def log_response response, execution_logger, options
@@ -131,7 +151,7 @@ def response_body_hidden_message
131151
def log_response_to_application_logger response
132152
logger.info "Received response for webhook #{uuid} status=#{response.code}"
133153
logger.debug "headers=#{response.to_hash}"
134-
logger.debug "body=#{response.body}"
154+
logger.debug "body=#{response.unsafe_body}"
135155
end
136156

137157
def log_response_to_execution_logger response, execution_logger
@@ -140,15 +160,12 @@ def log_response_to_execution_logger response, execution_logger
140160
execution_logger.info "#{header.split("-").collect(&:capitalize).join('-')}: #{response[header]}"
141161
end
142162

143-
safe_body = nil
144-
145163
if response.body
146-
safe_body = response.body.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')
147-
if response.body != safe_body
164+
if response.unsafe_body?
148165
execution_logger.debug "Note that invalid UTF-8 byte sequences were removed from response body before saving the logs"
149166
end
167+
execution_logger.info response.body
150168
end
151-
execution_logger.info safe_body
152169
end
153170

154171
def log_completion_message options, execution_logger, success
@@ -182,7 +199,7 @@ def http_request(uri)
182199
end
183200

184201
def build_uri(pact, verification)
185-
URI(PactBroker::Webhooks::Render.call(url, pact, verification){ | value | CGI::escape(value)} )
202+
URI(PactBroker::Webhooks::Render.call(url, pact, verification){ | value | CGI::escape(value) if !value.nil? } )
186203
end
187204

188205
def url_with_credentials pact, verification

spec/lib/pact_broker/domain/webhook_request_spec.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ module Domain
299299
end
300300

301301
it "sets the response on the result" do
302-
expect(execute.response).to be_instance_of(Net::HTTPOK)
302+
expect(execute.response).to be_instance_of(WebhookResponseWithUtf8SafeBody)
303303
end
304304
end
305305

@@ -316,7 +316,7 @@ module Domain
316316
end
317317

318318
it "sets the response on the result" do
319-
expect(execute.response).to be_instance_of(Net::HTTPInternalServerError)
319+
expect(execute.response).to be_instance_of(WebhookResponseWithUtf8SafeBody)
320320
end
321321
end
322322

0 commit comments

Comments
 (0)