summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/aaa/mod_authnz_ldap.c30
-rw-r--r--modules/filters/mod_deflate.dsp6
-rw-r--r--modules/filters/mod_reqtimeout.c259
-rw-r--r--modules/filters/mod_reqtimeout.dsp222
-rw-r--r--modules/http/http_request.c79
-rw-r--r--modules/loggers/mod_log_config.c45
-rw-r--r--modules/mappers/mod_dir.c27
-rw-r--r--modules/mappers/mod_negotiation.c8
-rw-r--r--modules/mappers/mod_rewrite.c2
-rw-r--r--modules/metadata/mod_cern_meta.c10
-rw-r--r--modules/metadata/mod_headers.c21
-rw-r--r--modules/proxy/mod_proxy.c22
-rw-r--r--modules/proxy/mod_proxy.h2
-rw-r--r--modules/proxy/mod_proxy_ajp.c4
-rw-r--r--modules/proxy/mod_proxy_balancer.c19
-rw-r--r--modules/proxy/mod_proxy_http.c9
-rw-r--r--modules/proxy/mod_proxy_scgi.c3
-rw-r--r--modules/proxy/mod_proxy_scgi.dsp123
-rw-r--r--modules/proxy/proxy_util.c2
-rw-r--r--modules/ssl/NWGNUmakefile1
-rw-r--r--modules/ssl/ssl_engine_io.c11
21 files changed, 668 insertions, 237 deletions
diff --git a/modules/aaa/mod_authnz_ldap.c b/modules/aaa/mod_authnz_ldap.c
index bb08d20f..037bbcff 100644
--- a/modules/aaa/mod_authnz_ldap.c
+++ b/modules/aaa/mod_authnz_ldap.c
@@ -154,6 +154,29 @@ static apr_xlate_t* get_conv_set (request_rec *r)
}
+static const char* authn_ldap_xlate_password(request_rec *r,
+ const char* sent_password)
+{
+ apr_xlate_t *convset = NULL;
+ apr_size_t inbytes;
+ apr_size_t outbytes;
+ char *outbuf;
+
+ if (charset_conversions && (convset = get_conv_set(r)) ) {
+ inbytes = strlen(sent_password);
+ outbytes = (inbytes+1)*3;
+ outbuf = apr_pcalloc(r->pool, outbytes);
+
+ /* Convert the password to UTF-8. */
+ if (apr_xlate_conv_buffer(convset, sent_password, &inbytes, outbuf,
+ &outbytes) == APR_SUCCESS)
+ return outbuf;
+ }
+
+ return sent_password;
+}
+
+
/*
* Build the search filter, or at least as much of the search filter that
* will fit in the buffer. We don't worry about the buffer not being able
@@ -344,6 +367,7 @@ static authn_status authn_ldap_check_password(request_rec *r, const char *user,
int result = 0;
int remote_user_attribute_set = 0;
const char *dn = NULL;
+ const char *utfpassword;
authn_ldap_request_t *req =
(authn_ldap_request_t *)apr_pcalloc(r->pool, sizeof(authn_ldap_request_t));
@@ -397,9 +421,13 @@ start_over:
/* build the username filter */
authn_ldap_build_filter(filtbuf, r, user, NULL, sec);
+ /* convert password to utf-8 */
+ utfpassword = authn_ldap_xlate_password(r, password);
+
/* do the user search */
result = util_ldap_cache_checkuserid(r, ldc, sec->url, sec->basedn, sec->scope,
- sec->attributes, filtbuf, password, &dn, &vals);
+ sec->attributes, filtbuf, utfpassword,
+ &dn, &vals);
util_ldap_connection_close(ldc);
/* sanity check - if server is down, retry it up to 5 times */
diff --git a/modules/filters/mod_deflate.dsp b/modules/filters/mod_deflate.dsp
index f99035ed..06ce9683 100644
--- a/modules/filters/mod_deflate.dsp
+++ b/modules/filters/mod_deflate.dsp
@@ -42,8 +42,8 @@ RSC=rc.exe
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "HAVE_ZUTIL_H" /FD /c
-# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/zlib" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_deflate_src" /FD /c
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/zlib" /D "NDEBUG" /D "ZLIB_DLL" /D "HAVE_ZUTIL_H" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_deflate_src" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /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 "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/zlib" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_ZUTIL_H" /Fd"Debug\mod_deflate_src" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/zlib" /D "_DEBUG" /D "ZLIB_DLL" /D "HAVE_ZUTIL_H" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_deflate_src" /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
diff --git a/modules/filters/mod_reqtimeout.c b/modules/filters/mod_reqtimeout.c
index 4aec0fcd..e0d79a5a 100644
--- a/modules/filters/mod_reqtimeout.c
+++ b/modules/filters/mod_reqtimeout.c
@@ -14,15 +14,18 @@
* limitations under the License.
*/
+#define CORE_PRIVATE
#include "httpd.h"
#include "http_config.h"
#include "http_request.h"
#include "http_connection.h"
#include "http_protocol.h"
#include "http_log.h"
+#include "http_core.h"
#include "util_filter.h"
#define APR_WANT_STRFUNC
#include "apr_strings.h"
+#include "apr_version.h"
module AP_MODULE_DECLARE_DATA reqtimeout_module;
@@ -38,6 +41,7 @@ typedef struct
apr_time_t body_rate_factor;
} reqtimeout_srv_cfg;
+/* this struct is used both as conn_config and as filter context */
typedef struct
{
apr_time_t timeout_at;
@@ -47,14 +51,11 @@ typedef struct
int new_max_timeout;
int in_keep_alive;
char *type;
+ apr_socket_t *socket;
apr_time_t rate_factor;
+ apr_bucket_brigade *tmpbb;
} reqtimeout_con_cfg;
-typedef struct
-{
- apr_socket_t *socket;
-} reqtimeout_ctx;
-
static const char *const reqtimeout_filter_name = "reqtimeout";
static void extend_timeout(reqtimeout_con_cfg *ccfg, apr_bucket_brigade *bb)
@@ -74,24 +75,95 @@ static void extend_timeout(reqtimeout_con_cfg *ccfg, apr_bucket_brigade *bb)
}
}
+static apr_status_t check_time_left(reqtimeout_con_cfg *ccfg,
+ apr_time_t *time_left_p)
+{
+ *time_left_p = ccfg->timeout_at - apr_time_now();
+ if (*time_left_p <= 0)
+ return APR_TIMEUP;
+
+ if (*time_left_p < apr_time_from_sec(1)) {
+ *time_left_p = apr_time_from_sec(1);
+ }
+ return APR_SUCCESS;
+}
+
+static apr_status_t have_lf_or_eos(apr_bucket_brigade *bb)
+{
+ apr_bucket *b = APR_BRIGADE_LAST(bb);
+
+ for ( ; b != APR_BRIGADE_SENTINEL(bb) ; b = APR_BUCKET_PREV(b) ) {
+ const char *str;
+ apr_size_t len;
+ apr_status_t rv;
+
+ if (APR_BUCKET_IS_EOS(b))
+ return APR_SUCCESS;
+
+ if (APR_BUCKET_IS_METADATA(b))
+ continue;
+
+ rv = apr_bucket_read(b, &str, &len, APR_BLOCK_READ);
+ if (rv != APR_SUCCESS)
+ return rv;
+
+ if (len == 0)
+ continue;
+
+ if (str[len-1] == APR_ASCII_LF)
+ return APR_SUCCESS;
+ }
+ return APR_INCOMPLETE;
+}
+
+/*
+ * Append bbIn to bbOut and merge small buckets, to avoid DoS by high memory
+ * usage
+ */
+static apr_status_t brigade_append(apr_bucket_brigade *bbOut, apr_bucket_brigade *bbIn)
+{
+ while (!APR_BRIGADE_EMPTY(bbIn)) {
+ apr_bucket *e = APR_BRIGADE_FIRST(bbIn);
+ const char *str;
+ apr_size_t len;
+ apr_status_t rv;
+
+ rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ);
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+
+ APR_BUCKET_REMOVE(e);
+ if (APR_BUCKET_IS_METADATA(e) || len > APR_BUCKET_BUFF_SIZE/4) {
+ APR_BRIGADE_INSERT_TAIL(bbOut, e);
+ }
+ else {
+ if (len > 0) {
+ rv = apr_brigade_write(bbOut, NULL, NULL, str, len);
+ if (rv != APR_SUCCESS) {
+ apr_bucket_destroy(e);
+ return rv;
+ }
+ }
+ apr_bucket_destroy(e);
+ }
+ }
+ return APR_SUCCESS;
+}
+
+
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
static apr_status_t reqtimeout_filter(ap_filter_t *f,
apr_bucket_brigade *bb,
ap_input_mode_t mode,
apr_read_type_e block,
apr_off_t readbytes)
{
- reqtimeout_ctx *ctx;
apr_time_t time_left;
apr_time_t now;
apr_status_t rv;
apr_interval_time_t saved_sock_timeout = -1;
- reqtimeout_con_cfg *ccfg;
-
- ctx = f->ctx;
- AP_DEBUG_ASSERT(ctx != NULL);
-
- ccfg = ap_get_module_config(f->c->conn_config, &reqtimeout_module);
- AP_DEBUG_ASSERT(ccfg != NULL);
+ reqtimeout_con_cfg *ccfg = f->ctx;
if (ccfg->in_keep_alive) {
/* For this read, the normal keep-alive timeout must be used */
@@ -114,13 +186,14 @@ static apr_status_t reqtimeout_filter(ap_filter_t *f,
return ap_get_brigade(f->next, bb, mode, block, readbytes);
}
- time_left = ccfg->timeout_at - now;
- if (time_left <= 0) {
- ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, f->c,
- "Request %s read timeout", ccfg->type);
- return APR_TIMEUP;
+ if (!ccfg->socket) {
+ ccfg->socket = ap_get_module_config(f->c->conn_config, &core_module);
}
+ rv = check_time_left(ccfg, &time_left);
+ if (rv != APR_SUCCESS)
+ goto out;
+
if (block == APR_NONBLOCK_READ || mode == AP_MODE_INIT
|| mode == AP_MODE_EATCRLF) {
rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
@@ -130,41 +203,116 @@ static apr_status_t reqtimeout_filter(ap_filter_t *f,
return rv;
}
- if (time_left < apr_time_from_sec(1)) {
- time_left = apr_time_from_sec(1);
- }
+ rv = apr_socket_timeout_get(ccfg->socket, &saved_sock_timeout);
+ AP_DEBUG_ASSERT(rv == APR_SUCCESS);
- rv = apr_socket_timeout_get(ctx->socket, &saved_sock_timeout);
+ rv = apr_socket_timeout_set(ccfg->socket, MIN(time_left, saved_sock_timeout));
AP_DEBUG_ASSERT(rv == APR_SUCCESS);
- if (saved_sock_timeout >= time_left) {
- rv = apr_socket_timeout_set(ctx->socket, time_left);
- AP_DEBUG_ASSERT(rv == APR_SUCCESS);
+ if (mode == AP_MODE_GETLINE) {
+ /*
+ * For a blocking AP_MODE_GETLINE read, apr_brigade_split_line()
+ * would loop until a whole line has been read. As this would make it
+ * impossible to enforce a total timeout, we only do non-blocking
+ * reads.
+ */
+ apr_off_t remaining = HUGE_STRING_LEN;
+ do {
+ apr_off_t bblen;
+#if APR_MAJOR_VERSION < 2
+ apr_int32_t nsds;
+ apr_interval_time_t poll_timeout;
+ apr_pollfd_t pollset;
+#endif
+
+ rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE, APR_NONBLOCK_READ, remaining);
+ if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) {
+ break;
+ }
+
+ if (!APR_BRIGADE_EMPTY(bb)) {
+ if (ccfg->min_rate > 0) {
+ extend_timeout(ccfg, bb);
+ }
+
+ rv = have_lf_or_eos(bb);
+ if (rv != APR_INCOMPLETE) {
+ break;
+ }
+
+ rv = apr_brigade_length(bb, 1, &bblen);
+ if (rv != APR_SUCCESS) {
+ break;
+ }
+ remaining -= bblen;
+ if (remaining <= 0) {
+ break;
+ }
+
+ /* Haven't got a whole line yet, save what we have ... */
+ if (!ccfg->tmpbb) {
+ ccfg->tmpbb = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
+ }
+ rv = brigade_append(ccfg->tmpbb, bb);
+ if (rv != APR_SUCCESS)
+ break;
+ }
+
+ /* ... and wait for more */
+#if APR_MAJOR_VERSION < 2
+ pollset.p = f->c->pool;
+ pollset.desc_type = APR_POLL_SOCKET;
+ pollset.reqevents = APR_POLLIN|APR_POLLHUP;
+ pollset.desc.s = ccfg->socket;
+ apr_socket_timeout_get(ccfg->socket, &poll_timeout);
+ rv = apr_poll(&pollset, 1, &nsds, poll_timeout);
+#else
+ rv = apr_socket_wait(ccfg->socket, APR_WAIT_READ);
+#endif
+ if (rv != APR_SUCCESS)
+ break;
+
+ rv = check_time_left(ccfg, &time_left);
+ if (rv != APR_SUCCESS)
+ break;
+
+ rv = apr_socket_timeout_set(ccfg->socket,
+ MIN(time_left, saved_sock_timeout));
+ AP_DEBUG_ASSERT(rv == APR_SUCCESS);
+
+ } while (1);
+
+ if (ccfg->tmpbb)
+ APR_BRIGADE_PREPEND(bb, ccfg->tmpbb);
+
}
else {
- saved_sock_timeout = -1;
- }
-
- rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
-
- if (saved_sock_timeout != -1) {
- apr_socket_timeout_set(ctx->socket, saved_sock_timeout);
+ /* mode != AP_MODE_GETLINE */
+ rv = ap_get_brigade(f->next, bb, mode, block, readbytes);
+ if (ccfg->min_rate > 0 && rv == APR_SUCCESS) {
+ extend_timeout(ccfg, bb);
+ }
}
- if (ccfg->min_rate > 0 && rv == APR_SUCCESS) {
- extend_timeout(ccfg, bb);
- }
+ apr_socket_timeout_set(ccfg->socket, saved_sock_timeout);
+out:
if (APR_STATUS_IS_TIMEUP(rv)) {
ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, f->c,
"Request %s read timeout", ccfg->type);
+ /*
+ * If we allow a normal lingering close, the client may keep this
+ * process/thread busy for another 30s (MAX_SECS_TO_LINGER).
+ * Therefore we tell ap_lingering_close() to shorten this period to
+ * 2s (SECONDS_TO_LINGER).
+ */
+ apr_table_setn(f->c->notes, "short-lingering-close", "1");
}
return rv;
}
-static int reqtimeout_pre_conn(conn_rec *c, void *csd)
+static int reqtimeout_init(conn_rec *c)
{
- reqtimeout_ctx *ctx;
reqtimeout_con_cfg *ccfg;
reqtimeout_srv_cfg *cfg;
@@ -173,12 +321,9 @@ static int reqtimeout_pre_conn(conn_rec *c, void *csd)
AP_DEBUG_ASSERT(cfg != NULL);
if (cfg->header_timeout <= 0 && cfg->body_timeout <= 0) {
/* not configured for this vhost */
- return OK;
+ return DECLINED;
}
- ctx = apr_pcalloc(c->pool, sizeof(reqtimeout_ctx));
- ctx->socket = csd;
-
ccfg = apr_pcalloc(c->pool, sizeof(reqtimeout_con_cfg));
ccfg->new_timeout = cfg->header_timeout;
ccfg->new_max_timeout = cfg->header_max_timeout;
@@ -187,8 +332,9 @@ static int reqtimeout_pre_conn(conn_rec *c, void *csd)
ccfg->rate_factor = cfg->header_rate_factor;
ap_set_module_config(c->conn_config, &reqtimeout_module, ccfg);
- ap_add_input_filter("reqtimeout", ctx, NULL, c);
- return OK;
+ ap_add_input_filter("reqtimeout", ccfg, NULL, c);
+ /* we are not handling the connection, we just do initialization */
+ return DECLINED;
}
static int reqtimeout_after_headers(request_rec *r)
@@ -198,7 +344,7 @@ static int reqtimeout_after_headers(request_rec *r)
ap_get_module_config(r->connection->conn_config, &reqtimeout_module);
if (ccfg == NULL) {
- /* not configured for this vhost */
+ /* not configured for this connection */
return OK;
}
@@ -208,11 +354,13 @@ static int reqtimeout_after_headers(request_rec *r)
ccfg->timeout_at = 0;
ccfg->max_timeout_at = 0;
- ccfg->new_timeout = cfg->body_timeout;
- ccfg->new_max_timeout = cfg->body_max_timeout;
- ccfg->min_rate = cfg->body_min_rate;
- ccfg->rate_factor = cfg->body_rate_factor;
- ccfg->type = "body";
+ if (r->method_number != M_CONNECT) {
+ ccfg->new_timeout = cfg->body_timeout;
+ ccfg->new_max_timeout = cfg->body_max_timeout;
+ ccfg->min_rate = cfg->body_min_rate;
+ ccfg->rate_factor = cfg->body_rate_factor;
+ ccfg->type = "body";
+ }
return OK;
}
@@ -224,7 +372,7 @@ static int reqtimeout_after_body(request_rec *r)
ap_get_module_config(r->connection->conn_config, &reqtimeout_module);
if (ccfg == NULL) {
- /* not configured for this vhost */
+ /* not configured for this connection */
return OK;
}
@@ -406,7 +554,16 @@ static void reqtimeout_hooks(apr_pool_t *pool)
*/
ap_register_input_filter(reqtimeout_filter_name, reqtimeout_filter, NULL,
AP_FTYPE_CONNECTION + 8);
- ap_hook_pre_connection(reqtimeout_pre_conn, NULL, NULL, APR_HOOK_MIDDLE);
+
+ /*
+ * mod_reqtimeout needs to be called before ap_process_http_request (which
+ * is run at APR_HOOK_REALLY_LAST) but after all other protocol modules.
+ * This ensures that it only influences normal http connections and not
+ * e.g. mod_ftp. Also, if mod_reqtimeout used the pre_connection hook, it
+ * would be inserted on mod_proxy's backend connections.
+ */
+ ap_hook_process_connection(reqtimeout_init, NULL, NULL, APR_HOOK_LAST);
+
ap_hook_post_read_request(reqtimeout_after_headers, NULL, NULL,
APR_HOOK_MIDDLE);
ap_hook_log_transaction(reqtimeout_after_body, NULL, NULL,
diff --git a/modules/filters/mod_reqtimeout.dsp b/modules/filters/mod_reqtimeout.dsp
index 0afa4683..078480de 100644
--- a/modules/filters/mod_reqtimeout.dsp
+++ b/modules/filters/mod_reqtimeout.dsp
@@ -1,111 +1,111 @@
-# Microsoft Developer Studio Project File - Name="mod_reqtimeout" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=mod_reqtimeout - Win32 Release
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "mod_reqtimeout.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "mod_reqtimeout.mak" CFG="mod_reqtimeout - Win32 Release"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "mod_reqtimeout - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "mod_reqtimeout - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "mod_reqtimeout - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# 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 "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_RL_DECLARE_EXPORT" /Fd"Release\mod_reqtimeout_src" /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /fo"Release/mod_reqtimeout.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_reqtimeout.so" /d LONG_NAME="reqtimeout_module for Apache"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_reqtimeout.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reqtimeout.so
-# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_reqtimeout.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reqtimeout.so /opt:ref
-# Begin Special Build Tool
-TargetPath=.\Release\mod_reqtimeout.so
-SOURCE="$(InputPath)"
-PostBuild_Desc=Embed .manifest
-PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
-# End Special Build Tool
-
-!ELSEIF "$(CFG)" == "mod_reqtimeout - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# 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 "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_RL_DECLARE_EXPORT" /Fd"Debug\mod_reqtimeout_src" /FD /c
-# ADD BASE MTL /nologo /D "_DEBUG" /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /fo"Debug/mod_reqtimeout.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_reqtimeout.so" /d LONG_NAME="reqtimeout_module for Apache"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_reqtimeout.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reqtimeout.so
-# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_reqtimeout.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reqtimeout.so
-# Begin Special Build Tool
-TargetPath=.\Debug\mod_reqtimeout.so
-SOURCE="$(InputPath)"
-PostBuild_Desc=Embed .manifest
-PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
-# End Special Build Tool
-
-!ENDIF
-
-# Begin Target
-
-# Name "mod_reqtimeout - Win32 Release"
-# Name "mod_reqtimeout - Win32 Debug"
-# Begin Source File
-
-SOURCE=.\mod_reqtimeout.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\build\win32\httpd.rc
-# End Source File
-# End Target
-# End Project
+# Microsoft Developer Studio Project File - Name="mod_reqtimeout" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_reqtimeout - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_reqtimeout.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_reqtimeout.mak" CFG="mod_reqtimeout - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_reqtimeout - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_reqtimeout - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_reqtimeout - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# 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 "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_RL_DECLARE_EXPORT" /Fd"Release\mod_reqtimeout_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_reqtimeout.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_reqtimeout.so" /d LONG_NAME="reqtimeout_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_reqtimeout.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reqtimeout.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_reqtimeout.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reqtimeout.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_reqtimeout.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_reqtimeout - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# 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 "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AP_RL_DECLARE_EXPORT" /Fd"Debug\mod_reqtimeout_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_reqtimeout.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_reqtimeout.so" /d LONG_NAME="reqtimeout_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_reqtimeout.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reqtimeout.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_reqtimeout.so" /base:@..\..\os\win32\BaseAddr.ref,mod_reqtimeout.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_reqtimeout.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_reqtimeout - Win32 Release"
+# Name "mod_reqtimeout - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_reqtimeout.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/http/http_request.c b/modules/http/http_request.c
index 3a7e5ef9..251aa33b 100644
--- a/modules/http/http_request.c
+++ b/modules/http/http_request.c
@@ -399,16 +399,46 @@ static request_rec *internal_internal_redirect(const char *new_uri,
new->proto_output_filters = r->proto_output_filters;
new->proto_input_filters = r->proto_input_filters;
- new->output_filters = new->proto_output_filters;
new->input_filters = new->proto_input_filters;
if (new->main) {
- /* Add back the subrequest filter, which we lost when
- * we set output_filters to include only the protocol
- * output filters from the original request.
- */
- ap_add_output_filter_handle(ap_subreq_core_filter_handle,
- NULL, new, new->connection);
+ ap_filter_t *f, *nextf;
+
+ /* If this is a subrequest, the filter chain may contain a
+ * mixture of filters specific to the old request (r), and
+ * some inherited from r->main. Here, inherit that filter
+ * chain, and remove all those which are specific to the old
+ * request; ensuring the subreq filter is left in place. */
+ new->output_filters = r->output_filters;
+
+ f = new->output_filters;
+ do {
+ nextf = f->next;
+
+ if (f->r == r && f->frec != ap_subreq_core_filter_handle) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ "dropping filter '%s' in internal redirect from %s to %s",
+ f->frec->name, r->unparsed_uri, new_uri);
+
+ /* To remove the filter, first set f->r to the *new*
+ * request_rec, so that ->output_filters on 'new' is
+ * changed (if necessary) when removing the filter. */
+ f->r = new;
+ ap_remove_output_filter(f);
+ }
+
+ f = nextf;
+
+ /* Stop at the protocol filters. If a protocol filter has
+ * been newly installed for this resource, better leave it
+ * in place, though it's probably a misconfiguration or
+ * filter bug to get into this state. */
+ } while (f && f != new->proto_output_filters);
+ }
+ else {
+ /* If this is not a subrequest, clear out all
+ * resource-specific filters. */
+ new->output_filters = new->proto_output_filters;
}
update_r_in_filters(new->input_filters, r, new);
@@ -466,15 +496,6 @@ AP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r)
r->output_filters = rr->output_filters;
r->input_filters = rr->input_filters;
- if (r->main) {
- ap_add_output_filter_handle(ap_subreq_core_filter_handle,
- NULL, r, r->connection);
- }
- else if (r->output_filters->frec == ap_subreq_core_filter_handle) {
- ap_remove_output_filter(r->output_filters);
- r->output_filters = r->output_filters->next;
- }
-
/* If any filters pointed at the now-defunct rr, we must point them
* at our "new" instance of r. In particular, some of rr's structures
* will now be bogus (say rr->headers_out). If a filter tried to modify
@@ -483,6 +504,32 @@ AP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r)
*/
update_r_in_filters(r->input_filters, rr, r);
update_r_in_filters(r->output_filters, rr, r);
+
+ if (r->main) {
+ ap_add_output_filter_handle(ap_subreq_core_filter_handle,
+ NULL, r, r->connection);
+ }
+ else {
+ /*
+ * We need to check if we now have the SUBREQ_CORE filter in our filter
+ * chain. If this is the case we need to remove it since we are NO
+ * subrequest. But we need to keep in mind that the SUBREQ_CORE filter
+ * does not necessarily need to be the first filter in our chain. So we
+ * need to go through the chain. But we only need to walk up the chain
+ * until the proto_output_filters as the SUBREQ_CORE filter is below the
+ * protocol filters.
+ */
+ ap_filter_t *next;
+
+ next = r->output_filters;
+ while (next && (next->frec != ap_subreq_core_filter_handle)
+ && (next != r->proto_output_filters)) {
+ next = next->next;
+ }
+ if (next && (next->frec == ap_subreq_core_filter_handle)) {
+ ap_remove_output_filter(next);
+ }
+ }
}
AP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r)
diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c
index 8ceadf7c..f32a67b0 100644
--- a/modules/loggers/mod_log_config.c
+++ b/modules/loggers/mod_log_config.c
@@ -506,20 +506,39 @@ static const char *log_env_var(request_rec *r, char *a)
static const char *log_cookie(request_rec *r, char *a)
{
- const char *cookies;
- const char *start_cookie;
-
- if ((cookies = apr_table_get(r->headers_in, "Cookie"))) {
- if ((start_cookie = ap_strstr_c(cookies,a))) {
- char *cookie, *end_cookie;
- start_cookie += strlen(a) + 1; /* cookie_name + '=' */
- cookie = apr_pstrdup(r->pool, start_cookie);
- /* kill everything in cookie after ';' */
- end_cookie = strchr(cookie, ';');
- if (end_cookie) {
- *end_cookie = '\0';
+ const char *cookies_entry;
+
+ /*
+ * This supports Netscape version 0 cookies while being tolerant to
+ * some properties of RFC2109/2965 version 1 cookies:
+ * - case-insensitive match of cookie names
+ * - white space between the tokens
+ * It does not support the following version 1 features:
+ * - quoted strings as cookie values
+ * - commas to separate cookies
+ */
+
+ if ((cookies_entry = apr_table_get(r->headers_in, "Cookie"))) {
+ char *cookie, *last1, *last2;
+ char *cookies = apr_pstrdup(r->pool, cookies_entry);
+
+ while ((cookie = apr_strtok(cookies, ";", &last1))) {
+ char *name = apr_strtok(cookie, "=", &last2);
+ char *value;
+ apr_collapse_spaces(name, name);
+
+ if (!strcasecmp(name, a) && (value = apr_strtok(NULL, "=", &last2))) {
+ char *last;
+ value += strspn(value, " \t"); /* Move past leading WS */
+ last = value + strlen(value) - 1;
+ while (last >= value && apr_isspace(*last)) {
+ *last = '\0';
+ --last;
+ }
+
+ return ap_escape_logitem(r->pool, value);
}
- return ap_escape_logitem(r->pool, cookie);
+ cookies = NULL;
}
}
return NULL;
diff --git a/modules/mappers/mod_dir.c b/modules/mappers/mod_dir.c
index e3a9537b..860b9dce 100644
--- a/modules/mappers/mod_dir.c
+++ b/modules/mappers/mod_dir.c
@@ -104,9 +104,7 @@ static int fixup_dflt(request_rec *r)
const char *name_ptr;
request_rec *rr;
int error_notfound = 0;
- if ((r->finfo.filetype != APR_NOFILE) || (r->handler != NULL)) {
- return DECLINED;
- }
+
name_ptr = d->dflt;
if (name_ptr == NULL) {
return DECLINED;
@@ -160,11 +158,6 @@ static int fixup_dir(request_rec *r)
int num_names;
int error_notfound = 0;
- /* only handle requests against directories */
- if (r->finfo.filetype != APR_DIR) {
- return DECLINED;
- }
-
/* In case mod_mime wasn't present, and no handler was assigned. */
if (!r->handler) {
r->handler = DIR_MAGIC_TYPE;
@@ -239,7 +232,7 @@ static int fixup_dir(request_rec *r)
name_ptr = apr_pstrcat(r->pool, name_ptr, "?", r->args, NULL);
}
- rr = ap_sub_req_lookup_uri(name_ptr, r, NULL);
+ rr = ap_sub_req_lookup_uri(name_ptr, r, r->output_filters);
/* The sub request lookup is very liberal, and the core map_to_storage
* handler will almost always result in HTTP_OK as /foo/index.html
@@ -298,12 +291,22 @@ static int fixup_dir(request_rec *r)
/* nothing for us to do, pass on through */
return DECLINED;
}
+static int dir_fixups(request_rec *r)
+{
+ if (r->finfo.filetype == APR_DIR) {
+ /* serve up a directory */
+ return fixup_dir(r);
+ }
+ else if ((r->finfo.filetype == APR_NOFILE) && (r->handler == NULL)) {
+ /* No handler and nothing in the filesystem - use fallback */
+ return fixup_dflt(r);
+ }
+ return DECLINED;
+}
static void register_hooks(apr_pool_t *p)
{
- /* the order of these is of no consequence */
- ap_hook_fixups(fixup_dir,NULL,NULL,APR_HOOK_LAST);
- ap_hook_fixups(fixup_dflt,NULL,NULL,APR_HOOK_LAST);
+ ap_hook_fixups(dir_fixups,NULL,NULL,APR_HOOK_LAST);
}
module AP_MODULE_DECLARE_DATA dir_module = {
diff --git a/modules/mappers/mod_negotiation.c b/modules/mappers/mod_negotiation.c
index d3ae87c6..6feb58c0 100644
--- a/modules/mappers/mod_negotiation.c
+++ b/modules/mappers/mod_negotiation.c
@@ -1165,8 +1165,10 @@ static int read_types_multi(negotiation_state *neg)
/* Double check, we still don't multi-resolve non-ordinary files
*/
- if (sub_req->finfo.filetype != APR_REG)
+ if (sub_req->finfo.filetype != APR_REG) {
+ /* XXX sub req not destroyed -- may be a bug/unintentional ? */
continue;
+ }
/* If it has a handler, we'll pretend it's a CGI script,
* since that's a good indication of the sort of thing it
@@ -2712,7 +2714,7 @@ static int setup_choice_response(request_rec *r, negotiation_state *neg,
if (!variant->sub_req) {
int status;
- sub_req = ap_sub_req_lookup_file(variant->file_name, r, NULL);
+ sub_req = ap_sub_req_lookup_file(variant->file_name, r, r->output_filters);
status = sub_req->status;
if (status != HTTP_OK &&
@@ -3123,7 +3125,7 @@ static int handle_multi(request_rec *r)
* a sub_req structure yet. Get one now.
*/
- sub_req = ap_sub_req_lookup_file(best->file_name, r, NULL);
+ sub_req = ap_sub_req_lookup_file(best->file_name, r, r->output_filters);
if (sub_req->status != HTTP_OK) {
res = sub_req->status;
ap_destroy_sub_req(sub_req);
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index 5b58f5b3..36609cca 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -3180,7 +3180,7 @@ static const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf,
}
/* determine the pattern type */
- newcond->ptype = 0;
+ newcond->ptype = CONDPAT_REGEX;
if (*a2 && a2[1]) {
if (!a2[2] && *a2 == '-') {
switch (a2[1]) {
diff --git a/modules/metadata/mod_cern_meta.c b/modules/metadata/mod_cern_meta.c
index 3b57eef8..b238e2f1 100644
--- a/modules/metadata/mod_cern_meta.c
+++ b/modules/metadata/mod_cern_meta.c
@@ -281,18 +281,18 @@ static int add_cern_meta_data(request_rec *r)
if (!dconf->metafiles) {
return DECLINED;
- };
+ }
/* if ./.web/$1.meta exists then output 'asis' */
if (r->finfo.filetype == 0) {
return DECLINED;
- };
+ }
/* is this a directory? */
if (r->finfo.filetype == APR_DIR || r->uri[strlen(r->uri) - 1] == '/') {
return DECLINED;
- };
+ }
/* what directory is this file in? */
scrap_book = apr_pstrdup(r->pool, r->filename);
@@ -311,7 +311,7 @@ static int add_cern_meta_data(request_rec *r)
"internal error in mod_cern_meta: %s", r->filename);
/* should really barf, but hey, let's be friends... */
return DECLINED;
- };
+ }
metafilename = apr_pstrcat(r->pool, scrap_book, "/",
dconf->metadir ? dconf->metadir : DEFAULT_METADIR,
@@ -345,7 +345,7 @@ static int add_cern_meta_data(request_rec *r)
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"meta file permissions deny server access: %s", metafilename);
return HTTP_FORBIDDEN;
- };
+ }
/* read the headers in */
rv = scan_meta_file(r, f);
diff --git a/modules/metadata/mod_headers.c b/modules/metadata/mod_headers.c
index b65fbfd0..65050b45 100644
--- a/modules/metadata/mod_headers.c
+++ b/modules/metadata/mod_headers.c
@@ -94,7 +94,8 @@ typedef enum {
hdr_merge = 'g', /* merge (merge, but avoid duplicates) */
hdr_unset = 'u', /* unset header */
hdr_echo = 'e', /* echo headers from request to response */
- hdr_edit = 'r' /* change value by regexp */
+ hdr_edit = 'r', /* change value by regexp, match once */
+ hdr_edit_r = 'R' /* change value by regexp, everymatch */
} hdr_actions;
/*
@@ -364,6 +365,7 @@ static char *parse_format_string(apr_pool_t *p, header_entry *hdr, const char *s
/* No string to parse with unset and echo commands */
if (hdr->action == hdr_unset ||
hdr->action == hdr_edit ||
+ hdr->action == hdr_edit_r ||
hdr->action == hdr_echo) {
return NULL;
}
@@ -413,11 +415,13 @@ static APR_INLINE const char *header_inout_cmd(cmd_parms *cmd,
new->action = hdr_echo;
else if (!strcasecmp(action, "edit"))
new->action = hdr_edit;
+ else if (!strcasecmp(action, "edit*"))
+ new->action = hdr_edit_r;
else
return "first argument must be 'add', 'set', 'append', 'merge', "
- "'unset', 'echo', or 'edit'.";
+ "'unset', 'echo', 'edit', or 'edit*'.";
- if (new->action == hdr_edit) {
+ if (new->action == hdr_edit || new->action == hdr_edit_r) {
if (subs == NULL) {
return "Header edit requires a match and a substitution";
}
@@ -558,6 +562,7 @@ static const char *process_regexp(header_entry *hdr, const char *value,
unsigned int nmatch = 10;
ap_regmatch_t pmatch[10];
const char *subs;
+ const char *remainder;
char *ret;
int diffsz;
if (ap_regexec(hdr->regex, value, nmatch, pmatch, 0)) {
@@ -566,10 +571,17 @@ static const char *process_regexp(header_entry *hdr, const char *value,
}
subs = ap_pregsub(pool, hdr->subs, value, nmatch, pmatch);
diffsz = strlen(subs) - (pmatch[0].rm_eo - pmatch[0].rm_so);
+ if (hdr->action == hdr_edit) {
+ remainder = value + pmatch[0].rm_eo;
+ }
+ else { /* recurse to edit multiple matches if applicable */
+ remainder = process_regexp(hdr, value + pmatch[0].rm_eo, pool);
+ diffsz += strlen(remainder) - strlen(value + pmatch[0].rm_eo);
+ }
ret = apr_palloc(pool, strlen(value) + 1 + diffsz);
memcpy(ret, value, pmatch[0].rm_so);
strcpy(ret + pmatch[0].rm_so, subs);
- strcat(ret, value + pmatch[0].rm_eo);
+ strcat(ret, remainder);
return ret;
}
@@ -695,6 +707,7 @@ static void do_headers_fixup(request_rec *r, apr_table_t *headers,
echo_header, (void *) &v, r->headers_in, NULL);
break;
case hdr_edit:
+ case hdr_edit_r:
if (apr_table_get(headers, hdr->header)) {
edit_do ed;
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
index 6a370563..1efe95ce 100644
--- a/modules/proxy/mod_proxy.c
+++ b/modules/proxy/mod_proxy.c
@@ -365,6 +365,28 @@ static const char *set_balancer_param(proxy_server_conf *conf,
else
return "scolonpathdelim must be On|Off";
}
+ else if (!strcasecmp(key, "failonstatus")) {
+ char *val_split;
+ char *status;
+ char *tok_state;
+
+ val_split = apr_pstrdup(p, val);
+
+ balancer->errstatuses = apr_array_make(p, 1, sizeof(int));
+
+ status = apr_strtok(val_split, ", ", &tok_state);
+ while (status != NULL) {
+ ival = atoi(status);
+ if (ap_is_HTTP_VALID_RESPONSE(ival)) {
+ *(int *)apr_array_push(balancer->errstatuses) = ival;
+ }
+ else {
+ return "failonstatus must be one or more HTTP response codes";
+ }
+ status = apr_strtok(NULL, ", ", &tok_state);
+ }
+
+ }
else {
return "unknown Balancer parameter";
}
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
index 358248f1..4a4bf17b 100644
--- a/modules/proxy/mod_proxy.h
+++ b/modules/proxy/mod_proxy.h
@@ -386,6 +386,8 @@ struct proxy_balancer {
#endif
void *context; /* general purpose storage */
int scolonsep; /* true if ';' seps sticky session paths */
+
+ apr_array_header_t *errstatuses; /* statuses to force members into error */
};
struct proxy_balancer_method {
diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c
index 78f8e402..ccb0783f 100644
--- a/modules/proxy/mod_proxy_ajp.c
+++ b/modules/proxy/mod_proxy_ajp.c
@@ -471,7 +471,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
}
if (ap_pass_brigade(r->output_filters,
output_brigade) != APR_SUCCESS) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
"proxy: error processing body.%s",
r->connection->aborted ?
" Client aborted connection." : "");
@@ -489,7 +489,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
APR_BRIGADE_INSERT_TAIL(output_brigade, e);
if (ap_pass_brigade(r->output_filters,
output_brigade) != APR_SUCCESS) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
"proxy: error processing end");
output_failed = 1;
}
diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c
index e5a010db..90f3d086 100644
--- a/modules/proxy/mod_proxy_balancer.c
+++ b/modules/proxy/mod_proxy_balancer.c
@@ -591,7 +591,6 @@ static int proxy_balancer_post_request(proxy_worker *worker,
proxy_server_conf *conf)
{
-#if 0
apr_status_t rv;
if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) {
@@ -600,8 +599,20 @@ static int proxy_balancer_post_request(proxy_worker *worker,
balancer->name);
return HTTP_INTERNAL_SERVER_ERROR;
}
- /* TODO: placeholder for post_request actions
- */
+ if (!apr_is_empty_array(balancer->errstatuses)) {
+ int i;
+ for (i = 0; i < balancer->errstatuses->nelts; i++) {
+ int val = ((int *)balancer->errstatuses->elts)[i];
+ if (r->status == val) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
+ "proxy: BALANCER: (%s). Forcing recovery for worker (%s), failonstatus %d",
+ balancer->name, worker->name, val);
+ worker->s->status |= PROXY_WORKER_IN_ERROR;
+ worker->s->error_time = apr_time_now();
+ break;
+ }
+ }
+ }
if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
@@ -611,8 +622,6 @@ static int proxy_balancer_post_request(proxy_worker *worker,
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"proxy_balancer_post_request for (%s)", balancer->name);
-#endif
-
if (worker && worker->s->busy)
worker->s->busy--;
diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c
index 83d4e23a..e0a8ae11 100644
--- a/modules/proxy/mod_proxy_http.c
+++ b/modules/proxy/mod_proxy_http.c
@@ -1473,14 +1473,13 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
if (apr_date_checkmask(buffer, "HTTP/#.# ###*")) {
int major, minor;
- if (2 != sscanf(buffer, "HTTP/%u.%u", &major, &minor)) {
- major = 1;
- minor = 1;
- }
+ major = buffer[5] - '0';
+ minor = buffer[7] - '0';
+
/* If not an HTTP/1 message or
* if the status line was > 8192 bytes
*/
- else if ((buffer[5] != '1') || (len >= sizeof(buffer)-1)) {
+ if ((major != 1) || (len >= sizeof(buffer)-1)) {
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
apr_pstrcat(p, "Corrupt status line returned by remote "
"server: ", buffer, NULL));
diff --git a/modules/proxy/mod_proxy_scgi.c b/modules/proxy/mod_proxy_scgi.c
index e152c277..b16fe153 100644
--- a/modules/proxy/mod_proxy_scgi.c
+++ b/modules/proxy/mod_proxy_scgi.c
@@ -246,7 +246,8 @@ static int send_headers(request_rec *r, proxy_conn_rec *conn)
const char *ns_len;
const apr_array_header_t *env_table;
const apr_table_entry_t *env;
- apr_size_t j, len, bodylen_size;
+ int j;
+ apr_size_t len, bodylen_size;
apr_size_t headerlen = sizeof(CONTENT_LENGTH)
+ sizeof(SCGI_MAGIC)
+ sizeof(SCGI_PROTOCOL_VERSION);
diff --git a/modules/proxy/mod_proxy_scgi.dsp b/modules/proxy/mod_proxy_scgi.dsp
new file mode 100644
index 00000000..8aee15e1
--- /dev/null
+++ b/modules/proxy/mod_proxy_scgi.dsp
@@ -0,0 +1,123 @@
+# Microsoft Developer Studio Project File - Name="mod_proxy_scgi" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_proxy_scgi - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_proxy_scgi.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_proxy_scgi.mak" CFG="mod_proxy_scgi - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_proxy_scgi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_proxy_scgi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_proxy_scgi - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# 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 "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_proxy_scgi_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_proxy_scgi.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_proxy_scgi.so" /d LONG_NAME="proxy_scgi_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /out:".\Release\mod_proxy_scgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_scgi.so
+# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_proxy_scgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_scgi.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_proxy_scgi.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_proxy_scgi - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# 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 "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_scgi_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_proxy_scgi.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_proxy_scgi.so" /d LONG_NAME="proxy_scgi_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_proxy_scgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_scgi.so
+# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_proxy_scgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_scgi.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_proxy_scgi.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_proxy_scgi - Win32 Release"
+# Name "mod_proxy_scgi - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
+# Begin Source File
+
+SOURCE=.\mod_proxy_scgi.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter ".h"
+# Begin Source File
+
+SOURCE=.\mod_proxy.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index a70a8758..95f4a784 100644
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -2509,8 +2509,8 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
*/
if (!connected && PROXY_WORKER_IS_USABLE(worker) &&
!(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) {
- worker->s->status |= PROXY_WORKER_IN_ERROR;
worker->s->error_time = apr_time_now();
+ worker->s->status |= PROXY_WORKER_IN_ERROR;
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
"ap_proxy_connect_backend disabling worker for (%s)",
worker->hostname);
diff --git a/modules/ssl/NWGNUmakefile b/modules/ssl/NWGNUmakefile
index 655cdd69..6d2b838d 100644
--- a/modules/ssl/NWGNUmakefile
+++ b/modules/ssl/NWGNUmakefile
@@ -48,7 +48,6 @@ XINCDIRS += \
# These flags will come after CFLAGS
#
XCFLAGS += \
- -relax_pointers \
$(EOLIST)
#
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
index d26a0c2b..9f5d2832 100644
--- a/modules/ssl/ssl_engine_io.c
+++ b/modules/ssl/ssl_engine_io.c
@@ -344,6 +344,13 @@ typedef struct {
* this char_buffer api might seem silly, but we don't need to copy
* any of this data and we need to remember the length.
*/
+
+/* Copy up to INL bytes from the char_buffer BUFFER into IN. Note
+ * that due to the strange way this API is designed/used, the
+ * char_buffer object is used to cache a segment of inctx->buffer, and
+ * then this function called to copy (part of) that segment to the
+ * beginning of inctx->buffer. So the segments to copy cannot be
+ * presumed to be non-overlapping, and memmove must be used. */
static int char_buffer_read(char_buffer_t *buffer, char *in, int inl)
{
if (!buffer->length) {
@@ -352,13 +359,13 @@ static int char_buffer_read(char_buffer_t *buffer, char *in, int inl)
if (buffer->length > inl) {
/* we have have enough to fill the caller's buffer */
- memcpy(in, buffer->value, inl);
+ memmove(in, buffer->value, inl);
buffer->value += inl;
buffer->length -= inl;
}
else {
/* swallow remainder of the buffer */
- memcpy(in, buffer->value, buffer->length);
+ memmove(in, buffer->value, buffer->length);
inl = buffer->length;
buffer->value = NULL;
buffer->length = 0;