1165 lines
43 KiB
C
1165 lines
43 KiB
C
|
|
#ifndef AWS_HTTP_REQUEST_RESPONSE_H
|
||
|
|
#define AWS_HTTP_REQUEST_RESPONSE_H
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||
|
|
* SPDX-License-Identifier: Apache-2.0.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include <aws/http/http.h>
|
||
|
|
|
||
|
|
#include <aws/io/future.h>
|
||
|
|
|
||
|
|
AWS_PUSH_SANE_WARNING_LEVEL
|
||
|
|
|
||
|
|
struct aws_http_connection;
|
||
|
|
struct aws_input_stream;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A stream exists for the duration of a request/response exchange.
|
||
|
|
* A client creates a stream to send a request and receive a response.
|
||
|
|
* A server creates a stream to receive a request and send a response.
|
||
|
|
* In http/2, a push-promise stream can be sent by a server and received by a client.
|
||
|
|
*/
|
||
|
|
struct aws_http_stream;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Controls whether a header's strings may be compressed by encoding the index of
|
||
|
|
* strings in a cache, rather than encoding the literal string.
|
||
|
|
*
|
||
|
|
* This setting has no effect on HTTP/1.x connections.
|
||
|
|
* On HTTP/2 connections this controls HPACK behavior.
|
||
|
|
* See RFC-7541 Section 7.1 for security considerations.
|
||
|
|
*/
|
||
|
|
enum aws_http_header_compression {
|
||
|
|
/**
|
||
|
|
* Compress header by encoding the cached index of its strings,
|
||
|
|
* or by updating the cache to contain these strings for future reference.
|
||
|
|
* Best for headers that are sent repeatedly.
|
||
|
|
* This is the default setting.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_HEADER_COMPRESSION_USE_CACHE,
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Encode header strings literally.
|
||
|
|
* If an intermediary re-broadcasts the headers, it is permitted to use cache.
|
||
|
|
* Best for unique headers that are unlikely to repeat.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_HEADER_COMPRESSION_NO_CACHE,
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Encode header strings literally and forbid all intermediaries from using
|
||
|
|
* cache when re-broadcasting.
|
||
|
|
* Best for header fields that are highly valuable or sensitive to recovery.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_HEADER_COMPRESSION_NO_FORWARD_CACHE,
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A lightweight HTTP header struct.
|
||
|
|
* Note that the underlying strings are not owned by the byte cursors.
|
||
|
|
*/
|
||
|
|
struct aws_http_header {
|
||
|
|
struct aws_byte_cursor name;
|
||
|
|
struct aws_byte_cursor value;
|
||
|
|
|
||
|
|
/* Controls whether the header's strings may be compressed via caching. */
|
||
|
|
enum aws_http_header_compression compression;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A transformable block of HTTP headers.
|
||
|
|
* Provides a nice API for getting/setting header names and values.
|
||
|
|
*
|
||
|
|
* All strings are copied and stored within this datastructure.
|
||
|
|
* The index of a given header may change any time headers are modified.
|
||
|
|
* When iterating headers, the following ordering rules apply:
|
||
|
|
*
|
||
|
|
* - Headers with the same name will always be in the same order, relative to one another.
|
||
|
|
* If "A: one" is added before "A: two", then "A: one" will always precede "A: two".
|
||
|
|
*
|
||
|
|
* - Headers with different names could be in any order, relative to one another.
|
||
|
|
* If "A: one" is seen before "B: bee" in one iteration, you might see "B: bee" before "A: one" on the next.
|
||
|
|
*/
|
||
|
|
struct aws_http_headers;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Header block type.
|
||
|
|
* INFORMATIONAL: Header block for 1xx informational (interim) responses.
|
||
|
|
* MAIN: Main header block sent with request or response.
|
||
|
|
* TRAILING: Headers sent after the body of a request or response.
|
||
|
|
*/
|
||
|
|
enum aws_http_header_block {
|
||
|
|
AWS_HTTP_HEADER_BLOCK_MAIN,
|
||
|
|
AWS_HTTP_HEADER_BLOCK_INFORMATIONAL,
|
||
|
|
AWS_HTTP_HEADER_BLOCK_TRAILING,
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The definition for an outgoing HTTP request or response.
|
||
|
|
* The message may be transformed (ex: signing the request) before its data is eventually sent.
|
||
|
|
*
|
||
|
|
* The message keeps internal copies of its trivial strings (method, path, headers)
|
||
|
|
* but does NOT take ownership of its body stream.
|
||
|
|
*
|
||
|
|
* A language binding would likely present this as an HttpMessage base class with
|
||
|
|
* HttpRequest and HttpResponse subclasses.
|
||
|
|
*/
|
||
|
|
struct aws_http_message;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Function to invoke when a message transformation completes.
|
||
|
|
* This function MUST be invoked or the application will soft-lock.
|
||
|
|
* `message` and `complete_ctx` must be the same pointers provided to the `aws_http_message_transform_fn`.
|
||
|
|
* `error_code` should should be AWS_ERROR_SUCCESS if transformation was successful,
|
||
|
|
* otherwise pass a different AWS_ERROR_X value.
|
||
|
|
*/
|
||
|
|
typedef void(
|
||
|
|
aws_http_message_transform_complete_fn)(struct aws_http_message *message, int error_code, void *complete_ctx);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A function that may modify a request or response before it is sent.
|
||
|
|
* The transformation may be asynchronous or immediate.
|
||
|
|
* The user MUST invoke the `complete_fn` when transformation is complete or the application will soft-lock.
|
||
|
|
* When invoking the `complete_fn`, pass along the `message` and `complete_ctx` provided here and an error code.
|
||
|
|
* The error code should be AWS_ERROR_SUCCESS if transformation was successful,
|
||
|
|
* otherwise pass a different AWS_ERROR_X value.
|
||
|
|
*/
|
||
|
|
typedef void(aws_http_message_transform_fn)(
|
||
|
|
struct aws_http_message *message,
|
||
|
|
void *user_data,
|
||
|
|
aws_http_message_transform_complete_fn *complete_fn,
|
||
|
|
void *complete_ctx);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked repeatedly times as headers are received.
|
||
|
|
* At this point, aws_http_stream_get_incoming_response_status() can be called for the client.
|
||
|
|
* And aws_http_stream_get_incoming_request_method() and aws_http_stream_get_incoming_request_uri() can be called for
|
||
|
|
* the server.
|
||
|
|
* This is always invoked on the HTTP connection's event-loop thread.
|
||
|
|
*
|
||
|
|
* Return AWS_OP_SUCCESS to continue processing the stream.
|
||
|
|
* Return aws_raise_error(E) to indicate failure and cancel the stream.
|
||
|
|
* The error you raise will be reflected in the error_code passed to the on_complete callback.
|
||
|
|
*/
|
||
|
|
typedef int(aws_http_on_incoming_headers_fn)(
|
||
|
|
struct aws_http_stream *stream,
|
||
|
|
enum aws_http_header_block header_block,
|
||
|
|
const struct aws_http_header *header_array,
|
||
|
|
size_t num_headers,
|
||
|
|
void *user_data);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked when the incoming header block of this type(informational/main/trailing) has been completely read.
|
||
|
|
* This is always invoked on the HTTP connection's event-loop thread.
|
||
|
|
*
|
||
|
|
* Return AWS_OP_SUCCESS to continue processing the stream.
|
||
|
|
* Return aws_raise_error(E) to indicate failure and cancel the stream.
|
||
|
|
* The error you raise will be reflected in the error_code passed to the on_complete callback.
|
||
|
|
*/
|
||
|
|
typedef int(aws_http_on_incoming_header_block_done_fn)(
|
||
|
|
struct aws_http_stream *stream,
|
||
|
|
enum aws_http_header_block header_block,
|
||
|
|
void *user_data);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Called repeatedly as body data is received.
|
||
|
|
* The data must be copied immediately if you wish to preserve it.
|
||
|
|
* This is always invoked on the HTTP connection's event-loop thread.
|
||
|
|
*
|
||
|
|
* Note that, if the connection is using manual_window_management then the window
|
||
|
|
* size has shrunk by the amount of body data received. If the window size
|
||
|
|
* reaches 0 no further data will be received. Increment the window size with
|
||
|
|
* aws_http_stream_update_window().
|
||
|
|
*
|
||
|
|
* Return AWS_OP_SUCCESS to continue processing the stream.
|
||
|
|
* Return aws_raise_error(E) to indicate failure and cancel the stream.
|
||
|
|
* The error you raise will be reflected in the error_code passed to the on_complete callback.
|
||
|
|
*/
|
||
|
|
typedef int(
|
||
|
|
aws_http_on_incoming_body_fn)(struct aws_http_stream *stream, const struct aws_byte_cursor *data, void *user_data);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked when request has been completely read.
|
||
|
|
* This is always invoked on the HTTP connection's event-loop thread.
|
||
|
|
*
|
||
|
|
* Return AWS_OP_SUCCESS to continue processing the stream.
|
||
|
|
* Return aws_raise_error(E) to indicate failure and cancel the stream.
|
||
|
|
* The error you raise will be reflected in the error_code passed to the on_complete callback.
|
||
|
|
*/
|
||
|
|
typedef int(aws_http_on_incoming_request_done_fn)(struct aws_http_stream *stream, void *user_data);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked when a request/response stream is complete, whether successful or unsuccessful
|
||
|
|
* This is always invoked on the HTTP connection's event-loop thread.
|
||
|
|
* This will not be invoked if the stream is never activated.
|
||
|
|
*/
|
||
|
|
typedef void(aws_http_on_stream_complete_fn)(struct aws_http_stream *stream, int error_code, void *user_data);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked when request/response stream destroy completely.
|
||
|
|
* This can be invoked within the same thead who release the refcount on http stream.
|
||
|
|
* This is invoked even if the stream is never activated.
|
||
|
|
*/
|
||
|
|
typedef void(aws_http_on_stream_destroy_fn)(void *user_data);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Tracing metrics for aws_http_stream.
|
||
|
|
* Data maybe not be available if the data of stream was never sent/received before it completes.
|
||
|
|
*/
|
||
|
|
struct aws_http_stream_metrics {
|
||
|
|
/* The time stamp when the request started to be encoded. -1 means data not available. Timestamp
|
||
|
|
* are from `aws_high_res_clock_get_ticks` */
|
||
|
|
int64_t send_start_timestamp_ns;
|
||
|
|
/* The time stamp when the request finished to be encoded. -1 means data not available.
|
||
|
|
* Timestamp are from `aws_high_res_clock_get_ticks` */
|
||
|
|
int64_t send_end_timestamp_ns;
|
||
|
|
/* The time duration for the request from start encoding to finish encoding (send_end_timestamp_ns -
|
||
|
|
* send_start_timestamp_ns). -1 means data not available. */
|
||
|
|
int64_t sending_duration_ns;
|
||
|
|
|
||
|
|
/* The time stamp when the response started to be received from the network channel. -1 means data not available.
|
||
|
|
* Timestamp are from `aws_high_res_clock_get_ticks` */
|
||
|
|
int64_t receive_start_timestamp_ns;
|
||
|
|
/* The time stamp when the response finished to be received from the network channel. -1 means data not available.
|
||
|
|
* Timestamp are from `aws_high_res_clock_get_ticks` */
|
||
|
|
int64_t receive_end_timestamp_ns;
|
||
|
|
/* The time duration for the request from start receiving to finish receiving. receive_end_timestamp_ns -
|
||
|
|
* receive_start_timestamp_ns. -1 means data not available. */
|
||
|
|
int64_t receiving_duration_ns;
|
||
|
|
|
||
|
|
/* The stream-id on the connection when this stream was activated. */
|
||
|
|
uint32_t stream_id;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked right before request/response stream is complete to report the tracing metrics for aws_http_stream.
|
||
|
|
* This may be invoked synchronously when aws_http_stream_release() is called.
|
||
|
|
* This is invoked even if the stream is never activated.
|
||
|
|
* See `aws_http_stream_metrics` for details.
|
||
|
|
*/
|
||
|
|
typedef void(aws_http_on_stream_metrics_fn)(
|
||
|
|
struct aws_http_stream *stream,
|
||
|
|
const struct aws_http_stream_metrics *metrics,
|
||
|
|
void *user_data);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Options for creating a stream which sends a request from the client and receives a response from the server.
|
||
|
|
*/
|
||
|
|
struct aws_http_make_request_options {
|
||
|
|
/**
|
||
|
|
* The sizeof() this struct, used for versioning.
|
||
|
|
* Required.
|
||
|
|
*/
|
||
|
|
size_t self_size;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Definition for outgoing request.
|
||
|
|
* Required.
|
||
|
|
* The request will be kept alive via refcounting until the request completes.
|
||
|
|
*/
|
||
|
|
struct aws_http_message *request;
|
||
|
|
|
||
|
|
void *user_data;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked repeatedly times as headers are received.
|
||
|
|
* Optional.
|
||
|
|
* See `aws_http_on_incoming_headers_fn`.
|
||
|
|
*/
|
||
|
|
aws_http_on_incoming_headers_fn *on_response_headers;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked when response header block has been completely read.
|
||
|
|
* Optional.
|
||
|
|
* See `aws_http_on_incoming_header_block_done_fn`.
|
||
|
|
*/
|
||
|
|
aws_http_on_incoming_header_block_done_fn *on_response_header_block_done;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked repeatedly as body data is received.
|
||
|
|
* Optional.
|
||
|
|
* See `aws_http_on_incoming_body_fn`.
|
||
|
|
*/
|
||
|
|
aws_http_on_incoming_body_fn *on_response_body;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked right before stream is complete, whether successful or unsuccessful
|
||
|
|
* Optional.
|
||
|
|
* See `aws_http_on_stream_metrics_fn`
|
||
|
|
*/
|
||
|
|
aws_http_on_stream_metrics_fn *on_metrics;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked when request/response stream is complete, whether successful or unsuccessful
|
||
|
|
* Optional.
|
||
|
|
* See `aws_http_on_stream_complete_fn`.
|
||
|
|
*/
|
||
|
|
aws_http_on_stream_complete_fn *on_complete;
|
||
|
|
|
||
|
|
/* Callback for when the request/response stream is completely destroyed. */
|
||
|
|
aws_http_on_stream_destroy_fn *on_destroy;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* When using HTTP/2, request body data will be provided over time. The stream will only be polled for writing
|
||
|
|
* when data has been supplied via `aws_http2_stream_write_data`
|
||
|
|
*/
|
||
|
|
bool http2_use_manual_data_writes;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Optional (ignored if 0).
|
||
|
|
* After a request is fully sent, if the server does not begin responding within N milliseconds, then fail with
|
||
|
|
* AWS_ERROR_HTTP_RESPONSE_FIRST_BYTE_TIMEOUT.
|
||
|
|
* It override the connection level settings, when the request completes, the
|
||
|
|
* original monitoring options will be applied back to the connection.
|
||
|
|
* TODO: Only supported in HTTP/1.1 now, support it in HTTP/2
|
||
|
|
*/
|
||
|
|
uint64_t response_first_byte_timeout_ms;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct aws_http_request_handler_options {
|
||
|
|
/* Set to sizeof() this struct, used for versioning. */
|
||
|
|
size_t self_size;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Required.
|
||
|
|
*/
|
||
|
|
struct aws_http_connection *server_connection;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* user_data passed to callbacks.
|
||
|
|
* Optional.
|
||
|
|
*/
|
||
|
|
void *user_data;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked repeatedly times as headers are received.
|
||
|
|
* Optional.
|
||
|
|
* See `aws_http_on_incoming_headers_fn`.
|
||
|
|
*/
|
||
|
|
aws_http_on_incoming_headers_fn *on_request_headers;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked when the request header block has been completely read.
|
||
|
|
* Optional.
|
||
|
|
* See `aws_http_on_incoming_header_block_done_fn`.
|
||
|
|
*/
|
||
|
|
aws_http_on_incoming_header_block_done_fn *on_request_header_block_done;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked as body data is received.
|
||
|
|
* Optional.
|
||
|
|
* See `aws_http_on_incoming_body_fn`.
|
||
|
|
*/
|
||
|
|
aws_http_on_incoming_body_fn *on_request_body;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked when request has been completely read.
|
||
|
|
* Optional.
|
||
|
|
* See `aws_http_on_incoming_request_done_fn`.
|
||
|
|
*/
|
||
|
|
aws_http_on_incoming_request_done_fn *on_request_done;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked when request/response stream is complete, whether successful or unsuccessful
|
||
|
|
* Optional.
|
||
|
|
* See `aws_http_on_stream_complete_fn`.
|
||
|
|
*/
|
||
|
|
aws_http_on_stream_complete_fn *on_complete;
|
||
|
|
|
||
|
|
/* Callback for when the request/response stream is completely destroyed. */
|
||
|
|
aws_http_on_stream_destroy_fn *on_destroy;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked when the data stream of an outgoing HTTP write operation is no longer in use.
|
||
|
|
* This is always invoked on the HTTP connection's event-loop thread.
|
||
|
|
*
|
||
|
|
* @param stream HTTP-stream this write operation was submitted to.
|
||
|
|
* @param error_code If error_code is AWS_ERROR_SUCCESS (0), the data was successfully sent.
|
||
|
|
* Any other error_code indicates that the HTTP-stream is in the process of terminating.
|
||
|
|
* If the error_code is AWS_ERROR_HTTP_STREAM_HAS_COMPLETED,
|
||
|
|
* the stream's termination has nothing to do with this write operation.
|
||
|
|
* Any other non-zero error code indicates a problem with this particular write
|
||
|
|
* operation's data.
|
||
|
|
* @param user_data User data for this write operation.
|
||
|
|
*/
|
||
|
|
typedef void aws_http_stream_write_complete_fn(struct aws_http_stream *stream, int error_code, void *user_data);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked when the data of an outgoing HTTP/1.1 chunk is no longer in use.
|
||
|
|
* This is always invoked on the HTTP connection's event-loop thread.
|
||
|
|
*
|
||
|
|
* @param stream HTTP-stream this chunk was submitted to.
|
||
|
|
* @param error_code If error_code is AWS_ERROR_SUCCESS (0), the data was successfully sent.
|
||
|
|
* Any other error_code indicates that the HTTP-stream is in the process of terminating.
|
||
|
|
* If the error_code is AWS_ERROR_HTTP_STREAM_HAS_COMPLETED,
|
||
|
|
* the stream's termination has nothing to do with this chunk.
|
||
|
|
* Any other non-zero error code indicates a problem with this particular chunk's data.
|
||
|
|
* @param user_data User data for this chunk.
|
||
|
|
*/
|
||
|
|
typedef aws_http_stream_write_complete_fn aws_http1_stream_write_chunk_complete_fn;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* HTTP/1.1 chunk extension for chunked encoding.
|
||
|
|
* Note that the underlying strings are not owned by the byte cursors.
|
||
|
|
*/
|
||
|
|
struct aws_http1_chunk_extension {
|
||
|
|
struct aws_byte_cursor key;
|
||
|
|
struct aws_byte_cursor value;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Encoding options for an HTTP/1.1 chunked transfer encoding chunk.
|
||
|
|
*/
|
||
|
|
struct aws_http1_chunk_options {
|
||
|
|
/*
|
||
|
|
* The data stream to be sent in a single chunk.
|
||
|
|
* The aws_input_stream must remain valid until on_complete is invoked.
|
||
|
|
* May be NULL in the final chunk with size 0.
|
||
|
|
*
|
||
|
|
* Note that, for Transfer-Encodings other than "chunked", the data is
|
||
|
|
* expected to already have that encoding applied. For example, if
|
||
|
|
* "Transfer-Encoding: gzip, chunked" then the data from aws_input_stream
|
||
|
|
* should already be in gzip format.
|
||
|
|
*/
|
||
|
|
struct aws_input_stream *chunk_data;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Size of the chunk_data input stream in bytes.
|
||
|
|
*/
|
||
|
|
uint64_t chunk_data_size;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A pointer to an array of chunked extensions.
|
||
|
|
* The num_extensions must match the length of the array.
|
||
|
|
* This data is deep-copied by aws_http1_stream_write_chunk(),
|
||
|
|
* it does not need to remain valid until on_complete is invoked.
|
||
|
|
*/
|
||
|
|
struct aws_http1_chunk_extension *extensions;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The number of elements defined in the extensions array.
|
||
|
|
*/
|
||
|
|
size_t num_extensions;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked when the chunk data is no longer in use, whether or not it was successfully sent.
|
||
|
|
* Optional.
|
||
|
|
* See `aws_http1_stream_write_chunk_complete_fn`.
|
||
|
|
*/
|
||
|
|
aws_http1_stream_write_chunk_complete_fn *on_complete;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* User provided data passed to the on_complete callback on its invocation.
|
||
|
|
*/
|
||
|
|
void *user_data;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked when the data of an outgoing HTTP2 data frame is no longer in use.
|
||
|
|
* This is always invoked on the HTTP connection's event-loop thread.
|
||
|
|
*
|
||
|
|
* @param stream HTTP2-stream this write was submitted to.
|
||
|
|
* @param error_code If error_code is AWS_ERROR_SUCCESS (0), the data was successfully sent.
|
||
|
|
* Any other error_code indicates that the HTTP-stream is in the process of terminating.
|
||
|
|
* If the error_code is AWS_ERROR_HTTP_STREAM_HAS_COMPLETED,
|
||
|
|
* the stream's termination has nothing to do with this write.
|
||
|
|
* Any other non-zero error code indicates a problem with this particular write's data.
|
||
|
|
* @param user_data User data for this write.
|
||
|
|
*/
|
||
|
|
typedef aws_http_stream_write_complete_fn aws_http2_stream_write_data_complete_fn;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Encoding options for manual H2 data frame writes
|
||
|
|
*/
|
||
|
|
struct aws_http2_stream_write_data_options {
|
||
|
|
/**
|
||
|
|
* The data to be sent.
|
||
|
|
* Optional.
|
||
|
|
* If not set, input stream with length 0 will be used.
|
||
|
|
*/
|
||
|
|
struct aws_input_stream *data;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set true when it's the last chunk to be sent.
|
||
|
|
* After a write with end_stream, no more data write will be accepted.
|
||
|
|
*/
|
||
|
|
bool end_stream;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Invoked when the data stream is no longer in use, whether or not it was successfully sent.
|
||
|
|
* Optional.
|
||
|
|
* See `aws_http2_stream_write_data_complete_fn`.
|
||
|
|
*/
|
||
|
|
aws_http2_stream_write_data_complete_fn *on_complete;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* User provided data passed to the on_complete callback on its invocation.
|
||
|
|
*/
|
||
|
|
void *user_data;
|
||
|
|
};
|
||
|
|
|
||
|
|
#define AWS_HTTP_REQUEST_HANDLER_OPTIONS_INIT \
|
||
|
|
{ \
|
||
|
|
.self_size = sizeof(struct aws_http_request_handler_options), \
|
||
|
|
}
|
||
|
|
|
||
|
|
AWS_EXTERN_C_BEGIN
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return whether both names are equivalent.
|
||
|
|
* This is a case-insensitive string comparison.
|
||
|
|
*
|
||
|
|
* Example Matches:
|
||
|
|
* "Content-Length" == "content-length" // upper or lower case ok
|
||
|
|
|
||
|
|
* Example Mismatches:
|
||
|
|
* "Content-Length" != " Content-Length" // leading whitespace bad
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
bool aws_http_header_name_eq(struct aws_byte_cursor name_a, struct aws_byte_cursor name_b);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create a new headers object.
|
||
|
|
* The caller has a hold on the object and must call aws_http_headers_release() when they are done with it.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_http_headers *aws_http_headers_new(struct aws_allocator *allocator);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Acquire a hold on the object, preventing it from being deleted until
|
||
|
|
* aws_http_headers_release() is called by all those with a hold on it.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
void aws_http_headers_acquire(struct aws_http_headers *headers);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Release a hold on the object.
|
||
|
|
* The object is deleted when all holds on it are released.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
void aws_http_headers_release(struct aws_http_headers *headers);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Add a header.
|
||
|
|
* The underlying strings are copied.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_headers_add_header(struct aws_http_headers *headers, const struct aws_http_header *header);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Add a header.
|
||
|
|
* The underlying strings are copied.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_headers_add(struct aws_http_headers *headers, struct aws_byte_cursor name, struct aws_byte_cursor value);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Add an array of headers.
|
||
|
|
* The underlying strings are copied.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_headers_add_array(struct aws_http_headers *headers, const struct aws_http_header *array, size_t count);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set a header value.
|
||
|
|
* The header is added if necessary and any existing values for this name are removed.
|
||
|
|
* The underlying strings are copied.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_headers_set(struct aws_http_headers *headers, struct aws_byte_cursor name, struct aws_byte_cursor value);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the total number of headers.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
size_t aws_http_headers_count(const struct aws_http_headers *headers);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the header at the specified index.
|
||
|
|
* The index of a given header may change any time headers are modified.
|
||
|
|
* When iterating headers, the following ordering rules apply:
|
||
|
|
*
|
||
|
|
* - Headers with the same name will always be in the same order, relative to one another.
|
||
|
|
* If "A: one" is added before "A: two", then "A: one" will always precede "A: two".
|
||
|
|
*
|
||
|
|
* - Headers with different names could be in any order, relative to one another.
|
||
|
|
* If "A: one" is seen before "B: bee" in one iteration, you might see "B: bee" before "A: one" on the next.
|
||
|
|
*
|
||
|
|
* AWS_ERROR_INVALID_INDEX is raised if the index is invalid.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_headers_get_index(
|
||
|
|
const struct aws_http_headers *headers,
|
||
|
|
size_t index,
|
||
|
|
struct aws_http_header *out_header);
|
||
|
|
|
||
|
|
/**
|
||
|
|
*
|
||
|
|
* Get all values with this name, combined into one new aws_string that you are responsible for destroying.
|
||
|
|
* If there are multiple headers with this name, their values are appended with comma-separators.
|
||
|
|
* If there are no headers with this name, NULL is returned and AWS_ERROR_HTTP_HEADER_NOT_FOUND is raised.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_string *aws_http_headers_get_all(const struct aws_http_headers *headers, struct aws_byte_cursor name);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the first value for this name, ignoring any additional values.
|
||
|
|
* AWS_ERROR_HTTP_HEADER_NOT_FOUND is raised if the name is not found.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_headers_get(
|
||
|
|
const struct aws_http_headers *headers,
|
||
|
|
struct aws_byte_cursor name,
|
||
|
|
struct aws_byte_cursor *out_value);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Test if header name exists or not in headers
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
bool aws_http_headers_has(const struct aws_http_headers *headers, struct aws_byte_cursor name);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Remove all headers with this name.
|
||
|
|
* AWS_ERROR_HTTP_HEADER_NOT_FOUND is raised if no headers with this name are found.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_headers_erase(struct aws_http_headers *headers, struct aws_byte_cursor name);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Remove the first header found with this name and value.
|
||
|
|
* AWS_ERROR_HTTP_HEADER_NOT_FOUND is raised if no such header is found.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_headers_erase_value(
|
||
|
|
struct aws_http_headers *headers,
|
||
|
|
struct aws_byte_cursor name,
|
||
|
|
struct aws_byte_cursor value);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Remove the header at the specified index.
|
||
|
|
*
|
||
|
|
* AWS_ERROR_INVALID_INDEX is raised if the index is invalid.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_headers_erase_index(struct aws_http_headers *headers, size_t index);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Clear all headers.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
void aws_http_headers_clear(struct aws_http_headers *headers);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the `:method` value (HTTP/2 headers only).
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http2_headers_get_request_method(const struct aws_http_headers *h2_headers, struct aws_byte_cursor *out_method);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set `:method` (HTTP/2 headers only).
|
||
|
|
* The headers makes its own copy of the underlying string.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http2_headers_set_request_method(struct aws_http_headers *h2_headers, struct aws_byte_cursor method);
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Get the `:scheme` value (HTTP/2 headers only).
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http2_headers_get_request_scheme(const struct aws_http_headers *h2_headers, struct aws_byte_cursor *out_scheme);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set `:scheme` (request pseudo headers only).
|
||
|
|
* The pseudo headers makes its own copy of the underlying string.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http2_headers_set_request_scheme(struct aws_http_headers *h2_headers, struct aws_byte_cursor scheme);
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Get the `:authority` value (request pseudo headers only).
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http2_headers_get_request_authority(
|
||
|
|
const struct aws_http_headers *h2_headers,
|
||
|
|
struct aws_byte_cursor *out_authority);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set `:authority` (request pseudo headers only).
|
||
|
|
* The pseudo headers makes its own copy of the underlying string.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http2_headers_set_request_authority(struct aws_http_headers *h2_headers, struct aws_byte_cursor authority);
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Get the `:path` value (request pseudo headers only).
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http2_headers_get_request_path(const struct aws_http_headers *h2_headers, struct aws_byte_cursor *out_path);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set `:path` (request pseudo headers only).
|
||
|
|
* The pseudo headers makes its own copy of the underlying string.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http2_headers_set_request_path(struct aws_http_headers *h2_headers, struct aws_byte_cursor path);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get `:status` (response pseudo headers only).
|
||
|
|
* If no status is set, AWS_ERROR_HTTP_DATA_NOT_AVAILABLE is raised.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http2_headers_get_response_status(const struct aws_http_headers *h2_headers, int *out_status_code);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set `:status` (response pseudo headers only).
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http2_headers_set_response_status(struct aws_http_headers *h2_headers, int status_code);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create a new HTTP/1.1 request message.
|
||
|
|
* The message is blank, all properties (method, path, etc) must be set individually.
|
||
|
|
* If HTTP/1.1 message used in HTTP/2 connection, the transformation will be automatically applied.
|
||
|
|
* A HTTP/2 message will created and sent based on the HTTP/1.1 message.
|
||
|
|
*
|
||
|
|
* The caller has a hold on the object and must call aws_http_message_release() when they are done with it.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_http_message *aws_http_message_new_request(struct aws_allocator *allocator);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Like aws_http_message_new_request(), but uses existing aws_http_headers instead of creating a new one.
|
||
|
|
* Acquires a hold on the headers, and releases it when the request is destroyed.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_http_message *aws_http_message_new_request_with_headers(
|
||
|
|
struct aws_allocator *allocator,
|
||
|
|
struct aws_http_headers *existing_headers);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create a new HTTP/1.1 response message.
|
||
|
|
* The message is blank, all properties (status, headers, etc) must be set individually.
|
||
|
|
*
|
||
|
|
* The caller has a hold on the object and must call aws_http_message_release() when they are done with it.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_http_message *aws_http_message_new_response(struct aws_allocator *allocator);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create a new HTTP/2 request message.
|
||
|
|
* pseudo headers need to be set from aws_http2_headers_set_request_* to the headers of the aws_http_message.
|
||
|
|
* Will be errored out if used in HTTP/1.1 connection.
|
||
|
|
*
|
||
|
|
* The caller has a hold on the object and must call aws_http_message_release() when they are done with it.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_http_message *aws_http2_message_new_request(struct aws_allocator *allocator);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create a new HTTP/2 response message.
|
||
|
|
* pseudo headers need to be set from aws_http2_headers_set_response_status to the headers of the aws_http_message.
|
||
|
|
* Will be errored out if used in HTTP/1.1 connection.
|
||
|
|
*
|
||
|
|
* The caller has a hold on the object and must call aws_http_message_release() when they are done with it.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_http_message *aws_http2_message_new_response(struct aws_allocator *allocator);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create an HTTP/2 message from HTTP/1.1 message.
|
||
|
|
* pseudo headers will be created from the context and added to the headers of new message.
|
||
|
|
* Normal headers will be copied to the headers of new message.
|
||
|
|
* Note:
|
||
|
|
* - if `host` exist, it will be removed and `:authority` will be added using the information.
|
||
|
|
* - `:scheme` always defaults to "https". To use a different scheme create the HTTP/2 message directly
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_http_message *aws_http2_message_new_from_http1(
|
||
|
|
struct aws_allocator *alloc,
|
||
|
|
const struct aws_http_message *http1_msg);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Acquire a hold on the object, preventing it from being deleted until
|
||
|
|
* aws_http_message_release() is called by all those with a hold on it.
|
||
|
|
*
|
||
|
|
* This function returns the passed in message (possibly NULL) so that acquire-and-assign can be done with a single
|
||
|
|
* statement.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_http_message *aws_http_message_acquire(struct aws_http_message *message);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Release a hold on the object.
|
||
|
|
* The object is deleted when all holds on it are released.
|
||
|
|
*
|
||
|
|
* This function always returns NULL so that release-and-assign-NULL can be done with a single statement.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_http_message *aws_http_message_release(struct aws_http_message *message);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Deprecated. This is equivalent to aws_http_message_release().
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
void aws_http_message_destroy(struct aws_http_message *message);
|
||
|
|
|
||
|
|
AWS_HTTP_API
|
||
|
|
bool aws_http_message_is_request(const struct aws_http_message *message);
|
||
|
|
|
||
|
|
AWS_HTTP_API
|
||
|
|
bool aws_http_message_is_response(const struct aws_http_message *message);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the protocol version of the http message.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
enum aws_http_version aws_http_message_get_protocol_version(const struct aws_http_message *message);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the method (request messages only).
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_message_get_request_method(
|
||
|
|
const struct aws_http_message *request_message,
|
||
|
|
struct aws_byte_cursor *out_method);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the method (request messages only).
|
||
|
|
* The request makes its own copy of the underlying string.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_message_set_request_method(struct aws_http_message *request_message, struct aws_byte_cursor method);
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Get the path-and-query value (request messages only).
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_message_get_request_path(const struct aws_http_message *request_message, struct aws_byte_cursor *out_path);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the path-and-query value (request messages only).
|
||
|
|
* The request makes its own copy of the underlying string.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_message_set_request_path(struct aws_http_message *request_message, struct aws_byte_cursor path);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the status code (response messages only).
|
||
|
|
* If no status is set, AWS_ERROR_HTTP_DATA_NOT_AVAILABLE is raised.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_message_get_response_status(const struct aws_http_message *response_message, int *out_status_code);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the status code (response messages only).
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_message_set_response_status(struct aws_http_message *response_message, int status_code);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the body stream.
|
||
|
|
* Returns NULL if no body stream is set.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_input_stream *aws_http_message_get_body_stream(const struct aws_http_message *message);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the body stream.
|
||
|
|
* NULL is an acceptable value for messages with no body.
|
||
|
|
* Note: The message does NOT take ownership of the body stream.
|
||
|
|
* The stream must not be destroyed until the message is complete.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
void aws_http_message_set_body_stream(struct aws_http_message *message, struct aws_input_stream *body_stream);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* aws_future<aws_http_message*>
|
||
|
|
*/
|
||
|
|
AWS_FUTURE_T_POINTER_WITH_RELEASE_DECLARATION(aws_future_http_message, struct aws_http_message, AWS_HTTP_API)
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Submit a chunk of data to be sent on an HTTP/1.1 stream.
|
||
|
|
* The stream must have specified "chunked" in a "transfer-encoding" header.
|
||
|
|
* For client streams, activate() must be called before any chunks are submitted.
|
||
|
|
* For server streams, the response must be submitted before any chunks.
|
||
|
|
* A final chunk with size 0 must be submitted to successfully complete the HTTP-stream.
|
||
|
|
*
|
||
|
|
* Returns AWS_OP_SUCCESS if the chunk has been submitted. The chunk's completion
|
||
|
|
* callback will be invoked when the HTTP-stream is done with the chunk data,
|
||
|
|
* whether or not it was successfully sent (see `aws_http1_stream_write_chunk_complete_fn`).
|
||
|
|
* The chunk data must remain valid until the completion callback is invoked.
|
||
|
|
*
|
||
|
|
* Returns AWS_OP_ERR and raises an error if the chunk could not be submitted.
|
||
|
|
* In this case, the chunk's completion callback will never be invoked.
|
||
|
|
* Note that it is always possible for the HTTP-stream to terminate unexpectedly
|
||
|
|
* prior to this call being made, in which case the error raised is
|
||
|
|
* AWS_ERROR_HTTP_STREAM_HAS_COMPLETED.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API int aws_http1_stream_write_chunk(
|
||
|
|
struct aws_http_stream *http1_stream,
|
||
|
|
const struct aws_http1_chunk_options *options);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The stream must have specified `http2_use_manual_data_writes` during request creation.
|
||
|
|
* For client streams, activate() must be called before any frames are submitted.
|
||
|
|
* For server streams, the response headers must be submitted before any frames.
|
||
|
|
* A write with options that has end_stream set to be true will end the stream and prevent any further write.
|
||
|
|
*
|
||
|
|
* @return AWS_OP_SUCCESS if the write was queued
|
||
|
|
* AWS_OP_ERROR indicating the attempt raised an error code.
|
||
|
|
* AWS_ERROR_INVALID_STATE will be raised for invalid usage.
|
||
|
|
* AWS_ERROR_HTTP_STREAM_HAS_COMPLETED will be raised if the stream ended for reasons behind the scenes.
|
||
|
|
*
|
||
|
|
* Typical usage will be something like:
|
||
|
|
* options.http2_use_manual_data_writes = true;
|
||
|
|
* stream = aws_http_connection_make_request(connection, &options);
|
||
|
|
* aws_http_stream_activate(stream);
|
||
|
|
* ...
|
||
|
|
* struct aws_http2_stream_write_data_options write;
|
||
|
|
* aws_http2_stream_write_data(stream, &write);
|
||
|
|
* ...
|
||
|
|
* struct aws_http2_stream_write_data_options last_write;
|
||
|
|
* last_write.end_stream = true;
|
||
|
|
* aws_http2_stream_write_data(stream, &write);
|
||
|
|
* ...
|
||
|
|
* aws_http_stream_release(stream);
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API int aws_http2_stream_write_data(
|
||
|
|
struct aws_http_stream *http2_stream,
|
||
|
|
const struct aws_http2_stream_write_data_options *options);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Add a list of headers to be added as trailing headers sent after the last chunk is sent.
|
||
|
|
* a "Trailer" header field which indicates the fields present in the trailer.
|
||
|
|
*
|
||
|
|
* Certain headers are forbidden in the trailer (e.g., Transfer-Encoding, Content-Length, Host). See RFC-7541
|
||
|
|
* Section 4.1.2 for more details.
|
||
|
|
*
|
||
|
|
* For client streams, activate() must be called before any chunks are submitted.
|
||
|
|
*
|
||
|
|
* For server streams, the response must be submitted before the trailer can be added
|
||
|
|
*
|
||
|
|
* aws_http1_stream_add_chunked_trailer must be called before the final size 0 chunk, and at the moment can only
|
||
|
|
* be called once, though this could change if need be.
|
||
|
|
*
|
||
|
|
* Returns AWS_OP_SUCCESS if the chunk has been submitted.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API int aws_http1_stream_add_chunked_trailer(
|
||
|
|
struct aws_http_stream *http1_stream,
|
||
|
|
const struct aws_http_headers *trailing_headers);
|
||
|
|
|
||
|
|
/**
|
||
|
|
*
|
||
|
|
* This datastructure has more functions for inspecting and modifying headers than
|
||
|
|
* are available on the aws_http_message datastructure.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_http_headers *aws_http_message_get_headers(const struct aws_http_message *message);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the message's const aws_http_headers.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
const struct aws_http_headers *aws_http_message_get_const_headers(const struct aws_http_message *message);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the number of headers.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
size_t aws_http_message_get_header_count(const struct aws_http_message *message);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the header at the specified index.
|
||
|
|
* This function cannot fail if a valid index is provided.
|
||
|
|
* Otherwise, AWS_ERROR_INVALID_INDEX will be raised.
|
||
|
|
*
|
||
|
|
* The underlying strings are stored within the message.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_message_get_header(
|
||
|
|
const struct aws_http_message *message,
|
||
|
|
struct aws_http_header *out_header,
|
||
|
|
size_t index);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Add a header to the end of the array.
|
||
|
|
* The message makes its own copy of the underlying strings.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_message_add_header(struct aws_http_message *message, struct aws_http_header header);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Add an array of headers to the end of the header array.
|
||
|
|
* The message makes its own copy of the underlying strings.
|
||
|
|
*
|
||
|
|
* This is a helper function useful when it's easier to define headers as a stack array, rather than calling add_header
|
||
|
|
* repeatedly.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_message_add_header_array(
|
||
|
|
struct aws_http_message *message,
|
||
|
|
const struct aws_http_header *headers,
|
||
|
|
size_t num_headers);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Remove the header at the specified index.
|
||
|
|
* Headers after this index are all shifted back one position.
|
||
|
|
*
|
||
|
|
* This function cannot fail if a valid index is provided.
|
||
|
|
* Otherwise, AWS_ERROR_INVALID_INDEX will be raised.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_message_erase_header(struct aws_http_message *message, size_t index);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create a stream, with a client connection sending a request.
|
||
|
|
* The request does not start sending automatically once the stream is created. You must call
|
||
|
|
* aws_http_stream_activate to begin execution of the request.
|
||
|
|
*
|
||
|
|
* The `options` are copied during this call.
|
||
|
|
*
|
||
|
|
* Tip for language bindings: Do not bind the `options` struct. Use something more natural for your language,
|
||
|
|
* such as Builder Pattern in Java, or Python's ability to take many optional arguments by name.
|
||
|
|
*
|
||
|
|
* Note: The header of the request will be sent as it is when the message to send protocol matches the protocol of the
|
||
|
|
* connection.
|
||
|
|
* - No `user-agent` will be added.
|
||
|
|
* - No security check will be enforced. eg: `referer` header privacy should be enforced by the user-agent who adds the
|
||
|
|
* header
|
||
|
|
* - When HTTP/1 message sent on HTTP/2 connection, `aws_http2_message_new_from_http1` will be applied under the hood.
|
||
|
|
* - When HTTP/2 message sent on HTTP/1 connection, no change will be made.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_http_stream *aws_http_connection_make_request(
|
||
|
|
struct aws_http_connection *client_connection,
|
||
|
|
const struct aws_http_make_request_options *options);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create a stream, with a server connection receiving and responding to a request.
|
||
|
|
* This function can only be called from the `aws_http_on_incoming_request_fn` callback.
|
||
|
|
* aws_http_stream_send_response() should be used to send a response.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_http_stream *aws_http_stream_new_server_request_handler(
|
||
|
|
const struct aws_http_request_handler_options *options);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Acquire refcount on the stream to prevent it from being cleaned up until it is released.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_http_stream *aws_http_stream_acquire(struct aws_http_stream *stream);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Users must release the stream when they are done with it, or its memory will never be cleaned up.
|
||
|
|
* This will not cancel the stream, its callbacks will still fire if the stream is still in progress.
|
||
|
|
*
|
||
|
|
* Tips for language bindings:
|
||
|
|
* - Invoke this from the wrapper class's finalizer/destructor.
|
||
|
|
* - Do not let the wrapper class be destroyed until on_complete() has fired.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
void aws_http_stream_release(struct aws_http_stream *stream);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Only used for client initiated streams (immediately following a call to aws_http_connection_make_request).
|
||
|
|
*
|
||
|
|
* Activates the request's outgoing stream processing.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API int aws_http_stream_activate(struct aws_http_stream *stream);
|
||
|
|
|
||
|
|
AWS_HTTP_API
|
||
|
|
struct aws_http_connection *aws_http_stream_get_connection(const struct aws_http_stream *stream);
|
||
|
|
|
||
|
|
/* Only valid in "request" streams, once response headers start arriving */
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_stream_get_incoming_response_status(const struct aws_http_stream *stream, int *out_status);
|
||
|
|
|
||
|
|
/* Only valid in "request handler" streams, once request headers start arriving */
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_stream_get_incoming_request_method(
|
||
|
|
const struct aws_http_stream *stream,
|
||
|
|
struct aws_byte_cursor *out_method);
|
||
|
|
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_stream_get_incoming_request_uri(const struct aws_http_stream *stream, struct aws_byte_cursor *out_uri);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Send response (only callable from "request handler" streams)
|
||
|
|
* The response object must stay alive at least until the stream's on_complete is called.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http_stream_send_response(struct aws_http_stream *stream, struct aws_http_message *response);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Increment the stream's flow-control window to keep data flowing.
|
||
|
|
*
|
||
|
|
* If the connection was created with `manual_window_management` set true,
|
||
|
|
* the flow-control window of each stream will shrink as body data is received
|
||
|
|
* (headers, padding, and other metadata do not affect the window).
|
||
|
|
* The connection's `initial_window_size` determines the starting size of each stream's window.
|
||
|
|
* If a stream's flow-control window reaches 0, no further data will be received.
|
||
|
|
*
|
||
|
|
* If `manual_window_management` is false, this call will have no effect.
|
||
|
|
* The connection maintains its flow-control windows such that
|
||
|
|
* no back-pressure is applied and data arrives as fast as possible.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
void aws_http_stream_update_window(struct aws_http_stream *stream, size_t increment_size);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Gets the HTTP/2 id associated with a stream. Even h1 streams have an id (using the same allocation procedure
|
||
|
|
* as http/2) for easier tracking purposes. For client streams, this will only be non-zero after a successful call
|
||
|
|
* to aws_http_stream_activate()
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
uint32_t aws_http_stream_get_id(const struct aws_http_stream *stream);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Cancel the stream in flight.
|
||
|
|
* For HTTP/1.1 streams, it's equivalent to closing the connection.
|
||
|
|
* For HTTP/2 streams, it's equivalent to calling reset on the stream with `AWS_HTTP2_ERR_CANCEL`.
|
||
|
|
*
|
||
|
|
* the stream will complete with the error code provided, unless the stream is
|
||
|
|
* already completing for other reasons, or the stream is not activated,
|
||
|
|
* in which case this call will have no impact.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
void aws_http_stream_cancel(struct aws_http_stream *stream, int error_code);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Reset the HTTP/2 stream (HTTP/2 only).
|
||
|
|
* Note that if the stream closes before this async call is fully processed, the RST_STREAM frame will not be sent.
|
||
|
|
*
|
||
|
|
* @param http2_stream HTTP/2 stream.
|
||
|
|
* @param http2_error aws_http2_error_code. Reason to reset the stream.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http2_stream_reset(struct aws_http_stream *http2_stream, uint32_t http2_error);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the error code received in rst_stream.
|
||
|
|
* Only valid if the stream has completed, and an RST_STREAM frame has received.
|
||
|
|
*
|
||
|
|
* @param http2_stream HTTP/2 stream.
|
||
|
|
* @param out_http2_error Gets to set to HTTP/2 error code received in rst_stream.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http2_stream_get_received_reset_error_code(struct aws_http_stream *http2_stream, uint32_t *out_http2_error);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the HTTP/2 error code sent in the RST_STREAM frame (HTTP/2 only).
|
||
|
|
* Only valid if the stream has completed, and has sent an RST_STREAM frame.
|
||
|
|
*
|
||
|
|
* @param http2_stream HTTP/2 stream.
|
||
|
|
* @param out_http2_error Gets to set to HTTP/2 error code sent in rst_stream.
|
||
|
|
*/
|
||
|
|
AWS_HTTP_API
|
||
|
|
int aws_http2_stream_get_sent_reset_error_code(struct aws_http_stream *http2_stream, uint32_t *out_http2_error);
|
||
|
|
|
||
|
|
AWS_EXTERN_C_END
|
||
|
|
AWS_POP_SANE_WARNING_LEVEL
|
||
|
|
|
||
|
|
#endif /* AWS_HTTP_REQUEST_RESPONSE_H */
|