]> granicus.if.org Git - apache/commitdiff
Add directives to control two protocol options:
authorJustin Erenkrantz <jerenkrantz@apache.org>
Mon, 30 Dec 2013 20:01:14 +0000 (20:01 +0000)
committerJustin Erenkrantz <jerenkrantz@apache.org>
Mon, 30 Dec 2013 20:01:14 +0000 (20:01 +0000)
 HttpContentLengthHeadZero - allow Content-Length of 0 to be returned on HEAD
 HttpExpectStrict - allow admin to control whether we must see "100-continue"

This is helpful when using Ceph's radosgw and httpd.

Inspired by: Yehuda Sadeh <yehuda@inktank.com>
See https://github.com/ceph/apache2/commits/precise

* include/http_core.h
  (core_server_config): Add http_cl_head_zero and http_expect_strict fields.
* modules/http/http_filters.c
  (ap_http_header_filter): Only clear out the C-L if http_cl_head_zero is not
  explictly set.
* server/core.c
  (merge_core_server_configs): Add new fields.
  (set_cl_head_zero, set_expect_strict): New config helpers.
  (HttpContentLengthHeadZero, HttpExpectStrict): Declare new directives.
* server/protocol.c
  (ap_read_request): Allow http_expect_strict to control if we return 417.
* include/ap_mmn.h
  (MODULE_MAGIC_NUMBER_MAJOR, MODULE_MAGIC_NUMBER_MINOR): Bump.
* CHANGES: Add a brief description.

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

CHANGES
include/ap_mmn.h
include/http_core.h
modules/http/http_filters.c
server/core.c
server/protocol.c

diff --git a/CHANGES b/CHANGES
index 93431803b5141c0b2af44b929ca8643c265d92d5..8de8e42cc241fd540f351c7d1cf9baf89d2febc5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) Add HttpContentLengthHeadZero and HttpExpectStrict directives.
+     [Yehuda Sadeh <yehuda inktank com>, Justin Erenkrantz]
+
   *) core: Support named groups and backreferences within the LocationMatch,
      DirectoryMatch, FilesMatch and ProxyMatch directives. [Graham Leggett]
 
index ec1a189b5d07450aec8bee6b1d2d65ce30031f37..0ba05f90fbca36a915dedf2eb4ace3f33146cbdb 100644 (file)
  * 20131112.0 (2.5.0-dev)  Add parse_errorlog_arg to ap_errorlog_provider
  * 20131112.1 (2.5.0-dev)  Add suspend_connection and resume_connection hooks
  * 20131112.2 (2.5.0-dev)  Add ap_regname
+ * 20131230.0 (2.5.0-dev)  cl_head_zero & expect_strict added to server_config
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
 
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
-#define MODULE_MAGIC_NUMBER_MAJOR 20131112
+#define MODULE_MAGIC_NUMBER_MAJOR 20131230
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 2                  /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 0                  /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
index 371e54d4bfa5441fdd735dbde10c872ad868036c..47cd98fb451ba5d566cae220037e18b874d70f38 100644 (file)
@@ -682,6 +682,16 @@ typedef struct {
 #define AP_HTTP_CONFORMANCE_STRICT    2
 #define AP_HTTP_CONFORMANCE_LOGONLY   4
     char http_conformance;
+
+#define AP_HTTP_CL_HEAD_ZERO_UNSET    0
+#define AP_HTTP_CL_HEAD_ZERO_ENABLE   1
+#define AP_HTTP_CL_HEAD_ZERO_DISABLE  2
+    int http_cl_head_zero;
+
+#define AP_HTTP_EXPECT_STRICT_UNSET    0
+#define AP_HTTP_EXPECT_STRICT_ENABLE   1
+#define AP_HTTP_EXPECT_STRICT_DISABLE  2
+    int http_expect_strict;
 } core_server_config;
 
 /* for AddOutputFiltersByType in core.c */
index 12249141086f5a7d4af2f32d9ddd6251b9053c95..dc3220e34493e95daac5efc085b18f897cf335d9 100644 (file)
@@ -1245,10 +1245,16 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f,
      * zero C-L to the client.  We can't just remove the C-L filter,
      * because well behaved 2.0 handlers will send their data down the stack,
      * and we will compute a real C-L for the head request. RBB
