]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
add ap_set_content_type_ex to differentiate
authorEric Covener <covener@apache.org>
Mon, 24 Jun 2024 17:22:51 +0000 (17:22 +0000)
committerEric Covener <covener@apache.org>
Mon, 24 Jun 2024 17:22:51 +0000 (17:22 +0000)
trusted sources

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1918551 13f79535-47bb-0310-9956-ffa450edef68

include/http_protocol.h
include/httpd.h
modules/http/http_protocol.c
modules/http/mod_mime.c
modules/mappers/mod_actions.c
modules/mappers/mod_negotiation.c
modules/mappers/mod_rewrite.c
modules/metadata/mod_headers.c
modules/metadata/mod_mime_magic.c
server/config.c
server/core.c

index 6979dc06e7c5ecb9d1419dfd0b160a28326ab7c0..2b509b341fe90ea9e479224b4877300578552879 100644 (file)
@@ -464,6 +464,17 @@ AP_DECLARE(void) ap_clear_method_list(ap_method_list_t *l);
  */
 AP_DECLARE(void) ap_set_content_type(request_rec *r, const char *ct);
 
+/**
+ * Set the content type for this request (r->content_type).
+ * @param r The current request
+ * @param ct The new content type
+ * @param trusted If non-zero, The content-type should come from a
+ *        trusted source such as server configuration rather
+ *        than application output.
+ * for the AddOutputFilterByType directive to work correctly.
+ */
+AP_DECLARE(void) ap_set_content_type_ex(request_rec *r, const char *ct, int trusted);
+
 /**
  * Set the Accept-Ranges header for this response
  * @param r The current request
index 6b7e10223e3f50e4522f759b70dffc9a7b5e2979..02ad3238937d3026f18b515d6a44cf844c079269 100644 (file)
@@ -684,6 +684,7 @@ typedef apr_uint64_t ap_request_bnotes_t;
  *
  */
 #define AP_REQUEST_STRONG_ETAG 1 >> 0
+#define AP_REQUEST_TRUSTED_CT  1 << 1
 
 /**
  * This is a convenience macro to ease with getting specific request
@@ -706,6 +707,12 @@ typedef apr_uint64_t ap_request_bnotes_t;
         AP_REQUEST_GET_BNOTE((r), AP_REQUEST_STRONG_ETAG)
 /** @} */
 
+/**
+ * Returns true if the content-type field is from a trusted source
+ */
+#define AP_REQUEST_IS_TRUSTED_CT(r) \
+    (!!AP_REQUEST_GET_BNOTE((r), AP_REQUEST_TRUSTED_CT))
+/** @} */
 
 /**
  * @defgroup module_magic Module Magic mime types
index f1ed1f6cc20f6aa26451a5bc7a4c866a69a6006b..701a7dd6bc3a7ce09edd36d2e383444ca00af786 100644 (file)
@@ -927,8 +927,14 @@ AP_DECLARE(void) ap_set_content_type(request_rec *r, const char *ct)
     }
     else if (!r->content_type || strcmp(r->content_type, ct)) {
         r->content_type = ct;
+        AP_REQUEST_SET_BNOTE(r, AP_REQUEST_TRUSTED_CT, 0);
     }
 }
+AP_DECLARE(void) ap_set_content_type_ex(request_rec *r, const char *ct, int trusted)
+{
+    ap_set_content_type(r, ct);
+    AP_REQUEST_SET_BNOTE(r, AP_REQUEST_TRUSTED_CT, trusted ? AP_REQUEST_TRUSTED_CT : 0);
+}
 
 AP_DECLARE(void) ap_set_accept_ranges(request_rec *r)
 {
index 13d258945632d3dc6171754e4da13a7752f64e75..a710c4ad0fc0ad547d20bb8dd440ac46118dfeb9 100644 (file)
@@ -817,7 +817,7 @@ static int find_ct(request_rec *r)
     int found_metadata = 0;
 
     if (r->finfo.filetype == APR_DIR) {
-        ap_set_content_type(r, DIR_MAGIC_TYPE);
+        ap_set_content_type_ex(r, DIR_MAGIC_TYPE, 1);
         return OK;
     }
 
@@ -918,7 +918,7 @@ static int find_ct(request_rec *r)
         if ((exinfo == NULL || !exinfo->forced_type) && !skipct) {
             if ((type = apr_hash_get(mime_type_extensions, ext,
                                      APR_HASH_KEY_STRING)) != NULL) {
-                ap_set_content_type(r, (char*) type);
+                ap_set_content_type_ex(r, (char*) type, 1);
                 found = 1;
             }
         }
@@ -927,7 +927,7 @@ static int find_ct(request_rec *r)
 
             /* empty string is treated as special case for RemoveType */
             if ((exinfo->forced_type && *exinfo->forced_type) && !skipct) {
-                ap_set_content_type(r, exinfo->forced_type);
+                ap_set_content_type_ex(r, exinfo->forced_type, 1);
                 found = 1;
             }
 
