diff options
author | Stefan Eissing <icing@apache.org> | 2022-04-04 10:24:09 +0200 |
---|---|---|
committer | Stefan Eissing <icing@apache.org> | 2022-04-04 10:24:09 +0200 |
commit | 4442201e61616a2a75909b26909121f469bfae7c (patch) | |
tree | 63f3ea4cfe577f6892cd704c0ac4f719bc985093 /include | |
parent | fr doc rebuild. (diff) | |
download | apache2-4442201e61616a2a75909b26909121f469bfae7c.tar.xz apache2-4442201e61616a2a75909b26909121f469bfae7c.zip |
*) core/mod_http/mod_http2:
- adds new meta bucket types REQUEST, RESPONSE and HEADERS to the API.
- adds a new method for setting standard response headers Date and Server
- adds helper methods for formatting parts of HTTP/1.x, like headers and
end chunks for use in non-core parts of the server, e.g. mod_proxy
- splits the HTTP_IN filter into a "generic HTTP" and "specific HTTP/1.x"
filter. The latter one named HTTP1_BODY_IN.
- Uses HTTP1_BODY_IN only for requests with HTTP version <= 1.1
- Removes the chunked input simulation from mod_http2
- adds body_indeterminate flag to request_rec that indicates that a request
body may be present and needs to be read/discarded. This replaces logic
that thinks without Content-Length and Transfer-Encoding, no request
body can exist.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1899547 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'include')
-rw-r--r-- | include/ap_mmn.h | 7 | ||||
-rw-r--r-- | include/http_protocol.h | 292 | ||||
-rw-r--r-- | include/httpd.h | 8 | ||||
-rw-r--r-- | include/mod_core.h | 5 |
4 files changed, 310 insertions, 2 deletions
diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 6457cb21d9..04fb184048 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -705,7 +705,10 @@ * 20211221.5 (2.5.1-dev) Add hook create_secondary_connection and method * ap_create_secondary_connection() to have connection * setup of http2-like connections in core. - * + * 20211221.6 (2.5.1-dev) Add new meta buckets request/response/headers + * Add field `body_indeterminate` in request_rec + * Add new http/1.x formatting helpers + * Add ap_assign_request() */ #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */ @@ -713,7 +716,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20211221 #endif -#define MODULE_MAGIC_NUMBER_MINOR 5 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 6 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/include/http_protocol.h b/include/http_protocol.h index 38eef396a3..b522f70928 100644 --- a/include/http_protocol.h +++ b/include/http_protocol.h @@ -68,6 +68,18 @@ AP_DECLARE(request_rec *) ap_create_request(conn_rec *c); request_rec *ap_read_request(conn_rec *c); /** + * Assign the method, uri and protocol to the request. + * @param r The current request + * @param method the HTTP method + * @param uri the request uri + * @param protocol the request protocol + * @return 1 on success, 0 on failure + */ +AP_DECLARE(int) ap_assign_request(request_rec *r, + const char *method, const char *uri, + const char *protocol); + +/** * Parse and validate the request line. * @param r The current request * @return 1 on success, 0 on failure @@ -1027,6 +1039,252 @@ AP_DECLARE(apr_bucket *) ap_bucket_error_create(int error, const char *buf, apr_pool_t *p, apr_bucket_alloc_t *list); +/** @see ap_bucket_type_request */ +typedef struct ap_bucket_request ap_bucket_request; + +/** + * @struct ap_bucket_request + * @brief A bucket referring to a HTTP request + * + */ +struct ap_bucket_request { + /** Number of buckets using this memory */ + apr_bucket_refcount refcount; + apr_pool_t *pool; /* pool that holds the contents, not for modification */ + const char *method; /* request method */ + const char *uri; /* request uri */ + const char *protocol; /* request protocol */ + apr_table_t *headers; /* request headers */ +}; + +/** @see ap_bucket_type_request */ +AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_request; + +/** + * Determine if a bucket is a request bucket + * @param e The bucket to inspect + * @return true or false + */ +#define AP_BUCKET_IS_REQUEST(e) (e->type == &ap_bucket_type_request) + +/** + * Make the bucket passed in a request bucket + * Copies all parameters to the given pool. + * @param b The bucket to make into a request bucket + * @param method the HTTP method + * @param uri the uri requested + * @param protocol the protocol requested + * @param headers the table of response headers. + * @param p A pool to allocate out of. + * @return The new bucket, or NULL if allocation failed + */ +AP_DECLARE(apr_bucket *) ap_bucket_request_make( + apr_bucket *b, + const char *method, + const char *uri, + const char *protocol, + apr_table_t *headers, + apr_pool_t *p); + +/** + * Make the bucket passed in a request bucket + * Uses all paramters without copying. + * @param b The bucket to make into a request bucket + * @param method the HTTP method + * @param uri the uri requested + * @param protocol the protocol requested + * @param headers the table of response headers. + * @param p A pool to allocate out of. + * @return The new bucket, or NULL if allocation failed + */ +AP_DECLARE(apr_bucket *) ap_bucket_request_maken( + apr_bucket *b, + const char *method, + const char *uri, + const char *protocol, + apr_table_t *headers, + apr_pool_t *p); + +/** + * Create a bucket referring to a HTTP request. + * Copies all parameters to the given pool. + * @param method the HTTP method + * @param uri the uri requested + * @param protocol the protocol requested + * @param headers the table of response headers. + * @param p A pool to allocate the error string out of. + * @param list The bucket allocator from which to allocate the bucket + * @return The new bucket, or NULL if allocation failed + */ +AP_DECLARE(apr_bucket *) ap_bucket_request_create( + const char *method, + const char *uri, + const char *protocol, + apr_table_t *headers, + apr_pool_t *p, + apr_bucket_alloc_t *list); + +/** + * Create a bucket referring to a HTTP request. + * Uses all paramters without copying. + * @param method the HTTP method + * @param uri the uri requested + * @param protocol the protocol requested + * @param headers the HTTP response headers. + * @param p A pool to allocate the error string out of. + * @param list The bucket allocator from which to allocate the bucket + * @return The new bucket, or NULL if allocation failed + */ +AP_DECLARE(apr_bucket *) ap_bucket_request_createn( + const char *method, + const char *uri, + const char *protocol, + apr_table_t *headers, + apr_pool_t *p, + apr_bucket_alloc_t *list); + +/** + * Clone a request bucket into another pool/bucket_alloc that may + * have a separate lifetime than the source bucket/pool. + * @param source the request bucket to clone + * @param p A pool to allocate the data out of. + * @param list The bucket allocator from which to allocate the bucket + * @return The new bucket, or NULL if allocation failed + */ +AP_DECLARE(apr_bucket *) ap_bucket_request_clone(apr_bucket *source, + apr_pool_t *p, + apr_bucket_alloc_t *list); + +/** @see ap_bucket_type_response */ +typedef struct ap_bucket_response ap_bucket_response; + +/** + * @struct ap_bucket_response + * @brief A bucket referring to a HTTP response + * + */ +struct ap_bucket_response { + /** Number of buckets using this memory */ + apr_bucket_refcount refcount; + apr_pool_t *pool; /* pool that holds the contents, not for modification */ + int status; /* The status code */ + const char *reason; /* The optional HTTP reason for the status. */ + apr_table_t *headers; /* The response headers */ + apr_table_t *notes; /* internal notes about the response */ +}; + +/** @see ap_bucket_type_headers */ +AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_response; + +/** + * Determine if a bucket is a response bucket + * @param e The bucket to inspect + * @return true or false + */ +#define AP_BUCKET_IS_RESPONSE(e) (e->type == &ap_bucket_type_response) + +/** + * Make the bucket passed in a response bucket + * @param b The bucket to make into a response bucket + * @param status The HTTP status code of the response. + * @param reason textual description of status, can be NULL. + * @param headers the table of response headers. + * @param notes internal notes on the response + * @param p A pool to allocate out of. + * @return The new bucket, or NULL if allocation failed + */ +AP_DECLARE(apr_bucket *) ap_bucket_response_make(apr_bucket *b, int status, + const char *reason, apr_table_t *headers, + apr_table_t *notes, apr_pool_t *p); + +/** + * Create a bucket referring to a HTTP response. + * @param status The HTTP status code. + * @param reason textual description of status, can be NULL. + * @param headers the HTTP response headers. + * @param notes internal notes on the response + * @param p A pool to allocate the error string out of. + * @param list The bucket allocator from which to allocate the bucket + * @return The new bucket, or NULL if allocation failed + */ +AP_DECLARE(apr_bucket *) ap_bucket_response_create( + int status, const char *reason, + apr_table_t *headers, + apr_table_t *notes, + apr_pool_t *p, + apr_bucket_alloc_t *list); + +/** + * Clone a RESPONSE bucket into another pool/bucket_alloc that may + * have a separate lifetime than the source bucket/pool. + * @param source the response bucket to clone + * @param p A pool to allocate the data out of. + * @param list The bucket allocator from which to allocate the bucket + * @return The new bucket, or NULL if allocation failed + */ +AP_DECLARE(apr_bucket *) ap_bucket_response_clone(apr_bucket *source, + apr_pool_t *p, + apr_bucket_alloc_t *list); + +/** @see ap_bucket_type_headers */ +typedef struct ap_bucket_headers ap_bucket_headers; + +/** + * @struct ap_bucket_headers + * @brief A bucket referring to an HTTP header set + * + */ +struct ap_bucket_headers { + /** Number of buckets using this memory */ + apr_bucket_refcount refcount; + apr_pool_t *pool; /* pool that holds the contents, not for modification */ + apr_table_t *headers; /* The headers */ + +}; + +/** @see ap_bucket_type_headers */ +AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_headers; + +/** + * Determine if a bucket is an headers bucket + * @param e The bucket to inspect + * @return true or false + */ +#define AP_BUCKET_IS_HEADERS(e) (e->type == &ap_bucket_type_headers) + +/** + * Make the bucket passed in a headers bucket + * @param b The bucket to make into a headers bucket + * @param headers the table of headers. + * @param p A pool to allocate out of. + * @return The new bucket, or NULL if allocation failed + */ +AP_DECLARE(apr_bucket *) ap_bucket_headers_make(apr_bucket *b, + apr_table_t *headers, apr_pool_t *p); + +/** + * Create a bucket referring to a table of HTTP headers. + * @param headers the HTTP headers in the bucket. + * @param p A pool to allocate the error string out of. + * @param list The bucket allocator from which to allocate the bucket + * @return The new bucket, or NULL if allocation failed + */ +AP_DECLARE(apr_bucket *) ap_bucket_headers_create(apr_table_t *headers, + apr_pool_t *p, + apr_bucket_alloc_t *list); + +/** + * Clone a HEADER bucket into another pool/bucket_alloc that may + * have a separate lifetime than the source bucket/pool. + * @param source the header bucket to clone + * @param p A pool to allocate the data out of. + * @param list The bucket allocator from which to allocate the bucket + * @return The new bucket, or NULL if allocation failed + */ +AP_DECLARE(apr_bucket *) ap_bucket_headers_clone(apr_bucket *source, + apr_pool_t *p, + apr_bucket_alloc_t *list); + AP_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f, apr_bucket_brigade *b); AP_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, apr_bucket_brigade *b); AP_DECLARE_NONSTD(apr_status_t) ap_content_length_filter(ap_filter_t *, @@ -1048,12 +1306,46 @@ AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, const request_rec *r AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub_r); /** + * Set standard response headers, such as `Date` and `Server` + * in r->headers_out. Takes care of precedence of existing + * values from proxied requests. + */ +AP_DECLARE(void) ap_set_std_response_headers(request_rec *r); + +/** * Send an interim (HTTP 1xx) response immediately. * @param r The request * @param send_headers Whether to send&clear headers in r->headers_out */ AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers); +/** + * Append the headers in HTTP/1.1 format to the brigade. + * @param b the brigade to append to + * @param r the reqeust this is done for (pool and logging) + * @param headers the headers to append + */ +AP_DECLARE(apr_status_t) ap_h1_append_headers(apr_bucket_brigade *b, + request_rec *r, + apr_table_t *headers); + +/** + * Append the HTTP/1.1 header termination (empty CRLF) to the brigade. + * @param b the brigade to append to + */ +AP_DECLARE(apr_status_t) ap_h1_terminate_header(apr_bucket_brigade *b); + +/** + * Insert/Append the last chunk in a HTTP/1.1 Transfer-Encoding chunked. + * @param b the brigade to add the chunk to + * @param eos the bucket before to add or NULL for insert at tail + * @param r the request handled + * @param trailers table of trailers or NULL + */ +AP_DECLARE(void) ap_h1_add_end_chunk(apr_bucket_brigade *b, + apr_bucket *eos, + request_rec *r, + apr_table_t *trailers); #ifdef __cplusplus } diff --git a/include/httpd.h b/include/httpd.h index 41e570799e..a4c32535c7 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -1144,6 +1144,14 @@ struct request_rec { * the elements of this field. */ ap_request_bnotes_t bnotes; + /** Indicates that the request has a body of unknown length and + * protocol handlers need to read it, even if only to discard the + * data. In HTTP/1.1 this is set on chunked transfer encodings, but + * newer HTTP versions can transfer such bodies by other means. The + * absence of a "Transfer-Encoding" header is no longer sufficient + * to conclude that no body is there. + */ + int body_indeterminate; }; /** diff --git a/include/mod_core.h b/include/mod_core.h index 8eab3e12c4..4897fee6f5 100644 --- a/include/mod_core.h +++ b/include/mod_core.h @@ -40,6 +40,7 @@ extern "C" { /* Handles for core filters */ AP_DECLARE_DATA extern ap_filter_rec_t *ap_http_input_filter_handle; +AP_DECLARE_DATA extern ap_filter_rec_t *ap_h1_body_in_filter_handle; AP_DECLARE_DATA extern ap_filter_rec_t *ap_http_header_filter_handle; AP_DECLARE_DATA extern ap_filter_rec_t *ap_chunk_filter_handle; AP_DECLARE_DATA extern ap_filter_rec_t *ap_http_outerror_filter_handle; @@ -52,6 +53,10 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes); +apr_status_t ap_h1_body_in_filter(ap_filter_t *f, apr_bucket_brigade *b, + ap_input_mode_t mode, apr_read_type_e block, + apr_off_t readbytes); + /* HTTP/1.1 chunked transfer encoding filter. */ apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b); |