Skip to content

Commit 4442201

Browse files
committed
*) 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
1 parent a6ed77c commit 4442201

18 files changed

+984
-325
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,7 @@ SET(LIBHTTPD_SOURCES
699699
server/eoc_bucket.c
700700
server/eor_bucket.c
701701
server/error_bucket.c
702+
server/headers_bucket.c
702703
server/listen.c
703704
server/log.c
704705
server/mpm/winnt/child.c

include/ap_mmn.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -705,15 +705,18 @@
705705
* 20211221.5 (2.5.1-dev) Add hook create_secondary_connection and method
706706
* ap_create_secondary_connection() to have connection
707707
* setup of http2-like connections in core.
708-
*
708+
* 20211221.6 (2.5.1-dev) Add new meta buckets request/response/headers
709+
* Add field `body_indeterminate` in request_rec
710+
* Add new http/1.x formatting helpers
711+
* Add ap_assign_request()
709712
*/
710713

711714
#define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
712715

713716
#ifndef MODULE_MAGIC_NUMBER_MAJOR
714717
#define MODULE_MAGIC_NUMBER_MAJOR 20211221
715718
#endif
716-
#define MODULE_MAGIC_NUMBER_MINOR 5 /* 0...n */
719+
#define MODULE_MAGIC_NUMBER_MINOR 6 /* 0...n */
717720

718721
/**
719722
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a

include/http_protocol.h

+292
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@ AP_DECLARE(request_rec *) ap_create_request(conn_rec *c);
6767
*/
6868
request_rec *ap_read_request(conn_rec *c);
6969

70+
/**
71+
* Assign the method, uri and protocol to the request.
72+
* @param r The current request
73+
* @param method the HTTP method
74+
* @param uri the request uri
75+
* @param protocol the request protocol
76+
* @return 1 on success, 0 on failure
77+
*/
78+
AP_DECLARE(int) ap_assign_request(request_rec *r,
79+
const char *method, const char *uri,
80+
const char *protocol);
81+
7082
/**
7183
* Parse and validate the request line.
7284
* @param r The current request
@@ -1027,6 +1039,252 @@ AP_DECLARE(apr_bucket *) ap_bucket_error_create(int error, const char *buf,
10271039
apr_pool_t *p,
10281040
apr_bucket_alloc_t *list);
10291041

1042+
/** @see ap_bucket_type_request */
1043+
typedef struct ap_bucket_request ap_bucket_request;
1044+
1045+
/**
1046+
* @struct ap_bucket_request
1047+
* @brief A bucket referring to a HTTP request
1048+
*
1049+
*/
1050+
struct ap_bucket_request {
1051+
/** Number of buckets using this memory */
1052+
apr_bucket_refcount refcount;
1053+
apr_pool_t *pool; /* pool that holds the contents, not for modification */
1054+
const char *method; /* request method */
1055+
const char *uri; /* request uri */
1056+
const char *protocol; /* request protocol */
1057+
apr_table_t *headers; /* request headers */
1058+
};
1059+
1060+
/** @see ap_bucket_type_request */
1061+
AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_request;
1062+
1063+
/**
1064+
* Determine if a bucket is a request bucket
1065+
* @param e The bucket to inspect
1066+
* @return true or false
1067+
*/
1068+
#define AP_BUCKET_IS_REQUEST(e) (e->type == &ap_bucket_type_request)
1069+
1070+
/**
1071+
* Make the bucket passed in a request bucket
1072+
* Copies all parameters to the given pool.
1073+
* @param b The bucket to make into a request bucket
1074+
* @param method the HTTP method
1075+
* @param uri the uri requested
1076+
* @param protocol the protocol requested
1077+
* @param headers the table of response headers.
1078+
* @param p A pool to allocate out of.
1079+
* @return The new bucket, or NULL if allocation failed
1080+
*/
1081+
AP_DECLARE(apr_bucket *) ap_bucket_request_make(
1082+
apr_bucket *b,
1083+
const char *method,
1084+
const char *uri,
1085+
const char *protocol,
1086+
apr_table_t *headers,
1087+
apr_pool_t *p);
1088+
1089+
/**
1090+
* Make the bucket passed in a request bucket
1091+
* Uses all paramters without copying.
1092+
* @param b The bucket to make into a request bucket
1093+
* @param method the HTTP method
1094+
* @param uri the uri requested
1095+
* @param protocol the protocol requested
1096+
* @param headers the table of response headers.
1097+
* @param p A pool to allocate out of.
1098+
* @return The new bucket, or NULL if allocation failed
1099+
*/
1100+
AP_DECLARE(apr_bucket *) ap_bucket_request_maken(
1101+
apr_bucket *b,
1102+
const char *method,
1103+
const char *uri,
1104+
const char *protocol,
1105+
apr_table_t *headers,
1106+
apr_pool_t *p);
1107+
1108+
/**
1109+
* Create a bucket referring to a HTTP request.
1110+
* Copies all parameters to the given pool.
1111+
* @param method the HTTP method
1112+
* @param uri the uri requested
1113+
* @param protocol the protocol requested
1114+
* @param headers the table of response headers.
1115+
* @param p A pool to allocate the error string out of.
1116+
* @param list The bucket allocator from which to allocate the bucket
1117+
* @return The new bucket, or NULL if allocation failed
1118+
*/
1119+
AP_DECLARE(apr_bucket *) ap_bucket_request_create(
1120+
const char *method,
1121+
const char *uri,
1122+
const char *protocol,
1123+
apr_table_t *headers,
1124+
apr_pool_t *p,
1125+
apr_bucket_alloc_t *list);
1126+
1127+
/**
1128+
* Create a bucket referring to a HTTP request.
1129+
* Uses all paramters without copying.
1130+
* @param method the HTTP method
1131+
* @param uri the uri requested
1132+
* @param protocol the protocol requested
1133+
* @param headers the HTTP response headers.
1134+
* @param p A pool to allocate the error string out of.
1135+
* @param list The bucket allocator from which to allocate the bucket
1136+
* @return The new bucket, or NULL if allocation failed
1137+
*/
1138+
AP_DECLARE(apr_bucket *) ap_bucket_request_createn(
1139+
const char *method,
1140+
const char *uri,
1141+
const char *protocol,
1142+
apr_table_t *headers,
1143+
apr_pool_t *p,
1144+
apr_bucket_alloc_t *list);
1145+
1146+
/**
1147+
* Clone a request bucket into another pool/bucket_alloc that may
1148+
* have a separate lifetime than the source bucket/pool.
1149+
* @param source the request bucket to clone
1150+
* @param p A pool to allocate the data out of.
1151+
* @param list The bucket allocator from which to allocate the bucket
1152+
* @return The new bucket, or NULL if allocation failed
1153+
*/
1154+
AP_DECLARE(apr_bucket *) ap_bucket_request_clone(apr_bucket *source,
1155+
apr_pool_t *p,
1156+
apr_bucket_alloc_t *list);
1157+
1158+
/** @see ap_bucket_type_response */
1159+
typedef struct ap_bucket_response ap_bucket_response;
1160+
1161+
/**
1162+
* @struct ap_bucket_response
1163+
* @brief A bucket referring to a HTTP response
1164+
*
1165+
*/
1166+
struct ap_bucket_response {
1167+
/** Number of buckets using this memory */
1168+
apr_bucket_refcount refcount;
1169+
apr_pool_t *pool; /* pool that holds the contents, not for modification */
1170+
int status; /* The status code */
1171+
const char *reason; /* The optional HTTP reason for the status. */
1172+
apr_table_t *headers; /* The response headers */
1173+
apr_table_t *notes; /* internal notes about the response */
1174+
};
1175+
1176+
/** @see ap_bucket_type_headers */
1177+
AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_response;
1178+
1179+
/**
1180+
* Determine if a bucket is a response bucket
1181+
* @param e The bucket to inspect
1182+
* @return true or false
1183+
*/
1184+
#define AP_BUCKET_IS_RESPONSE(e) (e->type == &ap_bucket_type_response)
1185+
1186+
/**
1187+
* Make the bucket passed in a response bucket
1188+
* @param b The bucket to make into a response bucket
1189+
* @param status The HTTP status code of the response.
1190+
* @param reason textual description of status, can be NULL.
1191+
* @param headers the table of response headers.
1192+
* @param notes internal notes on the response
1193+
* @param p A pool to allocate out of.
1194+
* @return The new bucket, or NULL if allocation failed
1195+
*/
1196+
AP_DECLARE(apr_bucket *) ap_bucket_response_make(apr_bucket *b, int status,
1197+
const char *reason, apr_table_t *headers,
1198+
apr_table_t *notes, apr_pool_t *p);
1199+
1200+
/**
1201+
* Create a bucket referring to a HTTP response.
1202+
* @param status The HTTP status code.
1203+
* @param reason textual description of status, can be NULL.
1204+
* @param headers the HTTP response headers.
1205+
* @param notes internal notes on the response
1206+
* @param p A pool to allocate the error string out of.
1207+
* @param list The bucket allocator from which to allocate the bucket
1208+
* @return The new bucket, or NULL if allocation failed
1209+
*/
1210+
AP_DECLARE(apr_bucket *) ap_bucket_response_create(
1211+
int status, const char *reason,
1212+
apr_table_t *headers,
1213+
apr_table_t *notes,
1214+
apr_pool_t *p,
1215+
apr_bucket_alloc_t *list);
1216+
1217+
/**
1218+
* Clone a RESPONSE bucket into another pool/bucket_alloc that may
1219+
* have a separate lifetime than the source bucket/pool.
1220+
* @param source the response bucket to clone
1221+
* @param p A pool to allocate the data out of.
1222+
* @param list The bucket allocator from which to allocate the bucket
1223+
* @return The new bucket, or NULL if allocation failed
1224+
*/
1225+
AP_DECLARE(apr_bucket *) ap_bucket_response_clone(apr_bucket *source,
1226+
apr_pool_t *p,
1227+
apr_bucket_alloc_t *list);
1228+
1229+
/** @see ap_bucket_type_headers */
1230+
typedef struct ap_bucket_headers ap_bucket_headers;
1231+
1232+
/**
1233+
* @struct ap_bucket_headers
1234+
* @brief A bucket referring to an HTTP header set
1235+
*
1236+
*/
1237+
struct ap_bucket_headers {
1238+
/** Number of buckets using this memory */
1239+
apr_bucket_refcount refcount;
1240+
apr_pool_t *pool; /* pool that holds the contents, not for modification */
1241+
apr_table_t *headers; /* The headers */
1242+
1243+
};
1244+
1245+
/** @see ap_bucket_type_headers */
1246+
AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_headers;
1247+
1248+
/**
1249+
* Determine if a bucket is an headers bucket
1250+
* @param e The bucket to inspect
1251+
* @return true or false
1252+
*/
1253+
#define AP_BUCKET_IS_HEADERS(e) (e->type == &ap_bucket_type_headers)
1254+
1255+
/**
1256+
* Make the bucket passed in a headers bucket
1257+
* @param b The bucket to make into a headers bucket
1258+
* @param headers the table of headers.
1259+
* @param p A pool to allocate out of.
1260+
* @return The new bucket, or NULL if allocation failed
1261+
*/
1262+
AP_DECLARE(apr_bucket *) ap_bucket_headers_make(apr_bucket *b,
1263+
apr_table_t *headers, apr_pool_t *p);
1264+
1265+
/**
1266+
* Create a bucket referring to a table of HTTP headers.
1267+
* @param headers the HTTP headers in the bucket.
1268+
* @param p A pool to allocate the error string out of.
1269+
* @param list The bucket allocator from which to allocate the bucket
1270+
* @return The new bucket, or NULL if allocation failed
1271+
*/
1272+
AP_DECLARE(apr_bucket *) ap_bucket_headers_create(apr_table_t *headers,
1273+
apr_pool_t *p,
1274+
apr_bucket_alloc_t *list);
1275+
1276+
/**
1277+
* Clone a HEADER bucket into another pool/bucket_alloc that may
1278+
* have a separate lifetime than the source bucket/pool.
1279+
* @param source the header bucket to clone
1280+
* @param p A pool to allocate the data out of.
1281+
* @param list The bucket allocator from which to allocate the bucket
1282+
* @return The new bucket, or NULL if allocation failed
1283+
*/
1284+
AP_DECLARE(apr_bucket *) ap_bucket_headers_clone(apr_bucket *source,
1285+
apr_pool_t *p,
1286+
apr_bucket_alloc_t *list);
1287+
10301288
AP_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f, apr_bucket_brigade *b);
10311289
AP_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, apr_bucket_brigade *b);
10321290
AP_DECLARE_NONSTD(apr_status_t) ap_content_length_filter(ap_filter_t *,
@@ -1047,13 +1305,47 @@ AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, const request_rec *r
10471305
*/
10481306
AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub_r);
10491307

