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