Gents,

rfc2817, Upgrading to TLS Within HTTP/1.1, says that a (mandatory) 
connection upgrade looks is requested as:

       OPTIONS * HTTP/1.1
       Host: example.bank.com
       Upgrade: TLS/1.0
       Connection: Upgrade

"SSLEngine optional" is needed for the upgrade to succeed.

This happens to collide with the "OPTIONS *" from the internal dummy 
connection (which used to be a "GET / HTTP/1.0" in early 2.2 versions).
There is probably only one single system/device on the planet that does 
that - Apple's IOS when printing with the "secure" button tapped.
If this is fixed there may be more browsers/libraries using it.

Thanks,
Roman.

Suggested patch, requesting to include (attached):

diff -rpNU 10 ../httpd-2.4.6-o/modules/http/http_core.c 
./modules/http/http_core.c
--- ../httpd-2.4.6-o/modules/http/http_core.c   2011-11-22 00:07:16.000000000 
+0100
+++ ./modules/http/http_core.c  2013-09-11 16:30:27.000000000 +0200
@@ -245,20 +245,34 @@ static int http_create_request(request_r
                                     NULL, r, r->connection);
     }
 
     return OK;
 }
 
 static int http_send_options(request_rec *r)
 {
     if ((r->method_number == M_OPTIONS) && r->uri && (r->uri[0] == '*') &&
          (r->uri[1] == '\0')) {
+        if(apr_table_get(r->headers_in, "Upgrade") != NULL) {
+                               /*
+                                  a connection upgrade to TLS with rfc2817
+                                  looks like:
+                                           OPTIONS * HTTP/1.1
+                                           Host: example.bank.com
+                                           Upgrade: TLS/1.0
+                                           Connection: Upgrade
+                                           ...
+                                  Check if the Upgrade header line is present
+                                  and don't return DONE if so.
+                               */
+            return DECLINED;
+        }
         return DONE;           /* Send HTTP pong, without Allow header */
     }
     return DECLINED;
 }
 
 static int http_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t 
