1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-08 15:02:10 +03:00

factor out TE=chunked checking

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1873748 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Eric Covener
2020-02-07 17:14:05 +00:00
parent 81313af01a
commit c1ac12fa3b
7 changed files with 57 additions and 16 deletions

View File

@@ -619,6 +619,7 @@
* and ap_proxy_tunnel_run() to proxy_util. * and ap_proxy_tunnel_run() to proxy_util.
* 20190312.6 (2.5.1-dev) Add proxy check_trans hook * 20190312.6 (2.5.1-dev) Add proxy check_trans hook
* 20190312.7 (2.5.1-dev) AP_REG_DEFAULT macro in ap_regex.h * 20190312.7 (2.5.1-dev) AP_REG_DEFAULT macro in ap_regex.h
* 20190312.8 (2.5.1-dev) ap_is_chunked() in httpd.h
*/ */
#define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */ #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
@@ -626,7 +627,7 @@
#ifndef MODULE_MAGIC_NUMBER_MAJOR #ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20190312 #define MODULE_MAGIC_NUMBER_MAJOR 20190312
#endif #endif
#define MODULE_MAGIC_NUMBER_MINOR 7 /* 0...n */ #define MODULE_MAGIC_NUMBER_MINOR 8 /* 0...n */
/** /**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a * Determine if the server's current MODULE_MAGIC_NUMBER is at least a

View File

@@ -2660,6 +2660,15 @@ AP_DECLARE(const char *)ap_dir_nofnmatch(ap_dir_match_t *w, const char *fname)
AP_DECLARE(const char *)ap_dir_fnmatch(ap_dir_match_t *w, const char *path, AP_DECLARE(const char *)ap_dir_fnmatch(ap_dir_match_t *w, const char *path,
const char *fname) __attribute__((nonnull(1,3))); const char *fname) __attribute__((nonnull(1,3)));
/**
* Determine if the final Transfer-Encoding is "chunked".
*
* @param p The pool to allocate from
* @param line the header field-value to scan
* @return 1 if the last Transfer-Encoding is "chunked", else 0
*/
AP_DECLARE(int) ap_is_chunked(apr_pool_t *p, const char *line);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -333,8 +333,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
lenp = apr_table_get(f->r->headers_in, "Content-Length"); lenp = apr_table_get(f->r->headers_in, "Content-Length");
if (tenc) { if (tenc) {
if (ap_cstr_casecmp(tenc, "chunked") == 0 /* fast path */ if (ap_is_chunked(f->r->pool, tenc)) {
|| ap_find_last_token(f->r->pool, tenc, "chunked")) {
ctx->state = BODY_CHUNK; ctx->state = BODY_CHUNK;
} }
else if (f->r->proxyreq == PROXYREQ_RESPONSE) { else if (f->r->proxyreq == PROXYREQ_RESPONSE) {

View File

@@ -257,10 +257,9 @@ AP_DECLARE(int) ap_set_keepalive(request_rec *r)
&& (r->header_only && (r->header_only
|| AP_STATUS_IS_HEADER_ONLY(r->status) || AP_STATUS_IS_HEADER_ONLY(r->status)
|| apr_table_get(r->headers_out, "Content-Length") || apr_table_get(r->headers_out, "Content-Length")
|| ap_find_last_token(r->pool, || ap_is_chunked(r->pool,
apr_table_get(r->headers_out, apr_table_get(r->headers_out,
"Transfer-Encoding"), "Transfer-Encoding"))
"chunked")
|| ((r->proto_num >= HTTP_VERSION(1,1)) || ((r->proto_num >= HTTP_VERSION(1,1))
&& (r->chunked = 1))) /* THIS CODE IS CORRECT, see above. */ && (r->chunked = 1))) /* THIS CODE IS CORRECT, see above. */
&& r->server->keep_alive && r->server->keep_alive

View File

@@ -311,8 +311,8 @@ static apr_status_t policy_keepalive_out_filter(ap_filter_t *f,
if (!(r->header_only if (!(r->header_only
|| AP_STATUS_IS_HEADER_ONLY(r->status) || AP_STATUS_IS_HEADER_ONLY(r->status)
|| apr_table_get(r->headers_out, "Content-Length") || apr_table_get(r->headers_out, "Content-Length")
|| ap_find_last_token(r->pool, apr_table_get(r->headers_out, || ap_is_chunked(r->pool, apr_table_get(r->headers_out,
"Transfer-Encoding"), "chunked") "Transfer-Encoding"))
|| r->proto_num >= HTTP_VERSION(1, 1))) { || r->proto_num >= HTTP_VERSION(1, 1))) {
handle_policy(r, result, "Keepalive should be possible (supply Content-Length or HTTP/1.1 Transfer-Encoding)", handle_policy(r, result, "Keepalive should be possible (supply Content-Length or HTTP/1.1 Transfer-Encoding)",

View File

@@ -1430,8 +1430,7 @@ request_rec *ap_read_request(conn_rec *conn)
* the final encoding ...; the server MUST respond with the 400 * the final encoding ...; the server MUST respond with the 400
* (Bad Request) status code and then close the connection". * (Bad Request) status code and then close the connection".
*/ */
if (!(ap_cstr_casecmp(tenc, "chunked") == 0 /* fast path */ if (!ap_is_chunked(r->pool, tenc)) {
|| ap_find_last_token(r->pool, tenc, "chunked"))) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02539) ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02539)
"client sent unknown Transfer-Encoding " "client sent unknown Transfer-Encoding "
"(%s): %s", tenc, r->uri); "(%s): %s", tenc, r->uri);

View File

@@ -1709,14 +1709,13 @@ AP_DECLARE(int) ap_find_token(apr_pool_t *p, const char *line, const char *tok)
} }
} }
static const char *find_last_token(apr_pool_t *p, const char *line,
AP_DECLARE(int) ap_find_last_token(apr_pool_t *p, const char *line, const char *tok)
const char *tok)
{ {
int llen, tlen, lidx; int llen, tlen, lidx;
if (!line) if (!line)
return 0; return NULL;
llen = strlen(line); llen = strlen(line);
tlen = strlen(tok); tlen = strlen(tok);
@@ -1724,9 +1723,44 @@ AP_DECLARE(int) ap_find_last_token(apr_pool_t *p, const char *line,
if (lidx < 0 || if (lidx < 0 ||
(lidx > 0 && !(apr_isspace(line[lidx - 1]) || line[lidx - 1] == ','))) (lidx > 0 && !(apr_isspace(line[lidx - 1]) || line[lidx - 1] == ',')))
return 0; return NULL;
return (ap_cstr_casecmpn(&line[lidx], tok, tlen) == 0); if (ap_cstr_casecmpn(&line[lidx], tok, tlen) == 0) {
return &line[lidx];
}
return NULL;
}
AP_DECLARE(int) ap_find_last_token(apr_pool_t *p, const char *line,
const char *tok)
{
return find_last_token(p, line, tok) != NULL;
}
AP_DECLARE(int) ap_is_chunked(apr_pool_t *p, const char *line)
{
const char *s;
if (!line)
return 0;
if (!ap_cstr_casecmp(line, "chunked")) {
return 1;
}
s = find_last_token(p, line, "chunked");
if (!s) return 0;
/* eat spaces right-to-left to see what precedes "chunked" */
while (--s > line) {
if (*s != ' ') break;
}
/* found delim, or leading ws (input wasn't parsed by httpd as a header) */
if (*s == ',' || *s == ' ') {
return 1;
}
return 0;
} }
AP_DECLARE(char *) ap_escape_shell_cmd(apr_pool_t *p, const char *str) AP_DECLARE(char *) ap_escape_shell_cmd(apr_pool_t *p, const char *str)