Skip to content

Commit 6268cfb

Browse files
authored
fix: Set charset of encoded structured events (#55)
Signed-off-by: Daniel Azuma <[email protected]>
1 parent aafddbf commit 6268cfb

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

lib/cloud_events/http_binding.rb

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,10 @@ def encode_structured_content event, format, **format_args
183183
handlers = @structured_formatters[format] || []
184184
handlers.reverse_each do |handler|
185185
content = handler.encode event, **format_args
186-
return [{ "Content-Type" => "application/cloudevents+#{format}" }, content] if content
186+
if content
187+
content_type = "application/cloudevents+#{format}; charset=#{charset_of content}"
188+
return [{ "Content-Type" => content_type }, content]
189+
end
187190
end
188191
raise HttpContentError, "Unknown cloudevents format: #{format.inspect}"
189192
end
@@ -206,7 +209,10 @@ def encode_batched_content events, format, **format_args
206209
handlers = @batched_formatters[format] || []
207210
handlers.reverse_each do |handler|
208211
content = handler.encode_batch events, **format_args
209-
return [{ "Content-Type" => "application/cloudevents-batch+#{format}" }, content] if content
212+
if content
213+
content_type = "application/cloudevents-batch+#{format}; charset=#{charset_of content}"
214+
return [{ "Content-Type" => content_type }, content]
215+
end
210216
end
211217
raise HttpContentError, "Unknown cloudevents format: #{format.inspect}"
212218
end
@@ -254,7 +260,7 @@ def encode_binary_content event
254260
# @return [String] Resulting decoded string in UTF-8.
255261
#
256262
def percent_decode str
257-
str = str.gsub(/"((?:[^"\\]|\\.)*)"/) { Regexp.last_match(1).gsub(/\\(.)/, '\1') }
263+
str = str.gsub(/"((?:[^"\\]|\\.)*)"/) { ::Regexp.last_match(1).gsub(/\\(.)/, '\1') }
258264
decoded_str = str.gsub(/%[0-9a-fA-F]{2}/) { |m| [m[1..-1].to_i(16)].pack "C" }
259265
decoded_str.force_encoding ::Encoding::UTF_8
260266
end
@@ -293,18 +299,28 @@ def read_with_charset io, charset
293299
begin
294300
str.force_encoding charset
295301
rescue ::ArgumentError
296-
# Do nothing for now if the charset is unrecognized
302+
# Use binary for now if the charset is unrecognized
303+
str.force_encoding ::Encoding::ASCII_8BIT
297304
end
298305
end
299306
str
300307
end
301308

302309
def string_content_type str
303-
if str.encoding == ::Encoding.ASCII_8BIT
310+
if str.encoding == ::Encoding::ASCII_8BIT
304311
"application/octet-stream"
305312
else
306313
"text/plain; charset=#{str.encoding.name.downcase}"
307314
end
308315
end
316+
317+
def charset_of str
318+
encoding = str.encoding
319+
if encoding == ::Encoding::ASCII_8BIT
320+
"binary"
321+
else
322+
encoding.name.downcase
323+
end
324+
end
309325
end
310326
end

test/test_http_binding.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
assert_equal my_subject, event.subject
8686
assert_equal my_time, event.time
8787
headers, body = http_binding.encode_batched_content [event], "json", sort: true
88-
assert_equal({ "Content-Type" => "application/cloudevents-batch+json" }, headers)
88+
assert_equal({ "Content-Type" => "application/cloudevents-batch+json; charset=utf-8" }, headers)
8989
assert_equal my_json_batch_encoded, body
9090
end
9191

@@ -144,7 +144,7 @@
144144
assert_equal my_subject, event.subject
145145
assert_equal my_time, event.time
146146
headers, body = http_binding.encode_structured_content event, "json", sort: true
147-
assert_equal({ "Content-Type" => "application/cloudevents+json" }, headers)
147+
assert_equal({ "Content-Type" => "application/cloudevents+json; charset=utf-8" }, headers)
148148
assert_equal my_json_struct_encoded, body
149149
end
150150

@@ -171,7 +171,7 @@
171171
assert_equal my_subject, event.subject
172172
assert_equal my_time, event.time
173173
headers, body = http_binding.encode_structured_content event, "json", sort: true
174-
assert_equal({ "Content-Type" => "application/cloudevents+json" }, headers)
174+
assert_equal({ "Content-Type" => "application/cloudevents+json; charset=utf-8" }, headers)
175175
assert_equal my_json_struct_encoded, body
176176
end
177177

0 commit comments

Comments
 (0)