1308+
/**
1309+
* Set standard response headers, such as `Date` and `Server`
1310+
* in r->headers_out. Takes care of precedence of existing
1311+
* values from proxied requests.
1312+
*/
1313+
AP_DECLARE(void) ap_set_std_response_headers(request_rec *r);
1314+
10501315
/**
10511316
* Send an interim (HTTP 1xx) response immediately.
10521317
* @param r The request
10531318
* @param send_headers Whether to send&clear headers in r->headers_out
10541319
*/
10551320
AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers);
10561321

1322+
/**
1323+
* Append the headers in HTTP/1.1 format to the brigade.
1324+
* @param b the brigade to append to
1325+
* @param r the reqeust this is done for (pool and logging)
1326+
* @param headers the headers to append
1327+
*/
1328+
AP_DECLARE(apr_status_t) ap_h1_append_headers(apr_bucket_brigade *b,
1329+
request_rec *r,
1330+
apr_table_t *headers);
1331+
1332+
/**
1333+
* Append the HTTP/1.1 header termination (empty CRLF) to the brigade.
1334+
* @param b the brigade to append to
1335+
*/
1336+
AP_DECLARE(apr_status_t) ap_h1_terminate_header(apr_bucket_brigade *b);
1337+
1338+
/**
1339+
* Insert/Append the last chunk in a HTTP/1.1 Transfer-Encoding chunked.
1340+
* @param b the brigade to add the chunk to
1341+
* @param eos the bucket before to add or NULL for insert at tail
1342+
* @param r the request handled
1343+
* @param trailers table of trailers or NULL
1344+
*/
1345+
AP_DECLARE(void) ap_h1_add_end_chunk(apr_bucket_brigade *b,
1346+
apr_bucket *eos,
1347+
request_rec *r,
1348+
apr_table_t *trailers);
10571349

