You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by je...@apache.org on 2013/12/30 21:01:14 UTC

svn commit: r1554303 - in /httpd/httpd/trunk: CHANGES include/ap_mmn.h include/http_core.h modules/http/http_filters.c server/core.c server/protocol.c

Author: jerenkrantz
Date: Mon Dec 30 20:01:14 2013
New Revision: 1554303

URL: http://svn.apache.org/r1554303
Log:
Add directives to control two protocol options:

 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 <ye...@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.

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/include/ap_mmn.h
    httpd/httpd/trunk/include/http_core.h
    httpd/httpd/trunk/modules/http/http_filters.c
    httpd/httpd/trunk/server/core.c
    httpd/httpd/trunk/server/protocol.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1554303&r1=1554302&r2=1554303&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Mon Dec 30 20:01:14 2013
@@ -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]
 

Modified: httpd/httpd/trunk/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_mmn.h?rev=1554303&r1=1554302&r2=1554303&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_mmn.h (original)
+++ httpd/httpd/trunk/include/ap_mmn.h Mon Dec 30 20:01:14 2013
@@ -444,14 +444,15 @@
  * 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

Modified: httpd/httpd/trunk/include/http_core.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/http_core.h?rev=1554303&r1=1554302&r2=1554303&view=diff
==============================================================================
--- httpd/httpd/trunk/include/http_core.h (original)
+++ httpd/httpd/trunk/include/http_core.h Mon Dec 30 20:01:14 2013
@@ -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 */

Modified: httpd/httpd/trunk/modules/http/http_filters.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http/http_filters.c?rev=1554303&r1=1554302&r2=1554303&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http/http_filters.c (original)
+++ httpd/httpd/trunk/modules/http/http_filters.c Mon Dec 30 20:01:14 2013
@@ -1245,10 +1245,16 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_
      * 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");
     }
 

Modified: httpd/httpd/trunk/server/core.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/core.c?rev=1554303&r1=1554302&r2=1554303&view=diff
==============================================================================
--- httpd/httpd/trunk/server/core.c (original)
+++ httpd/httpd/trunk/server/core.c Mon Dec 30 20:01:14 2013
@@ -519,6 +519,12 @@ static void *merge_core_server_configs(a
     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_p
     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
               "'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 }
 };
 

Modified: httpd/httpd/trunk/server/protocol.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/protocol.c?rev=1554303&r1=1554302&r2=1554303&view=diff
==============================================================================
--- httpd/httpd/trunk/server/protocol.c (original)
+++ httpd/httpd/trunk/server/protocol.c Mon Dec 30 20:01:14 2013
@@ -1221,14 +1221,23 @@ request_rec *ap_read_request(conn_rec *c
             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);
+            }
         }
     }