]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
factor out TE=chunked checking
authorEric Covener <covener@apache.org>
Fri, 7 Feb 2020 17:14:05 +0000 (17:14 +0000)
committerEric Covener <covener@apache.org>
Fri, 7 Feb 2020 17:14:05 +0000 (17:14 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1873748 13f79535-47bb-0310-9956-ffa450edef68

include/ap_mmn.h
include/httpd.h
modules/http/http_filters.c
modules/http/http_protocol.c
modules/test/mod_policy.c
server/protocol.c
server/util.c

index 401067e5108b09dddf10bed3ea4f154a3332dc83..5d1941228cf7be790f5a4e2ceec04bcefd14154a 100644 (file)
  *                         and ap_proxy_tunnel_run() to proxy_util.
  * 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.8 (2.5.1-dev)  ap_is_chunked() in httpd.h
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20190312
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR               /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 8              /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
index 03b7751fee4f22a4d37cd8e63d841d1f378ae17f..ee2acc25d9307917a734cb83dbc3ae93a98c4b52 100644 (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,
         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
 }
 #endif
index 327d902a3c9ba9302c882dd9c9efbfa0d55cbf41..42423e4ddedee23f7035aed674320d4087ed9f9d 100644 (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");
 
         if (tenc) {
-            if (ap_cstr_casecmp(tenc, "chunked") == 0 /* fast path */
-                    || ap_find_last_token(f->r->pool, tenc, "chunked")) {
+            if (ap_is_chunked(f->r->pool, tenc)) {
                 ctx->state = BODY_CHUNK;
             }
             else if (f->r->proxyreq == PROXYREQ_RESPONSE) {
index 899fb787e3bf0fb8d572d18fb3f5076d0f22347a..9cf0cbb2eed64aeed2bb7fd5b6f18987d6cd445b 100644 (file)
@@ -257,10 +257,9 @@ AP_DECLARE(int) ap_set_keepalive(request_rec *r)
         && (r->header_only
             || AP_STATUS_IS_HEADER_ONLY(r->status)
             || 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,
-                                                "Transfer-Encoding"),
-                                  "chunked")
+                                                "Transfer-Encoding"))
             || ((r->proto_num >= HTTP_VERSION(1,1))
                 && (r->chunked = 1))) /* THIS CODE IS CORRECT, see above. */
         && r->server->keep_alive
index ded77c761da92f740c31ef6302393659af90f552..841b1b16bdb699a4afecda8369679666628eb7de 100644 (file)
@@ -311,8 +311,8 @@ static apr_status_t policy_keepalive_out_filter(ap_filter_t *f,
         if (!(r->header_only
                 || AP_STATUS_IS_HEADER_ONLY(r->status)
                 || apr_table_get(r->headers_out, "Content-Length")
-                || ap_find_last_token(r->pool, apr_table_get(r->headers_out,
-                        "Transfer-Encoding"), "chunked")
+                || ap_is_chunked(r->pool, apr_table_get(r->headers_out,
+                        "Transfer-Encoding"))
                 || r->proto_num >= HTTP_VERSION(1, 1))) {
 
             handle_policy(r, result, "Keepalive should be possible (supply Content-Length or HTTP/1.1 Transfer-Encoding)",
index a0209715a24ebb9e7a2c90e5304640e19e253f0b..7313b0a190cda876ad83d64f19885cd716823de1 100644 (file)
@@ -1430,8 +1430,7 @@ request_rec *ap_read_request(conn_rec *conn)
              * the final encoding ...; the server MUST respond with the 400
              * (Bad Request) status code and then close the connection".
              */
-            if (!(ap_cstr_casecmp(tenc, "chunked") == 0 /* fast path */
-                    || ap_find_last_token(r->pool, tenc, "chunked"))) {
+            if (!ap_is_chunked(r->pool, tenc)) {
                 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02539)
                               "client sent unknown Transfer-Encoding "
                               "(%s): %s", tenc, r->uri);
index 044b073bf583b7e59f1f342efecb9c8010a6c9b6..7603895e02bd5ba6569a30e7d0d04c3d70914a01 100644 (file)
@@ -1709,14 +1709,13 @@ AP_DECLARE(int) ap_find_token(apr_pool_t *p, const char *line, const char *tok)
     }
 }
 
-
-AP_DECLARE(int) ap_find_last_token(apr_pool_t *p, const char *line,
-                                   const char *tok)
+static const char *find_last_token(apr_pool_t *p, const char *line,
+                            const char *tok)
 {
     int llen, tlen, lidx;
 
     if (!line)
-        return 0;
+        return NULL;
 
     llen = strlen(line);
     tlen = strlen(tok);
@@ -1724,9 +1723,44 @@ AP_DECLARE(int) ap_find_last_token(apr_pool_t *p, const char *line,
 
     if (lidx < 0 ||
         (lidx > 0 && !(apr_isspace(line[lidx - 1]) || line[lidx - 1] == ',')))
+        return NULL;
+
+    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;
+    }
 
-    return (ap_cstr_casecmpn(&line[lidx], tok, tlen) == 0);
+    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)