+     *
+     * Allow modification of this behavior through the
+     * HttpContentLengthHeadZero directive.
+     *
+     * The default (unset) behavior is to squelch the C-L in this case.
      */
     if (r->header_only
         && (clheader = apr_table_get(r->headers_out, "Content-Length"))
-        && !strcmp(clheader, "0")) {
+        && !strcmp(clheader, "0")
+        && conf->http_cl_head_zero != AP_HTTP_CL_HEAD_ZERO_ENABLE) {
         apr_table_unset(r->headers_out, "Content-Length");
     }
 
index bb528832f302b4ab7a14664930b27bac1504ce39..f7bef0fe0959edea8a94e184e539d932397f1d67 100644 (file)
@@ -519,6 +519,12 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv)
     if (virt->http_conformance != AP_HTTP_CONFORMANCE_UNSET)
         conf->http_conformance = virt->http_conformance;
 
+    if (virt->http_cl_head_zero != AP_HTTP_CL_HEAD_ZERO_UNSET)
+        conf->http_cl_head_zero = virt->http_cl_head_zero;
+
+    if (virt->http_expect_strict != AP_HTTP_EXPECT_STRICT_UNSET)
+        conf->http_expect_strict = virt->http_expect_strict;
+
     /* no action for virt->accf_map, not allowed per-vhost */
 
     if (virt->protocol)
@@ -3774,6 +3780,32 @@ static const char *set_http_method(cmd_parms *cmd, void *conf, const char *arg)
     return NULL;
 }
 
+static const char *set_cl_head_zero(cmd_parms *cmd, void *dummy, int arg)
+{
+    core_server_config *conf =
+        ap_get_core_module_config(cmd->server->module_config);
+
+    if (arg) {
+        conf->http_cl_head_zero = AP_HTTP_CL_HEAD_ZERO_ENABLE;
+    } else {
+        conf->http_cl_head_zero = AP_HTTP_CL_HEAD_ZERO_DISABLE;
+    }
+    return NULL;
+}
+
+static const char *set_expect_strict(cmd_parms *cmd, void *dummy, int arg)
+{
+    core_server_config *conf =
+        ap_get_core_module_config(cmd->server->module_config);
+
+    if (arg) {
+        conf->http_expect_strict = AP_HTTP_EXPECT_STRICT_ENABLE;
+    } else {
+        conf->http_expect_strict = AP_HTTP_EXPECT_STRICT_DISABLE;
+    }
+    return NULL;
+}
+
 static apr_hash_t *errorlog_hash;
 
 static int log_constant_item(const ap_errorlog_info *info, const char *arg,
@@ -4331,6 +4363,10 @@ AP_INIT_ITERATE("HttpProtocol", set_http_protocol, NULL, RSRC_CONF,
               "'liberal', 'strict', 'strict,log-only'"),
 AP_INIT_ITERATE("RegisterHttpMethod", set_http_method, NULL, RSRC_CONF,
                 "Registers non-standard HTTP methods"),
+AP_INIT_FLAG("HttpContentLengthHeadZero", set_cl_head_zero, NULL, OR_OPTIONS,
+  "whether to permit Content-Length of 0 responses to HEAD requests"),
+AP_INIT_FLAG("HttpExpectStrict", set_expect_strict, NULL, OR_OPTIONS,
+  "whether to return a 417 if a client doesn't send 100-Continue"),
 { NULL }
 };
 
index 18f0afb88cea6f3d57e500439e5356b83b9c9ba3..ab1b2d0d12775f8ccad6fd68b1ec7d68cb1c856e 100644 (file)
@@ -1221,14 +1221,23 @@ request_rec *ap_read_request(conn_rec *conn)
             r->expecting_100 = 1;
         }
         else {
-            r->status = HTTP_EXPECTATION_FAILED;
-            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00570)
-                          "client sent an unrecognized expectation value of "
-                          "Expect: %s", expect);
-            ap_send_error_response(r, 0);
-            ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
-            ap_run_log_transaction(r);
-            goto traceout;
+            core_server_config *conf;
+
+            conf = ap_get_core_module_config(r->server->module_config);
+            if (conf->http_expect_strict != AP_HTTP_EXPECT_STRICT_DISABLE) {
+                r->status = HTTP_EXPECTATION_FAILED;
+                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00570)
+                              "client sent an unrecognized expectation value "
+                              "of Expect: %s", expect);
+                ap_send_error_response(r, 0);
+                ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
+                ap_run_log_transaction(r);
+                goto traceout;
+            } else {
+                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00570)
+                              "client sent an unrecognized expectation value "
+                              "of Expect (not fatal): %s", expect);
+            }
         }
     }