1 #ifndef AWS_HTTP_REQUEST_RESPONSE_H 2 #define AWS_HTTP_REQUEST_RESPONSE_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/http/http.h> 10 11 struct aws_http_connection; 12 struct aws_input_stream; 13 14 /** 15 * A stream exists for the duration of a request/response exchange. 16 * A client creates a stream to send a request and receive a response. 17 * A server creates a stream to receive a request and send a response. 18 * In http/2, a push-promise stream can be sent by a server and received by a client. 19 */ 20 struct aws_http_stream; 21 22 /** 23 * Controls whether a header's strings may be compressed by encoding the index of 24 * strings in a cache, rather than encoding the literal string. 25 * 26 * This setting has no effect on HTTP/1.x connections. 27 * On HTTP/2 connections this controls HPACK behavior. 28 * See RFC-7541 Section 7.1 for security considerations. 29 */ 30 enum aws_http_header_compression { 31 /** 32 * Compress header by encoding the cached index of its strings, 33 * or by updating the cache to contain these strings for future reference. 34 * Best for headers that are sent repeatedly. 35 * This is the default setting. 36 */ 37 AWS_HTTP_HEADER_COMPRESSION_USE_CACHE, 38 39 /** 40 * Encode header strings literally. 41 * If an intermediary re-broadcasts the headers, it is permitted to use cache. 42 * Best for unique headers that are unlikely to repeat. 43 */ 44 AWS_HTTP_HEADER_COMPRESSION_NO_CACHE, 45 46 /** 47 * Encode header strings literally and forbid all intermediaries from using 48 * cache when re-broadcasting. 49 * Best for header fields that are highly valuable or sensitive to recovery. 50 */ 51 AWS_HTTP_HEADER_COMPRESSION_NO_FORWARD_CACHE, 52 }; 53 54 /** 55 * A lightweight HTTP header struct. 56 * Note that the underlying strings are not owned by the byte cursors. 57 */ 58 struct aws_http_header { 59 struct aws_byte_cursor name; 60 struct aws_byte_cursor value; 61 62 /* Controls whether the header's strings may be compressed via caching. */ 63 enum aws_http_header_compression compression; 64 }; 65 66 /** 67 * A transformable block of HTTP headers. 68 * Provides a nice API for getting/setting header names and values. 69 * 70 * All strings are copied and stored within this datastructure. 71 * The index of a given header may change any time headers are modified. 72 * When iterating headers, the following ordering rules apply: 73 * 74 * - Headers with the same name will always be in the same order, relative to one another. 75 * If "A: one" is added before "A: two", then "A: one" will always precede "A: two". 76 * 77 * - Headers with different names could be in any order, relative to one another. 78 * If "A: one" is seen before "B: bee" in one iteration, you might see "B: bee" before "A: one" on the next. 79 */ 80 struct aws_http_headers; 81 82 /** 83 * Header block type. 84 * INFORMATIONAL: Header block for 1xx informational (interim) responses. 85 * MAIN: Main header block sent with request or response. 86 * TRAILING: Headers sent after the body of a request or response. 87 */ 88 enum aws_http_header_block { 89 AWS_HTTP_HEADER_BLOCK_MAIN, 90 AWS_HTTP_HEADER_BLOCK_INFORMATIONAL, 91 AWS_HTTP_HEADER_BLOCK_TRAILING, 92 }; 93 94 /** 95 * The definition for an outgoing HTTP request or response. 96 * The message may be transformed (ex: signing the request) before its data is eventually sent. 97 * 98 * The message keeps internal copies of its trivial strings (method, path, headers) 99 * but does NOT take ownership of its body stream. 100 * 101 * A language binding would likely present this as an HttpMessage base class with 102 * HttpRequest and HttpResponse subclasses. 103 */ 104 struct aws_http_message; 105 106 /** 107 * Function to invoke when a message transformation completes. 108 * This function MUST be invoked or the application will soft-lock. 109 * `message` and `complete_ctx` must be the same pointers provided to the `aws_http_message_transform_fn`. 110 * `error_code` should should be AWS_ERROR_SUCCESS if transformation was successful, 111 * otherwise pass a different AWS_ERROR_X value. 112 */ 113 typedef void( 114 aws_http_message_transform_complete_fn)(struct aws_http_message *message, int error_code, void *complete_ctx); 115 116 /** 117 * A function that may modify a request or response before it is sent. 118 * The transformation may be asynchronous or immediate. 119 * The user MUST invoke the `complete_fn` when transformation is complete or the application will soft-lock. 120 * When invoking the `complete_fn`, pass along the `message` and `complete_ctx` provided here and an error code. 121 * The error code should be AWS_ERROR_SUCCESS if transformation was successful, 122 * otherwise pass a different AWS_ERROR_X value. 123 */ 124 typedef void(aws_http_message_transform_fn)( 125 struct aws_http_message *message, 126 void *user_data, 127 aws_http_message_transform_complete_fn *complete_fn, 128 void *complete_ctx); 129 130 /** 131 * Invoked repeatedly times as headers are received. 132 * At this point, aws_http_stream_get_incoming_response_status() can be called for the client. 133 * And aws_http_stream_get_incoming_request_method() and aws_http_stream_get_incoming_request_uri() can be called for 134 * the server. 135 * This is always invoked on the HTTP connection's event-loop thread. 136 * 137 * Return AWS_OP_SUCCESS to continue processing the stream. 138 * Return AWS_OP_ERR to indicate failure and cancel the stream. 139 */ 140 typedef int(aws_http_on_incoming_headers_fn)( 141 struct aws_http_stream *stream, 142 enum aws_http_header_block header_block, 143 const struct aws_http_header *header_array, 144 size_t num_headers, 145 void *user_data); 146 147 /** 148 * Invoked when the incoming header block of this type(informational/main/trailing) has been completely read. 149 * This is always invoked on the HTTP connection's event-loop thread. 150 * 151 * Return AWS_OP_SUCCESS to continue processing the stream. 152 * Return AWS_OP_ERR to indicate failure and cancel the stream. 153 */ 154 typedef int(aws_http_on_incoming_header_block_done_fn)( 155 struct aws_http_stream *stream, 156 enum aws_http_header_block header_block, 157 void *user_data); 158 159 /** 160 * Called repeatedly as body data is received. 161 * The data must be copied immediately if you wish to preserve it. 162 * This is always invoked on the HTTP connection's event-loop thread. 163 * 164 * Note that, if the connection is using manual_window_management then the window 165 * size has shrunk by the amount of body data received. If the window size 166 * reaches 0 no further data will be received. Increment the window size with 167 * aws_http_stream_update_window(). 168 * 169 * Return AWS_OP_SUCCESS to continue processing the stream. 170 * Return AWS_OP_ERR to indicate failure and cancel the stream. 171 */ 172 typedef int( 173 aws_http_on_incoming_body_fn)(struct aws_http_stream *stream, const struct aws_byte_cursor *data, void *user_data); 174 175 /** 176 * Invoked when request has been completely read. 177 * This is always invoked on the HTTP connection's event-loop thread. 178 * 179 * Return AWS_OP_SUCCESS to continue processing the stream. 180 * Return AWS_OP_ERR to indicate failure and cancel the stream. 181 */ 182 typedef int(aws_http_on_incoming_request_done_fn)(struct aws_http_stream *stream, void *user_data); 183 184 /** 185 * Invoked when request/response stream is complete, whether successful or unsuccessful 186 * This is always invoked on the HTTP connection's event-loop thread. 187 */ 188 typedef void(aws_http_on_stream_complete_fn)(struct aws_http_stream *stream, int error_code, void *user_data); 189 190 /** 191 * Options for creating a stream which sends a request from the client and receives a response from the server. 192 */ 193 struct aws_http_make_request_options { 194 /** 195 * The sizeof() this struct, used for versioning. 196 * Required. 197 */ 198 size_t self_size; 199 200 /** 201 * Definition for outgoing request. 202 * Required. 203 * This object must stay alive at least until on_complete is called. 204 */ 205 struct aws_http_message *request; 206 207 void *user_data; 208 209 /** 210 * Invoked repeatedly times as headers are received. 211 * Optional. 212 * See `aws_http_on_incoming_headers_fn`. 213 */ 214 aws_http_on_incoming_headers_fn *on_response_headers; 215 216 /** 217 * Invoked when response header block has been completely read. 218 * Optional. 219 * See `aws_http_on_incoming_header_block_done_fn`. 220 */ 221 aws_http_on_incoming_header_block_done_fn *on_response_header_block_done; 222 223 /** 224 * Invoked repeatedly as body data is received. 225 * Optional. 226 * See `aws_http_on_incoming_body_fn`. 227 */ 228 aws_http_on_incoming_body_fn *on_response_body; 229 230 /** 231 * Invoked when request/response stream is complete, whether successful or unsuccessful 232 * Optional. 233 * See `aws_http_on_stream_complete_fn`. 234 */ 235 aws_http_on_stream_complete_fn *on_complete; 236 }; 237 238 struct aws_http_request_handler_options { 239 /* Set to sizeof() this struct, used for versioning. */ 240 size_t self_size; 241 242 /** 243 * Required. 244 */ 245 struct aws_http_connection *server_connection; 246 247 /** 248 * user_data passed to callbacks. 249 * Optional. 250 */ 251 void *user_data; 252 253 /** 254 * Invoked repeatedly times as headers are received. 255 * Optional. 256 * See `aws_http_on_incoming_headers_fn`. 257 */ 258 aws_http_on_incoming_headers_fn *on_request_headers; 259 260 /** 261 * Invoked when the request header block has been completely read. 262 * Optional. 263 * See `aws_http_on_incoming_header_block_done_fn`. 264 */ 265 aws_http_on_incoming_header_block_done_fn *on_request_header_block_done; 266 267 /** 268 * Invoked as body data is received. 269 * Optional. 270 * See `aws_http_on_incoming_body_fn`. 271 */ 272 aws_http_on_incoming_body_fn *on_request_body; 273 274 /** 275 * Invoked when request has been completely read. 276 * Optional. 277 * See `aws_http_on_incoming_request_done_fn`. 278 */ 279 aws_http_on_incoming_request_done_fn *on_request_done; 280 281 /** 282 * Invoked when request/response stream is complete, whether successful or unsuccessful 283 * Optional. 284 * See `aws_http_on_stream_complete_fn`. 285 */ 286 aws_http_on_stream_complete_fn *on_complete; 287 }; 288 289 /** 290 * Invoked when the data of an outgoing HTTP/1.1 chunk is no longer in use. 291 * This is always invoked on the HTTP connection's event-loop thread. 292 * 293 * @param stream HTTP-stream this chunk was submitted to. 294 * @param error_code If error_code is AWS_ERROR_SUCCESS (0), the data was successfully sent. 295 * Any other error_code indicates that the HTTP-stream is in the process of terminating. 296 * If the error_code is AWS_ERROR_HTTP_STREAM_HAS_COMPLETED, 297 * the stream's termination has nothing to do with this chunk. 298 * Any other non-zero error code indicates a problem with this particular chunk's data. 299 * @param user_data User data for this chunk. 300 */ 301 typedef void aws_http1_stream_write_chunk_complete_fn(struct aws_http_stream *stream, int error_code, void *user_data); 302 303 /** 304 * HTTP/1.1 chunk extension for chunked encoding. 305 * Note that the underlying strings are not owned by the byte cursors. 306 */ 307 struct aws_http1_chunk_extension { 308 struct aws_byte_cursor key; 309 struct aws_byte_cursor value; 310 }; 311 312 /** 313 * Encoding options for an HTTP/1.1 chunked transfer encoding chunk. 314 */ 315 struct aws_http1_chunk_options { 316 /* 317 * The data stream to be sent in a single chunk. 318 * The aws_input_stream must remain valid until on_complete is invoked. 319 * May be NULL in the final chunk with size 0. 320 * 321 * Note that, for Transfer-Encodings other than "chunked", the data is 322 * expected to already have that encoding applied. For example, if 323 * "Transfer-Encoding: gzip, chunked" then the data from aws_input_stream 324 * should already be in gzip format. 325 */ 326 struct aws_input_stream *chunk_data; 327 328 /* 329 * Size of the chunk_data input stream in bytes. 330 */ 331 uint64_t chunk_data_size; 332 333 /** 334 * A pointer to an array of chunked extensions. 335 * The num_extensions must match the length of the array. 336 * This data is deep-copied by aws_http1_stream_write_chunk(), 337 * it does not need to remain valid until on_complete is invoked. 338 */ 339 struct aws_http1_chunk_extension *extensions; 340 341 /** 342 * The number of elements defined in the extensions array. 343 */ 344 size_t num_extensions; 345 346 /** 347 * Invoked when the chunk data is no longer in use, whether or not it was successfully sent. 348 * Optional. 349 * See `aws_http1_stream_write_chunk_complete_fn`. 350 */ 351 aws_http1_stream_write_chunk_complete_fn *on_complete; 352 353 /** 354 * User provided data passed to the on_complete callback on its invocation. 355 */ 356 void *user_data; 357 }; 358 359 #define AWS_HTTP_REQUEST_HANDLER_OPTIONS_INIT \ 360 { .self_size = sizeof(struct aws_http_request_handler_options), } 361 362 AWS_EXTERN_C_BEGIN 363 364 /** 365 * Return whether both names are equivalent. 366 * This is a case-insensitive string comparison. 367 * 368 * Example Matches: 369 * "Content-Length" == "content-length" // upper or lower case ok 370 371 * Example Mismatches: 372 * "Content-Length" != " Content-Length" // leading whitespace bad 373 */ 374 AWS_HTTP_API 375 bool aws_http_header_name_eq(struct aws_byte_cursor name_a, struct aws_byte_cursor name_b); 376 377 /** 378 * Create a new headers object. 379 * The caller has a hold on the object and must call aws_http_headers_release() when they are done with it. 380 */ 381 AWS_HTTP_API 382 struct aws_http_headers *aws_http_headers_new(struct aws_allocator *allocator); 383 384 /** 385 * Acquire a hold on the object, preventing it from being deleted until 386 * aws_http_headers_release() is called by all those with a hold on it. 387 */ 388 AWS_HTTP_API 389 void aws_http_headers_acquire(struct aws_http_headers *headers); 390 391 /** 392 * Release a hold on the object. 393 * The object is deleted when all holds on it are released. 394 */ 395 AWS_HTTP_API 396 void aws_http_headers_release(struct aws_http_headers *headers); 397 398 /** 399 * Add a header. 400 * The underlying strings are copied. 401 */ 402 AWS_HTTP_API 403 int aws_http_headers_add_header(struct aws_http_headers *headers, const struct aws_http_header *header); 404 405 /** 406 * Add a header. 407 * The underlying strings are copied. 408 */ 409 AWS_HTTP_API 410 int aws_http_headers_add(struct aws_http_headers *headers, struct aws_byte_cursor name, struct aws_byte_cursor value); 411 412 /** 413 * Add an array of headers. 414 * The underlying strings are copied. 415 */ 416 AWS_HTTP_API 417 int aws_http_headers_add_array(struct aws_http_headers *headers, const struct aws_http_header *array, size_t count); 418 419 /** 420 * Set a header value. 421 * The header is added if necessary and any existing values for this name are removed. 422 * The underlying strings are copied. 423 */ 424 AWS_HTTP_API 425 int aws_http_headers_set(struct aws_http_headers *headers, struct aws_byte_cursor name, struct aws_byte_cursor value); 426 427 /** 428 * Get the total number of headers. 429 */ 430 AWS_HTTP_API 431 size_t aws_http_headers_count(const struct aws_http_headers *headers); 432 433 /** 434 * Get the header at the specified index. 435 * The index of a given header may change any time headers are modified. 436 * When iterating headers, the following ordering rules apply: 437 * 438 * - Headers with the same name will always be in the same order, relative to one another. 439 * If "A: one" is added before "A: two", then "A: one" will always precede "A: two". 440 * 441 * - Headers with different names could be in any order, relative to one another. 442 * If "A: one" is seen before "B: bee" in one iteration, you might see "B: bee" before "A: one" on the next. 443 * 444 * AWS_ERROR_INVALID_INDEX is raised if the index is invalid. 445 */ 446 AWS_HTTP_API 447 int aws_http_headers_get_index( 448 const struct aws_http_headers *headers, 449 size_t index, 450 struct aws_http_header *out_header); 451 452 /** 453 * Get the first value for this name, ignoring any additional values. 454 * AWS_ERROR_HTTP_HEADER_NOT_FOUND is raised if the name is not found. 455 */ 456 AWS_HTTP_API 457 int aws_http_headers_get( 458 const struct aws_http_headers *headers, 459 struct aws_byte_cursor name, 460 struct aws_byte_cursor *out_value); 461 462 /** 463 * Test if header name exists or not in headers 464 */ 465 AWS_HTTP_API 466 bool aws_http_headers_has(const struct aws_http_headers *headers, struct aws_byte_cursor name); 467 468 /** 469 * Remove all headers with this name. 470 * AWS_ERROR_HTTP_HEADER_NOT_FOUND is raised if no headers with this name are found. 471 */ 472 AWS_HTTP_API 473 int aws_http_headers_erase(struct aws_http_headers *headers, struct aws_byte_cursor name); 474 475 /** 476 * Remove the first header found with this name and value. 477 * AWS_ERROR_HTTP_HEADER_NOT_FOUND is raised if no such header is found. 478 */ 479 AWS_HTTP_API 480 int aws_http_headers_erase_value( 481 struct aws_http_headers *headers, 482 struct aws_byte_cursor name, 483 struct aws_byte_cursor value); 484 485 /** 486 * Remove the header at the specified index. 487 * 488 * AWS_ERROR_INVALID_INDEX is raised if the index is invalid. 489 */ 490 AWS_HTTP_API 491 int aws_http_headers_erase_index(struct aws_http_headers *headers, size_t index); 492 493 /** 494 * Clear all headers. 495 */ 496 AWS_HTTP_API 497 void aws_http_headers_clear(struct aws_http_headers *headers); 498 499 /** 500 * Create a new request message. 501 * The message is blank, all properties (method, path, etc) must be set individually. 502 * 503 * The caller has a hold on the object and must call aws_http_message_release() when they are done with it. 504 */ 505 AWS_HTTP_API 506 struct aws_http_message *aws_http_message_new_request(struct aws_allocator *allocator); 507 508 /** 509 * Like aws_http_message_new_request(), but uses existing aws_http_headers instead of creating a new one. 510 * Acquires a hold on the headers, and releases it when the request is destroyed. 511 */ 512 AWS_HTTP_API 513 struct aws_http_message *aws_http_message_new_request_with_headers( 514 struct aws_allocator *allocator, 515 struct aws_http_headers *existing_headers); 516 517 /** 518 * Create a new response message. 519 * The message is blank, all properties (status, headers, etc) must be set individually. 520 * 521 * The caller has a hold on the object and must call aws_http_message_release() when they are done with it. 522 */ 523 AWS_HTTP_API 524 struct aws_http_message *aws_http_message_new_response(struct aws_allocator *allocator); 525 526 /** 527 * Acquire a hold on the object, preventing it from being deleted until 528 * aws_http_message_release() is called by all those with a hold on it. 529 */ 530 AWS_HTTP_API 531 void aws_http_message_acquire(struct aws_http_message *message); 532 533 /** 534 * Release a hold on the object. 535 * The object is deleted when all holds on it are released. 536 */ 537 AWS_HTTP_API 538 void aws_http_message_release(struct aws_http_message *message); 539 540 /** 541 * Deprecated. This is equivalent to aws_http_message_release(). 542 */ 543 AWS_HTTP_API 544 void aws_http_message_destroy(struct aws_http_message *message); 545 546 AWS_HTTP_API 547 bool aws_http_message_is_request(const struct aws_http_message *message); 548 549 AWS_HTTP_API 550 bool aws_http_message_is_response(const struct aws_http_message *message); 551 552 /** 553 * Get the method (request messages only). 554 */ 555 AWS_HTTP_API 556 int aws_http_message_get_request_method( 557 const struct aws_http_message *request_message, 558 struct aws_byte_cursor *out_method); 559 560 /** 561 * Set the method (request messages only). 562 * The request makes its own copy of the underlying string. 563 */ 564 AWS_HTTP_API 565 int aws_http_message_set_request_method(struct aws_http_message *request_message, struct aws_byte_cursor method); 566 567 /* 568 * Get the path-and-query value (request messages only). 569 */ 570 AWS_HTTP_API 571 int aws_http_message_get_request_path(const struct aws_http_message *request_message, struct aws_byte_cursor *out_path); 572 573 /** 574 * Set the path-and-query value (request messages only). 575 * The request makes its own copy of the underlying string. 576 */ 577 AWS_HTTP_API 578 int aws_http_message_set_request_path(struct aws_http_message *request_message, struct aws_byte_cursor path); 579 580 /** 581 * Get the status code (response messages only). 582 * If no status is set, AWS_ERROR_HTTP_DATA_NOT_AVAILABLE is raised. 583 */ 584 AWS_HTTP_API 585 int aws_http_message_get_response_status(const struct aws_http_message *response_message, int *out_status_code); 586 587 /** 588 * Set the status code (response messages only). 589 */ 590 AWS_HTTP_API 591 int aws_http_message_set_response_status(struct aws_http_message *response_message, int status_code); 592 593 /** 594 * Get the body stream. 595 * Returns NULL if no body stream is set. 596 */ 597 AWS_HTTP_API 598 struct aws_input_stream *aws_http_message_get_body_stream(const struct aws_http_message *message); 599 600 /** 601 * Set the body stream. 602 * NULL is an acceptable value for messages with no body. 603 * Note: The message does NOT take ownership of the body stream. 604 * The stream must not be destroyed until the message is complete. 605 */ 606 AWS_HTTP_API 607 void aws_http_message_set_body_stream(struct aws_http_message *message, struct aws_input_stream *body_stream); 608 609 /** 610 * Submit a chunk of data to be sent on an HTTP/1.1 stream. 611 * The stream must have specified "chunked" in a "transfer-encoding" header. 612 * For client streams, activate() must be called before any chunks are submitted. 613 * For server streams, the response must be submitted before any chunks. 614 * A final chunk with size 0 must be submitted to successfully complete the HTTP-stream. 615 * 616 * Returns AWS_OP_SUCCESS if the chunk has been submitted. The chunk's completion 617 * callback will be invoked when the HTTP-stream is done with the chunk data, 618 * whether or not it was successfully sent (see `aws_http1_stream_write_chunk_complete_fn`). 619 * The chunk data must remain valid until the completion callback is invoked. 620 * 621 * Returns AWS_OP_ERR and raises an error if the chunk could not be submitted. 622 * In this case, the chunk's completion callback will never be invoked. 623 * Note that it is always possible for the HTTP-stream to terminate unexpectedly 624 * prior to this call being made, in which case the error raised is 625 * AWS_ERROR_HTTP_STREAM_HAS_COMPLETED. 626 */ 627 AWS_HTTP_API int aws_http1_stream_write_chunk( 628 struct aws_http_stream *http1_stream, 629 const struct aws_http1_chunk_options *options); 630 631 /** 632 * Get the message's aws_http_headers. 633 * 634 * This datastructure has more functions for inspecting and modifying headers than 635 * are available on the aws_http_message datastructure. 636 */ 637 AWS_HTTP_API 638 struct aws_http_headers *aws_http_message_get_headers(struct aws_http_message *message); 639 640 /** 641 * Get the message's const aws_http_headers. 642 */ 643 AWS_HTTP_API 644 const struct aws_http_headers *aws_http_message_get_const_headers(const struct aws_http_message *message); 645 646 /** 647 * Get the number of headers. 648 */ 649 AWS_HTTP_API 650 size_t aws_http_message_get_header_count(const struct aws_http_message *message); 651 652 /** 653 * Get the header at the specified index. 654 * This function cannot fail if a valid index is provided. 655 * Otherwise, AWS_ERROR_INVALID_INDEX will be raised. 656 * 657 * The underlying strings are stored within the message. 658 */ 659 AWS_HTTP_API 660 int aws_http_message_get_header( 661 const struct aws_http_message *message, 662 struct aws_http_header *out_header, 663 size_t index); 664 665 /** 666 * Add a header to the end of the array. 667 * The message makes its own copy of the underlying strings. 668 */ 669 AWS_HTTP_API 670 int aws_http_message_add_header(struct aws_http_message *message, struct aws_http_header header); 671 672 /** 673 * Add an array of headers to the end of the header array. 674 * The message makes its own copy of the underlying strings. 675 * 676 * This is a helper function useful when it's easier to define headers as a stack array, rather than calling add_header 677 * repeatedly. 678 */ 679 AWS_HTTP_API 680 int aws_http_message_add_header_array( 681 struct aws_http_message *message, 682 const struct aws_http_header *headers, 683 size_t num_headers); 684 685 /** 686 * Remove the header at the specified index. 687 * Headers after this index are all shifted back one position. 688 * 689 * This function cannot fail if a valid index is provided. 690 * Otherwise, AWS_ERROR_INVALID_INDEX will be raised. 691 */ 692 AWS_HTTP_API 693 int aws_http_message_erase_header(struct aws_http_message *message, size_t index); 694 695 /** 696 * Create a stream, with a client connection sending a request. 697 * The request does not start sending automatically once the stream is created. You must call 698 * aws_http_stream_activate to begin execution of the request. 699 * 700 * The `options` are copied during this call. 701 * 702 * Tip for language bindings: Do not bind the `options` struct. Use something more natural for your language, 703 * such as Builder Pattern in Java, or Python's ability to take many optional arguments by name. 704 */ 705 AWS_HTTP_API 706 struct aws_http_stream *aws_http_connection_make_request( 707 struct aws_http_connection *client_connection, 708 const struct aws_http_make_request_options *options); 709 710 /** 711 * Create a stream, with a server connection receiving and responding to a request. 712 * This function can only be called from the `aws_http_on_incoming_request_fn` callback. 713 * aws_http_stream_send_response() should be used to send a response. 714 */ 715 AWS_HTTP_API 716 struct aws_http_stream *aws_http_stream_new_server_request_handler( 717 const struct aws_http_request_handler_options *options); 718 719 /** 720 * Users must release the stream when they are done with it, or its memory will never be cleaned up. 721 * This will not cancel the stream, its callbacks will still fire if the stream is still in progress. 722 * 723 * Tips for language bindings: 724 * - Invoke this from the wrapper class's finalizer/destructor. 725 * - Do not let the wrapper class be destroyed until on_complete() has fired. 726 */ 727 AWS_HTTP_API 728 void aws_http_stream_release(struct aws_http_stream *stream); 729 730 /** 731 * Only used for client initiated streams (immediately following a call to aws_http_connection_make_request). 732 * 733 * Activates the request's outgoing stream processing. 734 */ 735 AWS_HTTP_API int aws_http_stream_activate(struct aws_http_stream *stream); 736 737 AWS_HTTP_API 738 struct aws_http_connection *aws_http_stream_get_connection(const struct aws_http_stream *stream); 739 740 /* Only valid in "request" streams, once response headers start arriving */ 741 AWS_HTTP_API 742 int aws_http_stream_get_incoming_response_status(const struct aws_http_stream *stream, int *out_status); 743 744 /* Only valid in "request handler" streams, once request headers start arriving */ 745 AWS_HTTP_API 746 int aws_http_stream_get_incoming_request_method( 747 const struct aws_http_stream *stream, 748 struct aws_byte_cursor *out_method); 749 750 AWS_HTTP_API 751 int aws_http_stream_get_incoming_request_uri(const struct aws_http_stream *stream, struct aws_byte_cursor *out_uri); 752 753 /** 754 * Send response (only callable from "request handler" streams) 755 * The response object must stay alive at least until the stream's on_complete is called. 756 */ 757 AWS_HTTP_API 758 int aws_http_stream_send_response(struct aws_http_stream *stream, struct aws_http_message *response); 759 760 /** 761 * Increment the stream's flow-control window to keep data flowing. 762 * 763 * If the connection was created with `manual_window_management` set true, 764 * the flow-control window of each stream will shrink as body data is received 765 * (headers, padding, and other metadata do not affect the window). 766 * The connection's `initial_window_size` determines the starting size of each stream's window. 767 * If a stream's flow-control window reaches 0, no further data will be received. 768 * 769 * If `manual_window_management` is false, this call will have no effect. 770 * The connection maintains its flow-control windows such that 771 * no back-pressure is applied and data arrives as fast as possible. 772 */ 773 AWS_HTTP_API 774 void aws_http_stream_update_window(struct aws_http_stream *stream, size_t increment_size); 775 776 /** 777 * Gets the HTTP/2 id associated with a stream. Even h1 streams have an id (using the same allocation procedure 778 * as http/2) for easier tracking purposes. For client streams, this will only be non-zero after a successful call 779 * to aws_http_stream_activate() 780 */ 781 AWS_HTTP_API 782 uint32_t aws_http_stream_get_id(const struct aws_http_stream *stream); 783 784 /** 785 * Reset the HTTP/2 stream (HTTP/2 only). 786 * Note that if the stream closes before this async call is fully processed, the RST_STREAM frame will not be sent. 787 * 788 * @param http2_stream HTTP/2 stream. 789 * @param http2_error aws_http2_error_code. Reason to reset the stream. 790 */ 791 AWS_HTTP_API 792 int aws_http2_stream_reset(struct aws_http_stream *http2_stream, uint32_t http2_error); 793 794 /** 795 * Get the error code received in rst_stream. 796 * Only valid if the stream has completed, and an RST_STREAM frame has received. 797 * 798 * @param http2_stream HTTP/2 stream. 799 * @param out_http2_error Gets to set to HTTP/2 error code received in rst_stream. 800 */ 801 AWS_HTTP_API 802 int aws_http2_stream_get_received_reset_error_code(struct aws_http_stream *http2_stream, uint32_t *out_http2_error); 803 804 /** 805 * Get the HTTP/2 error code sent in the RST_STREAM frame (HTTP/2 only). 806 * Only valid if the stream has completed, and has sent an RST_STREAM frame. 807 * 808 * @param http2_stream HTTP/2 stream. 809 * @param out_http2_error Gets to set to HTTP/2 error code sent in rst_stream. 810 */ 811 AWS_HTTP_API 812 int aws_http2_stream_get_sent_reset_error_code(struct aws_http_stream *http2_stream, uint32_t *out_http2_error); 813 814 AWS_EXTERN_C_END 815 816 #endif /* AWS_HTTP_REQUEST_RESPONSE_H */ 817