*ptemp, server_rec *s)
 {
     apr_uint64_t val;
     if (ap_mpm_query(AP_MPMQ_IS_ASYNC, &async_mpm) != APR_SUCCESS) {
         async_mpm = 0;
diff -rNU 30 ../httpd-2.2.25-o/modules/http/http_core.c ./modules/http/http_core.c
--- ../httpd-2.2.25-o/modules/http/http_core.c	2007-11-15 23:08:30.000000000 +0100
+++ ./modules/http/http_core.c	2013-09-11 16:25:54.000000000 +0200
@@ -205,60 +205,74 @@
             csd = ap_get_module_config(c->conn_config, &core_module);
         }
         apr_socket_opt_set(csd, APR_INCOMPLETE_READ, 1);
         apr_socket_timeout_set(csd, c->base_server->keep_alive_timeout);
         /* Go straight to select() to wait for the next request */
     }
 
     return OK;
 }
 
 static int http_create_request(request_rec *r)
 {
     if (!r->main && !r->prev) {
         ap_add_output_filter_handle(ap_byterange_filter_handle,
                                     NULL, r, r->connection);
         ap_add_output_filter_handle(ap_content_length_filter_handle,
                                     NULL, r, r->connection);
         ap_add_output_filter_handle(ap_http_header_filter_handle,
                                     NULL, r, r->connection);
         ap_add_output_filter_handle(ap_http_outerror_filter_handle,
                                     NULL, r, r->connection);
     }
 
     return OK;
 }
 
 static int http_send_options(request_rec *r)
 {
     if ((r->method_number == M_OPTIONS) && r->uri && (r->uri[0] == '*') &&
          (r->uri[1] == '\0')) {
+        if(apr_table_get(r->headers_in, "Upgrade") != NULL) {
+                               /*
+                                  a connection upgrade to TLS with rfc2817
+                                  looks like:
+                                           OPTIONS * HTTP/1.1
+                                           Host: example.bank.com
+                                           Upgrade: TLS/1.0
+                                           Connection: Upgrade
+                                           ...
+                                  Check if the Upgrade header line is present
+                                  and don't return DONE if so.
+                               */
+            return DECLINED;
+        } 
         return DONE;           /* Send HTTP pong, without Allow header */
     }
     return DECLINED;
 }
 
 static void register_hooks(apr_pool_t *p)
 {
     /**
      * If we ae using an MPM That Supports Async Connections,
      * use a different processing function
      */
     int async_mpm = 0;
     if (ap_mpm_query(AP_MPMQ_IS_ASYNC, &async_mpm) == APR_SUCCESS
         && async_mpm == 1) {
         ap_hook_process_connection(ap_process_http_async_connection, NULL,
                                    NULL, APR_HOOK_REALLY_LAST);
     }
     else {
         ap_hook_process_connection(ap_process_http_connection, NULL, NULL,
                                    APR_HOOK_REALLY_LAST);
     }
 
     ap_hook_map_to_storage(ap_send_http_trace,NULL,NULL,APR_HOOK_MIDDLE);
     ap_hook_map_to_storage(http_send_options,NULL,NULL,APR_HOOK_MIDDLE);
     ap_hook_http_scheme(http_scheme,NULL,NULL,APR_HOOK_REALLY_LAST);
     ap_hook_default_port(http_port,NULL,NULL,APR_HOOK_REALLY_LAST);
     ap_hook_create_request(http_create_request, NULL, NULL, APR_HOOK_REALLY_LAST);
     ap_http_input_filter_handle =
         ap_register_input_filter("HTTP_IN", ap_http_filter,
                                  NULL, AP_FTYPE_PROTOCOL);
diff -rNU 30 ../httpd-2.4.6-o/modules/http/http_core.c ./modules/http/http_core.c
--- ../httpd-2.4.6-o/modules/http/http_core.c	2011-11-22 00:07:16.000000000 +0100
+++ ./modules/http/http_core.c	2013-09-11 16:30:27.000000000 +0200
@@ -225,60 +225,74 @@
 static int ap_process_http_connection(conn_rec *c)
 {
     if (async_mpm && !c->clogging_input_filters) {
         return ap_process_http_async_connection(c);
     }
     else {
         return ap_process_http_sync_connection(c);
     }
 }
 
 static int http_create_request(request_rec *r)
 {
     if (!r->main && !r->prev) {
         ap_add_output_filter_handle(ap_byterange_filter_handle,
                                     NULL, r, r->connection);
         ap_add_output_filter_handle(ap_content_length_filter_handle,
                                     NULL, r, r->connection);
         ap_add_output_filter_handle(ap_http_header_filter_handle,
                                     NULL, r, r->connection);
         ap_add_output_filter_handle(ap_http_outerror_filter_handle,
                                     NULL, r, r->connection);
     }
 
     return OK;
 }
 
 static int http_send_options(request_rec *r)
 {
     if ((r->method_number == M_OPTIONS) && r->uri && (r->uri[0] == '*') &&
          (r->uri[1] == '\0')) {
+        if(apr_table_get(r->headers_in, "Upgrade") != NULL) {
+                               /*
+                                  a connection upgrade to TLS with rfc2817
+                                  looks like:
+                                           OPTIONS * HTTP/1.1
+                                           Host: example.bank.com
+                                           Upgrade: TLS/1.0
+                                           Connection: Upgrade
+                                           ...
+                                  Check if the Upgrade header line is present
+                                  and don't return DONE if so.
+                               */
+            return DECLINED;
+        }
         return DONE;           /* Send HTTP pong, without Allow header */
     }
     return DECLINED;
 }
 
 static int http_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
 {
     apr_uint64_t val;
     if (ap_mpm_query(AP_MPMQ_IS_ASYNC, &async_mpm) != APR_SUCCESS) {
         async_mpm = 0;
     }
     ap_random_insecure_bytes(&val, sizeof(val));
     ap_multipart_boundary = apr_psprintf(p, "%0" APR_UINT64_T_HEX_FMT, val);
 
     return OK;
 }
 
 static void register_hooks(apr_pool_t *p)
 {
     ap_hook_post_config(http_post_config, NULL, NULL, APR_HOOK_MIDDLE);
     ap_hook_process_connection(ap_process_http_connection, NULL, NULL,
                                APR_HOOK_REALLY_LAST);
     ap_hook_map_to_storage(ap_send_http_trace,NULL,NULL,APR_HOOK_MIDDLE);
     ap_hook_map_to_storage(http_send_options,NULL,NULL,APR_HOOK_MIDDLE);
     ap_hook_http_scheme(http_scheme,NULL,NULL,APR_HOOK_REALLY_LAST);
     ap_hook_default_port(http_port,NULL,NULL,APR_HOOK_REALLY_LAST);
     ap_hook_create_request(http_create_request, NULL, NULL, APR_HOOK_REALLY_LAST);
     ap_http_input_filter_handle =
         ap_register_input_filter("HTTP_IN", ap_http_filter,
                                  NULL, AP_FTYPE_PROTOCOL);

Reply via email to