@@ -1032,33 +1032,33 @@ static int find_ct(request_rec *r)
             memcpy(tmp, ctp->subtype, ctp->subtype_len);
             tmp += ctp->subtype_len;
             *tmp = 0;
-            ap_set_content_type(r, base_content_type);
+            ap_set_content_type_ex(r, base_content_type, AP_REQUEST_IS_TRUSTED_CT(r));
             while (pp != NULL) {
                 if (charset && !strcmp(pp->attr, "charset")) {
                     if (!override) {
-                        ap_set_content_type(r,
+                        ap_set_content_type_ex(r,
                                             apr_pstrcat(r->pool,
                                                         r->content_type,
                                                         "; charset=",
                                                         charset,
-                                                        NULL));
+                                                        NULL), AP_REQUEST_IS_TRUSTED_CT(r));
                         override = 1;
                     }
                 }
                 else {
-                    ap_set_content_type(r,
+                    ap_set_content_type_ex(r,
                                         apr_pstrcat(r->pool,
                                                     r->content_type,
                                                     "; ", pp->attr,
                                                     "=", pp->val,
-                                                    NULL));
+                                                    NULL), AP_REQUEST_IS_TRUSTED_CT(r));
                 }
                 pp = pp->next;
             }
             if (charset && !override) {
-                ap_set_content_type(r, apr_pstrcat(r->pool, r->content_type,
+                ap_set_content_type_ex(r, apr_pstrcat(r->pool, r->content_type,
                                                    "; charset=", charset,
-                                                   NULL));
+                                                   NULL), AP_REQUEST_IS_TRUSTED_CT(r));
             }
         }
     }
index ac9c3b7428fbceefdfe6e74b7d93f91e67f6e32c..5e398b53d9ef72deb29826c5e6bdfe2663aa6c7a 100644 (file)
@@ -182,8 +182,10 @@ static int action_handler(request_rec *r)
         return DECLINED;
 
     /* Second, check for actions (which override the method scripts) */
-    action = r->handler ? r->handler :
-        ap_field_noparam(r->pool, r->content_type);
+    action = r->handler;
+    if (!action && AP_REQUEST_IS_TRUSTED_CT(r)) {
+        action = ap_field_noparam(r->pool, r->content_type);
+    }
 
     if (action && (t = apr_table_get(conf->action_types, action))) {
         int virtual = (*t++ == '0' ? 0 : 1);
index c056b284550d1bddcc5def659899cd43fb12b47c..a528f81439772763dcc2b03146481017c5b195a1 100644 (file)
@@ -1167,7 +1167,7 @@ static int read_types_multi(negotiation_state *neg)
          * might be doing.
          */
         if (sub_req->handler && !sub_req->content_type) {
-            ap_set_content_type(sub_req, CGI_MAGIC_TYPE);
+            ap_set_content_type_ex(sub_req, CGI_MAGIC_TYPE, 1);
         }
 
         /*
@@ -3003,14 +3003,14 @@ static int handle_map_file(request_rec *r)
         /* set MIME type and charset as negotiated */
         if (best->mime_type && *best->mime_type) {
             if (best->content_charset && *best->content_charset) {
-                ap_set_content_type(r, apr_pstrcat(r->pool,
+                ap_set_content_type_ex(r, apr_pstrcat(r->pool,
                                                    best->mime_type,
                                                    "; charset=",
                                                    best->content_charset,
-                                                   NULL));
+                                                   NULL), 1);
             }
             else {
-                ap_set_content_type(r, apr_pstrdup(r->pool, best->mime_type));
+                ap_set_content_type_ex(r, apr_pstrdup(r->pool, best->mime_type), 1);
             }
         }
 
index b70c878210405e3dd6eeb51825bc485e06c89734..79732d106a2679177aa0b757a452d6eee857358c 100644 (file)
@@ -5419,7 +5419,7 @@ static int hook_mimetype(request_rec *r)
         rewritelog(r, 1, NULL, "force filename %s to have MIME-type '%s'",
                    r->filename, t);
 
-        ap_set_content_type(r, t);
+        ap_set_content_type_ex(r, t, 1);
     }
 
     /* handler */
