1 | #ifndef AWS_EVENT_STREAM_H_ |
2 | #define AWS_EVENT_STREAM_H_ |
3 | |
4 | /* |
5 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
6 | * |
7 | * Licensed under the Apache License, Version 2.0 (the "License"). |
8 | * You may not use this file except in compliance with the License. |
9 | * A copy of the License is located at |
10 | * |
11 | * http://aws.amazon.com/apache2.0 |
12 | * |
13 | * or in the "license" file accompanying this file. This file is distributed |
14 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
15 | * express or implied. See the License for the specific language governing |
16 | * permissions and limitations under the License. |
17 | */ |
18 | |
19 | #include <aws/common/array_list.h> |
20 | #include <aws/common/byte_buf.h> |
21 | #include <aws/event-stream/event_stream_exports.h> |
22 | |
23 | #include <stdio.h> |
24 | |
25 | enum aws_event_stream_errors { |
26 | AWS_ERROR_EVENT_STREAM_BUFFER_LENGTH_MISMATCH = 0x1000, |
27 | AWS_ERROR_EVENT_STREAM_INSUFFICIENT_BUFFER_LEN, |
28 | AWS_ERROR_EVENT_STREAM_MESSAGE_FIELD_SIZE_EXCEEDED, |
29 | AWS_ERROR_EVENT_STREAM_PRELUDE_CHECKSUM_FAILURE, |
30 | AWS_ERROR_EVENT_STREAM_MESSAGE_CHECKSUM_FAILURE, |
31 | , |
32 | , |
33 | AWS_ERROR_EVENT_STREAM_MESSAGE_PARSER_ILLEGAL_STATE, |
34 | }; |
35 | |
36 | struct aws_event_stream_message_prelude { |
37 | uint32_t total_len; |
38 | uint32_t ; |
39 | uint32_t prelude_crc; |
40 | }; |
41 | |
42 | struct aws_event_stream_message { |
43 | struct aws_allocator *alloc; |
44 | uint8_t *message_buffer; |
45 | uint8_t owns_buffer; |
46 | }; |
47 | |
48 | #define AWS_EVENT_STREAM_PRELUDE_LENGTH (uint32_t)(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t)) |
49 | |
50 | #define AWS_EVENT_STREAM_TRAILER_LENGTH (uint32_t)(sizeof(uint32_t)) |
51 | |
52 | enum { |
53 | = 0, |
54 | , |
55 | , |
56 | , |
57 | , |
58 | , |
59 | , |
60 | , |
61 | /* 64 bit integer (millis since epoch) */ |
62 | , |
63 | |
64 | }; |
65 | |
66 | struct { |
67 | uint8_t ; |
68 | char [INT8_MAX]; |
69 | enum aws_event_stream_header_value_type ; |
70 | union { |
71 | uint8_t *; |
72 | uint8_t [16]; |
73 | } ; |
74 | |
75 | uint16_t ; |
76 | int8_t ; |
77 | }; |
78 | |
79 | struct aws_event_stream_streaming_decoder; |
80 | typedef int(aws_event_stream_process_state_fn)( |
81 | struct aws_event_stream_streaming_decoder *decoder, |
82 | const uint8_t *data, |
83 | size_t len, |
84 | size_t *processed); |
85 | |
86 | /** |
87 | * Called by aws_aws_event_stream_streaming_decoder when payload data has been received. |
88 | * 'data' doesn't belong to you, so copy the data if it is needed beyond the scope of your callback. |
89 | * final_segment == 1 indicates the current data is the last payload buffer for that message. |
90 | */ |
91 | typedef void(aws_event_stream_process_on_payload_segment_fn)( |
92 | struct aws_event_stream_streaming_decoder *decoder, |
93 | struct aws_byte_buf *payload, |
94 | int8_t final_segment, |
95 | void *user_data); |
96 | |
97 | /** |
98 | * Called by aws_aws_event_stream_streaming_decoder when a new message has arrived. The prelude will contain metadata |
99 | * about the message. At this point no headers or payload have been received. prelude is copyable. |
100 | */ |
101 | typedef void(aws_event_stream_prelude_received_fn)( |
102 | struct aws_event_stream_streaming_decoder *decoder, |
103 | struct aws_event_stream_message_prelude *prelude, |
104 | void *user_data); |
105 | |
106 | /** |
107 | * Called by aws_aws_event_stream_streaming_decoder when a header is encountered. 'header' is not yours. Copy the data |
108 | * you want from it if your scope extends beyond your callback. |
109 | */ |
110 | typedef void()( |
111 | struct aws_event_stream_streaming_decoder *decoder, |
112 | struct aws_event_stream_message_prelude *prelude, |
113 | struct aws_event_stream_header_value_pair *, |
114 | void *user_data); |
115 | |
116 | /** |
117 | * Called by aws_aws_event_stream_streaming_decoder when an error is encountered. The decoder is not in a good state for |
118 | * usage after this callback. |
119 | */ |
120 | typedef void(aws_event_stream_on_error_fn)( |
121 | struct aws_event_stream_streaming_decoder *decoder, |
122 | struct aws_event_stream_message_prelude *prelude, |
123 | int error_code, |
124 | const char *message, |
125 | void *user_data); |
126 | |
127 | struct aws_event_stream_streaming_decoder { |
128 | struct aws_allocator *alloc; |
129 | uint8_t working_buffer[AWS_EVENT_STREAM_PRELUDE_LENGTH]; |
130 | size_t message_pos; |
131 | uint32_t running_crc; |
132 | size_t ; |
133 | size_t ; |
134 | struct aws_event_stream_header_value_pair ; |
135 | struct aws_event_stream_message_prelude prelude; |
136 | aws_event_stream_process_state_fn *state; |
137 | aws_event_stream_process_on_payload_segment_fn *on_payload; |
138 | aws_event_stream_prelude_received_fn *on_prelude; |
139 | aws_event_stream_header_received_fn *; |
140 | aws_event_stream_on_error_fn *on_error; |
141 | void *user_context; |
142 | }; |
143 | |
144 | AWS_EXTERN_C_BEGIN |
145 | |
146 | /** |
147 | * Initializes with a list of headers, the payload, and a payload length. CRCs will be computed for you. |
148 | * If headers or payload is NULL, then the fields will be appropriately set to indicate no headers and/or no payload. |
149 | * Both payload and headers will result in an allocation. |
150 | */ |
151 | AWS_EVENT_STREAM_API int aws_event_stream_message_init( |
152 | struct aws_event_stream_message *message, |
153 | struct aws_allocator *alloc, |
154 | struct aws_array_list *, |
155 | struct aws_byte_buf *payload); |
156 | |
157 | /** |
158 | * Zero allocation, Zero copy. The message will simply wrap the buffer. The message functions are only useful as long as |
159 | * buffer is referencable memory. |
160 | */ |
161 | AWS_EVENT_STREAM_API int aws_event_stream_message_from_buffer( |
162 | struct aws_event_stream_message *message, |
163 | struct aws_allocator *alloc, |
164 | struct aws_byte_buf *buffer); |
165 | |
166 | /** |
167 | * Allocates memory and copies buffer. Otherwise the same as aws_aws_event_stream_message_from_buffer. This is slower, |
168 | * but possibly safer. |
169 | */ |
170 | AWS_EVENT_STREAM_API int aws_event_stream_message_from_buffer_copy( |
171 | struct aws_event_stream_message *message, |
172 | struct aws_allocator *alloc, |
173 | const struct aws_byte_buf *buffer); |
174 | |
175 | /** |
176 | * Cleans up any internally allocated memory. Always call this for API compatibility reasons, even if you only used the |
177 | * aws_aws_event_stream_message_from_buffer function. |
178 | */ |
179 | AWS_EVENT_STREAM_API void aws_event_stream_message_clean_up(struct aws_event_stream_message *message); |
180 | |
181 | /** |
182 | * Returns the total length of the message (including the length field). |
183 | */ |
184 | AWS_EVENT_STREAM_API uint32_t aws_event_stream_message_total_length(const struct aws_event_stream_message *message); |
185 | |
186 | /** |
187 | * Returns the length of the headers portion of the message. |
188 | */ |
189 | AWS_EVENT_STREAM_API uint32_t (const struct aws_event_stream_message *message); |
190 | |
191 | /** |
192 | * Returns the prelude crc (crc32) |
193 | */ |
194 | AWS_EVENT_STREAM_API uint32_t aws_event_stream_message_prelude_crc(const struct aws_event_stream_message *message); |
195 | |
196 | /** |
197 | * Writes the message to fd in json format. All strings and binary fields are base64 encoded. |
198 | */ |
199 | AWS_EVENT_STREAM_API int aws_event_stream_message_to_debug_str( |
200 | FILE *fd, |
201 | const struct aws_event_stream_message *message); |
202 | |
203 | /** |
204 | * Adds the headers for the message to list. The memory in each header is owned as part of the message, do not free it |
205 | * or pass its address around. |
206 | */ |
207 | AWS_EVENT_STREAM_API int ( |
208 | const struct aws_event_stream_message *message, |
209 | struct aws_array_list *); |
210 | |
211 | /** |
212 | * Returns a pointer to the beginning of the message payload. |
213 | */ |
214 | AWS_EVENT_STREAM_API const uint8_t *aws_event_stream_message_payload(const struct aws_event_stream_message *message); |
215 | |
216 | /** |
217 | * Returns the length of the message payload. |
218 | */ |
219 | AWS_EVENT_STREAM_API uint32_t aws_event_stream_message_payload_len(const struct aws_event_stream_message *message); |
220 | |
221 | /** |
222 | * Returns the checksum of the entire message (crc32) |
223 | */ |
224 | AWS_EVENT_STREAM_API uint32_t aws_event_stream_message_message_crc(const struct aws_event_stream_message *message); |
225 | |
226 | /** |
227 | * Returns the message as a buffer ready for transport. |
228 | */ |
229 | AWS_EVENT_STREAM_API const uint8_t *aws_event_stream_message_buffer(const struct aws_event_stream_message *message); |
230 | |
231 | /** |
232 | * Initialize a streaming decoder for messages with callbacks for usage and an optional user context pointer. |
233 | */ |
234 | AWS_EVENT_STREAM_API void aws_event_stream_streaming_decoder_init( |
235 | struct aws_event_stream_streaming_decoder *decoder, |
236 | struct aws_allocator *alloc, |
237 | aws_event_stream_process_on_payload_segment_fn *on_payload_segment, |
238 | aws_event_stream_prelude_received_fn *on_prelude, |
239 | aws_event_stream_header_received_fn *, |
240 | aws_event_stream_on_error_fn *on_error, |
241 | void *user_data); |
242 | |
243 | /** |
244 | * Currently, no memory is allocated inside aws_aws_event_stream_streaming_decoder, but for future API compatibility, |
245 | * you should call this when finished with it. |
246 | */ |
247 | AWS_EVENT_STREAM_API void aws_event_stream_streaming_decoder_clean_up( |
248 | struct aws_event_stream_streaming_decoder *decoder); |
249 | |
250 | /** |
251 | * initializes a headers list for you. It will default to a capacity of 4 in dynamic mode. |
252 | */ |
253 | AWS_EVENT_STREAM_API int ( |
254 | struct aws_array_list *, |
255 | struct aws_allocator *allocator); |
256 | |
257 | /** |
258 | * Cleans up the headers list. Also deallocates any headers that were the result of a copy flag for strings or buffer. |
259 | */ |
260 | AWS_EVENT_STREAM_API void (struct aws_array_list *); |
261 | |
262 | /** |
263 | * Adds a string header to the list of headers. If copy is set to true, this will result in an allocation for the header |
264 | * value. Otherwise, the value will be set to the memory address of 'value'. |
265 | */ |
266 | AWS_EVENT_STREAM_API int ( |
267 | struct aws_array_list *, |
268 | const char *name, |
269 | uint8_t name_len, |
270 | const char *value, |
271 | uint16_t value_len, |
272 | int8_t copy); |
273 | |
274 | /** |
275 | * Adds a byte header to the list of headers. |
276 | */ |
277 | AWS_EVENT_STREAM_API int ( |
278 | struct aws_array_list *, |
279 | const char *name, |
280 | uint8_t name_len, |
281 | int8_t value); |
282 | |
283 | /** |
284 | * Adds a bool header to the list of headers. |
285 | */ |
286 | AWS_EVENT_STREAM_API int ( |
287 | struct aws_array_list *, |
288 | const char *name, |
289 | uint8_t name_len, |
290 | int8_t value); |
291 | |
292 | /** |
293 | * adds a 16 bit integer to the list of headers. |
294 | */ |
295 | AWS_EVENT_STREAM_API int ( |
296 | struct aws_array_list *, |
297 | const char *name, |
298 | uint8_t name_len, |
299 | int16_t value); |
300 | |
301 | /** |
302 | * adds a 32 bit integer to the list of headers. |
303 | */ |
304 | AWS_EVENT_STREAM_API int ( |
305 | struct aws_array_list *, |
306 | const char *name, |
307 | uint8_t name_len, |
308 | int32_t value); |
309 | |
310 | /** |
311 | * adds a 64 bit integer to the list of headers. |
312 | */ |
313 | AWS_EVENT_STREAM_API int ( |
314 | struct aws_array_list *, |
315 | const char *name, |
316 | uint8_t name_len, |
317 | int64_t value); |
318 | |
319 | /** |
320 | * Adds a byte-buffer header to the list of headers. If copy is set to true, this will result in an allocation for the |
321 | * header value. Otherwise, the value will be set to the memory address of 'value'. |
322 | */ |
323 | AWS_EVENT_STREAM_API int ( |
324 | struct aws_array_list *, |
325 | const char *name, |
326 | uint8_t name_len, |
327 | uint8_t *value, |
328 | uint16_t value_len, |
329 | int8_t copy); |
330 | |
331 | /** |
332 | * adds a 64 bit integer representing milliseconds since unix epoch to the list of headers. |
333 | */ |
334 | AWS_EVENT_STREAM_API int ( |
335 | struct aws_array_list *, |
336 | const char *name, |
337 | uint8_t name_len, |
338 | int64_t value); |
339 | |
340 | /** |
341 | * adds a uuid buffer to the list of headers. Value must always be 16 bytes long. |
342 | */ |
343 | AWS_EVENT_STREAM_API int ( |
344 | struct aws_array_list *, |
345 | const char *name, |
346 | uint8_t name_len, |
347 | const uint8_t *value); |
348 | |
349 | /** |
350 | * Returns the header name. Note: this value is not null terminated |
351 | */ |
352 | AWS_EVENT_STREAM_API struct aws_byte_buf ( |
353 | struct aws_event_stream_header_value_pair *); |
354 | |
355 | /** |
356 | * Returns the header value as a string. Note: this value is not null terminated. |
357 | */ |
358 | AWS_EVENT_STREAM_API struct aws_byte_buf ( |
359 | struct aws_event_stream_header_value_pair *); |
360 | |
361 | /** |
362 | * Returns the header value as a byte |
363 | */ |
364 | AWS_EVENT_STREAM_API int8_t (struct aws_event_stream_header_value_pair *); |
365 | |
366 | /** |
367 | * Returns the header value as a boolean value. |
368 | */ |
369 | AWS_EVENT_STREAM_API int8_t (struct aws_event_stream_header_value_pair *); |
370 | |
371 | /** |
372 | * Returns the header value as a 16 bit integer. |
373 | */ |
374 | AWS_EVENT_STREAM_API int16_t (struct aws_event_stream_header_value_pair *); |
375 | |
376 | /** |
377 | * Returns the header value as a 32 bit integer. |
378 | */ |
379 | AWS_EVENT_STREAM_API int32_t (struct aws_event_stream_header_value_pair *); |
380 | |
381 | /** |
382 | * Returns the header value as a 64 bit integer. |
383 | */ |
384 | AWS_EVENT_STREAM_API int64_t (struct aws_event_stream_header_value_pair *); |
385 | |
386 | /** |
387 | * Returns the header value as a pointer to a byte buffer, call aws_event_stream_header_value_length to determine |
388 | * the length of the buffer. |
389 | */ |
390 | AWS_EVENT_STREAM_API struct aws_byte_buf ( |
391 | struct aws_event_stream_header_value_pair *); |
392 | |
393 | /** |
394 | * Returns the header value as a 64 bit integer representing milliseconds since unix epoch. |
395 | */ |
396 | AWS_EVENT_STREAM_API int64_t |
397 | (struct aws_event_stream_header_value_pair *); |
398 | |
399 | /** |
400 | * Returns the header value a byte buffer which is 16 bytes long. Represents a UUID. |
401 | */ |
402 | AWS_EVENT_STREAM_API struct aws_byte_buf ( |
403 | struct aws_event_stream_header_value_pair *); |
404 | |
405 | /** |
406 | * Returns the length of the header value buffer. This is mostly intended for string and byte buffer types. |
407 | */ |
408 | AWS_EVENT_STREAM_API uint16_t (struct aws_event_stream_header_value_pair *); |
409 | |
410 | /** |
411 | * The main driver of the decoder. Pass data that should be decoded with its length. A likely use-case here is in |
412 | * response to a read event from an io-device |
413 | */ |
414 | AWS_EVENT_STREAM_API int aws_event_stream_streaming_decoder_pump( |
415 | struct aws_event_stream_streaming_decoder *decoder, |
416 | const struct aws_byte_buf *data); |
417 | |
418 | /** |
419 | * Initializes internal datastructures used by aws-c-event-stream. |
420 | * Must be called before using any functionality in aws-c-event-stream. |
421 | */ |
422 | AWS_EVENT_STREAM_API void aws_event_stream_library_init(struct aws_allocator *allocator); |
423 | |
424 | /** |
425 | * Clean up internal datastructures used by aws-c-event-stream. |
426 | * Must not be called until application is done using functionality in aws-c-event-stream. |
427 | */ |
428 | AWS_EVENT_STREAM_API void aws_event_stream_library_clean_up(void); |
429 | |
430 | AWS_EXTERN_C_END |
431 | |
432 | #endif /* AWS_EVENT_STREAM_H_ */ |
433 | |