diff --git a/CHANGES b/CHANGES index 3362ff2007..39b30428d8 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) mod_ssl: Send the error message for speaking http to an https port using + HTTP/1.0 instead of HTTP/0.9. PR 50823. [Stefan Fritsch] + *) mod_authz_core: Fix parsing of Require arguments in . PR 53048. [Stefan Fritsch] diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index 2ffe21f419..510e16060d 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -813,12 +813,12 @@ static apr_status_t ssl_filter_write(ap_filter_t *f, /* Just use a simple request. Any request will work for this, because * we use a flag in the conn_rec->conn_vector now. The fake request just * gets the request back to the Apache core so that a response can be sent. - * - * To avoid calling back for more data from the socket, use an HTTP/0.9 - * request, and tack on an EOS bucket. + * Since we use an HTTP/1.x request, we also have to inject the empty line + * that terminates the headers, or the core will read more data from the + * socket. */ #define HTTP_ON_HTTPS_PORT \ - "GET /" CRLF + "GET / HTTP/1.0" CRLF #define HTTP_ON_HTTPS_PORT_BUCKET(alloc) \ apr_bucket_immortal_create(HTTP_ON_HTTPS_PORT, \ @@ -848,6 +848,7 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f, { SSLConnRec *sslconn = myConnConfig(f->c); apr_bucket *bucket; + int send_eos = 1; switch (status) { case MODSSL_ERROR_HTTP_ON_HTTPS: @@ -857,11 +858,12 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f, "trying to send HTML error page"); ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, sslconn->server); - sslconn->non_ssl_request = 1; + sslconn->non_ssl_request = NON_SSL_SEND_HDR_SEP; ssl_io_filter_disable(sslconn, f); /* fake the request line */ bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc); + send_eos = 0; break; case MODSSL_ERROR_BAD_GATEWAY: @@ -877,9 +879,10 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f, } APR_BRIGADE_INSERT_TAIL(bb, bucket); - bucket = apr_bucket_eos_create(f->c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, bucket); - + if (send_eos) { + bucket = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, bucket); + } return APR_SUCCESS; } @@ -1282,6 +1285,13 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f, } if (!inctx->ssl) { + SSLConnRec *sslconn = myConnConfig(f->c); + if (sslconn->non_ssl_request == NON_SSL_SEND_HDR_SEP) { + apr_bucket *bucket = apr_bucket_immortal_create(CRLF, 2, f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, bucket); + sslconn->non_ssl_request = NON_SSL_SET_ERROR_MSG; + return APR_SUCCESS; + } return ap_get_brigade(f->next, bb, mode, block, readbytes); } diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index 35b2a854a9..1db1ab124f 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -140,7 +140,7 @@ int ssl_hook_ReadReq(request_rec *r) return DECLINED; } - if (sslconn->non_ssl_request) { + if (sslconn->non_ssl_request == NON_SSL_SET_ERROR_MSG) { const char *errmsg; char *thisurl; char *thisport = ""; @@ -169,8 +169,7 @@ int ssl_hook_ReadReq(request_rec *r) /* Now that we have caught this error, forget it. we are done * with using SSL on this request. */ - sslconn->non_ssl_request = 0; - + sslconn->non_ssl_request = NON_SSL_OK; return HTTP_BAD_REQUEST; } diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index 1b5d0428ce..f393ecfad4 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -454,7 +454,11 @@ typedef struct { int verify_depth; int is_proxy; int disabled; - int non_ssl_request; + enum { + NON_SSL_OK = 0, /* is SSL request, or error handling completed */ + NON_SSL_SEND_HDR_SEP, /* Need to send the header separator */ + NON_SSL_SET_ERROR_MSG /* Need to set the error message */ + } non_ssl_request; /* Track the handshake/renegotiation state for the connection so * that all client-initiated renegotiations can be rejected, as a