10581350
#ifdef __cplusplus
10591351
}

include/httpd.h

+8
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,14 @@ struct request_rec {
11441144
* the elements of this field.
11451145
*/
11461146
ap_request_bnotes_t bnotes;
1147+
/** Indicates that the request has a body of unknown length and
1148+
* protocol handlers need to read it, even if only to discard the
1149+
* data. In HTTP/1.1 this is set on chunked transfer encodings, but
1150+
* newer HTTP versions can transfer such bodies by other means. The
1151+
* absence of a "Transfer-Encoding" header is no longer sufficient
1152+
* to conclude that no body is there.
1153+
*/
1154+
int body_indeterminate;
11471155
};
11481156

11491157
/**

include/mod_core.h

+5
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ extern "C" {
4040

4141
/* Handles for core filters */
4242
AP_DECLARE_DATA extern ap_filter_rec_t *ap_http_input_filter_handle;
43+
AP_DECLARE_DATA extern ap_filter_rec_t *ap_h1_body_in_filter_handle;
4344
AP_DECLARE_DATA extern ap_filter_rec_t *ap_http_header_filter_handle;
4445
AP_DECLARE_DATA extern ap_filter_rec_t *ap_chunk_filter_handle;
4546
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,
5253
ap_input_mode_t mode, apr_read_type_e block,
5354
apr_off_t readbytes);
5455

56+
apr_status_t ap_h1_body_in_filter(ap_filter_t *f, apr_bucket_brigade *b,
57+
ap_input_mode_t mode, apr_read_type_e block,
58+
apr_off_t readbytes);
59+
5560
/* HTTP/1.1 chunked transfer encoding filter. */
5661
apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b);
5762

libhttpd.dsp

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)