@@ -129,6 +129,9 @@ def register_formatter_methods formatter,
129129 # the request.
130130 #
131131 # @param env [Hash] The Rack environment.
132+ # @param allow_opaque [boolean] If true, returns opaque event objects if
133+ # the input is not in a recognized format. If false, raises
134+ # {CloudEvents::UnsupportedFormatError} in that case. Default is false.
132135 # @param format_args [keywords] Extra args to pass to the formatter.
133136 # @return [CloudEvents::Event] if the request includes a single structured
134137 # or binary event.
@@ -137,38 +140,76 @@ def register_formatter_methods formatter,
137140 # @raise [CloudEvents::CloudEventsError] if an event could not be decoded
138141 # from the request.
139142 #
140- def decode_rack_env env , **format_args
143+ def decode_rack_env env , allow_opaque : false , **format_args
141144 content_type_header = env [ "CONTENT_TYPE" ]
142145 content_type = ContentType . new content_type_header if content_type_header
143146 if content_type &.media_type == "application"
144147 case content_type . subtype_base
145148 when "cloudevents"
146149 content = read_with_charset env [ "rack.input" ] , content_type . charset
147- return decode_structured_content content , content_type , **format_args
150+ return decode_structured_content content , content_type , allow_opaque , **format_args
148151 when "cloudevents-batch"
149152 content = read_with_charset env [ "rack.input" ] , content_type . charset
150- return decode_batched_content content , content_type , **format_args
153+ return decode_batched_content content , content_type , allow_opaque , **format_args
151154 end
152155 end
153156 decode_binary_content env , content_type
154157 end
155158
156159 ##
157- # Encode a single event in the given format.
160+ # Encode an event or batch of events into HTTP headers and body.
161+ #
162+ # You may provide an event, an array of events, or an opaque event. You may
163+ # also specify what content mode and format to use.
158164 #
159165 # The result is a two-element array where the first element is a headers
160166 # list (as defined in the Rack specification) and the second is a string
161- # containing the HTTP body content. The headers list will contain only
162- # a `Content-Type` header.
167+ # containing the HTTP body content. When using structured content mode, the
168+ # headers list will contain only a `Content-Type` header and the body will
169+ # contain the serialized event. When using binary mode, the header list
170+ # will contain the serialized event attributes and the body will contain
171+ # the serialized event data.
172+ #
173+ # @param event [CloudEvents::Event,Array<CloudEvents::Event>,CloudEvents::Event::Opaque]
174+ # The event, batch, or opaque event.
175+ # @param structured_format [boolean,String] If given, the data will be
176+ # encoded in structured content mode. You can pass a string to select
177+ # a format name, or pass `true` to use the default format. If set to
178+ # `false` (the default), the data will be encoded in binary mode.
179+ # @param format_args [keywords] Extra args to pass to the formatter.
180+ # @return [Array(headers,String)]
181+ #
182+ def encode_event event , structured_format : false , **format_args
183+ if event . is_a? Event ::Opaque
184+ [ { "Content-Type" => event . content_type . to_s } , event . content ]
185+ elsif !structured_format
186+ encode_binary_content event , **format_args
187+ elsif event . is_a? ::Array
188+ structured_format = default_batched_encoder if structured_format == true
189+ raise ArgumentError , "Format name not specified, and no default is set" unless structured_format
190+ encode_batched_content event , structured_format , **format_args
191+ elsif event . is_a? Event
192+ structured_format = default_structured_encoder if structured_format == true
193+ raise ArgumentError , "Format name not specified, and no default is set" unless structured_format
194+ encode_structured_content event , structured_format , **format_args
195+ else
196+ raise ArgumentError , "Unknown event type: #{ event . class } "
197+ end
198+ end
199+
200+ ##
201+ # Encode a single event in structured content mode in the given format.
202+ #
203+ # @deprecated Will be removed in vresion 1.0. Use encode_event instead.
204+ #
205+ # @private
163206 #
164207 # @param event [CloudEvents::Event] The event.
165- # @param format [String] The format name. Optional.
208+ # @param format [String] The format name.
166209 # @param format_args [keywords] Extra args to pass to the formatter.
167210 # @return [Array(headers,String)]
168211 #
169- def encode_structured_content event , format = nil , **format_args
170- format ||= default_structured_encoder
171- raise ArgumentError , "Format name not specified, and no default is set" unless format
212+ def encode_structured_content event , format , **format_args
172213 Array ( @event_encoders [ format ] ) . reverse_each do |handler |
173214 result = handler . encode_event event , **format_args
174215 return [ { "Content-Type" => result [ 1 ] . to_s } , result [ 0 ] ] if result
@@ -177,21 +218,18 @@ def encode_structured_content event, format = nil, **format_args
177218 end
178219
179220 ##
180- # Encode a batch of events to content data in the given format.
221+ # Encode a batch of events in structured content mode in the given format.
181222 #
182- # The result is a two-element array where the first element is a headers
183- # list (as defined in the Rack specification) and the second is a string
184- # containing the HTTP body content. The headers list will contain only
185- # a `Content-Type` header.
223+ # @deprecated Will be removed in vresion 1.0. Use encode_event instead.
224+ #
225+ # @private
186226 #
187227 # @param events [Array<CloudEvents::Event>] The batch of events.
188- # @param format [String] The format name. Optional.
228+ # @param format [String] The format name.
189229 # @param format_args [keywords] Extra args to pass to the formatter.
190230 # @return [Array(headers,String)]
191231 #
192- def encode_batched_content events , format = nil , **format_args
193- format ||= default_batched_encoder
194- raise ArgumentError , "Format name not specified, and no default is set" unless format
232+ def encode_batched_content events , format , **format_args
195233 Array ( @batch_encoders [ format ] ) . reverse_each do |handler |
196234 result = handler . encode_batch events , **format_args
197235 return [ { "Content-Type" => result [ 1 ] . to_s } , result [ 0 ] ] if result
@@ -200,16 +238,17 @@ def encode_batched_content events, format = nil, **format_args
200238 end
201239
202240 ##
203- # Encode an event to content and headers, in binary content mode.
241+ # Encode an event in binary content mode.
204242 #
205- # The result is a two-element array where the first element is a headers
206- # list (as defined in the Rack specification) and the second is a string
207- # containing the HTTP body content.
243+ # @deprecated Will be removed in vresion 1.0. Use encode_event instead.
244+ #
245+ # @private
208246 #
209247 # @param event [CloudEvents::Event] The event.
248+ # @param format_args [keywords] Extra args to pass to the formatter.
210249 # @return [Array(headers,String)]
211250 #
212- def encode_binary_content event
251+ def encode_binary_content event , ** format_args
213252 headers = { }
214253 body = event . data
215254 content_type = event . data_content_type
@@ -218,7 +257,7 @@ def encode_binary_content event
218257 headers [ "CE-#{ key } " ] = percent_encode value
219258 end
220259 end
221- body , content_type = encode_data body , content_type
260+ body , content_type = encode_data body , content_type , ** format_args
222261 headers [ "Content-Type" ] = content_type . to_s if content_type
223262 [ headers , body ]
224263 end
@@ -278,24 +317,26 @@ def add_named_formatter collection, formatter, name
278317 # Decode a single event from the given request body and content type in
279318 # structured mode.
280319 #
281- def decode_structured_content input , content_type , **format_args
320+ def decode_structured_content input , content_type , allow_opaque , **format_args
282321 @event_decoders . reverse_each do |decoder |
283322 event = decoder . decode_event input , content_type , **format_args
284323 return event if event
285324 end
286- raise HttpContentError , "Unknown cloudevents content type: #{ content_type } "
325+ return Event ::Opaque . new input , content_type , batch : false if allow_opaque
326+ raise UnsupportedFormatError , "Unknown cloudevents content type: #{ content_type } "
287327 end
288328
289329 ##
290330 # Decode a batch of events from the given request body and content type in
291331 # batched structured mode.
292332 #
293- def decode_batched_content input , content_type , **format_args
333+ def decode_batched_content input , content_type , allow_opaque , **format_args
294334 @batch_decoders . reverse_each do |decoder |
295335 events = decoder . decode_batch input , content_type , **format_args
296336 return events if events
297337 end
298- raise HttpContentError , "Unknown cloudevents content type: #{ content_type } "
338+ return Event ::Opaque . new input , content_type , batch : true if allow_opaque
339+ raise UnsupportedFormatError , "Unknown cloudevents content type: #{ content_type } "
299340 end
300341
301342 ##
0 commit comments