summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorStefan Eissing <icing@apache.org>2022-04-04 08:24:09 +0000
committerStefan Eissing <icing@apache.org>2022-04-04 08:24:09 +0000
commit4442201e61616a2a75909b26909121f469bfae7c (patch)
tree63f3ea4cfe577f6892cd704c0ac4f719bc985093 /include
parenta6ed77c35e71805db39f79a9d8e171bb7737e712 (diff)
downloadhttpd-4442201e61616a2a75909b26909121f469bfae7c.tar.gz
*) 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.h7
-rw-r--r--include/http_protocol.h292
-rw-r--r--include/httpd.h8
-rw-r--r--include/mod_core.h5
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);