diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/aaa/mod_authnz_ldap.c | 30 | ||||
-rw-r--r-- | modules/filters/mod_deflate.dsp | 6 | ||||
-rw-r--r-- | modules/filters/mod_reqtimeout.c | 259 | ||||
-rw-r--r-- | modules/filters/mod_reqtimeout.dsp | 222 | ||||
-rw-r--r-- | modules/http/http_request.c | 79 | ||||
-rw-r--r-- | modules/loggers/mod_log_config.c | 45 | ||||
-rw-r--r-- | modules/mappers/mod_dir.c | 27 | ||||
-rw-r--r-- | modules/mappers/mod_negotiation.c | 8 | ||||
-rw-r--r-- | modules/mappers/mod_rewrite.c | 2 | ||||
-rw-r--r-- | modules/metadata/mod_cern_meta.c | 10 | ||||
-rw-r--r-- | modules/metadata/mod_headers.c | 21 | ||||
-rw-r--r-- | modules/proxy/mod_proxy.c | 22 | ||||
-rw-r--r-- | modules/proxy/mod_proxy.h | 2 | ||||
-rw-r--r-- | modules/proxy/mod_proxy_ajp.c | 4 | ||||
-rw-r--r-- | modules/proxy/mod_proxy_balancer.c | 19 | ||||
-rw-r--r-- | modules/proxy/mod_proxy_http.c | 9 | ||||
-rw-r--r-- | modules/proxy/mod_proxy_scgi.c | 3 | ||||
-rw-r--r-- | modules/proxy/mod_proxy_scgi.dsp | 123 | ||||
-rw-r--r-- | modules/proxy/proxy_util.c | 2 | ||||
-rw-r--r-- | modules/ssl/NWGNUmakefile | 1 | ||||
-rw-r--r-- | modules/ssl/ssl_engine_io.c | 11 |
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; |