@@ -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
310326end
0 commit comments