index 77737d90caac7cd98109d92cb2e1192c052e09ac..ae3f33069f0543e9afe7f64b330081c93f4fdeb6 100644 (file)
@@ -870,7 +870,7 @@ static int do_headers_fixup(request_rec *r, apr_table_t *headers,
         case hdr_set:
             if (r->headers_in != headers && 
                 !ap_cstr_casecmp(hdr->header, "Content-Type")) {
-                 ap_set_content_type(r, process_tags(hdr, r));
+                 ap_set_content_type_ex(r, process_tags(hdr, r), 1);
             }
             apr_table_setn(headers, hdr->header, process_tags(hdr, r));
             break;
@@ -878,7 +878,7 @@ static int do_headers_fixup(request_rec *r, apr_table_t *headers,
             if (NULL == apr_table_get(headers, hdr->header)) {
                 if (r->headers_in != headers &&
                     !ap_cstr_casecmp(hdr->header, "Content-Type")) {
-                    ap_set_content_type(r, process_tags(hdr, r));
+                    ap_set_content_type_ex(r, process_tags(hdr, r), 1);
                 }
                 apr_table_setn(headers, hdr->header, process_tags(hdr, r));
             }
@@ -887,7 +887,7 @@ static int do_headers_fixup(request_rec *r, apr_table_t *headers,
             apr_table_unset(headers, hdr->header);
             if (r->headers_in != headers &&
                 !ap_cstr_casecmp(hdr->header, "Content-Type")) {
-                ap_set_content_type(r, NULL);
+                ap_set_content_type_ex(r, NULL, 1);
             }
             break;
         case hdr_echo:
@@ -901,7 +901,7 @@ static int do_headers_fixup(request_rec *r, apr_table_t *headers,
                 const char *repl = process_regexp(hdr, r->content_type, r);
                 if (repl == NULL)
                     return 0;
-                if (r->headers_in != headers) ap_set_content_type(r, repl);
+                if (r->headers_in != headers) ap_set_content_type_ex(r, repl, 1);
             }
             if (apr_table_get(headers, hdr->header)) {
                 edit_do ed;
index e45f209b73c516a9bb7a60c2bca4b50ad716945c..05585ba7764dce02cf98de782faf0e2e4707ee25 100644 (file)
@@ -788,7 +788,7 @@ static int magic_rsl_to_request(request_rec *r)
     /* XXX: this could be done at config time I'm sure... but I'm
      * confused by all this magic_rsl stuff. -djg */
     ap_content_type_tolower(tmp);
-    ap_set_content_type(r, tmp);
+    ap_set_content_type_ex(r, tmp, 1);
 
     if (state == rsl_encoding) {
         tmp = rsl_strdup(r, encoding_frag,
@@ -2326,7 +2326,7 @@ static int revision_suffix(request_rec *r)
 
     /* extract content type/encoding/language from sub-request */
     if (sub->content_type) {
-        ap_set_content_type(r, apr_pstrdup(r->pool, sub->content_type));
+        ap_set_content_type_ex(r, apr_pstrdup(r->pool, sub->content_type), 1);
 #if MIME_MAGIC_DEBUG
         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01557)
                     MODNAME ": subrequest %s got %s",
index b59fea1d4fddd2b875bbf1391a94fc3ab1d27083..712bcab3db7ab8300672066127108f1cb99efee9 100644 (file)
@@ -418,7 +418,7 @@ AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r)
     }
 
     if (!r->handler) {
-        if (r->content_type) {
+        if (r->content_type && AP_REQUEST_IS_TRUSTED_CT(r)) {
             handler = r->content_type;
             if ((p=ap_strchr_c(handler, ';')) != NULL) {
                 char *new_handler = (char *)apr_pmemdup(r->pool, handler,
index 35853824603847cec693ee38c26fad81f044ecdb..9f92981ef0ddaf3f1aab6c10fd95cb7db199d094 100644 (file)
@@ -5098,7 +5098,7 @@ static int core_override_type(request_rec *r)
     /* Check for overrides with ForceType / SetHandler
      */
     if (conf->mime_type && strcmp(conf->mime_type, "none"))
-        ap_set_content_type(r, (char*) conf->mime_type);
+        ap_set_content_type_ex(r, (char*) conf->mime_type, 1);
 
     if (conf->expr_handler) { 
         const char *err;