summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorStefan Fritsch <sf@sfritsch.de>2015-04-28 22:06:31 +0200
committerStefan Fritsch <sf@sfritsch.de>2015-04-28 22:06:31 +0200
commit080d5e16db802902200a9ce5b6c40f8f1fdc1f73 (patch)
tree69845ca856fe6817f103544e88541d80411fe9a8 /modules
parentcb35beef2a938b80c9e4b5d6a408eca437aa74db (diff)
downloadapache2-080d5e16db802902200a9ce5b6c40f8f1fdc1f73.tar.gz
Imported Upstream version 2.4.12
Diffstat (limited to 'modules')
-rw-r--r--modules/aaa/mod_auth_basic.c6
-rw-r--r--modules/aaa/mod_auth_form.c8
-rw-r--r--modules/aaa/mod_authnz_fcgi.c16
-rw-r--r--modules/aaa/mod_authz_core.c9
-rw-r--r--modules/arch/netware/mod_nw_ssl.c6
-rw-r--r--modules/arch/win32/mod_isapi.c24
-rw-r--r--modules/cache/cache_util.c10
-rw-r--r--modules/cache/mod_cache.c14
-rw-r--r--modules/cache/mod_cache_socache.c58
-rw-r--r--modules/cache/mod_cache_socache.dsp4
-rw-r--r--modules/core/mod_macro.c44
-rw-r--r--modules/core/mod_so.c4
-rw-r--r--modules/core/mod_watchdog.h6
-rw-r--r--modules/database/mod_dbd.c7
-rw-r--r--modules/dav/fs/repos.c13
-rw-r--r--modules/dav/main/mod_dav.c5
-rw-r--r--modules/examples/mod_example_hooks.c10
-rw-r--r--modules/filters/mod_include.c16
-rw-r--r--modules/filters/mod_ratelimit.c4
-rw-r--r--modules/filters/mod_substitute.c86
-rw-r--r--modules/filters/mod_xml2enc.c9
-rw-r--r--modules/generators/mod_autoindex.c4
-rw-r--r--modules/generators/mod_cgi.c18
-rw-r--r--modules/http/byterange_filter.c6
-rw-r--r--modules/http/http_filters.c67
-rw-r--r--modules/http/http_protocol.c6
-rw-r--r--modules/http/http_request.c4
-rw-r--r--modules/ldap/util_ldap.c2
-rw-r--r--modules/ldap/util_ldap_cache_mgr.c8
-rw-r--r--modules/loggers/mod_log_config.c29
-rw-r--r--modules/loggers/mod_logio.c12
-rw-r--r--modules/lua/lua_apr.c4
-rw-r--r--modules/lua/lua_request.c10
-rw-r--r--modules/lua/mod_lua.c37
-rw-r--r--modules/mappers/mod_dir.c2
-rw-r--r--modules/mappers/mod_negotiation.c2
-rw-r--r--modules/mappers/mod_rewrite.c1
-rw-r--r--modules/proxy/mod_proxy.c36
-rw-r--r--modules/proxy/mod_proxy.h19
-rw-r--r--modules/proxy/mod_proxy_ajp.c5
-rw-r--r--modules/proxy/mod_proxy_balancer.c2
-rw-r--r--modules/proxy/mod_proxy_connect.c30
-rw-r--r--modules/proxy/mod_proxy_fcgi.c129
-rw-r--r--modules/proxy/mod_proxy_fdpass.c55
-rw-r--r--modules/proxy/mod_proxy_ftp.c60
-rw-r--r--modules/proxy/mod_proxy_http.c42
-rw-r--r--modules/proxy/mod_proxy_wstunnel.c32
-rw-r--r--modules/proxy/proxy_util.c218
-rw-r--r--modules/slotmem/mod_slotmem_shm.c6
-rw-r--r--modules/ssl/mod_ssl.c10
-rw-r--r--modules/ssl/ssl_engine_config.c13
-rw-r--r--modules/ssl/ssl_engine_init.c21
-rw-r--r--modules/ssl/ssl_engine_io.c33
-rw-r--r--modules/ssl/ssl_engine_kernel.c14
-rw-r--r--modules/ssl/ssl_engine_pphrase.c4
-rw-r--r--modules/ssl/ssl_engine_vars.c6
-rw-r--r--modules/ssl/ssl_private.h16
-rw-r--r--modules/ssl/ssl_util_ssl.c15
-rw-r--r--modules/ssl/ssl_util_stapling.c143
59 files changed, 943 insertions, 537 deletions
diff --git a/modules/aaa/mod_auth_basic.c b/modules/aaa/mod_auth_basic.c
index 75044d48..5ef40f75 100644
--- a/modules/aaa/mod_auth_basic.c
+++ b/modules/aaa/mod_auth_basic.c
@@ -315,8 +315,8 @@ static int authenticate_basic_user(request_rec *r)
/* We need an authentication realm. */
if (!ap_auth_name(r)) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR,
- 0, r, APLOGNO(01615) "need AuthName: %s", r->uri);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01615)
+ "need AuthName: %s", r->uri);
return HTTP_INTERNAL_SERVER_ERROR;
}
@@ -428,7 +428,7 @@ static int authenticate_basic_user(request_rec *r)
break;
}
- /* If we're returning 403, tell them to try again. */
+ /* If we're returning 401, tell them to try again. */
if (return_code == HTTP_UNAUTHORIZED) {
note_basic_auth_failure(r);
}
diff --git a/modules/aaa/mod_auth_form.c b/modules/aaa/mod_auth_form.c
index cfb4a7f2..263c8e63 100644
--- a/modules/aaa/mod_auth_form.c
+++ b/modules/aaa/mod_auth_form.c
@@ -903,16 +903,16 @@ static int authenticate_form_authn(request_rec * r)
* never be secure. Abort the auth attempt in this case.
*/
if (PROXYREQ_PROXY == r->proxyreq) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR,
- 0, r, APLOGNO(01809) "form auth cannot be used for proxy "
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01809)
+ "form auth cannot be used for proxy "
"requests due to XSS risk, access denied: %s", r->uri);
return HTTP_INTERNAL_SERVER_ERROR;
}
/* We need an authentication realm. */
if (!ap_auth_name(r)) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR,
- 0, r, APLOGNO(01810) "need AuthName: %s", r->uri);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01810)
+ "need AuthName: %s", r->uri);
return HTTP_INTERNAL_SERVER_ERROR;
}
diff --git a/modules/aaa/mod_authnz_fcgi.c b/modules/aaa/mod_authnz_fcgi.c
index 673b0e77..51b15edd 100644
--- a/modules/aaa/mod_authnz_fcgi.c
+++ b/modules/aaa/mod_authnz_fcgi.c
@@ -406,13 +406,12 @@ enum {
*
* Returns 0 if it can't find the end of the headers, and 1 if it found the
* end of the headers. */
-static int handle_headers(request_rec *r,
- int *state,
- char *readbuf)
+static int handle_headers(request_rec *r, int *state,
+ const char *readbuf, apr_size_t readlen)
{
const char *itr = readbuf;
- while (*itr) {
+ while (readlen--) {
if (*itr == '\r') {
switch (*state) {
case HDR_STATE_GOT_CRLF:
@@ -472,7 +471,7 @@ static apr_status_t handle_response(const fcgi_provider_conf *conf,
{
apr_bucket *b;
apr_bucket_brigade *ob;
- apr_size_t orspbuflen;
+ apr_size_t orspbuflen = 0;
apr_status_t rv = APR_SUCCESS;
const char *fn = "handle_response";
int header_state = HDR_STATE_READING_HEADERS;
@@ -555,7 +554,8 @@ static apr_status_t handle_response(const fcgi_provider_conf *conf,
APR_BRIGADE_INSERT_TAIL(ob, b);
if (!seen_end_of_headers) {
- int st = handle_headers(r, &header_state, readbuf);
+ int st = handle_headers(r, &header_state,
+ readbuf, readbuflen);
if (st == 1) {
int status;
@@ -642,6 +642,10 @@ static apr_status_t handle_response(const fcgi_provider_conf *conf,
"%d", fn, type);
break;
}
+ /* Leave on above switch's inner error. */
+ if (rv != APR_SUCCESS) {
+ break;
+ }
/*
* Read/discard any trailing padding.
diff --git a/modules/aaa/mod_authz_core.c b/modules/aaa/mod_authz_core.c
index c9ed22ff..c68b56bd 100644
--- a/modules/aaa/mod_authz_core.c
+++ b/modules/aaa/mod_authz_core.c
@@ -168,6 +168,13 @@ static void *merge_authz_core_dir_config(apr_pool_t *p,
return (void*)conf;
}
+/* Only per-server directive we have is GLOBAL_ONLY */
+static void *merge_authz_core_svr_config(apr_pool_t *p,
+ void *basev, void *newv)
+{
+ return basev;
+}
+
static void *create_authz_core_svr_config(apr_pool_t *p, server_rec *s)
{
authz_core_srv_conf *authcfg;
@@ -1140,7 +1147,7 @@ AP_DECLARE_MODULE(authz_core) =
create_authz_core_dir_config, /* dir config creater */
merge_authz_core_dir_config, /* dir merger */
create_authz_core_svr_config, /* server config */
- NULL, /* merge server config */
+ merge_authz_core_svr_config , /* merge server config */
authz_cmds,
register_hooks /* register hooks */
};
diff --git a/modules/arch/netware/mod_nw_ssl.c b/modules/arch/netware/mod_nw_ssl.c
index a6e15e7f..d3443002 100644
--- a/modules/arch/netware/mod_nw_ssl.c
+++ b/modules/arch/netware/mod_nw_ssl.c
@@ -1086,7 +1086,7 @@ char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r,
else if (strcEQ(var, "SERVER_SOFTWARE"))
result = ap_get_server_banner();
else if (strcEQ(var, "API_VERSION")) {
- result = apr_itoa(p, MODULE_MAGIC_NUMBER);
+ result = apr_itoa(p, MODULE_MAGIC_NUMBER_MAJOR);
resdup = FALSE;
}
else if (strcEQ(var, "TIME_YEAR")) {
@@ -1192,8 +1192,8 @@ static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f,
/* Send the interim 101 response. */
upgradebb = apr_brigade_create(r->pool, f->c->bucket_alloc);
- ap_fputstrs(f->next, upgradebb, SWITCH_STATUS_LINE, CRLF,
- UPGRADE_HEADER, CRLF, CONNECTION_HEADER, CRLF, CRLF, NULL);
+ ap_fputs(f->next, upgradebb, SWITCH_STATUS_LINE CRLF
+ UPGRADE_HEADER CRLF CONNECTION_HEADER CRLF CRLF);
b = apr_bucket_flush_create(f->c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(upgradebb, b);
diff --git a/modules/arch/win32/mod_isapi.c b/modules/arch/win32/mod_isapi.c
index 801c7dea..ce0875a5 100644
--- a/modules/arch/win32/mod_isapi.c
+++ b/modules/arch/win32/mod_isapi.c
@@ -955,7 +955,7 @@ static int APR_THREAD_FUNC regfnServerSupportFunction(isapi_cid *cid,
return 1;
}
else if (cid->dconf.log_unsupported) {
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02671)
"ServerSupportFunction "
"HSE_REQ_DONE_WITH_SESSION is not supported: %s",
r->filename);
@@ -1000,7 +1000,7 @@ static int APR_THREAD_FUNC regfnServerSupportFunction(isapi_cid *cid,
case HSE_REQ_GET_SSPI_INFO:
if (cid->dconf.log_unsupported)
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02672)
"ServerSupportFunction HSE_REQ_GET_SSPI_INFO "
"is not supported: %s", r->filename);
apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER));
@@ -1035,7 +1035,7 @@ static int APR_THREAD_FUNC regfnServerSupportFunction(isapi_cid *cid,
return 1;
}
if (cid->dconf.log_unsupported)
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02673)
"ServerSupportFunction HSE_REQ_IO_COMPLETION "
"is not supported: %s", r->filename);
apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER));
@@ -1055,7 +1055,7 @@ static int APR_THREAD_FUNC regfnServerSupportFunction(isapi_cid *cid,
if (!cid->dconf.fake_async && (tf->dwFlags & HSE_IO_ASYNC)) {
if (cid->dconf.log_unsupported)
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02674)
"ServerSupportFunction HSE_REQ_TRANSMIT_FILE "
"as HSE_IO_ASYNC is not supported: %s", r->filename);
apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER));
@@ -1170,7 +1170,7 @@ static int APR_THREAD_FUNC regfnServerSupportFunction(isapi_cid *cid,
case HSE_REQ_REFRESH_ISAPI_ACL:
if (cid->dconf.log_unsupported)
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02675)
"ServerSupportFunction "
"HSE_REQ_REFRESH_ISAPI_ACL "
"is not supported: %s", r->filename);
@@ -1227,7 +1227,7 @@ static int APR_THREAD_FUNC regfnServerSupportFunction(isapi_cid *cid,
case HSE_REQ_GET_IMPERSONATION_TOKEN: /* Added in ISAPI 4.0 */
if (cid->dconf.log_unsupported)
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02676)
"ServerSupportFunction "
"HSE_REQ_GET_IMPERSONATION_TOKEN "
"is not supported: %s", r->filename);
@@ -1306,7 +1306,7 @@ static int APR_THREAD_FUNC regfnServerSupportFunction(isapi_cid *cid,
case HSE_REQ_ABORTIVE_CLOSE:
if (cid->dconf.log_unsupported)
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02677)
"ServerSupportFunction HSE_REQ_ABORTIVE_CLOSE"
" is not supported: %s", r->filename);
apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER));
@@ -1314,7 +1314,7 @@ static int APR_THREAD_FUNC regfnServerSupportFunction(isapi_cid *cid,
case HSE_REQ_GET_CERT_INFO_EX: /* Added in ISAPI 4.0 */
if (cid->dconf.log_unsupported)
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02678)
"ServerSupportFunction "
"HSE_REQ_GET_CERT_INFO_EX "
"is not supported: %s", r->filename);
@@ -1363,7 +1363,7 @@ static int APR_THREAD_FUNC regfnServerSupportFunction(isapi_cid *cid,
case HSE_REQ_CLOSE_CONNECTION: /* Added after ISAPI 4.0 */
if (cid->dconf.log_unsupported)
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02679)
"ServerSupportFunction "
"HSE_REQ_CLOSE_CONNECTION "
"is not supported: %s", r->filename);
@@ -1381,7 +1381,7 @@ static int APR_THREAD_FUNC regfnServerSupportFunction(isapi_cid *cid,
/* Undocumented - defined by the Microsoft Jan '00 Platform SDK
*/
if (cid->dconf.log_unsupported)
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02680)
"ServerSupportFunction "
"HSE_REQ_EXTENSION_TRIGGER "
"is not supported: %s", r->filename);
@@ -1390,7 +1390,7 @@ static int APR_THREAD_FUNC regfnServerSupportFunction(isapi_cid *cid,
default:
if (cid->dconf.log_unsupported)
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02681)
"ServerSupportFunction (%d) not supported: "
"%s", HSE_code, r->filename);
apr_set_os_error(APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER));
@@ -1702,7 +1702,7 @@ static int isapi_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte
rv = apr_thread_mutex_create(&loaded.lock, APR_THREAD_MUTEX_DEFAULT,
loaded.pool);
if (rv != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL,
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, APLOGNO(02682)
"Failed to create module cache lock");
return rv;
}
diff --git a/modules/cache/cache_util.c b/modules/cache/cache_util.c
index bf450931..b7454ad6 100644
--- a/modules/cache/cache_util.c
+++ b/modules/cache/cache_util.c
@@ -443,7 +443,7 @@ int ap_cache_check_no_cache(cache_request_rec *cache, request_rec *r)
return 0;
}
else {
- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02657)
"Incoming request is asking for an uncached version of "
"%s, but we have been configured to ignore it and serve "
"cached content anyway", r->unparsed_uri);
@@ -483,7 +483,7 @@ int ap_cache_check_no_store(cache_request_rec *cache, request_rec *r)
return 0;
}
else {
- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02658)
"Incoming request is asking for a no-store version of "
"%s, but we have been configured to ignore it and serve "
"cached content anyway", r->unparsed_uri);
@@ -1258,8 +1258,10 @@ apr_table_t *cache_merge_headers_out(request_rec *r)
if (r->content_type
&& !apr_table_get(headers_out, "Content-Type")) {
- apr_table_setn(headers_out, "Content-Type",
- ap_make_content_type(r, r->content_type));
+ const char *ctype = ap_make_content_type(r, r->content_type);
+ if (ctype) {
+ apr_table_setn(headers_out, "Content-Type", ctype);
+ }
}
if (r->content_encoding
diff --git a/modules/cache/mod_cache.c b/modules/cache/mod_cache.c
index cd839ed7..b95f0a8a 100644
--- a/modules/cache/mod_cache.c
+++ b/modules/cache/mod_cache.c
@@ -234,6 +234,11 @@ static int cache_quick_handler(request_rec *r, int lookup)
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv,
r, APLOGNO(00752) "Cache locked for url, not caching "
"response: %s", r->uri);
+ /* cache_select() may have added conditional headers */
+ if (cache->stale_headers) {
+ r->headers_in = cache->stale_headers;
+ }
+
}
}
else {
@@ -636,7 +641,6 @@ static int cache_handler(request_rec *r)
static apr_status_t cache_out_filter(ap_filter_t *f, apr_bucket_brigade *in)
{
request_rec *r = f->r;
- apr_bucket *e;
cache_request_rec *cache = (cache_request_rec *)f->ctx;
if (!cache) {
@@ -652,10 +656,8 @@ static apr_status_t cache_out_filter(ap_filter_t *f, apr_bucket_brigade *in)
"cache: running CACHE_OUT filter");
/* clean out any previous response up to EOS, if any */
- for (e = APR_BRIGADE_FIRST(in);
- e != APR_BRIGADE_SENTINEL(in);
- e = APR_BUCKET_NEXT(e))
- {
+ while (!APR_BRIGADE_EMPTY(in)) {
+ apr_bucket *e = APR_BRIGADE_FIRST(in);
if (APR_BUCKET_IS_EOS(e)) {
apr_bucket_brigade *bb = apr_brigade_create(r->pool,
r->connection->bucket_alloc);
@@ -1201,6 +1203,8 @@ static apr_status_t cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
apr_table_unset(r->headers_in, "If-Range");
apr_table_unset(r->headers_in, "If-Unmodified-Since");
+ /* Currently HTTP_NOT_MODIFIED, and after the redirect, handlers won't think to set status to HTTP_OK */
+ r->status = HTTP_OK;
ap_internal_redirect(r->unparsed_uri, r);
return APR_SUCCESS;
diff --git a/modules/cache/mod_cache_socache.c b/modules/cache/mod_cache_socache.c
index a138e6b8..6bd9466b 100644
--- a/modules/cache/mod_cache_socache.c
+++ b/modules/cache/mod_cache_socache.c
@@ -22,6 +22,7 @@
#include "http_config.h"
#include "http_log.h"
#include "http_core.h"
+#include "http_protocol.h"
#include "ap_provider.h"
#include "ap_socache.h"
#include "util_filter.h"
@@ -30,6 +31,7 @@
#include "util_mutex.h"
#include "mod_cache.h"
+#include "mod_status.h"
#include "cache_socache_common.h"
@@ -1375,6 +1377,56 @@ static apr_status_t destroy_cache(void *data)
return APR_SUCCESS;
}
+static int socache_status_hook(request_rec *r, int flags)
+{
+ apr_status_t status = APR_SUCCESS;
+ cache_socache_conf *conf = ap_get_module_config(r->server->module_config,
+ &cache_socache_module);
+ if (!conf->provider || !conf->provider->socache_provider ||
+ !conf->provider->socache_instance) {
+ return DECLINED;
+ }
+
+ ap_rputs("<hr>\n"
+ "<table cellspacing=0 cellpadding=0>\n"
+ "<tr><td bgcolor=\"#000000\">\n"
+ "<b><font color=\"#ffffff\" face=\"Arial,Helvetica\">"
+ "mod_cache_socache Status:</font></b>\n"
+ "</td></tr>\n"
+ "<tr><td bgcolor=\"#ffffff\">\n", r);
+
+ if (socache_mutex) {
+ status = apr_global_mutex_lock(socache_mutex);
+ if (status != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02816)
+ "could not acquire lock for cache status");
+ }
+ }
+
+ if (status != APR_SUCCESS) {
+ ap_rputs("No cache status data available\n", r);
+ } else {
+ conf->provider->socache_provider->status(conf->provider->socache_instance,
+ r, flags);
+ }
+
+ if (socache_mutex && status == APR_SUCCESS) {
+ status = apr_global_mutex_unlock(socache_mutex);
+ if (status != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(02817)
+ "could not release lock for cache status");
+ }
+ }
+
+ ap_rputs("</td></tr>\n</table>\n", r);
+ return OK;
+}
+
+static void socache_status_register(apr_pool_t *p)
+{
+ APR_OPTIONAL_HOOK(ap, status_hook, socache_status_hook, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
static int socache_precfg(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptmp)
{
apr_status_t rv = ap_mutex_register(pconf, cache_socache_id, NULL,
@@ -1384,6 +1436,10 @@ static int socache_precfg(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptmp)
"failed to register %s mutex", cache_socache_id);
return 500; /* An HTTP status would be a misnomer! */
}
+
+ /* Register to handle mod_status status page generation */
+ socache_status_register(pconf);
+
return OK;
}
@@ -1394,7 +1450,7 @@ static int socache_post_config(apr_pool_t *pconf, apr_pool_t *plog,
apr_status_t rv;
const char *errmsg;
static struct ap_socache_hints socache_hints =
- { 64, 32, 60000000 };
+ { 64, 2048, 60000000 };
for (s = base_server; s; s = s->next) {
cache_socache_conf *conf =
diff --git a/modules/cache/mod_cache_socache.dsp b/modules/cache/mod_cache_socache.dsp
index e5d582e2..1dd82145 100644
--- a/modules/cache/mod_cache_socache.dsp
+++ b/modules/cache/mod_cache_socache.dsp
@@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
-# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fd"Release\mod_cache_socache_src" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fd"Release\mod_cache_socache_src" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
@@ -75,7 +75,7 @@ PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).ma
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
-# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Fd"Debug\mod_cache_socache_src" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../srclib/apr-util/include" /I "../../srclib/apr/include" /I "../../include" /I "../generators" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Fd"Debug\mod_cache_socache_src" /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
diff --git a/modules/core/mod_macro.c b/modules/core/mod_macro.c
index 75180930..016f5f49 100644
--- a/modules/core/mod_macro.c
+++ b/modules/core/mod_macro.c
@@ -15,7 +15,7 @@
*/
/*
- $Id: mod_macro.c 1562134 2014-01-28 18:11:59Z jim $
+ $Id: mod_macro.c 1631118 2014-10-11 21:12:18Z jailletc36 $
*/
#include "httpd.h"
@@ -115,17 +115,16 @@ static apr_array_header_t *get_arguments(apr_pool_t * pool, const char *line)
/*
warn if anything non blank appears, but ignore comments...
*/
-static void warn_if_non_blank(
- const char * what,
- char * ptr,
- ap_configfile_t * cfg)
+static void warn_if_non_blank(const char * what,
+ char * ptr,
+ ap_configfile_t * cfg)
{
char * p;
for (p=ptr; *p; p++) {
if (*p == '#')
break;
if (*p != ' ' && *p != '\t') {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL,
"%s on line %d of %s: %s",
what, cfg->line_number, cfg->name, ptr);
break;
@@ -164,8 +163,8 @@ static char *get_lines_till_end_token(apr_pool_t * pool,
if (!strncmp(first, "</", 2)) {
any_nesting--;
if (any_nesting < 0) {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING,
- 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_WARNING,
+ 0, NULL, APLOGNO(02793)
"bad (negative) nesting on line %d of %s",
config_file->line_number - line_number_start,
where);
@@ -185,14 +184,14 @@ static char *get_lines_till_end_token(apr_pool_t * pool,
}
warn_if_non_blank(
- "non blank chars found after directive closing",
+ APLOGNO(02794) "non blank chars found after directive closing",
endp+1, config_file);
macro_nesting--;
if (!macro_nesting) {
if (any_nesting) {
ap_log_error(APLOG_MARK,
- APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ APLOG_WARNING, 0, NULL, APLOGNO(02795)
"bad cumulated nesting (%+d) in %s",
any_nesting, where);
}
@@ -257,7 +256,7 @@ static const char *check_macro_arguments(apr_pool_t * pool,
macro->name, macro->location, i + 1);
}
else if (!looks_like_an_argument(tab[i])) {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(02796)
"macro '%s' (%s) "
"argument name '%s' (#%d) without expected prefix, "
"better prefix argument names with one of '%s'.",
@@ -271,7 +270,7 @@ static const char *check_macro_arguments(apr_pool_t * pool,
/* must not use the same argument name twice */
if (!strcmp(tab[i], tab[j])) {
return apr_psprintf(pool,
- "argument name conflict in macro '%s' (%s): "
+ "argument name conflict in macro '%s' (%s): "
"argument '%s': #%d and #%d, "
"change argument names!",
macro->name, macro->location,
@@ -281,11 +280,11 @@ static const char *check_macro_arguments(apr_pool_t * pool,
/* warn about common prefix, but only if non empty names */
if (ltabi && ltabj &&
!strncmp(tab[i], tab[j], ltabi < ltabj ? ltabi : ltabj)) {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING,
- 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_WARNING,
+ 0, NULL, APLOGNO(02797)
"macro '%s' (%s): "
- "argument name prefix conflict (%s #%d and %s #%d),"
- " be careful about your macro definition!",
+ "argument name prefix conflict (%s #%d and %s #%d), "
+ "be careful about your macro definition!",
macro->name, macro->location,
tab[i], i + 1, tab[j], j + 1);
}
@@ -305,7 +304,7 @@ static void check_macro_use_arguments(const char *where,
int i;
for (i = 0; i < array->nelts; i++) {
if (empty_string_p(tab[i])) {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(02798)
"%s: empty argument #%d", where, i + 1);
}
}
@@ -506,7 +505,7 @@ static const char *check_macro_contents(apr_pool_t * pool,
const char *errmsg;
if (macro->contents->nelts == 0) {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(02799)
"macro '%s' (%s): empty contents!",
macro->name, macro->location);
return NULL; /* no need to further warnings... */
@@ -526,7 +525,7 @@ static const char *check_macro_contents(apr_pool_t * pool,
for (i = 0; i < nelts; i++) {
if (!used->elts[i]) {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(02800)
"macro '%s' (%s): argument '%s' (#%d) never used",
macro->name, macro->location, names[i], i + 1);
}
@@ -719,7 +718,8 @@ static const char *macro_section(cmd_parms * cmd,
return BEGIN_MACRO " macro definition: empty name";
}
- warn_if_non_blank("non blank chars found after " BEGIN_MACRO " closing '>'",
+ warn_if_non_blank(APLOGNO(02801) "non blank chars found after "
+ BEGIN_MACRO " closing '>'",
endp+1, cmd->config_file);
/* coldly drop '>[^>]*$' out */
@@ -736,7 +736,7 @@ static const char *macro_section(cmd_parms * cmd,
if (macro != NULL) {
/* already defined: warn about the redefinition */
- ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(02802)
"macro '%s' multiply defined: "
"%s, redefined on line %d of \"%s\"",
macro->name, macro->location,
@@ -761,7 +761,7 @@ static const char *macro_section(cmd_parms * cmd,
apr_psprintf(pool, "macro '%s' (%s)", macro->name, macro->location);
if (looks_like_an_argument(name)) {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, APLOGNO(02803)
"%s better prefix a macro name with any of '%s'",
where, ARG_PREFIX);
}
diff --git a/modules/core/mod_so.c b/modules/core/mod_so.c
index 6df596a9..eeacec67 100644
--- a/modules/core/mod_so.c
+++ b/modules/core/mod_so.c
@@ -209,8 +209,8 @@ static const char *load_module(cmd_parms *cmd, void *dummy,
for (i = 0; i < sconf->loaded_modules->nelts; i++) {
modi = &modie[i];
if (modi->name != NULL && strcmp(modi->name, modname) == 0) {
- ap_log_perror(APLOG_MARK, APLOG_WARNING, 0,
- cmd->pool, APLOGNO(01574) "module %s is already loaded, skipping",
+ ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, cmd->pool, APLOGNO(01574)
+ "module %s is already loaded, skipping",
modname);
return NULL;
}
diff --git a/modules/core/mod_watchdog.h b/modules/core/mod_watchdog.h
index 13d23ba9..8e7112cf 100644
--- a/modules/core/mod_watchdog.h
+++ b/modules/core/mod_watchdog.h
@@ -21,9 +21,9 @@
* @file mod_watchdog.h
* @brief Watchdog module for Apache
*
- * @defgroup MOD_WATCHDOG watchdog
+ * @defgroup MOD_WATCHDOG mod_watchdog
* @ingroup APACHE_MODS
- * \@{
+ * @{
*/
#include "httpd.h"
@@ -210,4 +210,4 @@ APR_DECLARE_EXTERNAL_HOOK(ap, AP_WD, int, watchdog_step, (
#endif
#endif /* MOD_WATCHDOG_H */
-/** \@} */
+/** @} */
diff --git a/modules/database/mod_dbd.c b/modules/database/mod_dbd.c
index 5ff1ea20..72126652 100644
--- a/modules/database/mod_dbd.c
+++ b/modules/database/mod_dbd.c
@@ -327,7 +327,7 @@ DBD_DECLARE_NONSTD(void) ap_dbd_prepare(server_rec *s, const char *query,
if (apr_hash_get(svr->cfg->queries, label, APR_HASH_KEY_STRING)
&& strcmp(query, "")) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02653)
"conflicting SQL statements with label %s", label);
}
@@ -799,7 +799,8 @@ DBD_DECLARE_NONSTD(ap_dbd_t*) ap_dbd_open(apr_pool_t *pool, server_rec *s)
/* If nothing is configured, we shouldn't be here */
if (cfg->name == no_dbdriver) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "not configured");
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02654)
+ "not configured");
return NULL;
}
@@ -822,7 +823,7 @@ DBD_DECLARE_NONSTD(ap_dbd_t*) ap_dbd_open(apr_pool_t *pool, server_rec *s)
rv = apr_reslist_acquire(group->reslist, (void*) &rec);
if (rv != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(02655)
"Failed to acquire DBD connection from pool!");
return NULL;
}
diff --git a/modules/dav/fs/repos.c b/modules/dav/fs/repos.c
index 6c4c44b1..950646ee 100644
--- a/modules/dav/fs/repos.c
+++ b/modules/dav/fs/repos.c
@@ -874,12 +874,13 @@ static int dav_fs_is_parent_resource(
&& ctx2->pathname[len1] == '/');
}
-static apr_status_t tmpfile_cleanup(void *data) {
- dav_stream *ds = data;
- if (ds->temppath) {
- apr_file_remove(ds->temppath, ds->p);
- }
- return APR_SUCCESS;
+static apr_status_t tmpfile_cleanup(void *data)
+{
+ dav_stream *ds = data;
+ if (ds->temppath) {
+ apr_file_remove(ds->temppath, ds->p);
+ }
+ return APR_SUCCESS;
}
/* custom mktemp that creates the file with APR_OS_DEFAULT permissions */
diff --git a/modules/dav/main/mod_dav.c b/modules/dav/main/mod_dav.c
index 07a4e2c5..2af117d2 100644
--- a/modules/dav/main/mod_dav.c
+++ b/modules/dav/main/mod_dav.c
@@ -315,6 +315,7 @@ static const char *dav_cmd_davmintimeout(cmd_parms *cmd, void *config,
static int dav_error_response(request_rec *r, int status, const char *body)
{
r->status = status;
+ r->status_line = ap_get_status_line(status);
ap_set_content_type(r, "text/html; charset=ISO-8859-1");
@@ -711,8 +712,8 @@ static dav_error *dav_get_resource(request_rec *r, int label_allowed,
if (conf->provider == NULL) {
return dav_new_error(r->pool, HTTP_METHOD_NOT_ALLOWED, 0, 0,
apr_psprintf(r->pool,
- "DAV not enabled for %s",
- ap_escape_html(r->pool, r->uri)));
+ "DAV not enabled for %s",
+ ap_escape_html(r->pool, r->uri)));
}
/* resolve the resource */
diff --git a/modules/examples/mod_example_hooks.c b/modules/examples/mod_example_hooks.c
index 1c8ca4c1..1130f7eb 100644
--- a/modules/examples/mod_example_hooks.c
+++ b/modules/examples/mod_example_hooks.c
@@ -15,7 +15,7 @@
*/
/*
- * Apache example module. Provide demonstrations of how modules do things.
+ * Apache example_hooks module. Provide demonstrations of how modules do things.
* It is not meant to be used in a production server. Since it participates
* in all of the processing phases, it could conceivable interfere with
* the proper operation of other modules -- particularly the ones related
@@ -26,7 +26,7 @@
* prefixed with 'x_' instead of 'example_'.
*
* To use mod_example_hooks, configure the Apache build with
- * --enable-example and compile. Set up a <Location> block in your
+ * --enable-example-hooks and compile. Set up a <Location> block in your
* configuration file like so:
*
* <Location /example>
@@ -328,11 +328,11 @@ static x_cfg *our_cconfig(const conn_rec *c)
static void example_log_each(apr_pool_t *p, server_rec *s, const char *note)
{
if (s != NULL) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_example: %s", note);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_example_hooks: %s", note);
} else {
apr_file_t *out = NULL;
apr_file_open_stderr(&out, p);
- apr_file_printf(out, "mod_example traced in non-loggable "
+ apr_file_printf(out, "mod_example_hooks traced in non-loggable "
"context: %s\n", note);
}
}
@@ -703,7 +703,7 @@ static void *x_merge_server_config(apr_pool_t *p, void *server1_conf,
* declaration near the bottom of this file.) Note that these may be *
* called for situations that don't relate primarily to our function - in *
* other words, the fixup handler shouldn't assume that the request has *
- * to do with "example" stuff. *
+ * to do with "example_hooks" stuff. *
* *
* With the exception of the content handler, all of our routines will be *
* called for each request, unless an earlier handler from another module *
diff --git a/modules/filters/mod_include.c b/modules/filters/mod_include.c
index af90db67..e8d8ea78 100644
--- a/modules/filters/mod_include.c
+++ b/modules/filters/mod_include.c
@@ -697,7 +697,7 @@ static const char *include_expr_var_fn(ap_expr_eval_ctx_t *eval_ctx,
{
const char *res, *name = data;
include_ctx_t *ctx = eval_ctx->data;
- if (name[0] == 'e') {
+ if ((name[0] == 'e') || (name[0] == 'E')) {
/* keep legacy "env" semantics */
if ((res = apr_table_get(ctx->r->notes, arg)) != NULL)
return res;
@@ -968,8 +968,8 @@ static APR_INLINE int re_check(include_ctx_t *ctx, const char *string,
compiled = ap_pregcomp(ctx->dpool, rexp, AP_REG_EXTENDED);
if (!compiled) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, "unable to "
- "compile pattern \"%s\"", rexp);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, APLOGNO(02667)
+ "unable to compile pattern \"%s\"", rexp);
return -1;
}
@@ -1698,7 +1698,7 @@ static int find_file(request_rec *r, const char *directive, const char *tag,
APR_FILEPATH_NOTABSOLUTE, r->pool);
if (rv != APR_SUCCESS) {
- error_fmt = "unable to access file \"%s\" "
+ error_fmt = APLOGNO(02668) "unable to access file \"%s\" "
"in parsed file %s";
}
else {
@@ -1711,13 +1711,13 @@ static int find_file(request_rec *r, const char *directive, const char *tag,
if ((rv = apr_stat(finfo, to_send,
APR_FINFO_GPROT | APR_FINFO_MIN, rr->pool)) != APR_SUCCESS
&& rv != APR_INCOMPLETE) {
- error_fmt = "unable to get information about \"%s\" "
- "in parsed file %s";
+ error_fmt = APLOGNO(02669) "unable to get information "
+ "about \"%s\" in parsed file %s";
}
}
else {
- error_fmt = "unable to lookup information about \"%s\" "
- "in parsed file %s";
+ error_fmt = APLOGNO(02670) "unable to lookup information "
+ "about \"%s\" in parsed file %s";
}
}
diff --git a/modules/filters/mod_ratelimit.c b/modules/filters/mod_ratelimit.c
index 939ab8e9..59e130e7 100644
--- a/modules/filters/mod_ratelimit.c
+++ b/modules/filters/mod_ratelimit.c
@@ -146,7 +146,7 @@ rate_limit_filter(ap_filter_t *f, apr_bucket_brigade *input_bb)
if (rv != APR_SUCCESS) {
ctx->state = RATE_ERROR;
- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r, APLOGNO(01455)
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, f->r, APLOGNO(01455)
"rl: full speed brigade pass failed.");
}
}
@@ -218,7 +218,7 @@ rate_limit_filter(ap_filter_t *f, apr_bucket_brigade *input_bb)
if (rv != APR_SUCCESS) {
ctx->state = RATE_ERROR;
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, APLOGNO(01457)
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, f->r, APLOGNO(01457)
"rl: brigade pass failed.");
break;
}
diff --git a/modules/filters/mod_substitute.c b/modules/filters/mod_substitute.c
index 15cd8ee4..9326348c 100644
--- a/modules/filters/mod_substitute.c
+++ b/modules/filters/mod_substitute.c
@@ -33,6 +33,13 @@
#define APR_WANT_STRFUNC
#include "apr_want.h"
+/*
+ * We want to limit the memory usage in a way that is predictable.
+ * Therefore we limit the resulting length of the line.
+ * This is the default value.
+ */
+#define AP_SUBST_MAX_LINE_LENGTH (1024*1024)
+
static const char substitute_filter_name[] = "SUBSTITUTE";
module AP_MODULE_DECLARE_DATA substitute_module;
@@ -48,6 +55,8 @@ typedef struct subst_pattern_t {
typedef struct {
apr_array_header_t *patterns;
+ apr_size_t max_line_length;
+ int max_line_length_set;
} subst_dir_conf;
typedef struct {
@@ -64,6 +73,7 @@ static void *create_substitute_dcfg(apr_pool_t *p, char *d)
(subst_dir_conf *) apr_pcalloc(p, sizeof(subst_dir_conf));
dcfg->patterns = apr_array_make(p, 10, sizeof(subst_pattern_t));
+ dcfg->max_line_length = AP_SUBST_MAX_LINE_LENGTH;
return dcfg;
}
@@ -76,15 +86,14 @@ static void *merge_substitute_dcfg(apr_pool_t *p, void *basev, void *overv)
a->patterns = apr_array_append(p, over->patterns,
base->patterns);
+ a->max_line_length = over->max_line_length_set ?
+ over->max_line_length : base->max_line_length;
+ a->max_line_length_set = over->max_line_length_set ?
+ over->max_line_length_set : base->max_line_length_set;
return a;
}
#define AP_MAX_BUCKETS 1000
-/*
- * We want to limit the memory usage in a way that is predictable. Therefore
- * we limit the resulting length of the line to this value.
- */
-#define AP_SUBST_MAX_LINE_LENGTH (128*MAX_STRING_LEN)
#define SEDRMPATBCKT(b, offset, tmp_b, patlen) do { \
apr_bucket_split(b, offset); \
@@ -143,9 +152,9 @@ static apr_status_t do_pattmatch(ap_filter_t *f, apr_bucket *inb,
const char *repl;
/*
* space_left counts how many bytes we have left until the
- * line length reaches AP_SUBST_MAX_LINE_LENGTH.
+ * line length reaches max_line_length.
*/
- apr_size_t space_left = AP_SUBST_MAX_LINE_LENGTH;
+ apr_size_t space_left = cfg->max_line_length;
apr_size_t repl_len = strlen(script->replacement);
while ((repl = apr_strmatch(script->pattern, buff, bytes)))
{
@@ -161,7 +170,7 @@ static apr_status_t do_pattmatch(ap_filter_t *f, apr_bucket *inb,
* are constanting allocing space and copying
* strings.
*/
- if (vb.strlen + len + repl_len > AP_SUBST_MAX_LINE_LENGTH)
+ if (vb.strlen + len + repl_len > cfg->max_line_length)
return APR_ENOMEM;
ap_varbuf_strmemcat(&vb, buff, len);
ap_varbuf_strmemcat(&vb, script->replacement, repl_len);
@@ -228,19 +237,25 @@ static apr_status_t do_pattmatch(ap_filter_t *f, apr_bucket *inb,
int left = bytes;
const char *pos = buff;
char *repl;
- apr_size_t space_left = AP_SUBST_MAX_LINE_LENGTH;
+ apr_size_t space_left = cfg->max_line_length;
while (!ap_regexec_len(script->regexp, pos, left,
AP_MAX_REG_MATCH, regm, 0)) {
apr_status_t rv;
have_match = 1;
if (script->flatten && !force_quick) {
+ /* check remaining buffer size */
+ /* Note that the last param in ap_varbuf_regsub below
+ * must stay positive. If it gets 0, it would mean
+ * unlimited space available. */
+ if (vb.strlen + regm[0].rm_so >= cfg->max_line_length)
+ return APR_ENOMEM;
/* copy bytes before the match */
if (regm[0].rm_so > 0)
ap_varbuf_strmemcat(&vb, pos, regm[0].rm_so);
- /* add replacement string */
+ /* add replacement string, last argument is unsigned! */
rv = ap_varbuf_regsub(&vb, script->replacement, pos,
AP_MAX_REG_MATCH, regm,
- AP_SUBST_MAX_LINE_LENGTH - vb.strlen);
+ cfg->max_line_length - vb.strlen);
if (rv != APR_SUCCESS)
return rv;
}
@@ -309,6 +324,9 @@ static apr_status_t substitute_filter(ap_filter_t *f, apr_bucket_brigade *bb)
apr_bucket *tmp_b;
apr_bucket_brigade *tmp_bb = NULL;
apr_status_t rv;
+ subst_dir_conf *cfg =
+ (subst_dir_conf *) ap_get_module_config(f->r->per_dir_config,
+ &substitute_module);
substitute_module_ctx *ctx = f->ctx;
@@ -381,7 +399,7 @@ static apr_status_t substitute_filter(ap_filter_t *f, apr_bucket_brigade *bb)
&fbytes, ctx->tpool);
if (rv != APR_SUCCESS)
goto err;
- if (fbytes > AP_SUBST_MAX_LINE_LENGTH) {
+ if (fbytes > cfg->max_line_length) {
rv = APR_ENOMEM;
goto err;
}
@@ -447,7 +465,7 @@ static apr_status_t substitute_filter(ap_filter_t *f, apr_bucket_brigade *bb)
&fbytes, ctx->tpool);
if (rv != APR_SUCCESS)
goto err;
- if (fbytes > AP_SUBST_MAX_LINE_LENGTH) {
+ if (fbytes > cfg->max_line_length) {
/* Avoid pflattening further lines, we will
* abort later on anyway.
*/
@@ -627,6 +645,44 @@ static const char *set_pattern(cmd_parms *cmd, void *cfg, const char *line)
return NULL;
}
+#define KBYTE 1024
+#define MBYTE 1048576
+#define GBYTE 1073741824
+
+static const char *set_max_line_length(cmd_parms *cmd, void *cfg, const char *arg)
+{
+ subst_dir_conf *dcfg = (subst_dir_conf *)cfg;
+ apr_off_t max;
+ char *end;
+ apr_status_t rv;
+
+ rv = apr_strtoff(&max, arg, &end, 10);
+ if (rv == APR_SUCCESS) {
+ if ((*end == 'K' || *end == 'k') && !end[1]) {
+ max *= KBYTE;
+ }
+ else if ((*end == 'M' || *end == 'm') && !end[1]) {
+ max *= MBYTE;
+ }
+ else if ((*end == 'G' || *end == 'g') && !end[1]) {
+ max *= GBYTE;
+ }
+ else if (*end && /* neither empty nor [Bb] */
+ ((*end != 'B' && *end != 'b') || end[1])) {
+ rv = APR_EGENERAL;
+ }
+ }
+
+ if (rv != APR_SUCCESS || max < 0)
+ {
+ return "SubstituteMaxLineLength must be a non-negative integer optionally "
+ "suffixed with 'b', 'k', 'm' or 'g'.";
+ }
+ dcfg->max_line_length = (apr_size_t)max;
+ dcfg->max_line_length_set = 1;
+ return NULL;
+}
+
#define PROTO_FLAGS AP_FILTER_PROTO_CHANGE|AP_FILTER_PROTO_CHANGE_LENGTH
static void register_hooks(apr_pool_t *pool)
{
@@ -635,8 +691,10 @@ static void register_hooks(apr_pool_t *pool)
}
static const command_rec substitute_cmds[] = {
- AP_INIT_TAKE1("Substitute", set_pattern, NULL, OR_ALL,
+ AP_INIT_TAKE1("Substitute", set_pattern, NULL, OR_FILEINFO,
"Pattern to filter the response content (s/foo/bar/[inf])"),
+ AP_INIT_TAKE1("SubstituteMaxLineLength", set_max_line_length, NULL, OR_FILEINFO,
+ "Maximum line length"),
{NULL}
};
diff --git a/modules/filters/mod_xml2enc.c b/modules/filters/mod_xml2enc.c
index a4202a28..d28c97d1 100644
--- a/modules/filters/mod_xml2enc.c
+++ b/modules/filters/mod_xml2enc.c
@@ -142,8 +142,7 @@ static void fix_skipto(request_rec* r, xml2ctx* ctx)
&bstart);
ap_assert(rv == APR_SUCCESS);
while (b = APR_BRIGADE_FIRST(ctx->bbsave), b != bstart) {
- APR_BUCKET_REMOVE(b);
- apr_bucket_destroy(b);
+ apr_bucket_delete(b);
}
ctx->bytes -= (p-ctx->buf);
ctx->buf = p ;
@@ -228,8 +227,7 @@ static void sniff_encoding(request_rec* r, xml2ctx* ctx)
/* cut out the <meta> we're invalidating */
while (cutb != cute) {
b = APR_BUCKET_NEXT(cutb);
- APR_BUCKET_REMOVE(cutb);
- apr_bucket_destroy(cutb);
+ apr_bucket_delete(cutb);
cutb = b;
}
/* and leave a string */
@@ -435,8 +433,7 @@ static apr_status_t xml2enc_ffunc(ap_filter_t* f, apr_bucket_brigade* bb)
/* remove the data we've just read */
rv = apr_brigade_partition(bb, bytes, &bstart);
while (b = APR_BRIGADE_FIRST(bb), b != bstart) {
- APR_BUCKET_REMOVE(b);
- apr_bucket_destroy(b);
+ apr_bucket_delete(b);
}
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r, APLOGNO(01438)
"xml2enc: consuming %" APR_SIZE_T_FMT
diff --git a/modules/generators/mod_autoindex.c b/modules/generators/mod_autoindex.c
index 3d36c77b..5e86e407 100644
--- a/modules/generators/mod_autoindex.c
+++ b/modules/generators/mod_autoindex.c
@@ -1416,7 +1416,7 @@ static char *terminate_description(autoindex_config_rec *d, char *desc,
apr_int32_t autoindex_opts, int desc_width)
{
int maxsize = desc_width;
- register int x;
+ int x;
/*
* If there's no DescriptionWidth in effect, default to the old
@@ -1782,7 +1782,7 @@ static void output_directories(struct ent **ar, int n,
}
}
else {
- ap_rputs("</td><td>&nbsp;", r);
+ ap_rvputs(r, "</td><td", (d->style_sheet != NULL) ? " class=\"indexcoldesc\">" : ">", "&nbsp;", NULL);
}
}
ap_rputs("</td></tr>\n", r);
diff --git a/modules/generators/mod_cgi.c b/modules/generators/mod_cgi.c
index 7808262f..beb02f27 100644
--- a/modules/generators/mod_cgi.c
+++ b/modules/generators/mod_cgi.c
@@ -162,7 +162,7 @@ AP_INIT_TAKE1("ScriptLogBuffer", set_scriptlog_buffer, NULL, RSRC_CONF,
};
static int log_scripterror(request_rec *r, cgi_server_conf * conf, int ret,
- apr_status_t rv, char *error)
+ apr_status_t rv, char *logno, char *error)
{
apr_file_t *f = NULL;
apr_finfo_t finfo;
@@ -170,7 +170,7 @@ static int log_scripterror(request_rec *r, cgi_server_conf * conf, int ret,
int log_flags = rv ? APLOG_ERR : APLOG_ERR;
ap_log_rerror(APLOG_MARK, log_flags, rv, r,
- "%s: %s", error, r->filename);
+ "%s%s: %s", logno ? logno : "", error, r->filename);
/* XXX Very expensive mainline case! Open, then getfileinfo! */
if (!conf->logname ||
@@ -203,6 +203,7 @@ static apr_status_t log_script_err(request_rec *r, apr_file_t *script_err)
char argsbuffer[HUGE_STRING_LEN];
char *newline;
apr_status_t rv;
+ cgi_server_conf *conf = ap_get_module_config(r->server->module_config, &cgi_module);
while ((rv = apr_file_gets(argsbuffer, HUGE_STRING_LEN,
script_err)) == APR_SUCCESS) {
@@ -210,8 +211,7 @@ static apr_status_t log_script_err(request_rec *r, apr_file_t *script_err)
if (newline) {
*newline = '\0';
}
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01215)
- "%s", argsbuffer);
+ log_scripterror(r, conf, r->status, 0, APLOGNO(01215), argsbuffer);
}
return rv;
@@ -774,24 +774,24 @@ static int cgi_handler(request_rec *r)
conf = ap_get_module_config(r->server->module_config, &cgi_module);
if (!(ap_allow_options(r) & OPT_EXECCGI) && !is_scriptaliased(r))
- return log_scripterror(r, conf, HTTP_FORBIDDEN, 0,
+ return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(02809),
"Options ExecCGI is off in this directory");
if (nph && is_included)
- return log_scripterror(r, conf, HTTP_FORBIDDEN, 0,
+ return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(02810),
"attempt to include NPH CGI script");
if (r->finfo.filetype == APR_NOFILE)
- return log_scripterror(r, conf, HTTP_NOT_FOUND, 0,
+ return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(02811),
"script not found or unable to stat");
if (r->finfo.filetype == APR_DIR)
- return log_scripterror(r, conf, HTTP_FORBIDDEN, 0,
+ return log_scripterror(r, conf, HTTP_FORBIDDEN, 0, APLOGNO(02812),
"attempt to invoke directory as script");
if ((r->used_path_info == AP_REQ_REJECT_PATH_INFO) &&
r->path_info && *r->path_info)
{
/* default to accept */
- return log_scripterror(r, conf, HTTP_NOT_FOUND, 0,
+ return log_scripterror(r, conf, HTTP_NOT_FOUND, 0, APLOGNO(02813),
"AcceptPathInfo off disallows user's path");
}
/*
diff --git a/modules/http/byterange_filter.c b/modules/http/byterange_filter.c
index 09f19565..de585c57 100644
--- a/modules/http/byterange_filter.c
+++ b/modules/http/byterange_filter.c
@@ -380,8 +380,7 @@ static apr_status_t copy_brigade_range(apr_bucket_brigade *bb,
return rv;
}
out_first = APR_BUCKET_NEXT(copy);
- APR_BUCKET_REMOVE(copy);
- apr_bucket_destroy(copy);
+ apr_bucket_delete(copy);
}
else {
out_first = copy;
@@ -400,8 +399,7 @@ static apr_status_t copy_brigade_range(apr_bucket_brigade *bb,
}
copy = APR_BUCKET_NEXT(copy);
if (copy != APR_BRIGADE_SENTINEL(bbout)) {
- APR_BUCKET_REMOVE(copy);
- apr_bucket_destroy(copy);
+ apr_bucket_delete(copy);
}
}
break;
diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c
index 2a0a979d..733e9c82 100644
--- a/modules/http/http_filters.c
+++ b/modules/http/http_filters.c
@@ -231,6 +231,49 @@ static apr_status_t get_chunk_line(http_ctx_t *ctx, apr_bucket_brigade *b,
}
+static apr_status_t read_chunked_trailers(http_ctx_t *ctx, ap_filter_t *f,
+ apr_bucket_brigade *b, int merge)
+{
+ int rv;
+ apr_bucket *e;
+ request_rec *r = f->r;
+ apr_table_t *saved_headers_in = r->headers_in;
+ int saved_status = r->status;
+
+ r->status = HTTP_OK;
+ r->headers_in = r->trailers_in;
+ apr_table_clear(r->headers_in);
+ ctx->state = BODY_NONE;
+ ap_get_mime_headers(r);
+
+ if(r->status == HTTP_OK) {
+ r->status = saved_status;
+ e = apr_bucket_eos_create(f->c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(b, e);
+ ctx->eos_sent = 1;
+ rv = APR_SUCCESS;
+ }
+ else {
+ const char *error_notes = apr_table_get(r->notes,
+ "error-notes");
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+ "Error while reading HTTP trailer: %i%s%s",
+ r->status, error_notes ? ": " : "",
+ error_notes ? error_notes : "");
+ rv = APR_EINVAL;
+ }
+
+ if(!merge) {
+ r->headers_in = saved_headers_in;
+ }
+ else {
+ r->headers_in = apr_table_overlay(r->pool, saved_headers_in,
+ r->trailers_in);
+ }
+
+ return rv;
+}
+
/* This is the HTTP_INPUT filter for HTTP requests and responses from
* proxied servers (mod_proxy). It handles chunked and content-length
* bodies. This can only be inserted/used after the headers
@@ -240,6 +283,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
ap_input_mode_t mode, apr_read_type_e block,
apr_off_t readbytes)
{
+ core_server_config *conf;
apr_bucket *e;
http_ctx_t *ctx = f->ctx;
apr_status_t rv;
@@ -247,6 +291,9 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
int http_error = HTTP_REQUEST_ENTITY_TOO_LARGE;
apr_bucket_brigade *bb;
+ conf = (core_server_config *)
+ ap_get_module_config(f->r->server->module_config, &core_module);
+
/* just get out of the way of things we don't want. */
if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) {
return ap_get_brigade(f->next, b, mode, block, readbytes);
@@ -364,7 +411,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
* in a state of expecting one.
*/
f->r->expecting_100 = 0;
- tmp = apr_pstrcat(f->r->pool, AP_SERVER_PROTOCOL, " ",
+ tmp = apr_pstrcat(f->r->pool, AP_SERVER_PROTOCOL " ",
ap_get_status_line(HTTP_CONTINUE), CRLF CRLF,
NULL);
len = strlen(tmp);
@@ -425,13 +472,8 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
}
if (!ctx->remaining) {
- /* Handle trailers by calling ap_get_mime_headers again! */
- ctx->state = BODY_NONE;
- ap_get_mime_headers(f->r);
- e = apr_bucket_eos_create(f->c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(b, e);
- ctx->eos_sent = 1;
- return APR_SUCCESS;
+ return read_chunked_trailers(ctx, f, b,
+ conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE);
}
}
}
@@ -534,13 +576,8 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
}
if (!ctx->remaining) {
- /* Handle trailers by calling ap_get_mime_headers again! */
- ctx->state = BODY_NONE;
- ap_get_mime_headers(f->r);
- e = apr_bucket_eos_create(f->c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(b, e);
- ctx->eos_sent = 1;
- return APR_SUCCESS;
+ return read_chunked_trailers(ctx, f, b,
+ conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE);
}
}
break;
diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c
index fe2cc208..a7f30fcf 100644
--- a/modules/http/http_protocol.c
+++ b/modules/http/http_protocol.c
@@ -1608,8 +1608,8 @@ AP_DECLARE(void) ap_method_list_add(ap_method_list_t *l, const char *method)
* bitmask.
*/
methnum = ap_method_number_of(method);
- l->method_mask |= (AP_METHOD_BIT << methnum);
if (methnum != M_INVALID) {
+ l->method_mask |= (AP_METHOD_BIT << methnum);
return;
}
/*
@@ -1641,15 +1641,15 @@ AP_DECLARE(void) ap_method_list_remove(ap_method_list_t *l,
* by a module, use the bitmask.
*/
methnum = ap_method_number_of(method);
- l->method_mask |= ~(AP_METHOD_BIT << methnum);
if (methnum != M_INVALID) {
+ l->method_mask &= ~(AP_METHOD_BIT << methnum);
return;
}
/*
* Otherwise, see if the method name is in the array of string names.
*/
if (l->method_list->nelts != 0) {
- register int i, j, k;
+ int i, j, k;
methods = (char **)l->method_list->elts;
for (i = 0; i < l->method_list->nelts; ) {
if (strcmp(method, methods[i]) == 0) {
diff --git a/modules/http/http_request.c b/modules/http/http_request.c
index 796d506e..cdfec8b5 100644
--- a/modules/http/http_request.c
+++ b/modules/http/http_request.c
@@ -463,6 +463,7 @@ static request_rec *internal_internal_redirect(const char *new_uri,
new->main = r->main;
new->headers_in = r->headers_in;
+ new->trailers_in = r->trailers_in;
new->headers_out = apr_table_make(r->pool, 12);
if (ap_is_HTTP_REDIRECT(new->status)) {
const char *location = apr_table_get(r->headers_out, "Location");
@@ -470,6 +471,7 @@ static request_rec *internal_internal_redirect(const char *new_uri,
apr_table_setn(new->headers_out, "Location", location);
}
new->err_headers_out = r->err_headers_out;
+ new->trailers_out = apr_table_make(r->pool, 5);
new->subprocess_env = rename_original_env(r->pool, r->subprocess_env);
new->notes = apr_table_make(r->pool, 5);
@@ -583,6 +585,8 @@ AP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r)
r->headers_out);
r->err_headers_out = apr_table_overlay(r->pool, rr->err_headers_out,
r->err_headers_out);
+ r->trailers_out = apr_table_overlay(r->pool, rr->trailers_out,
+ r->trailers_out);
r->subprocess_env = apr_table_overlay(r->pool, rr->subprocess_env,
r->subprocess_env);
diff --git a/modules/ldap/util_ldap.c b/modules/ldap/util_ldap.c
index 0cc51c40..7440d9eb 100644
--- a/modules/ldap/util_ldap.c
+++ b/modules/ldap/util_ldap.c
@@ -1824,7 +1824,7 @@ start_over:
* combination, which might be reused unintentionally next time this
* connection is used from the connection pool.
*/
- ldc->must_rebind = 0;
+ ldc->must_rebind = 1;
ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "LDC %pp used for authn, must be rebound", ldc);
}
diff --git a/modules/ldap/util_ldap_cache_mgr.c b/modules/ldap/util_ldap_cache_mgr.c
index ae7e652a..2389b5d0 100644
--- a/modules/ldap/util_ldap_cache_mgr.c
+++ b/modules/ldap/util_ldap_cache_mgr.c
@@ -359,9 +359,11 @@ util_ald_cache_t *util_ald_create_cache(util_ldap_state_t *st,
cache->maxentries = cache_size;
cache->numentries = 0;
cache->size = cache_size / 3;
- if (cache->size < 64) cache->size = 64;
- for (i = 0; primes[i] && primes[i] < cache->size; ++i) ;
- cache->size = primes[i]? primes[i] : primes[i-1];
+ if (cache->size < 64)
+ cache->size = 64;
+ for (i = 0; primes[i] && primes[i] < cache->size; ++i)
+ ;
+ cache->size = primes[i] ? primes[i] : primes[i-1];
cache->nodes = (util_cache_node_t **)util_ald_alloc(cache, cache->size * sizeof(util_cache_node_t *));
if (!cache->nodes) {
diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c
index 792756db..c1b0e1ba 100644
--- a/modules/loggers/mod_log_config.c
+++ b/modules/loggers/mod_log_config.c
@@ -431,6 +431,12 @@ static const char *log_header_in(request_rec *r, char *a)
return ap_escape_logitem(r->pool, apr_table_get(r->headers_in, a));
}
+static const char *log_trailer_in(request_rec *r, char *a)
+{
+ return ap_escape_logitem(r->pool, apr_table_get(r->trailers_in, a));
+}
+
+
static APR_INLINE char *find_multiple_headers(apr_pool_t *pool,
const apr_table_t *table,
const char *key)
@@ -514,6 +520,11 @@ static const char *log_header_out(request_rec *r, char *a)
return ap_escape_logitem(r->pool, cp);
}
+static const char *log_trailer_out(request_rec *r, char *a)
+{
+ return ap_escape_logitem(r->pool, apr_table_get(r->trailers_out, a));
+}
+
static const char *log_note(request_rec *r, char *a)
{
return ap_escape_logitem(r->pool, apr_table_get(r->notes, a));
@@ -916,7 +927,7 @@ static char *parse_log_misc_string(apr_pool_t *p, log_format_item *it,
static char *parse_log_item(apr_pool_t *p, log_format_item *it, const char **sa)
{
const char *s = *sa;
- ap_log_handler *handler;
+ ap_log_handler *handler = NULL;
if (*s != '%') {
return parse_log_misc_string(p, it, sa);
@@ -986,7 +997,16 @@ static char *parse_log_item(apr_pool_t *p, log_format_item *it, const char **sa)
break;
default:
- handler = (ap_log_handler *)apr_hash_get(log_hash, s++, 1);
+ /* check for '^' + two character format first */
+ if (*s == '^' && *(s+1) && *(s+2)) {
+ handler = (ap_log_handler *)apr_hash_get(log_hash, s, 3);
+ if (handler) {
+ s += 3;
+ }
+ }
+ if (!handler) {
+ handler = (ap_log_handler *)apr_hash_get(log_hash, s++, 1);
+ }
if (!handler) {
char dummy[2];
@@ -1516,7 +1536,7 @@ static void ap_register_log_handler(apr_pool_t *p, char *tag,
log_struct->func = handler;
log_struct->want_orig_default = def;
- apr_hash_set(log_hash, tag, 1, (const void *)log_struct);
+ apr_hash_set(log_hash, tag, strlen(tag), (const void *)log_struct);
}
static ap_log_writer_init *ap_log_set_writer_init(ap_log_writer_init *handle)
{
@@ -1694,6 +1714,9 @@ static int log_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
log_pfn_register(p, "U", log_request_uri, 1);
log_pfn_register(p, "s", log_status, 1);
log_pfn_register(p, "R", log_handler, 1);
+
+ log_pfn_register(p, "^ti", log_trailer_in, 0);
+ log_pfn_register(p, "^to", log_trailer_out, 0);
}
/* reset to default conditions */
diff --git a/modules/loggers/mod_logio.c b/modules/loggers/mod_logio.c
index ad387a9b..359d4673 100644
--- a/modules/loggers/mod_logio.c
+++ b/modules/loggers/mod_logio.c
@@ -52,7 +52,8 @@ typedef struct logio_config_t {
* Optional function for the core to add to bytes_out
*/
-static void ap_logio_add_bytes_out(conn_rec *c, apr_off_t bytes){
+static void ap_logio_add_bytes_out(conn_rec *c, apr_off_t bytes)
+{
logio_config_t *cf = ap_get_module_config(c->conn_config, &logio_module);
cf->bytes_out += bytes;
@@ -62,7 +63,8 @@ static void ap_logio_add_bytes_out(conn_rec *c, apr_off_t bytes){
* Optional function for modules to adjust bytes_in
*/
-static void ap_logio_add_bytes_in(conn_rec *c, apr_off_t bytes){
+static void ap_logio_add_bytes_in(conn_rec *c, apr_off_t bytes)
+{
logio_config_t *cf = ap_get_module_config(c->conn_config, &logio_module);
cf->bytes_in += bytes;
@@ -132,7 +134,8 @@ static apr_status_t logio_in_filter(ap_filter_t *f,
apr_bucket_brigade *bb,
ap_input_mode_t mode,
apr_read_type_e block,
- apr_off_t readbytes) {
+ apr_off_t readbytes)
+{
apr_off_t length;
apr_status_t status;
logio_config_t *cf = ap_get_module_config(f->c->conn_config, &logio_module);
@@ -151,7 +154,8 @@ static apr_status_t logio_in_filter(ap_filter_t *f,
* The hooks...
*/
-static int logio_pre_conn(conn_rec *c, void *csd) {
+static int logio_pre_conn(conn_rec *c, void *csd)
+{
logio_config_t *cf = apr_pcalloc(c->pool, sizeof(*cf));
ap_set_module_config(c->conn_config, &logio_module, cf);
diff --git a/modules/lua/lua_apr.c b/modules/lua/lua_apr.c
index 94761ba4..fd3ba20e 100644
--- a/modules/lua/lua_apr.c
+++ b/modules/lua/lua_apr.c
@@ -52,8 +52,8 @@ static int lua_table_set(lua_State *L)
while ( (badchar = ap_strchr(badchar, '\n')) ) {
*badchar = ' ';
}
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, t->r,
- APLOGNO(02614) "mod_lua: Value for '%s' in table '%s' contains newline!",
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, t->r, APLOGNO(02614)
+ "mod_lua: Value for '%s' in table '%s' contains newline!",
key, t->n);
apr_table_set(t->t, key, replacement);
}
diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c
index 8b740c22..6dc6b9f5 100644
--- a/modules/lua/lua_request.c
+++ b/modules/lua/lua_request.c
@@ -2086,13 +2086,13 @@ static int lua_set_cookie(lua_State *L)
if (expires > 0) {
rv = apr_rfc822_date(cdate, apr_time_from_sec(expires));
if (rv == APR_SUCCESS) {
- strexpires = apr_psprintf(r->pool, "Expires=\"%s\";", cdate);
+ strexpires = apr_psprintf(r->pool, "Expires=%s;", cdate);
}
}
/* Create path segment */
if (path != NULL && strlen(path) > 0) {
- strpath = apr_psprintf(r->pool, "Path=\"%s\";", path);
+ strpath = apr_psprintf(r->pool, "Path=%s;", path);
}
/* Create domain segment */
@@ -2171,13 +2171,13 @@ static int lua_websocket_greet(lua_State *L)
r->read_chunked = 0;
ap_rflush(r);
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
- "Websocket: Upgraded from HTTP to Websocket");
+ "Websocket: Upgraded from HTTP to Websocket");
lua_pushboolean(L, 1);
return 1;
}
}
- ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r,
- "Websocket: Upgrade from HTTP to Websocket failed");
+ ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02666)
+ "Websocket: Upgrade from HTTP to Websocket failed");
return 0;
}
diff --git a/modules/lua/mod_lua.c b/modules/lua/mod_lua.c
index 90f34cda..e6d2cfcc 100644
--- a/modules/lua/mod_lua.c
+++ b/modules/lua/mod_lua.c
@@ -66,9 +66,13 @@ typedef struct {
const char *file_name;
const char *function_name;
ap_lua_vm_spec *spec;
- apr_array_header_t *args;
} lua_authz_provider_spec;
+typedef struct {
+ lua_authz_provider_spec *spec;
+ apr_array_header_t *args;
+} lua_authz_provider_func;
+
apr_hash_t *lua_authz_providers;
typedef struct
@@ -500,9 +504,9 @@ static apr_status_t lua_output_filter_handle(ap_filter_t *f, apr_bucket_brigade
ap_remove_output_filter(f);
apr_brigade_cleanup(pbbIn);
apr_brigade_cleanup(ctx->tmpBucket);
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "lua: Error while executing filter: %s",
- lua_tostring(L, -1));
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02663)
+ "lua: Error while executing filter: %s",
+ lua_tostring(L, -1));
return HTTP_INTERNAL_SERVER_ERROR;
}
}
@@ -1692,6 +1696,7 @@ static const char *lua_authz_parse(cmd_parms *cmd, const char *require_line,
{
const char *provider_name;
lua_authz_provider_spec *spec;
+ lua_authz_provider_func *func = apr_pcalloc(cmd->pool, sizeof(lua_authz_provider_func));
apr_pool_userdata_get((void**)&provider_name, AUTHZ_PROVIDER_NAME_NOTE,
cmd->temp_pool);
@@ -1699,16 +1704,17 @@ static const char *lua_authz_parse(cmd_parms *cmd, const char *require_line,
spec = apr_hash_get(lua_authz_providers, provider_name, APR_HASH_KEY_STRING);
ap_assert(spec != NULL);
+ func->spec = spec;
if (require_line && *require_line) {
const char *arg;
- spec->args = apr_array_make(cmd->pool, 2, sizeof(const char *));
+ func->args = apr_array_make(cmd->pool, 2, sizeof(const char *));
while ((arg = ap_getword_conf(cmd->pool, &require_line)) && *arg) {
- APR_ARRAY_PUSH(spec->args, const char *) = arg;
+ APR_ARRAY_PUSH(func->args, const char *) = arg;
}
}
- *parsed_require_line = spec;
+ *parsed_require_line = func;
return NULL;
}
@@ -1722,7 +1728,8 @@ static authz_status lua_authz_check(request_rec *r, const char *require_line,
&lua_module);
const ap_lua_dir_cfg *cfg = ap_get_module_config(r->per_dir_config,
&lua_module);
- const lua_authz_provider_spec *prov_spec = parsed_require_line;
+ const lua_authz_provider_func *prov_func = parsed_require_line;
+ const lua_authz_provider_spec *prov_spec = prov_func->spec;
int result;
int nargs = 0;
@@ -1744,19 +1751,19 @@ static authz_status lua_authz_check(request_rec *r, const char *require_line,
return AUTHZ_GENERAL_ERROR;
}
ap_lua_run_lua_request(L, r);
- if (prov_spec->args) {
+ if (prov_func->args) {
int i;
- if (!lua_checkstack(L, prov_spec->args->nelts)) {
+ if (!lua_checkstack(L, prov_func->args->nelts)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02315)
"Error: authz provider %s: too many arguments", prov_spec->name);
ap_lua_release_state(L, spec, r);
return AUTHZ_GENERAL_ERROR;
}
- for (i = 0; i < prov_spec->args->nelts; i++) {
- const char *arg = APR_ARRAY_IDX(prov_spec->args, i, const char *);
+ for (i = 0; i < prov_func->args->nelts; i++) {
+ const char *arg = APR_ARRAY_IDX(prov_func->args, i, const char *);
lua_pushstring(L, arg);
}
- nargs = prov_spec->args->nelts;
+ nargs = prov_func->args->nelts;
}
if (lua_pcall(L, 1 + nargs, 1, 0)) {
const char *err = lua_tostring(L, -1);
@@ -2003,7 +2010,7 @@ static int lua_post_config(apr_pool_t *pconf, apr_pool_t *plog,
/* Create shared memory space */
rs = apr_temp_dir_get(&tempdir, pconf);
if (rs != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rs, s,
+ ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, APLOGNO(02664)
"mod_lua IVM: Failed to find temporary directory");
return HTTP_INTERNAL_SERVER_ERROR;
}
@@ -2012,7 +2019,7 @@ static int lua_post_config(apr_pool_t *pconf, apr_pool_t *plog,
rs = apr_shm_create(&lua_ivm_shm, sizeof(apr_pool_t**),
(const char *) lua_ivm_shmfile, pconf);
if (rs != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rs, s,
+ ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, APLOGNO(02665)
"mod_lua: Failed to create shared memory segment on file %s",
lua_ivm_shmfile);
return HTTP_INTERNAL_SERVER_ERROR;
diff --git a/modules/mappers/mod_dir.c b/modules/mappers/mod_dir.c
index 2a359c7f..542236b5 100644
--- a/modules/mappers/mod_dir.c
+++ b/modules/mappers/mod_dir.c
@@ -262,7 +262,7 @@ static int fixup_dir(request_rec *r)
if (r->args != NULL) {
ifile = apr_pstrcat(r->pool, ap_escape_uri(r->pool, r->uri),
- "/", "?", r->args, NULL);
+ "/?", r->args, NULL);
}
else {
ifile = apr_pstrcat(r->pool, ap_escape_uri(r->pool, r->uri),
diff --git a/modules/mappers/mod_negotiation.c b/modules/mappers/mod_negotiation.c
index 5ec0d4d0..0089a6c9 100644
--- a/modules/mappers/mod_negotiation.c
+++ b/modules/mappers/mod_negotiation.c
@@ -1707,7 +1707,7 @@ static void set_language_quality(negotiation_state *neg, var_rec *variant)
* we are allowed to use the prefix of in HTTP/1.1
*/
char *lang = ((char **) (variant->content_languages->elts))[j];
- int idx = -1;
+ int idx;
/* If we wish to fallback or
* we use our own LanguagePriority index.
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index 2fe9bf9e..de0c11ba 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -4161,7 +4161,6 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
r->filename));
r->filename = apr_pstrcat(r->pool, "proxy:", r->filename, NULL);
- apr_table_setn(r->notes, "rewrite-proxy", "1");
return 1;
}
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
index b331a6c5..885a2c9e 100644
--- a/modules/proxy/mod_proxy.c
+++ b/modules/proxy/mod_proxy.c
@@ -174,6 +174,15 @@ static const char *set_worker_param(apr_pool_t *p,
return "DisableReuse must be On|Off";
worker->s->disablereuse_set = 1;
}
+ else if (!strcasecmp(key, "enablereuse")) {
+ if (!strcasecmp(val, "on"))
+ worker->s->disablereuse = 0;
+ else if (!strcasecmp(val, "off"))
+ worker->s->disablereuse = 1;
+ else
+ return "EnableReuse must be On|Off";
+ worker->s->disablereuse_set = 1;
+ }
else if (!strcasecmp(key, "route")) {
/* Worker route.
*/
@@ -548,9 +557,9 @@ static const char *proxy_interpolate(request_rec *r, const char *str)
return str;
}
/* OK, this is syntax we want to interpolate. Is there such a var ? */
- var = apr_pstrndup(r->pool, start+2, end-(start+2));
+ var = apr_pstrmemdup(r->pool, start+2, end-(start+2));
val = apr_table_get(r->subprocess_env, var);
- firstpart = apr_pstrndup(r->pool, str, (start-str));
+ firstpart = apr_pstrmemdup(r->pool, str, (start-str));
if (val == NULL) {
return apr_pstrcat(r->pool, firstpart,
@@ -938,7 +947,6 @@ static int proxy_handler(request_rec *r)
strncmp(r->filename, "proxy:", 6) != 0) {
r->proxyreq = PROXYREQ_REVERSE;
r->filename = apr_pstrcat(r->pool, r->handler, r->filename, NULL);
- apr_table_setn(r->notes, "rewrite-proxy", "1");
}
else {
return DECLINED;
@@ -1044,7 +1052,7 @@ static int proxy_handler(request_rec *r)
return HTTP_MOVED_PERMANENTLY;
}
- scheme = apr_pstrndup(r->pool, uri, p - uri);
+ scheme = apr_pstrmemdup(r->pool, uri, p - uri);
/* Check URI's destination host against NoProxy hosts */
/* Bypass ProxyRemote server lookup if configured as NoProxy */
for (direct_connect = i = 0; i < conf->dirconn->nelts &&
@@ -1461,23 +1469,23 @@ static const char *
return add_proxy(cmd, dummy, f1, r1, 1);
}
-static char *de_socketfy(apr_pool_t *p, char *url)
+PROXY_DECLARE(const char *) ap_proxy_de_socketfy(apr_pool_t *p, const char *url)
{
- char *ptr;
+ const char *ptr;
/*
* We could be passed a URL during the config stage that contains
* the UDS path... ignore it
*/
if (!strncasecmp(url, "unix:", 5) &&
- ((ptr = ap_strchr(url, '|')) != NULL)) {
+ ((ptr = ap_strchr_c(url, '|')) != NULL)) {
/* move past the 'unix:...|' UDS path info */
- char *ret, *c;
+ const char *ret, *c;
ret = ptr + 1;
/* special case: "unix:....|scheme:" is OK, expand
* to "unix:....|scheme://localhost"
* */
- c = ap_strchr(ret, ':');
+ c = ap_strchr_c(ret, ':');
if (c == NULL) {
return NULL;
}
@@ -1582,7 +1590,7 @@ static const char *
}
new->fake = apr_pstrdup(cmd->pool, f);
- new->real = apr_pstrdup(cmd->pool, de_socketfy(cmd->pool, r));
+ new->real = apr_pstrdup(cmd->pool, ap_proxy_de_socketfy(cmd->pool, r));
new->flags = flags;
if (use_regex) {
new->regex = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED);
@@ -1631,7 +1639,7 @@ static const char *
new->balancer = balancer;
}
else {
- proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, de_socketfy(cmd->pool, r));
+ proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, ap_proxy_de_socketfy(cmd->pool, r));
int reuse = 0;
if (!worker) {
const char *err = ap_proxy_define_worker(cmd->pool, &worker, NULL, conf, r, 0);
@@ -2110,7 +2118,7 @@ static const char *add_member(cmd_parms *cmd, void *dummy, const char *arg)
}
/* Try to find existing worker */
- worker = ap_proxy_get_worker(cmd->temp_pool, balancer, conf, de_socketfy(cmd->temp_pool, name));
+ worker = ap_proxy_get_worker(cmd->temp_pool, balancer, conf, ap_proxy_de_socketfy(cmd->temp_pool, name));
if (!worker) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01147)
"Defining worker '%s' for balancer '%s'",
@@ -2196,7 +2204,7 @@ static const char *
}
}
else {
- worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, de_socketfy(cmd->temp_pool, name));
+ worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, ap_proxy_de_socketfy(cmd->temp_pool, name));
if (!worker) {
if (in_proxy_section) {
err = ap_proxy_define_worker(cmd->pool, &worker, NULL,
@@ -2336,7 +2344,7 @@ static const char *proxysection(cmd_parms *cmd, void *mconfig, const char *arg)
}
else {
worker = ap_proxy_get_worker(cmd->temp_pool, NULL, sconf,
- de_socketfy(cmd->temp_pool, (char*)conf->p));
+ ap_proxy_de_socketfy(cmd->temp_pool, (char*)conf->p));
if (!worker) {
err = ap_proxy_define_worker(cmd->pool, &worker, NULL,
sconf, conf->p, 0);
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
index 4ead22e7..89f5c095 100644
--- a/modules/proxy/mod_proxy.h
+++ b/modules/proxy/mod_proxy.h
@@ -865,6 +865,17 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
proxy_conn_rec *conn,
proxy_worker *worker,
server_rec *s);
+
+/**
+ * Make a connection to a Unix Domain Socket (UDS) path
+ * @param sock UDS to connect
+ * @param uds_path UDS path to connect to
+ * @param p pool to make the sock addr
+ * @return APR_SUCCESS or error status
+ */
+PROXY_DECLARE(apr_status_t) ap_proxy_connect_uds(apr_socket_t *sock,
+ const char *uds_path,
+ apr_pool_t *p);
/**
* Make a connection record for backend connection
* @param proxy_function calling proxy scheme (http, ajp, ...)
@@ -1012,6 +1023,14 @@ int ap_proxy_lb_workers(void);
*/
PROXY_DECLARE(apr_port_t) ap_proxy_port_of_scheme(const char *scheme);
+/**
+ * Strip a unix domain socket (UDS) prefix from the input URL
+ * @param p pool to allocate result from
+ * @param url a URL potentially prefixed with a UDS path
+ * @return URL with the UDS prefix removed
+ */
+PROXY_DECLARE(const char *) ap_proxy_de_socketfy(apr_pool_t *p, const char *url);
+
extern module PROXY_DECLARE_DATA proxy_module;
#endif /*MOD_PROXY_H*/
diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c
index cf52a7d9..6a83aa2f 100644
--- a/modules/proxy/mod_proxy_ajp.c
+++ b/modules/proxy/mod_proxy_ajp.c
@@ -123,10 +123,7 @@ static apr_off_t get_content_length(request_rec * r)
{
apr_off_t len = 0;
- if (r->clength > 0) {
- return r->clength;
- }
- else if (r->main == NULL) {
+ if (r->main == NULL) {
const char *clp = apr_table_get(r->headers_in, "Content-Length");
if (clp) {
diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c
index acfd3861..f33aa936 100644
--- a/modules/proxy/mod_proxy_balancer.c
+++ b/modules/proxy/mod_proxy_balancer.c
@@ -98,7 +98,7 @@ static int proxy_balancer_canon(request_rec *r, char *url)
if (path == NULL)
return HTTP_BAD_REQUEST;
- r->filename = apr_pstrcat(r->pool, "proxy:", BALANCER_PREFIX, host,
+ r->filename = apr_pstrcat(r->pool, "proxy:" BALANCER_PREFIX, host,
"/", path, (search) ? "?" : "", (search) ? search : "", NULL);
r->path_info = apr_pstrcat(r->pool, "/", path, NULL);
diff --git a/modules/proxy/mod_proxy_connect.c b/modules/proxy/mod_proxy_connect.c
index 9a1bfefb..2a34a15b 100644
--- a/modules/proxy/mod_proxy_connect.c
+++ b/modules/proxy/mod_proxy_connect.c
@@ -210,7 +210,6 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
char buffer[HUGE_STRING_LEN];
apr_socket_t *client_socket = ap_get_conn_socket(c);
int failed, rc;
- int client_error = 0;
apr_pollset_t *pollset;
apr_pollfd_t pollfd;
const apr_pollfd_t *signalled;
@@ -320,7 +319,7 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
/* Add client side to the poll */
pollfd.p = r->pool;
pollfd.desc_type = APR_POLL_SOCKET;
- pollfd.reqevents = APR_POLLIN;
+ pollfd.reqevents = APR_POLLIN | APR_POLLHUP;
pollfd.desc.s = client_socket;
pollfd.client_data = NULL;
apr_pollset_add(pollset, &pollfd);
@@ -434,31 +433,35 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
if (cur->desc.s == sock) {
pollevent = cur->rtnevents;
- if (pollevent & APR_POLLIN) {
+ if (pollevent & (APR_POLLIN | APR_POLLHUP)) {
#ifdef DEBUGGING
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01025)
"sock was readable");
#endif
rv = proxy_connect_transfer(r, backconn, c, bb, "sock");
- }
- else if ((pollevent & APR_POLLERR)
- || (pollevent & APR_POLLHUP)) {
- rv = APR_EPIPE;
- ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(01026)
- "err/hup on backconn");
}
- if (rv != APR_SUCCESS)
- client_error = 1;
+ else if (pollevent & APR_POLLERR) {
+ rv = APR_EPIPE;
+ backconn->aborted = 1;
+ ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(01026)
+ "err on backconn");
+ }
}
else if (cur->desc.s == client_socket) {
pollevent = cur->rtnevents;
- if (pollevent & APR_POLLIN) {
+ if (pollevent & (APR_POLLIN | APR_POLLHUP)) {
#ifdef DEBUGGING
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01027)
"client was readable");
#endif
rv = proxy_connect_transfer(r, c, backconn, bb, "client");
}
+ else if (pollevent & APR_POLLERR) {
+ rv = APR_EPIPE;
+ c->aborted = 1;
+ ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(01026)
+ "err on client");
+ }
}
else {
rv = APR_EBADF;
@@ -481,12 +484,11 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
* Close the socket and clean up
*/
- if (client_error)
+ if (backconn->aborted)
apr_socket_close(sock);
else
ap_lingering_close(backconn);
- c->aborted = 1;
c->keepalive = AP_CONN_CLOSE;
return OK;
diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c
index e2fb59cd..f528b3df 100644
--- a/modules/proxy/mod_proxy_fcgi.c
+++ b/modules/proxy/mod_proxy_fcgi.c
@@ -20,6 +20,10 @@
module AP_MODULE_DECLARE_DATA proxy_fcgi_module;
+typedef struct {
+ int need_dirwalk;
+} fcgi_req_config_t;
+
/*
* Canonicalise http-like URLs.
* scheme is the scheme for the URL
@@ -29,8 +33,11 @@ module AP_MODULE_DECLARE_DATA proxy_fcgi_module;
static int proxy_fcgi_canon(request_rec *r, char *url)
{
char *host, sport[7];
- const char *err, *path;
+ const char *err;
+ char *path;
apr_port_t port, def_port;
+ fcgi_req_config_t *rconf = NULL;
+ const char *pathinfo_type = NULL;
if (strncasecmp(url, "fcgi:", 5) == 0) {
url += 5;
@@ -76,11 +83,51 @@ static int proxy_fcgi_canon(request_rec *r, char *url)
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01060)
"set r->filename to %s", r->filename);
- if (apr_table_get(r->subprocess_env, "proxy-fcgi-pathinfo")) {
- r->path_info = apr_pstrcat(r->pool, "/", path, NULL);
+ rconf = ap_get_module_config(r->request_config, &proxy_fcgi_module);
+ if (rconf == NULL) {
+ rconf = apr_pcalloc(r->pool, sizeof(fcgi_req_config_t));
+ ap_set_module_config(r->request_config, &proxy_fcgi_module, rconf);
+ }
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01061)
- "set r->path_info to %s", r->path_info);
+ if (NULL != (pathinfo_type = apr_table_get(r->subprocess_env, "proxy-fcgi-pathinfo"))) {
+ /* It has to be on disk for this to work */
+ if (!strcasecmp(pathinfo_type, "full")) {
+ rconf->need_dirwalk = 1;
+ ap_unescape_url_keep2f(path, 0);
+ }
+ else if (!strcasecmp(pathinfo_type, "first-dot")) {
+ char *split = ap_strchr(path, '.');
+ if (split) {
+ char *slash = ap_strchr(split, '/');
+ if (slash) {
+ r->path_info = apr_pstrdup(r->pool, slash);
+ ap_unescape_url_keep2f(r->path_info, 0);
+ *slash = '\0'; /* truncate path */
+ }
+ }
+ }
+ else if (!strcasecmp(pathinfo_type, "last-dot")) {
+ char *split = ap_strrchr(path, '.');
+ if (split) {
+ char *slash = ap_strchr(split, '/');
+ if (slash) {
+ r->path_info = apr_pstrdup(r->pool, slash);
+ ap_unescape_url_keep2f(r->path_info, 0);
+ *slash = '\0'; /* truncate path */
+ }
+ }
+ }
+ else {
+ /* before proxy-fcgi-pathinfo had multi-values. This requires the
+ * the FCGI server to fixup PATH_INFO because it's the entire path
+ */
+ r->path_info = apr_pstrcat(r->pool, "/", path, NULL);
+ if (!strcasecmp(pathinfo_type, "unescape")) {
+ ap_unescape_url_keep2f(r->path_info, 0);
+ }
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01061)
+ "set r->path_info to %s", r->path_info);
+ }
}
return OK;
@@ -204,9 +251,26 @@ static apr_status_t send_environment(proxy_conn_rec *conn, request_rec *r,
apr_status_t rv;
apr_size_t avail_len, len, required_len;
int next_elem, starting_elem;
+ char *proxyfilename = r->filename;
+ fcgi_req_config_t *rconf = ap_get_module_config(r->request_config, &proxy_fcgi_module);
+
+ if (rconf) {
+ if (rconf->need_dirwalk) {
+ ap_directory_walk(r);
+ }
+ }
+
+ /* Strip balancer prefix */
+ if (r->filename && !strncmp(r->filename, "proxy:balancer://", 17)) {
+ char *newfname = apr_pstrdup(r->pool, r->filename+17);
+ newfname = ap_strchr(newfname, '/');
+ r->filename = newfname;
+ }
ap_add_common_vars(r);
ap_add_cgi_vars(r);
+
+ r->filename = proxyfilename;
/* XXX are there any FastCGI specific env vars we need to send? */
@@ -308,13 +372,12 @@ enum {
*
* Returns 0 if it can't find the end of the headers, and 1 if it found the
* end of the headers. */
-static int handle_headers(request_rec *r,
- int *state,
- char *readbuf)
+static int handle_headers(request_rec *r, int *state,
+ const char *readbuf, apr_size_t readlen)
{
const char *itr = readbuf;
- while (*itr) {
+ while (readlen--) {
if (*itr == '\r') {
switch (*state) {
case HDR_STATE_GOT_CRLF:
@@ -368,7 +431,7 @@ static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf,
const char **err)
{
apr_bucket_brigade *ib, *ob;
- int seen_end_of_headers = 0, done = 0;
+ int seen_end_of_headers = 0, done = 0, ignore_body = 0;
apr_status_t rv = APR_SUCCESS;
int script_error_status = HTTP_OK;
conn_rec *c = r->connection;
@@ -561,7 +624,8 @@ recv_again:
APR_BRIGADE_INSERT_TAIL(ob, b);
if (! seen_end_of_headers) {
- int st = handle_headers(r, &header_state, iobuf);
+ int st = handle_headers(r, &header_state,
+ iobuf, readbuflen);
if (st == 1) {
int status;
@@ -577,9 +641,16 @@ recv_again:
APR_BRIGADE_INSERT_TAIL(ob, tmp_b);
r->status = status;
ap_pass_brigade(r->output_filters, ob);
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01070)
- "Error parsing script headers");
- rv = APR_EINVAL;
+ if (status == HTTP_NOT_MODIFIED) {
+ /* The 304 response MUST NOT contain
+ * a message-body, ignore it. */
+ ignore_body = 1;
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01070)
+ "Error parsing script headers");
+ rv = APR_EINVAL;
+ }
break;
}
@@ -598,7 +669,7 @@ recv_again:
}
if (script_error_status == HTTP_OK
- && !APR_BRIGADE_EMPTY(ob)) {
+ && !APR_BRIGADE_EMPTY(ob) && !ignore_body) {
/* Send the part of the body that we read while
* reading the headers.
*/
@@ -626,7 +697,7 @@ recv_again:
* but that could be a huge amount of data; so we pass
* along smaller chunks
*/
- if (script_error_status == HTTP_OK) {
+ if (script_error_status == HTTP_OK && !ignore_body) {
rv = ap_pass_brigade(r->output_filters, ob);
if (rv != APR_SUCCESS) {
*err = "passing brigade to output filters";
@@ -636,7 +707,7 @@ recv_again:
apr_brigade_cleanup(ob);
}
- /* If we didn't read all the data go back and get the
+ /* If we didn't read all the data, go back and get the
* rest of it. */
if (clen > readbuflen) {
clen -= readbuflen;
@@ -663,7 +734,7 @@ recv_again:
/* TODO: Should probably clean up this logging a bit... */
if (clen) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01071)
- "Got error '%s'", iobuf);
+ "Got error '%.*s'", (int)readbuflen, iobuf);
}
if (clen > readbuflen) {
@@ -681,12 +752,16 @@ recv_again:
"Got bogus record %d", type);
break;
}
+ /* Leave on above switch's inner error. */
+ if (rv != APR_SUCCESS) {
+ break;
+ }
if (plen) {
rv = get_data_full(conn, iobuf, plen);
if (rv != APR_SUCCESS) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
- APLOGNO(02537) "Error occurred reading padding");
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02537)
+ "Error occurred reading padding");
break;
}
}
@@ -714,7 +789,7 @@ static int fcgi_do_request(apr_pool_t *p, request_rec *r,
char *url, char *server_portstr)
{
/* Request IDs are arbitrary numbers that we assign to a
- * single request. This would allow multiplex/pipelinig of
+ * single request. This would allow multiplex/pipelining of
* multiple requests to the same FastCGI connection, but
* we don't support that, and always use a value of '1' to
* keep things simple. */
@@ -814,11 +889,15 @@ static int proxy_fcgi_handler(request_rec *r, proxy_worker *worker,
goto cleanup;
}
- /* XXX Setting close to 0 is a great way to end up with
- * timeouts at this point, since we lack good ways to manage the
- * back end fastcgi processes. This should be revisited when we
- * have a better story on that part of things. */
+ /* This scheme handler does not reuse connections by default, to
+ * avoid tieing up a fastcgi that isn't expecting to work on
+ * parallel requests. But if the user went out of their way to
+ * type the default value of disablereuse=off, we'll allow it.
+ */
backend->close = 1;
+ if (worker->s->disablereuse_set && !worker->s->disablereuse) {
+ backend->close = 0;
+ }
/* Step Two: Make the Connection */
if (ap_proxy_connect_backend(FCGI_SCHEME, backend, worker, r->server)) {
diff --git a/modules/proxy/mod_proxy_fdpass.c b/modules/proxy/mod_proxy_fdpass.c
index 26a7b13e..63cf4696 100644
--- a/modules/proxy/mod_proxy_fdpass.c
+++ b/modules/proxy/mod_proxy_fdpass.c
@@ -24,12 +24,6 @@
#error This module only works on unix platforms with the correct OS support
#endif
-#include "apr_version.h"
-#if APR_MAJOR_VERSION < 2
-/* for apr_wait_for_io_or_timeout */
-#include "apr_support.h"
-#endif
-
#include "mod_proxy_fdpass.h"
module AP_MODULE_DECLARE_DATA proxy_fdpass_module;
@@ -54,54 +48,10 @@ static int proxy_fdpass_canon(request_rec *r, char *url)
return OK;
}
-/* TODO: In APR 2.x: Extend apr_sockaddr_t to possibly be a path !!! */
-static apr_status_t socket_connect_un(apr_socket_t *sock,
- struct sockaddr_un *sa)
-{
- apr_status_t rv;
- apr_os_sock_t rawsock;
- apr_interval_time_t t;
-
- rv = apr_os_sock_get(&rawsock, sock);
- if (rv != APR_SUCCESS) {
- return rv;
- }
-
- rv = apr_socket_timeout_get(sock, &t);
- if (rv != APR_SUCCESS) {
- return rv;
- }
-
- do {
- rv = connect(rawsock, (struct sockaddr*)sa,
- sizeof(*sa) + strlen(sa->sun_path));
- } while (rv == -1 && errno == EINTR);
-
- if ((rv == -1) && (errno == EINPROGRESS || errno == EALREADY)
- && (t > 0)) {
-#if APR_MAJOR_VERSION < 2
- rv = apr_wait_for_io_or_timeout(NULL, sock, 0);
-#else
- rv = apr_socket_wait(sock, APR_WAIT_WRITE);
-#endif
-
- if (rv != APR_SUCCESS) {
- return rv;
- }
- }
-
- if (rv == -1 && errno != EISCONN) {
- return errno;
- }
-
- return APR_SUCCESS;
-}
-
static apr_status_t get_socket_from_path(apr_pool_t *p,
const char* path,
apr_socket_t **out_sock)
{
- struct sockaddr_un sa;
apr_socket_t *s;
apr_status_t rv;
*out_sock = NULL;
@@ -112,10 +62,7 @@ static apr_status_t get_socket_from_path(apr_pool_t *p,
return rv;
}
- sa.sun_family = AF_UNIX;
- apr_cpystrn(sa.sun_path, path, sizeof(sa.sun_path));
-
- rv = socket_connect_un(s, &sa);
+ rv = ap_proxy_connect_uds(s, path, p);
if (rv != APR_SUCCESS) {
return rv;
}
diff --git a/modules/proxy/mod_proxy_ftp.c b/modules/proxy/mod_proxy_ftp.c
index cf5d5130..5c689aa1 100644
--- a/modules/proxy/mod_proxy_ftp.c
+++ b/modules/proxy/mod_proxy_ftp.c
@@ -275,8 +275,7 @@ static apr_status_t ftp_string_read(conn_rec *c, apr_bucket_brigade *bb,
pos += len;
}
}
- APR_BUCKET_REMOVE(e);
- apr_bucket_destroy(e);
+ apr_bucket_delete(e);
}
*pos = '\0';
}
@@ -448,7 +447,7 @@ static apr_status_t proxy_send_dir_filter(ap_filter_t *f,
apr_bucket_brigade *out = apr_brigade_create(p, c->bucket_alloc);
apr_status_t rv;
- register int n;
+ int n;
char *dir, *path, *reldir, *site, *str, *type;
const char *pwd = apr_table_get(r->notes, "Directory-PWD");
@@ -634,8 +633,7 @@ static apr_status_t proxy_send_dir_filter(ap_filter_t *f,
/* len+1 to leave space for the trailing nil char */
apr_cpystrn(ctx->buffer+strlen(ctx->buffer), response, len+1);
- APR_BUCKET_REMOVE(e);
- apr_bucket_destroy(e);
+ apr_bucket_delete(e);
}
/* EOS? jump to footer */
@@ -1767,39 +1765,39 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
r, origin, bb, &ftpmessage);
/* then extract the Last-Modified time from it (YYYYMMDDhhmmss or YYYYMMDDhhmmss.xxx GMT). */
if (rc == 213) {
- struct {
- char YYYY[4+1];
- char MM[2+1];
- char DD[2+1];
- char hh[2+1];
- char mm[2+1];
- char ss[2+1];
- } time_val;
- if (6 == sscanf(ftpmessage, "%4[0-9]%2[0-9]%2[0-9]%2[0-9]%2[0-9]%2[0-9]",
- time_val.YYYY, time_val.MM, time_val.DD, time_val.hh, time_val.mm, time_val.ss)) {
+ struct {
+ char YYYY[4+1];
+ char MM[2+1];
+ char DD[2+1];
+ char hh[2+1];
+ char mm[2+1];
+ char ss[2+1];
+ } time_val;
+ if (6 == sscanf(ftpmessage, "%4[0-9]%2[0-9]%2[0-9]%2[0-9]%2[0-9]%2[0-9]",
+ time_val.YYYY, time_val.MM, time_val.DD, time_val.hh, time_val.mm, time_val.ss)) {
struct tm tms;
- memset (&tms, '\0', sizeof tms);
- tms.tm_year = atoi(time_val.YYYY) - 1900;
- tms.tm_mon = atoi(time_val.MM) - 1;
- tms.tm_mday = atoi(time_val.DD);
- tms.tm_hour = atoi(time_val.hh);
- tms.tm_min = atoi(time_val.mm);
- tms.tm_sec = atoi(time_val.ss);
+ memset (&tms, '\0', sizeof tms);
+ tms.tm_year = atoi(time_val.YYYY) - 1900;
+ tms.tm_mon = atoi(time_val.MM) - 1;
+ tms.tm_mday = atoi(time_val.DD);
+ tms.tm_hour = atoi(time_val.hh);
+ tms.tm_min = atoi(time_val.mm);
+ tms.tm_sec = atoi(time_val.ss);
#ifdef HAVE_TIMEGM /* Does system have timegm()? */
- mtime = timegm(&tms);
- mtime *= APR_USEC_PER_SEC;
+ mtime = timegm(&tms);
+ mtime *= APR_USEC_PER_SEC;
#elif HAVE_GMTOFF /* does struct tm have a member tm_gmtoff? */
/* mktime will subtract the local timezone, which is not what we want.
- * Add it again because the MDTM string is GMT
- */
- mtime = mktime(&tms);
- mtime += tms.tm_gmtoff;
- mtime *= APR_USEC_PER_SEC;
+ * Add it again because the MDTM string is GMT
+ */
+ mtime = mktime(&tms);
+ mtime += tms.tm_gmtoff;
+ mtime *= APR_USEC_PER_SEC;
#else
- mtime = 0L;
+ mtime = 0L;
#endif
}
- }
+ }
#endif /* USE_MDTM */
/* FIXME: Handle range requests - send REST */
buf = apr_pstrcat(p, "RETR ", ftp_escape_globbingchars(p, path, fdconf), CRLF, NULL);
diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c
index 141452bf..98a93dd2 100644
--- a/modules/proxy/mod_proxy_http.c
+++ b/modules/proxy/mod_proxy_http.c
@@ -687,7 +687,6 @@ static apr_status_t proxy_buckets_lifetime_transform(request_rec *r,
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00964)
"Unhandled bucket type of type %s in"
" proxy_buckets_lifetime_transform", e->type->name);
- apr_bucket_delete(e);
rv = APR_EGENERAL;
}
}
@@ -750,14 +749,8 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r,
if (!r->kept_body && r->main) {
/* XXX: Why DON'T sub-requests use keepalives? */
p_conn->close = 1;
- if (old_cl_val) {
- old_cl_val = NULL;
- apr_table_unset(r->headers_in, "Content-Length");
- }
- if (old_te_val) {
- old_te_val = NULL;
- apr_table_unset(r->headers_in, "Transfer-Encoding");
- }
+ old_cl_val = NULL;
+ old_te_val = NULL;
rb_method = RB_STREAM_CL;
e = apr_bucket_eos_create(input_brigade->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(input_brigade, e);
@@ -783,7 +776,6 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r,
"client %s (%s) requested Transfer-Encoding "
"chunked body with Content-Length (C-L ignored)",
c->client_ip, c->remote_host ? c->remote_host: "");
- apr_table_unset(r->headers_in, "Content-Length");
old_cl_val = NULL;
origin->keepalive = AP_CONN_CLOSE;
p_conn->close = 1;
@@ -1011,8 +1003,11 @@ static request_rec *make_fake_req(conn_rec *c, request_rec *r)
rp->status = HTTP_OK;
rp->headers_in = apr_table_make(pool, 50);
+ rp->trailers_in = apr_table_make(pool, 5);
+
rp->subprocess_env = apr_table_make(pool, 50);
rp->headers_out = apr_table_make(pool, 12);
+ rp->trailers_out = apr_table_make(pool, 5);
rp->err_headers_out = apr_table_make(pool, 5);
rp->notes = apr_table_make(pool, 5);
@@ -1093,6 +1088,7 @@ static void ap_proxy_read_headers(request_rec *r, request_rec *rr,
psc = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
r->headers_out = apr_table_make(r->pool, 20);
+ r->trailers_out = apr_table_make(r->pool, 5);
*pread_len = 0;
/*
@@ -1223,6 +1219,14 @@ apr_status_t ap_proxygetline(apr_bucket_brigade *bb, char *s, int n, request_rec
#define AP_MAX_INTERIM_RESPONSES 10
#endif
+static int add_trailers(void *data, const char *key, const char *val)
+{
+ if (val) {
+ apr_table_add((apr_table_t*)data, key, val);
+ }
+ return 1;
+}
+
static
apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
proxy_conn_rec **backend_ptr,
@@ -1640,6 +1644,18 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
if (!r->header_only && /* not HEAD request */
(proxy_status != HTTP_NO_CONTENT) && /* not 204 */
(proxy_status != HTTP_NOT_MODIFIED)) { /* not 304 */
+ const char *tmp;
+ /* Add minimal headers needed to allow http_in filter
+ * detecting end of body without waiting for a timeout. */
+ if ((tmp = apr_table_get(r->headers_out, "Transfer-Encoding"))) {
+ apr_table_set(backend->r->headers_in, "Transfer-Encoding", tmp);
+ }
+ else if ((tmp = apr_table_get(r->headers_out, "Content-Length"))) {
+ apr_table_set(backend->r->headers_in, "Content-Length", tmp);
+ }
+ else if (te) {
+ apr_table_set(backend->r->headers_in, "Transfer-Encoding", te);
+ }
ap_discard_request_body(backend->r);
}
return proxy_status;
@@ -1735,6 +1751,12 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
/* next time try a non-blocking read */
mode = APR_NONBLOCK_READ;
+ if (!apr_is_empty_table(backend->r->trailers_in)) {
+ apr_table_do(add_trailers, r->trailers_out,
+ backend->r->trailers_in, NULL);
+ apr_table_clear(backend->r->trailers_in);
+ }
+
apr_brigade_length(bb, 0, &readbytes);
backend->worker->s->read += readbytes;
#if DEBUGGING
diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c
index a2172fe2..1eb6ac89 100644
--- a/modules/proxy/mod_proxy_wstunnel.c
+++ b/modules/proxy/mod_proxy_wstunnel.c
@@ -141,40 +141,17 @@ static int proxy_wstunnel_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o,
return rv;
}
-/* Search thru the input filters and remove the reqtimeout one */
-static void remove_reqtimeout(ap_filter_t *next)
-{
- ap_filter_t *reqto = NULL;
- ap_filter_rec_t *filter;
-
- filter = ap_get_input_filter_handle("reqtimeout");
- if (!filter) {
- return;
- }
-
- while (next) {
- if (next->frec == filter) {
- reqto = next;
- break;
- }
- next = next->next;
- }
- if (reqto) {
- ap_remove_input_filter(reqto);
- }
-}
-
/*
* process the request and write the response.
*/
-static int ap_proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
+static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
proxy_conn_rec *conn,
proxy_worker *worker,
proxy_server_conf *conf,
apr_uri_t *uri,
char *url, char *server_portstr)
{
- apr_status_t rv = APR_SUCCESS;
+ apr_status_t rv;
apr_pollset_t *pollset;
apr_pollfd_t pollfd;
const apr_pollfd_t *signalled;
@@ -236,7 +213,7 @@ static int ap_proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
pollfd.desc.s = client_socket;
apr_pollset_add(pollset, &pollfd);
- remove_reqtimeout(c->input_filters);
+ ap_remove_input_filter_byhandle(c->input_filters, "reqtimeout");
r->output_filters = c->output_filters;
r->proto_output_filters = c->output_filters;
@@ -271,6 +248,7 @@ static int ap_proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
}
else if (pollevent & APR_POLLERR) {
rv = APR_EPIPE;
+ backconn->aborted = 1;
ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02447)
"error on backconn");
}
@@ -394,7 +372,7 @@ static int proxy_wstunnel_handler(request_rec *r, proxy_worker *worker,
/* Step Three: Process the Request */
- status = ap_proxy_wstunnel_request(p, r, backend, worker, conf, uri, locurl,
+ status = proxy_wstunnel_request(p, r, backend, worker, conf, uri, locurl,
server_portstr);
break;
}
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index bc840499..83131c12 100644
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -940,7 +940,7 @@ PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r,
part = url;
}
}
- if (l1 >= l2 && strncasecmp(real, part, l2) == 0) {
+ if (l2 > 0 && l1 >= l2 && strncasecmp(real, part, l2) == 0) {
u = apr_pstrcat(r->pool, ent[i].fake, &part[l2], NULL);
return ap_is_url(u) ? u : ap_construct_url(r->pool, u, r);
}
@@ -1528,6 +1528,8 @@ PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p,
return NULL;
}
+ url = ap_proxy_de_socketfy(p, url);
+
c = ap_strchr_c(url, ':');
if (c == NULL || c[1] != '/' || c[2] != '/' || c[3] == '\0') {
return NULL;
@@ -1683,9 +1685,13 @@ PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p,
memset(wshared, 0, sizeof(proxy_worker_shared));
+ if (uri.port && uri.port == ap_proxy_port_of_scheme(uri.scheme)) {
+ uri.port = 0;
+ }
ptr = apr_uri_unparse(p, &uri, APR_URI_UNP_REVEALPASSWORD);
if (PROXY_STRNCPY(wshared->name, ptr) != APR_SUCCESS) {
- return apr_psprintf(p, "worker name (%s) too long", ptr);
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(02808)
+ "Alert! worker name (%s) too long; truncated to: %s", ptr, wshared->name);
}
if (PROXY_STRNCPY(wshared->scheme, uri.scheme) != APR_SUCCESS) {
return apr_psprintf(p, "worker scheme (%s) too long", uri.scheme);
@@ -1897,6 +1903,40 @@ static int ap_proxy_retry_worker(const char *proxy_function, proxy_worker *worke
}
}
+/*
+ * In the case of the reverse proxy, we need to see if we
+ * were passed a UDS url (eg: from mod_proxy) and adjust uds_path
+ * as required.
+ */
+static void fix_uds_filename(request_rec *r, char **url)
+{
+ char *ptr, *ptr2;
+ if (!r || !r->filename) return;
+
+ if (!strncmp(r->filename, "proxy:", 6) &&
+ (ptr2 = ap_strcasestr(r->filename, "unix:")) &&
+ (ptr = ap_strchr(ptr2, '|'))) {
+ apr_uri_t urisock;
+ apr_status_t rv;
+ *ptr = '\0';
+ rv = apr_uri_parse(r->pool, ptr2, &urisock);
+ if (rv == APR_SUCCESS) {
+ char *rurl = ptr+1;
+ char *sockpath = ap_runtime_dir_relative(r->pool, urisock.path);
+ apr_table_setn(r->notes, "uds_path", sockpath);
+ *url = apr_pstrdup(r->pool, rurl); /* so we get the scheme for the uds */
+ /* r->filename starts w/ "proxy:", so add after that */
+ memmove(r->filename+6, rurl, strlen(rurl)+1);
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
+ "*: rewrite of url due to UDS(%s): %s (%s)",
+ sockpath, *url, r->filename);
+ }
+ else {
+ *ptr = '|';
+ }
+ }
+}
+
PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
proxy_balancer **balancer,
request_rec *r,
@@ -1911,8 +1951,8 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
"%s: found worker %s for %s",
(*worker)->s->scheme, (*worker)->s->name, *url);
-
*balancer = NULL;
+ fix_uds_filename(r, url);
access_status = OK;
}
else if (r->proxyreq == PROXYREQ_PROXY) {
@@ -1932,10 +1972,8 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
}
else if (r->proxyreq == PROXYREQ_REVERSE) {
if (conf->reverse) {
- char *ptr;
- char *ptr2;
ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
- "*: found reverse proxy worker for %s", *url);
+ "*: using default reverse proxy worker for %s (no keepalive)", *url);
*balancer = NULL;
*worker = conf->reverse;
access_status = OK;
@@ -1945,36 +1983,7 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
* regarding the Connection header in the request.
*/
apr_table_setn(r->subprocess_env, "proxy-nokeepalive", "1");
- /*
- * In the case of the generic reverse proxy, we need to see if we
- * were passed a UDS url (eg: from mod_proxy) and adjust uds_path
- * as required.
- *
- * NOTE: Here we use a quick note lookup, but we could also
- * check to see if r->filename starts with 'proxy:'
- */
- if (apr_table_get(r->notes, "rewrite-proxy") &&
- (ptr2 = ap_strcasestr(r->filename, "unix:")) &&
- (ptr = ap_strchr(ptr2, '|'))) {
- apr_uri_t urisock;
- apr_status_t rv;
- *ptr = '\0';
- rv = apr_uri_parse(r->pool, ptr2, &urisock);
- if (rv == APR_SUCCESS) {
- char *rurl = ptr+1;
- char *sockpath = ap_runtime_dir_relative(r->pool, urisock.path);
- apr_table_setn(r->notes, "uds_path", sockpath);
- *url = apr_pstrdup(r->pool, rurl); /* so we get the scheme for the uds */
- /* r->filename starts w/ "proxy:", so add after that */
- memmove(r->filename+6, rurl, strlen(rurl)+1);
- ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
- "*: rewrite of url due to UDS(%s): %s (%s)",
- sockpath, *url, r->filename);
- }
- else {
- *ptr = '|';
- }
- }
+ fix_uds_filename(r, url);
}
}
}
@@ -2493,6 +2502,7 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
nbytes += apr_snprintf(buffer + nbytes, sizeof(buffer) - nbytes,
"Proxy-agent: %s" CRLF CRLF,
ap_get_server_banner());
+ ap_xlate_proto_to_ascii(buffer, nbytes);
apr_socket_send(backend->sock, buffer, &nbytes);
/* Receive the whole CONNECT response */
@@ -2504,7 +2514,8 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
len += nbytes;
left -= nbytes;
buffer[len] = '\0';
- if (strstr(buffer + len - nbytes, "\r\n\r\n") != NULL) {
+ if (strstr(buffer + len - nbytes, CRLF_ASCII CRLF_ASCII) != NULL) {
+ ap_xlate_proto_from_ascii(buffer, len);
complete = 1;
break;
}
@@ -2516,7 +2527,7 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
status = apr_socket_recv(backend->sock, drain_buffer, &nbytes);
drain_buffer[nbytes] = '\0';
nbytes = sizeof(drain_buffer) - 1;
- if (strstr(drain_buffer, "\r\n\r\n") != NULL) {
+ if (strstr(drain_buffer, CRLF_ASCII CRLF_ASCII) != NULL) {
break;
}
}
@@ -2524,7 +2535,7 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
/* Check for HTTP_OK response status */
if (status == APR_SUCCESS) {
- int major, minor;
+ unsigned int major, minor;
/* Only scan for three character status code */
char code_str[4];
@@ -2542,7 +2553,7 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00950)
"send_http_connect: the forward proxy returned code is '%s'",
code_str);
- status = APR_INCOMPLETE;
+ status = APR_INCOMPLETE;
}
}
}
@@ -2552,13 +2563,16 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
#if APR_HAVE_SYS_UN_H
-/* lifted from mod_proxy_fdpass.c; tweaked addrlen in connect() call */
-static apr_status_t socket_connect_un(apr_socket_t *sock,
- struct sockaddr_un *sa)
+/* TODO: In APR 2.x: Extend apr_sockaddr_t to possibly be a path !!! */
+PROXY_DECLARE(apr_status_t) ap_proxy_connect_uds(apr_socket_t *sock,
+ const char *uds_path,
+ apr_pool_t *p)
{
apr_status_t rv;
apr_os_sock_t rawsock;
apr_interval_time_t t;
+ struct sockaddr_un *sa;
+ apr_socklen_t addrlen, pathlen;
rv = apr_os_sock_get(&rawsock, sock);
if (rv != APR_SUCCESS) {
@@ -2570,29 +2584,30 @@ static apr_status_t socket_connect_un(apr_socket_t *sock,
return rv;
}
+ pathlen = strlen(uds_path);
+ /* copy the UDS path (including NUL) to the sockaddr_un */
+ addrlen = APR_OFFSETOF(struct sockaddr_un, sun_path) + pathlen;
+ sa = (struct sockaddr_un *)apr_palloc(p, addrlen + 1);
+ memcpy(sa->sun_path, uds_path, pathlen + 1);
+ sa->sun_family = AF_UNIX;
+
do {
- const socklen_t addrlen = APR_OFFSETOF(struct sockaddr_un, sun_path)
- + strlen(sa->sun_path) + 1;
rv = connect(rawsock, (struct sockaddr*)sa, addrlen);
- } while (rv == -1 && errno == EINTR);
+ } while (rv == -1 && (rv = errno) == EINTR);
- if ((rv == -1) && (errno == EINPROGRESS || errno == EALREADY)
- && (t > 0)) {
+ if (rv && rv != EISCONN) {
+ if ((rv == EINPROGRESS || rv == EALREADY) && (t > 0)) {
#if APR_MAJOR_VERSION < 2
- rv = apr_wait_for_io_or_timeout(NULL, sock, 0);
+ rv = apr_wait_for_io_or_timeout(NULL, sock, 0);
#else
- rv = apr_socket_wait(sock, APR_WAIT_WRITE);
+ rv = apr_socket_wait(sock, APR_WAIT_WRITE);
#endif
-
+ }
if (rv != APR_SUCCESS) {
return rv;
}
}
- if (rv == -1 && errno != EISCONN) {
- return errno;
- }
-
return APR_SUCCESS;
}
#endif
@@ -2625,8 +2640,6 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
#if APR_HAVE_SYS_UN_H
if (conn->uds_path)
{
- struct sockaddr_un sa;
-
rv = apr_socket_create(&newsock, AF_UNIX, SOCK_STREAM, 0,
conn->scpool);
if (rv != APR_SUCCESS) {
@@ -2640,10 +2653,7 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
}
conn->connection = NULL;
- sa.sun_family = AF_UNIX;
- apr_cpystrn(sa.sun_path, conn->uds_path, sizeof(sa.sun_path));
-
- rv = socket_connect_un(newsock, &sa);
+ rv = ap_proxy_connect_uds(newsock, conn->uds_path, conn->scpool);
if (rv != APR_SUCCESS) {
apr_socket_close(newsock);
ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(02454)
@@ -2654,6 +2664,13 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
worker->s->hostname);
break;
}
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02823)
+ "%s: connection established with Unix domain socket "
+ "%s (%s)",
+ proxy_function,
+ conn->uds_path,
+ worker->s->hostname);
}
else
#endif
@@ -2746,6 +2763,12 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
backend_addr = backend_addr->next;
continue;
}
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02824)
+ "%s: connection established with %pI (%s)",
+ proxy_function,
+ backend_addr,
+ worker->s->hostname);
}
/* Set a timeout on the socket */
@@ -2817,6 +2840,33 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
return connected ? OK : DECLINED;
}
+static apr_status_t connection_shutdown(void *theconn)
+{
+ proxy_conn_rec *conn = (proxy_conn_rec *)theconn;
+ conn_rec *c = conn->connection;
+ if (c) {
+ if (!c->aborted) {
+ apr_interval_time_t saved_timeout = 0;
+ apr_socket_timeout_get(conn->sock, &saved_timeout);
+ if (saved_timeout) {
+ apr_socket_timeout_set(conn->sock, 0);
+ }
+
+ (void)ap_shutdown_conn(c, 0);
+ c->aborted = 1;
+
+ if (saved_timeout) {
+ apr_socket_timeout_set(conn->sock, saved_timeout);
+ }
+ }
+
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02642)
+ "proxy: connection shutdown");
+ }
+ return APR_SUCCESS;
+}
+
+
PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
proxy_conn_rec *conn,
conn_rec *c,
@@ -2889,6 +2939,11 @@ PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
}
apr_socket_timeout_set(conn->sock, current_timeout);
+ /* Shutdown the connection before closing it (eg. SSL connections
+ * need to be close-notify-ed).
+ */
+ apr_pool_pre_cleanup_register(conn->scpool, conn, connection_shutdown);
+
return OK;
}
@@ -3202,7 +3257,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
char *buf;
const apr_array_header_t *headers_in_array;
const apr_table_entry_t *headers_in;
- apr_table_t *headers_in_copy;
+ apr_table_t *saved_headers_in;
apr_bucket *e;
int do_100_continue;
conn_rec *origin = p_conn->connection;
@@ -3274,6 +3329,21 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(header_brigade, e);
+ /*
+ * Save the original headers in here and restore them when leaving, since
+ * we will apply proxy purpose only modifications (eg. clearing hop-by-hop
+ * headers, add Via or X-Forwarded-* or Expect...), whereas the originals
+ * will be needed later to prepare the correct response and logging.
+ *
+ * Note: We need to take r->pool for apr_table_copy as the key / value
+ * pairs in r->headers_in have been created out of r->pool and
+ * p might be (and actually is) a longer living pool.
+ * This would trigger the bad pool ancestry abort in apr_table_copy if
+ * apr is compiled with APR_POOL_DEBUG.
+ */
+ saved_headers_in = r->headers_in;
+ r->headers_in = apr_table_copy(r->pool, saved_headers_in);
+
/* handle Via */
if (conf->viaopt == via_block) {
/* Block all outgoing Via: headers */
@@ -3372,21 +3442,10 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
}
proxy_run_fixups(r);
- /*
- * Make a copy of the headers_in table before clearing the connection
- * headers as we need the connection headers later in the http output
- * filter to prepare the correct response headers.
- *
- * Note: We need to take r->pool for apr_table_copy as the key / value
- * pairs in r->headers_in have been created out of r->pool and
- * p might be (and actually is) a longer living pool.
- * This would trigger the bad pool ancestry abort in apr_table_copy if
- * apr is compiled with APR_POOL_DEBUG.
- */
- headers_in_copy = apr_table_copy(r->pool, r->headers_in);
- ap_proxy_clear_connection(r, headers_in_copy);
+ ap_proxy_clear_connection(r, r->headers_in);
+
/* send request headers */
- headers_in_array = apr_table_elts(headers_in_copy);
+ headers_in_array = apr_table_elts(r->headers_in);
headers_in = (const apr_table_entry_t *) headers_in_array->elts;
for (counter = 0; counter < headers_in_array->nelts; counter++) {
if (headers_in[counter].key == NULL
@@ -3432,7 +3491,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
/* for sub-requests, ignore freshness/expiry headers */
if (r->main) {
- if ( !strcasecmp(headers_in[counter].key, "If-Match")
+ if ( !strcasecmp(headers_in[counter].key, "If-Match")
|| !strcasecmp(headers_in[counter].key, "If-Modified-Since")
|| !strcasecmp(headers_in[counter].key, "If-Range")
|| !strcasecmp(headers_in[counter].key, "If-Unmodified-Since")
@@ -3448,6 +3507,11 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(header_brigade, e);
}
+
+ /* Restore the original headers in (see comment above),
+ * we won't modify them anymore.
+ */
+ r->headers_in = saved_headers_in;
return OK;
}
diff --git a/modules/slotmem/mod_slotmem_shm.c b/modules/slotmem/mod_slotmem_shm.c
index b6cfa0a2..d0106992 100644
--- a/modules/slotmem/mod_slotmem_shm.c
+++ b/modules/slotmem/mod_slotmem_shm.c
@@ -213,19 +213,19 @@ static apr_status_t restore_slotmem(void *ptr, const char *name, apr_size_t size
rv = APR_SUCCESS;
apr_md5(digest2, ptr, nbytes);
if (memcmp(digest, digest2, APR_MD5_DIGESTSIZE)) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
APLOGNO(02551) "bad md5 match");
rv = APR_EGENERAL;
}
}
}
else {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
APLOGNO(02552) "at EOF... bypassing md5 match check (old persist file?)");
}
}
else if (nbytes != size) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
APLOGNO(02553) "Expected %" APR_SIZE_T_FMT ": Read %" APR_SIZE_T_FMT,
size, nbytes);
rv = APR_EGENERAL;
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c
index 316dc650..63852d07 100644
--- a/modules/ssl/mod_ssl.c
+++ b/modules/ssl/mod_ssl.c
@@ -138,6 +138,9 @@ static const command_rec ssl_config_cmds[] = {
SSL_CMD_SRV(Compression, FLAG,
"Enable SSL level compression "
"(`on', `off')")
+ SSL_CMD_SRV(SessionTickets, FLAG,
+ "Enable or disable TLS session tickets"
+ "(`on', `off')")
SSL_CMD_SRV(InsecureRenegotiation, FLAG,
"Enable support for insecure renegotiation")
SSL_CMD_ALL(UserName, TAKE1,
@@ -299,9 +302,12 @@ static apr_status_t ssl_cleanup_pre_config(void *data)
#endif
ERR_remove_state(0);
- /* Don't call ERR_free_strings here; ERR_load_*_strings only
- * actually load the error strings once per process due to static
+ /* Don't call ERR_free_strings in earlier versions, ERR_load_*_strings only
+ * actually loaded the error strings once per process due to static
* variable abuse in OpenSSL. */
+#if (OPENSSL_VERSION_NUMBER >= 0x00090805f)
+ ERR_free_strings();
+#endif
/* Also don't call CRYPTO_cleanup_all_ex_data here; any registered
* ex_data indices may have been cached in static variables in
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
index e1470d1b..e3c147ad 100644
--- a/modules/ssl/ssl_engine_config.c
+++ b/modules/ssl/ssl_engine_config.c
@@ -222,6 +222,7 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
#ifndef OPENSSL_NO_COMP
sc->compression = UNSET;
#endif
+ sc->session_tickets = UNSET;
modssl_ctx_init_proxy(sc, p);
@@ -394,6 +395,7 @@ void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
#ifndef OPENSSL_NO_COMP
cfgMergeBool(compression);
#endif
+ cfgMergeBool(session_tickets);
modssl_ctx_cfg_merge_proxy(p, base->proxy, add->proxy, mrg->proxy);
@@ -760,6 +762,17 @@ const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag)
#endif
}
+const char *ssl_cmd_SSLSessionTickets(cmd_parms *cmd, void *dcfg, int flag)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+#ifndef SSL_OP_NO_TICKET
+ return "This version of OpenSSL does not support using "
+ "SSLSessionTickets.";
+#endif
+ sc->session_tickets = flag ? TRUE : FALSE;
+ return NULL;
+}
+
const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag)
{
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index ef2185d2..63e89578 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -272,7 +272,7 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
return HTTP_INTERNAL_SERVER_ERROR;
}
#ifdef HAVE_OCSP_STAPLING
- ssl_stapling_ex_init();
+ ssl_stapling_certinfo_hash_init(p);
#endif
/*
@@ -553,6 +553,16 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
}
#endif
+#ifdef SSL_OP_NO_TICKET
+ /*
+ * Configure using RFC 5077 TLS session tickets
+ * for session resumption.
+ */
+ if (sc->session_tickets == FALSE) {
+ SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
+ }
+#endif
+
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
if (sc->insecure_reneg == TRUE) {
SSL_CTX_set_options(ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
@@ -1039,7 +1049,7 @@ static apr_status_t ssl_init_server_certs(server_rec *s,
if (!(cert = SSL_CTX_get0_certificate(mctx->ssl_ctx))) {
#else
ssl = SSL_new(mctx->ssl_ctx);
- if (ssl) {
+ if (ssl) {
/* Workaround bug in SSL_get_certificate in OpenSSL 0.9.8y */
SSL_set_connect_state(ssl);
cert = SSL_get_certificate(ssl);
@@ -1067,7 +1077,7 @@ static apr_status_t ssl_init_server_certs(server_rec *s,
* later, we defer to the code in ssl_init_server_ctx.
*/
if ((mctx->stapling_enabled == TRUE) &&
- !ssl_stapling_init_cert(s, mctx, cert)) {
+ !ssl_stapling_init_cert(s, p, ptemp, mctx, cert)) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02567)
"Unable to configure certificate %s for stapling",
key_id);
@@ -1425,7 +1435,8 @@ static apr_status_t ssl_init_server_ctx(server_rec *s,
SSL_CERT_SET_FIRST);
while (ret) {
cert = SSL_CTX_get0_certificate(sc->server->ssl_ctx);
- if (!cert || !ssl_stapling_init_cert(s, sc->server, cert)) {
+ if (!cert || !ssl_stapling_init_cert(s, p, ptemp, sc->server,
+ cert)) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02604)
"Unable to configure certificate %s:%d "
"for stapling", sc->vhost_id, i);
@@ -1542,7 +1553,7 @@ apr_status_t ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
klen = strlen(key);
if ((ps = (server_rec *)apr_hash_get(table, key, klen))) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO(02662)
"Init: SSL server IP/port conflict: "
"%s (%s:%d) vs. %s (%s:%d)",
ssl_util_vhostid(p, s),
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
index 7f60cc27..9dd181e0 100644
--- a/modules/ssl/ssl_engine_io.c
+++ b/modules/ssl/ssl_engine_io.c
@@ -1090,7 +1090,7 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx)
"request to '%s'", hostname_note);
ssl_log_ssl_error(SSLLOG_MARK, APLOG_WARNING, server);
}
- }
+ }
#endif
if ((n = SSL_connect(filter_ctx->pssl)) <= 0) {
@@ -1928,8 +1928,14 @@ void ssl_io_filter_init(conn_rec *c, request_rec *r, SSL *ssl)
ssl_io_filter_cleanup, apr_pool_cleanup_null);
if (APLOG_CS_IS_LEVEL(c, mySrvFromConn(c), APLOG_TRACE4)) {
- BIO_set_callback(SSL_get_rbio(ssl), ssl_io_data_cb);
- BIO_set_callback_arg(SSL_get_rbio(ssl), (void *)ssl);
+ BIO *rbio = SSL_get_rbio(ssl),
+ *wbio = SSL_get_wbio(ssl);
+ BIO_set_callback(rbio, ssl_io_data_cb);
+ BIO_set_callback_arg(rbio, (void *)ssl);
+ if (wbio && wbio != rbio) {
+ BIO_set_callback(wbio, ssl_io_data_cb);
+ BIO_set_callback_arg(wbio, (void *)ssl);
+ }
}
return;
@@ -1954,8 +1960,8 @@ void ssl_io_filter_register(apr_pool_t *p)
#define DUMP_WIDTH 16
-static void ssl_io_data_dump(server_rec *srvr,
- const char *s,
+static void ssl_io_data_dump(server_rec *s,
+ const char *b,
long len)
{
char buf[256];
@@ -1964,12 +1970,12 @@ static void ssl_io_data_dump(server_rec *srvr,
unsigned char ch;
trunc = 0;
- for(; (len > 0) && ((s[len-1] == ' ') || (s[len-1] == '\0')); len--)
+ for(; (len > 0) && ((b[len-1] == ' ') || (b[len-1] == '\0')); len--)
trunc++;
rows = (len / DUMP_WIDTH);
if ((rows * DUMP_WIDTH) < len)
rows++;
- ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, srvr,
+ ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, s,
"+-------------------------------------------------------------------------+");
for(i = 0 ; i< rows; i++) {
#if APR_CHARSET_EBCDIC
@@ -1979,7 +1985,7 @@ static void ssl_io_data_dump(server_rec *srvr,
j = len % DUMP_WIDTH;
if (j == 0)
j = DUMP_WIDTH;
- memcpy(ebcdic_text,(char *)(s) + i * DUMP_WIDTH, j);
+ memcpy(ebcdic_text,(char *)(b) + i * DUMP_WIDTH, j);
ap_xlate_proto_from_ascii(ebcdic_text, j);
#endif /* APR_CHARSET_EBCDIC */
apr_snprintf(tmp, sizeof(tmp), "| %04x: ", i * DUMP_WIDTH);
@@ -1988,7 +1994,7 @@ static void ssl_io_data_dump(server_rec *srvr,
if (((i * DUMP_WIDTH) + j) >= len)
apr_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf));
else {
- ch = ((unsigned char)*((char *)(s) + i * DUMP_WIDTH + j)) & 0xff;
+ ch = ((unsigned char)*((char *)(b) + i * DUMP_WIDTH + j)) & 0xff;
apr_snprintf(tmp, sizeof(tmp), "%02x%c", ch , j==7 ? '-' : ' ');
apr_cpystrn(buf+strlen(buf), tmp, sizeof(buf)-strlen(buf));
}
@@ -1998,7 +2004,7 @@ static void ssl_io_data_dump(server_rec *srvr,
if (((i * DUMP_WIDTH) + j) >= len)
apr_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf));
else {
- ch = ((unsigned char)*((char *)(s) + i * DUMP_WIDTH + j)) & 0xff;
+ ch = ((unsigned char)*((char *)(b) + i * DUMP_WIDTH + j)) & 0xff;
#if APR_CHARSET_EBCDIC
apr_snprintf(tmp, sizeof(tmp), "%c", (ch >= 0x20 && ch <= 0x7F) ? ebcdic_text[j] : '.');
#else /* APR_CHARSET_EBCDIC */
@@ -2008,13 +2014,12 @@ static void ssl_io_data_dump(server_rec *srvr,
}
}
apr_cpystrn(buf+strlen(buf), " |", sizeof(buf)-strlen(buf));
- ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, srvr,
- "%s", buf);
+ ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, s, "%s", buf);
}
if (trunc > 0)
- ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, srvr,
+ ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, s,
"| %04ld - <SPACES/NULS>", len + trunc);
- ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, srvr,
+ ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, s,
"+-------------------------------------------------------------------------+");
return;
}
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
index 3f905e7b..14afbf4a 100644
--- a/modules/ssl/ssl_engine_kernel.c
+++ b/modules/ssl/ssl_engine_kernel.c
@@ -54,8 +54,8 @@ static apr_status_t upgrade_connection(request_rec *r)
bb = apr_brigade_create(r->pool, conn->bucket_alloc);
- rv = ap_fputstrs(conn->output_filters, bb, SWITCH_STATUS_LINE, CRLF,
- UPGRADE_HEADER, CRLF, CONNECTION_HEADER, CRLF, CRLF, NULL);
+ rv = ap_fputs(conn->output_filters, bb, SWITCH_STATUS_LINE CRLF
+ UPGRADE_HEADER CRLF CONNECTION_HEADER CRLF CRLF);
if (rv == APR_SUCCESS) {
APR_BRIGADE_INSERT_TAIL(bb,
apr_bucket_flush_create(conn->bucket_alloc));
@@ -2049,8 +2049,14 @@ static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
* we need to set that callback here.
*/
if (APLOGtrace4(s)) {
- BIO_set_callback(SSL_get_rbio(ssl), ssl_io_data_cb);
- BIO_set_callback_arg(SSL_get_rbio(ssl), (void *)ssl);
+ BIO *rbio = SSL_get_rbio(ssl),
+ *wbio = SSL_get_wbio(ssl);
+ BIO_set_callback(rbio, ssl_io_data_cb);
+ BIO_set_callback_arg(rbio, (void *)ssl);
+ if (wbio && wbio != rbio) {
+ BIO_set_callback(wbio, ssl_io_data_cb);
+ BIO_set_callback_arg(wbio, (void *)ssl);
+ }
}
return 1;
diff --git a/modules/ssl/ssl_engine_pphrase.c b/modules/ssl/ssl_engine_pphrase.c
index a1f8734c..e158a476 100644
--- a/modules/ssl/ssl_engine_pphrase.c
+++ b/modules/ssl/ssl_engine_pphrase.c
@@ -415,12 +415,10 @@ static apr_status_t ssl_pipe_child_create(apr_pool_t *p, const char *progname)
APR_FULL_BLOCK,
APR_NO_PIPE)) == APR_SUCCESS)) {
char **args;
- const char *pname;
apr_tokenize_to_argv(progname, &args, p);
- pname = apr_pstrdup(p, args[0]);
procnew = (apr_proc_t *)apr_pcalloc(p, sizeof(*procnew));
- rc = apr_proc_create(procnew, pname, (const char * const *)args,
+ rc = apr_proc_create(procnew, args[0], (const char * const *)args,
NULL, procattr, p);
if (rc == APR_SUCCESS) {
/* XXX: not sure if we aught to...
diff --git a/modules/ssl/ssl_engine_vars.c b/modules/ssl/ssl_engine_vars.c
index 922bf7c1..695bc14b 100644
--- a/modules/ssl/ssl_engine_vars.c
+++ b/modules/ssl/ssl_engine_vars.c
@@ -73,7 +73,9 @@ static apr_array_header_t *expr_peer_ext_list_fn(ap_expr_eval_ctx_t *ctx,
static const char *expr_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
{
char *var = (char *)data;
- return ssl_var_lookup_ssl(ctx->p, ctx->c, ctx->r, var);
+ SSLConnRec *sslconn = myConnConfig(ctx->c);
+
+ return sslconn ? ssl_var_lookup_ssl(ctx->p, ctx->c, ctx->r, var) : NULL;
}
static int ssl_expr_lookup(ap_expr_lookup_parms *parms)
@@ -261,7 +263,7 @@ char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r,
else if (strcEQ(var, "SERVER_SOFTWARE"))
result = ap_get_server_banner();
else if (strcEQ(var, "API_VERSION")) {
- result = apr_itoa(p, MODULE_MAGIC_NUMBER);
+ result = apr_itoa(p, MODULE_MAGIC_NUMBER_MAJOR);
resdup = FALSE;
}
else if (strcEQ(var, "TIME_YEAR")) {
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
index e8e2cff0..98e9d35a 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -151,6 +151,13 @@
/* OCSP stapling */
#if !defined(OPENSSL_NO_OCSP) && defined(SSL_CTX_set_tlsext_status_cb)
#define HAVE_OCSP_STAPLING
+/* backward compatibility with OpenSSL < 1.0 */
+#ifndef sk_OPENSSL_STRING_num
+#define sk_OPENSSL_STRING_num sk_num
+#endif
+#ifndef sk_OPENSSL_STRING_value
+#define sk_OPENSSL_STRING_value sk_value
+#endif
#ifndef sk_OPENSSL_STRING_pop
#define sk_OPENSSL_STRING_pop sk_pop
#endif
@@ -640,6 +647,7 @@ struct SSLSrvConfigRec {
#ifndef OPENSSL_NO_COMP
BOOL compression;
#endif
+ BOOL session_tickets;
};
/**
@@ -694,6 +702,7 @@ const char *ssl_cmd_SSLCARevocationFile(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag);
const char *ssl_cmd_SSLCompression(cmd_parms *, void *, int flag);
+const char *ssl_cmd_SSLSessionTickets(cmd_parms *, void *, int flag);
const char *ssl_cmd_SSLVerifyClient(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLVerifyDepth(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLSessionCache(cmd_parms *, void *, const char *);
@@ -812,10 +821,11 @@ const char *ssl_cmd_SSLStaplingErrorCacheTimeout(cmd_parms *, void *, const char
const char *ssl_cmd_SSLStaplingReturnResponderErrors(cmd_parms *, void *, int);
const char *ssl_cmd_SSLStaplingFakeTryLater(cmd_parms *, void *, int);
const char *ssl_cmd_SSLStaplingResponderTimeout(cmd_parms *, void *, const char *);
-const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *, void *, const char *);
apr_status_t modssl_init_stapling(server_rec *, apr_pool_t *, apr_pool_t *, modssl_ctx_t *);
-void ssl_stapling_ex_init(void);
-int ssl_stapling_init_cert(server_rec *s, modssl_ctx_t *mctx, X509 *x);
+void ssl_stapling_certinfo_hash_init(apr_pool_t *);
+int ssl_stapling_init_cert(server_rec *, apr_pool_t *, apr_pool_t *,
+ modssl_ctx_t *, X509 *);
#endif
#ifdef HAVE_SRP
int ssl_callback_SRPServerParams(SSL *, int *, void *);
diff --git a/modules/ssl/ssl_util_ssl.c b/modules/ssl/ssl_util_ssl.c
index 0bf37768..b6183e8b 100644
--- a/modules/ssl/ssl_util_ssl.c
+++ b/modules/ssl/ssl_util_ssl.c
@@ -125,6 +125,7 @@ int SSL_smart_shutdown(SSL *ssl)
{
int i;
int rc;
+ int flush;
/*
* Repeat the calls, because SSL_shutdown internally dispatches through a
@@ -134,8 +135,20 @@ int SSL_smart_shutdown(SSL *ssl)
* connection and OpenSSL cannot recognize it.
*/
rc = 0;
+ flush = !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN);
for (i = 0; i < 4 /* max 2x pending + 2x data = 4 */; i++) {
- if ((rc = SSL_shutdown(ssl)))
+ rc = SSL_shutdown(ssl);
+ if (rc >= 0 && flush && (SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
+ /* Once the close notity is sent through the output filters,
+ * ensure it is flushed through the socket.
+ */
+ if (BIO_flush(SSL_get_wbio(ssl)) <= 0) {
+ rc = -1;
+ break;
+ }
+ flush = 0;
+ }
+ if (rc != 0)
break;
}
return rc;
diff --git a/modules/ssl/ssl_util_stapling.c b/modules/ssl/ssl_util_stapling.c
index 2dc8fcea..0e83baf3 100644
--- a/modules/ssl/ssl_util_stapling.c
+++ b/modules/ssl/ssl_util_stapling.c
@@ -43,36 +43,32 @@
#define MAX_STAPLING_DER 10240
-/* Cached info stored in certificate ex_info. */
+/* Cached info stored in the global stapling_certinfo hash. */
typedef struct {
- /* Index in session cache SHA1 hash of certificate */
- UCHAR idx[20];
- /* Certificate ID for OCSP requests or NULL if ID cannot be determined */
+ /* Index in session cache (SHA-1 digest of DER encoded certificate) */
+ UCHAR idx[SHA_DIGEST_LENGTH];
+ /* Certificate ID for OCSP request */
OCSP_CERTID *cid;
- /* Responder details */
+ /* URI of the OCSP responder */
char *uri;
} certinfo;
-static void certinfo_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
- int idx, long argl, void *argp)
+static apr_status_t ssl_stapling_certid_free(void *data)
{
- certinfo *cinf = ptr;
+ OCSP_CERTID *cid = data;
- if (!cinf)
- return;
- if (cinf->uri)
- OPENSSL_free(cinf->uri);
- OPENSSL_free(cinf);
+ if (cid) {
+ OCSP_CERTID_free(cid);
+ }
+
+ return APR_SUCCESS;
}
-static int stapling_ex_idx = -1;
+static apr_hash_t *stapling_certinfo;
-void ssl_stapling_ex_init(void)
+void ssl_stapling_certinfo_hash_init(apr_pool_t *p)
{
- if (stapling_ex_idx != -1)
- return;
- stapling_ex_idx = X509_get_ex_new_index(0, "X509 cached OCSP info", 0, 0,
- certinfo_free);
+ stapling_certinfo = apr_hash_make(p);
}
static X509 *stapling_get_issuer(modssl_ctx_t *mctx, X509 *x)
@@ -106,70 +102,96 @@ static X509 *stapling_get_issuer(modssl_ctx_t *mctx, X509 *x)
}
-int ssl_stapling_init_cert(server_rec *s, modssl_ctx_t *mctx, X509 *x)
+int ssl_stapling_init_cert(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp,
+ modssl_ctx_t *mctx, X509 *x)
{
- certinfo *cinf;
+ UCHAR idx[SHA_DIGEST_LENGTH];
+ certinfo *cinf = NULL;
X509 *issuer = NULL;
+ OCSP_CERTID *cid = NULL;
STACK_OF(OPENSSL_STRING) *aia = NULL;
- if (x == NULL)
+ if ((x == NULL) || (X509_digest(x, EVP_sha1(), idx, NULL) != 1))
return 0;
- cinf = X509_get_ex_data(x, stapling_ex_idx);
+
+ cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx));
if (cinf) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02215)
- "ssl_stapling_init_cert: certificate already initialized!");
- return 0;
- }
- cinf = OPENSSL_malloc(sizeof(certinfo));
- if (!cinf) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02216)
- "ssl_stapling_init_cert: error allocating memory!");
- return 0;
+ /*
+ * We already parsed the certificate, and no OCSP URI was found.
+ * The certificate might be used for multiple vhosts, though,
+ * so we check for a ForceURL for this vhost.
+ */
+ if (!cinf->uri && !mctx->stapling_force_url) {
+ ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x,
+ APLOGNO(02814) "ssl_stapling_init_cert: no OCSP URI "
+ "in certificate and no SSLStaplingForceURL "
+ "configured for server %s", mctx->sc->vhost_id);
+ return 0;
+ }
+ return 1;
}
- cinf->cid = NULL;
- cinf->uri = NULL;
- X509_set_ex_data(x, stapling_ex_idx, cinf);
-
- issuer = stapling_get_issuer(mctx, x);
- if (issuer == NULL) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02217)
- "ssl_stapling_init_cert: Can't retrieve issuer certificate!");
+ if (!(issuer = stapling_get_issuer(mctx, x))) {
+ ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, APLOGNO(02217)
+ "ssl_stapling_init_cert: can't retrieve issuer "
+ "certificate!");
return 0;
}
- cinf->cid = OCSP_cert_to_id(NULL, x, issuer);
+ cid = OCSP_cert_to_id(NULL, x, issuer);
X509_free(issuer);
- if (!cinf->cid)
+ if (!cid) {
+ ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, APLOGNO(02815)
+ "ssl_stapling_init_cert: can't create CertID "
+ "for OCSP request");
return 0;
- X509_digest(x, EVP_sha1(), cinf->idx, NULL);
+ }
aia = X509_get1_ocsp(x);
- if (aia) {
- cinf->uri = sk_OPENSSL_STRING_pop(aia);
- X509_email_free(aia);
- }
- if (!cinf->uri && !mctx->stapling_force_url) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02218)
- "ssl_stapling_init_cert: no responder URL");
+ if (!aia && !mctx->stapling_force_url) {
+ OCSP_CERTID_free(cid);
+ ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x,
+ APLOGNO(02218) "ssl_stapling_init_cert: no OCSP URI "
+ "in certificate and no SSLStaplingForceURL set");
return 0;
}
+
+ /* At this point, we have determined that there's something to store */
+ cinf = apr_pcalloc(p, sizeof(certinfo));
+ memcpy (cinf->idx, idx, sizeof(idx));
+ cinf->cid = cid;
+ /* make sure cid is also freed at pool cleanup */
+ apr_pool_cleanup_register(p, cid, ssl_stapling_certid_free,
+ apr_pool_cleanup_null);
+ if (aia) {
+ /* allocate uri from the pconf pool */
+ cinf->uri = apr_pstrdup(p, sk_OPENSSL_STRING_value(aia, 0));
+ X509_email_free(aia);
+ }
+
+ ssl_log_xerror(SSLLOG_MARK, APLOG_TRACE1, 0, ptemp, s, x,
+ "ssl_stapling_init_cert: storing certinfo for server %s",
+ mctx->sc->vhost_id);
+
+ apr_hash_set(stapling_certinfo, cinf->idx, sizeof(cinf->idx), cinf);
+
return 1;
}
-static certinfo *stapling_get_cert_info(server_rec *s, modssl_ctx_t *mctx,
+static certinfo *stapling_get_certinfo(server_rec *s, modssl_ctx_t *mctx,
SSL *ssl)
{
certinfo *cinf;
X509 *x;
+ UCHAR idx[SHA_DIGEST_LENGTH];
x = SSL_get_certificate(ssl);
- if (x == NULL)
+ if ((x == NULL) || (X509_digest(x, EVP_sha1(), idx, NULL) != 1))
return NULL;
- cinf = X509_get_ex_data(x, stapling_ex_idx);
+ cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx));
if (cinf && cinf->cid)
return cinf;
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01926)
- "stapling_get_cert_info: stapling not supported for certificate");
+ "stapling_get_certinfo: stapling not supported for certificate");
return NULL;
}
@@ -188,13 +210,13 @@ static BOOL stapling_cache_response(server_rec *s, modssl_ctx_t *mctx,
BOOL ok, apr_pool_t *pool)
{
SSLModConfigRec *mc = myModConfig(s);
- unsigned char resp_der[MAX_STAPLING_DER];
+ unsigned char resp_der[MAX_STAPLING_DER]; /* includes one-byte flag + response */
unsigned char *p;
- int resp_derlen;
+ int resp_derlen, stored_len;
BOOL rv;
apr_time_t expiry;
- resp_derlen = i2d_OCSP_RESPONSE(rsp, NULL) + 1;
+ resp_derlen = i2d_OCSP_RESPONSE(rsp, NULL);
if (resp_derlen <= 0) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01927)
@@ -202,7 +224,8 @@ static BOOL stapling_cache_response(server_rec *s, modssl_ctx_t *mctx,
return FALSE;
}
- if (resp_derlen > sizeof resp_der) {
+ stored_len = resp_derlen + 1; /* response + ok flag */
+ if (stored_len > sizeof resp_der) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01928)
"OCSP stapling response too big (%u bytes)", resp_derlen);
return FALSE;
@@ -226,7 +249,7 @@ static BOOL stapling_cache_response(server_rec *s, modssl_ctx_t *mctx,
rv = mc->stapling_cache->store(mc->stapling_cache_context, s,
cinf->idx, sizeof(cinf->idx),
- expiry, resp_der, resp_derlen, pool);
+ expiry, resp_der, stored_len, pool);
if (rv != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01929)
"stapling_cache_response: OCSP response session store error!");
@@ -585,7 +608,7 @@ static int stapling_cb(SSL *ssl, void *arg)
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01951)
"stapling_cb: OCSP Stapling callback called");
- cinf = stapling_get_cert_info(s, mctx, ssl);
+ cinf = stapling_get_certinfo(s, mctx, ssl);
if (cinf == NULL) {
return SSL_TLSEXT_ERR_NOACK;
}