summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorArno Töll <arno@debian.org>2013-02-28 21:57:03 +0100
committerArno Töll <arno@debian.org>2013-02-28 21:57:03 +0100
commit1697a801fb875664f7b269260511f5f4126a5e83 (patch)
tree89da4a9495e2ba6d6cb4e4dbae4184c7238a985a /server
parent5c4fba3ffbe778bdffe10a93d04821579601a020 (diff)
downloadapache2-1697a801fb875664f7b269260511f5f4126a5e83.tar.gz
Imported Upstream version 2.4.4upstream/2.4.4
Diffstat (limited to 'server')
-rw-r--r--server/Makefile.in2
-rw-r--r--server/config.c12
-rw-r--r--server/core.c19
-rw-r--r--server/error_bucket.c2
-rw-r--r--server/gen_test_char.c4
-rw-r--r--server/listen.c5
-rw-r--r--server/log.c10
-rw-r--r--server/mpm/event/event.c6
-rw-r--r--server/mpm/netware/mpm_netware.c4
-rw-r--r--server/mpm/prefork/prefork.c13
-rw-r--r--server/mpm/winnt/child.c5
-rw-r--r--server/mpm/winnt/mpm_winnt.c42
-rw-r--r--server/mpm/winnt/mpm_winnt.h2
-rw-r--r--server/mpm/winnt/service.c4
-rw-r--r--server/protocol.c29
-rw-r--r--server/provider.c2
-rw-r--r--server/util.c126
-rw-r--r--server/util_expr_eval.c3
-rw-r--r--server/util_md5.c10
-rw-r--r--server/util_pcre.c12
-rw-r--r--server/util_script.c6
-rw-r--r--server/vhost.c5
22 files changed, 226 insertions, 97 deletions
diff --git a/server/Makefile.in b/server/Makefile.in
index 42d1fe5c..19010759 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -60,7 +60,7 @@ export_files:
for dir in $(EXPORT_DIRS_APR); do \
ls $$dir/ap[ru].h $$dir/ap[ru]_*.h 2>/dev/null; \
done; \
- ) | sort -u > $@
+ ) | sed -e s,//,/,g | sort -u > $@
exports.c: export_files
$(AWK) -f $(top_srcdir)/build/make_exports.awk `cat $?` > $@
diff --git a/server/config.c b/server/config.c
index fb07623b..bc0804a4 100644
--- a/server/config.c
+++ b/server/config.c
@@ -976,12 +976,20 @@ static const char *invoke_cmd(const command_rec *cmd, cmd_parms *parms,
return cmd->AP_TAKE3(parms, mconfig, w, w2, w3);
case ITERATE:
- while (*(w = ap_getword_conf(parms->pool, &args)) != '\0') {
+ w = ap_getword_conf(parms->pool, &args);
+
+ if (*w == '\0')
+ return apr_pstrcat(parms->pool, cmd->name,
+ " requires at least one argument",
+ cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL);
+ while (*w != '\0') {
errmsg = cmd->AP_TAKE1(parms, mconfig, w);
if (errmsg && strcmp(errmsg, DECLINE_CMD) != 0)
return errmsg;
+
+ w = ap_getword_conf(parms->pool, &args);
}
return errmsg;
@@ -2013,7 +2021,7 @@ AP_DECLARE(const char *) ap_process_fnmatch_configs(server_rec *s,
}
if (!apr_fnmatch_test(fname)) {
- return ap_process_resource_config(s, fname, conftree, p, ptemp);
+ return process_resource_config_nofnmatch(s, fname, conftree, p, ptemp, 0, optional);
}
else {
apr_status_t status;
diff --git a/server/core.c b/server/core.c
index 03137577..6f6d5686 100644
--- a/server/core.c
+++ b/server/core.c
@@ -1144,7 +1144,10 @@ AP_DECLARE(const char *) ap_check_cmd_context(cmd_parms *cmd,
|| (found = find_parent(cmd->directive, "<LocationMatch"))))
|| ((forbidden & NOT_IN_FILES)
&& ((found = find_parent(cmd->directive, "<Files"))
- || (found = find_parent(cmd->directive, "<FilesMatch"))))) {
+ || (found = find_parent(cmd->directive, "<FilesMatch"))
+ || (found = find_parent(cmd->directive, "<If"))
+ || (found = find_parent(cmd->directive, "<ElseIf"))
+ || (found = find_parent(cmd->directive, "<Else"))))) {
return apr_pstrcat(cmd->pool, cmd->cmd->name, gt,
" cannot occur within ", found->directive,
"> section", NULL);
@@ -2354,7 +2357,11 @@ static const char *ifsection(cmd_parms *cmd, void *mconfig, const char *arg)
arg = apr_pstrndup(cmd->temp_pool, arg, endp - arg);
-
+ /*
+ * Set a dummy value so that other directives notice that they are inside
+ * a config section.
+ */
+ cmd->path = "*If";
/* Only if not an .htaccess file */
if (!old_path) {
cmd->override = OR_ALL|ACCESS_CONF;
@@ -3222,9 +3229,12 @@ static const char *set_serv_tokens(cmd_parms *cmd, void *dummy,
else if (!strcasecmp(arg1, "Prod") || !strcasecmp(arg1, "ProductOnly")) {
ap_server_tokens = SrvTk_PRODUCT_ONLY;
}
- else {
+ else if (!strcasecmp(arg1, "Full")) {
ap_server_tokens = SrvTk_FULL;
}
+ else {
+ return "ServerTokens takes 1 argument, 'Prod', 'Major', 'Minor', 'Min', 'OS', or 'Full'";
+ }
return NULL;
}
@@ -4255,7 +4265,8 @@ static int default_handler(request_rec *r)
if (r->method_number == M_GET || r->method_number == M_POST) {
if (r->finfo.filetype == APR_NOFILE) {
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00128)
- "File does not exist: %s", r->filename);
+ "File does not exist: %s",
+ apr_pstrcat(r->pool, r->filename, r->path_info, NULL));
return HTTP_NOT_FOUND;
}
diff --git a/server/error_bucket.c b/server/error_bucket.c
index d113c171..9c118e61 100644
--- a/server/error_bucket.c
+++ b/server/error_bucket.c
@@ -45,7 +45,7 @@ AP_DECLARE(apr_bucket *) ap_bucket_error_make(apr_bucket *b, int error,
h = apr_bucket_alloc(sizeof(*h), b->list);
h->status = error;
- h->data = (buf) ? apr_pstrdup(p, buf) : NULL;
+ h->data = apr_pstrdup(p, buf);
b = apr_bucket_shared_make(b, h, 0, 0);
b->type = &ap_bucket_type_error;
diff --git a/server/gen_test_char.c b/server/gen_test_char.c
index 1c40bde9..e25238f3 100644
--- a/server/gen_test_char.c
+++ b/server/gen_test_char.c
@@ -29,10 +29,10 @@
#include "apr.h"
#include "apr_lib.h"
-#if defined(WIN32) || defined(OS2)
-#define NEED_ENHANCED_ESCAPES
#endif
+#if defined(WIN32) || defined(OS2)
+#define NEED_ENHANCED_ESCAPES
#endif
#if APR_HAVE_STDIO_H
diff --git a/server/listen.c b/server/listen.c
index a85095d4..7950a100 100644
--- a/server/listen.c
+++ b/server/listen.c
@@ -213,8 +213,11 @@ static void ap_apply_accept_filter(apr_pool_t *p, ap_listen_rec *lis,
if (accf) {
#if APR_HAS_SO_ACCEPTFILTER
+ /* In APR 1.x, the 2nd and 3rd parameters are char * instead of
+ * const char *, so make a copy of those args here.
+ */
rv = apr_socket_accept_filter(s, apr_pstrdup(p, accf),
- apr_pstrdup(p,""));
+ apr_pstrdup(p, ""));
if (rv != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(rv)) {
ap_log_perror(APLOG_MARK, APLOG_WARNING, rv, p, APLOGNO(00075)
"Failed to enable the '%s' Accept Filter",
diff --git a/server/log.c b/server/log.c
index b33aa1fc..05d99ad6 100644
--- a/server/log.c
+++ b/server/log.c
@@ -1015,6 +1015,7 @@ static int do_errorlog_format(apr_array_header_t *fmt, ap_errorlog_info *info,
int skipping = 0;
ap_errorlog_format_item *items = (ap_errorlog_format_item *)fmt->elts;
+ AP_DEBUG_ASSERT(fmt->nelts > 0);
for (i = 0; i < fmt->nelts; ++i) {
ap_errorlog_format_item *item = &items[i];
if (item->flags & AP_ERRORLOG_FLAG_FIELD_SEP) {
@@ -1087,7 +1088,8 @@ static void write_logline(char *errstr, apr_size_t len, apr_file_t *logf,
}
#ifdef HAVE_SYSLOG
else {
- syslog(level < LOG_PRIMASK ? level : APLOG_DEBUG, "%s", errstr);
+ syslog(level < LOG_PRIMASK ? level : APLOG_DEBUG, "%.*s",
+ (int)len, errstr);
}
#endif
}
@@ -1112,7 +1114,8 @@ static void log_error_core(const char *file, int line, int module_index,
int done = 0;
int line_number = 0;
- if (r && r->connection) {
+ if (r) {
+ AP_DEBUG_ASSERT(r->connection != NULL);
c = r->connection;
}
@@ -1262,8 +1265,7 @@ static void log_error_core(const char *file, int line, int module_index,
&errstr_start, &errstr_end, fmt, args);
}
- if (!*errstr)
- {
+ if (!*errstr) {
/*
* Don't log empty lines. This can happen with once-per-conn/req
* info if an item with AP_ERRORLOG_FLAG_REQUIRED is NULL.
diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c
index fa724688..1b42e696 100644
--- a/server/mpm/event/event.c
+++ b/server/mpm/event/event.c
@@ -19,10 +19,10 @@
*
* After a client completes the first request, the client can keep the
* connection open to send more requests with the same socket. This can save
- * signifigant overhead in creating TCP connections. However, the major
+ * significant overhead in creating TCP connections. However, the major
* disadvantage is that Apache traditionally keeps an entire child
* process/thread waiting for data from the client. To solve this problem,
- * this MPM has a dedicated thread for handling both the Listenting sockets,
+ * this MPM has a dedicated thread for handling both the Listening sockets,
* and all sockets that are in a Keep Alive status.
*
* The MPM assumes the underlying apr_pollset implementation is somewhat
@@ -30,7 +30,7 @@
* enables the MPM to avoid extra high level locking or having to wake up the
* listener thread when a keep-alive socket needs to be sent to it.
*
- * This MPM not preform well on older platforms that do not have very good
+ * This MPM does not perform well on older platforms that do not have very good
* threading, like Linux with a 2.4 kernel, but this does not matter, since we
* require EPoll or KQueue.
*
diff --git a/server/mpm/netware/mpm_netware.c b/server/mpm/netware/mpm_netware.c
index 77840492..6b049c98 100644
--- a/server/mpm/netware/mpm_netware.c
+++ b/server/mpm/netware/mpm_netware.c
@@ -942,7 +942,7 @@ static int netware_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
"caught SIGTERM, shutting down");
while (worker_thread_count > 0) {
- printf ("\rShutdown pending. Waiting for %d thread(s) to terminate...",
+ printf ("\rShutdown pending. Waiting for %u thread(s) to terminate...",
worker_thread_count);
apr_thread_yield();
}
@@ -963,7 +963,7 @@ static int netware_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
/* Wait for all of the threads to terminate before initiating the restart */
while (worker_thread_count > 0) {
- printf ("\rRestart pending. Waiting for %d thread(s) to terminate...",
+ printf ("\rRestart pending. Waiting for %u thread(s) to terminate...",
worker_thread_count);
apr_thread_yield();
}
diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c
index d0cf59b4..ae0fd374 100644
--- a/server/mpm/prefork/prefork.c
+++ b/server/mpm/prefork/prefork.c
@@ -564,9 +564,16 @@ static void child_main(int child_num_arg)
status = apr_pollset_add(pollset, &pfd);
if (status != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, APLOGNO(00157)
- "Couldn't add listener to pollset; check system or user limits");
- clean_child_exit(APEXIT_CHILDSICK);
+ /* If the child processed a SIGWINCH before setting up the
+ * pollset, this error path is expected and harmless,
+ * since the listener fd was already closed; so don't
+ * pollute the logs in that case. */
+ if (!die_now) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, APLOGNO(00157)
+ "Couldn't add listener to pollset; check system or user limits");
+ clean_child_exit(APEXIT_CHILDSICK);
+ }
+ clean_child_exit(0);
}
lr->accept_func = ap_unixd_accept;
diff --git a/server/mpm/winnt/child.c b/server/mpm/winnt/child.c
index ae34b07b..7983851a 100644
--- a/server/mpm/winnt/child.c
+++ b/server/mpm/winnt/child.c
@@ -761,7 +761,7 @@ apr_status_t winnt_insert_network_bucket(conn_rec *c,
*/
static DWORD __stdcall worker_main(void *thread_num_val)
{
- apr_thread_t *thd = NULL;
+ apr_thread_t *thd;
apr_os_thread_t osthd;
static int requests_this_child = 0;
winnt_conn_ctx_t *context = NULL;
@@ -773,7 +773,6 @@ static DWORD __stdcall worker_main(void *thread_num_val)
apr_int32_t disconnected;
osthd = apr_os_thread_current();
- apr_os_thread_put(&thd, &osthd, pchild);
while (1) {
@@ -811,6 +810,8 @@ static DWORD __stdcall worker_main(void *thread_num_val)
continue;
}
+ thd = NULL;
+ apr_os_thread_put(&thd, &osthd, context->ptrans);
c->current_thread = thd;
/* follow ap_process_connection(c, context->sock) logic
diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c
index 4f6f8fe5..4e3b23ce 100644
--- a/server/mpm/winnt/mpm_winnt.c
+++ b/server/mpm/winnt/mpm_winnt.c
@@ -95,9 +95,6 @@ int winnt_mpm_state = AP_MPMQ_STARTING;
*/
apr_pool_t *pconf;
-/* definitions from child.c */
-void child_main(apr_pool_t *pconf);
-
/* Only one of these, the pipe from our parent, meant only for
* one child worker's consumption (not to be inherited!)
* XXX: decorate this name for the trunk branch, was left simplified
@@ -189,10 +186,10 @@ static void winnt_note_child_killed(int slot)
* signal_restart_name and signal_shutdown_name.
*/
#define MAX_SIGNAL_NAME 30 /* Long enough for apPID_shutdown, where PID is an int */
-char signal_name_prefix[MAX_SIGNAL_NAME];
-char signal_restart_name[MAX_SIGNAL_NAME];
-char signal_shutdown_name[MAX_SIGNAL_NAME];
-void setup_signal_names(char *prefix)
+static char signal_name_prefix[MAX_SIGNAL_NAME];
+static char signal_restart_name[MAX_SIGNAL_NAME];
+static char signal_shutdown_name[MAX_SIGNAL_NAME];
+static void setup_signal_names(char *prefix)
{
apr_snprintf(signal_name_prefix, sizeof(signal_name_prefix), prefix);
apr_snprintf(signal_shutdown_name, sizeof(signal_shutdown_name),
@@ -280,7 +277,7 @@ static void get_handles_from_parent(server_rec *s, HANDLE *child_exit_event,
void *sb_shared;
apr_status_t rv;
- /* *** We now do this was back in winnt_rewrite_args
+ /* *** We now do this way back in winnt_rewrite_args
* pipe = GetStdHandle(STD_INPUT_HANDLE);
*/
if (!ReadFile(pipe, &ready_event, sizeof(HANDLE),
@@ -454,7 +451,7 @@ static void get_listeners_from_parent(server_rec *s)
/* Open the pipe to the parent process to receive the inherited socket
* data. The sockets have been set to listening in the parent process.
*
- * *** We now do this was back in winnt_rewrite_args
+ * *** We now do this way back in winnt_rewrite_args
* pipe = GetStdHandle(STD_INPUT_HANDLE);
*/
for (lr = ap_listeners; lr; lr = lr->next, ++lcnt) {
@@ -824,7 +821,7 @@ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_even
}
if (SetEvent(child_exit_event) == 0) {
ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), s, APLOGNO(00426)
- "Parent: SetEvent for child process %pp failed.",
+ "Parent: SetEvent for child process event %pp failed.",
event_handles[CHILD_HANDLE]);
}
/* Don't wait to verify that the child process really exits,
@@ -844,14 +841,16 @@ static int master_main(server_rec *s, HANDLE shutdown_event, HANDLE restart_even
|| exitcode == APEXIT_CHILDINIT
|| exitcode == APEXIT_INIT) {
ap_log_error(APLOG_MARK, APLOG_CRIT, 0, ap_server_conf, APLOGNO(00427)
- "Parent: child process exited with status %lu -- Aborting.", exitcode);
+ "Parent: child process %lu exited with status %lu -- Aborting.",
+ child_pid, exitcode);
shutdown_pending = 1;
}
else {
int i;
restart_pending = 1;
ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, APLOGNO(00428)
- "Parent: child process exited with status %lu -- Restarting.", exitcode);
+ "Parent: child process %lu exited with status %lu -- Restarting.",
+ child_pid, exitcode);
for (i = 0; i < ap_threads_per_child; i++) {
ap_update_child_status_from_indexes(0, i, SERVER_DEAD, NULL);
}
@@ -886,21 +885,21 @@ die_now:
/* Signal the child processes to exit */
if (SetEvent(child_exit_event) == 0) {
ap_log_error(APLOG_MARK,APLOG_ERR, apr_get_os_error(), ap_server_conf, APLOGNO(00429)
- "Parent: SetEvent for child process %pp failed",
+ "Parent: SetEvent for child process event %pp failed",
event_handles[CHILD_HANDLE]);
}
if (event_handles[CHILD_HANDLE]) {
rv = WaitForSingleObject(event_handles[CHILD_HANDLE], timeout);
if (rv == WAIT_OBJECT_0) {
ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, APLOGNO(00430)
- "Parent: Child process exited successfully.");
+ "Parent: Child process %lu exited successfully.", child_pid);
CloseHandle(event_handles[CHILD_HANDLE]);
event_handles[CHILD_HANDLE] = NULL;
}
else {
ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, APLOGNO(00431)
- "Parent: Forcing termination of child process %pp",
- event_handles[CHILD_HANDLE]);
+ "Parent: Forcing termination of child process %lu",
+ child_pid);
TerminateProcess(event_handles[CHILD_HANDLE], 1);
CloseHandle(event_handles[CHILD_HANDLE]);
event_handles[CHILD_HANDLE] = NULL;
@@ -1372,7 +1371,8 @@ static int winnt_pre_config(apr_pool_t *pconf_, apr_pool_t *plog, apr_pool_t *pt
service_name);
exit(APEXIT_INIT);
}
- else if (!one_process && !my_generation) {
+ else if (ap_state_query(AP_SQ_RUN_MODE) == AP_SQ_RM_NORMAL
+ && !one_process && !my_generation) {
/* Open a null handle to soak stdout in this process.
* We need to emulate apr_proc_detach, unix performs this
* same check in the pre_config hook (although it is
@@ -1404,12 +1404,12 @@ static int winnt_check_config(apr_pool_t *pconf, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec* s)
{
int is_parent;
- static int restart_num = 0;
int startup = 0;
/* We want this only in the parent and only the first time around */
is_parent = (parent_pid == my_pid);
- if (is_parent && restart_num++ == 0) {
+ if (is_parent &&
+ ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
startup = 1;
}
@@ -1496,7 +1496,6 @@ static int winnt_check_config(apr_pool_t *pconf, apr_pool_t *plog,
static int winnt_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec* s)
{
- static int restart_num = 0;
apr_status_t rv = 0;
/* Handle the following SCM aspects in this phase:
@@ -1556,7 +1555,8 @@ static int winnt_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pt
if (parent_pid == my_pid)
{
- if (restart_num++ == 1)
+ if (ap_state_query(AP_SQ_MAIN_STATE) != AP_SQ_MS_CREATE_PRE_CONFIG
+ && ap_state_query(AP_SQ_CONFIG_GEN) == 1)
{
/* This code should be run once in the parent and not run
* across a restart
diff --git a/server/mpm/winnt/mpm_winnt.h b/server/mpm/winnt/mpm_winnt.h
index f900fbf5..7452f9fb 100644
--- a/server/mpm/winnt/mpm_winnt.h
+++ b/server/mpm/winnt/mpm_winnt.h
@@ -80,8 +80,6 @@ extern DWORD stack_res_flag;
extern void clean_child_exit(int);
-void setup_signal_names(char *prefix);
-
typedef enum {
SIGNAL_PARENT_SHUTDOWN,
SIGNAL_PARENT_RESTART,
diff --git a/server/mpm/winnt/service.c b/server/mpm/winnt/service.c
index bf5f021a..f1d2c377 100644
--- a/server/mpm/winnt/service.c
+++ b/server/mpm/winnt/service.c
@@ -593,7 +593,7 @@ apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc,
schService = OpenService(schSCManager, mpm_service_name,
SERVICE_CHANGE_CONFIG);
if (!schService) {
- ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR,
+ ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP,
apr_get_os_error(), NULL,
"OpenService failed");
}
@@ -605,7 +605,7 @@ apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc,
launch_cmd, NULL, NULL,
"Tcpip\0Afd\0", NULL, NULL,
mpm_display_name)) {
- ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR,
+ ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP,
apr_get_os_error(), NULL,
"ChangeServiceConfig failed");
diff --git a/server/protocol.c b/server/protocol.c
index 30b3cd5e..e1ef2049 100644
--- a/server/protocol.c
+++ b/server/protocol.c
@@ -561,9 +561,6 @@ static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
const char *uri;
const char *pro;
-#if 0
- conn_rec *conn = r->connection;
-#endif
int major = 1, minor = 0; /* Assume HTTP/1.0 if non-"HTTP" protocol */
char http[5];
apr_size_t len;
@@ -627,20 +624,10 @@ static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
ap_escape_logitem(r->pool, r->the_request));
}
- /* we've probably got something to do, ignore graceful restart requests */
-
r->request_time = apr_time_now();
ll = r->the_request;
r->method = ap_getword_white(r->pool, &ll);
-#if 0
-/* XXX If we want to keep track of the Method, the protocol module should do
- * it. That support isn't in the scoreboard yet. Hopefully next week
- * sometime. rbb */
- ap_update_connection_status(AP_CHILD_THREAD_FROM_ID(conn->id), "Method",
- r->method);
-#endif
-
uri = ap_getword_white(r->pool, &ll);
/* Provide quick information about the request method as soon as known */
@@ -663,8 +650,6 @@ static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
}
r->protocol = apr_pstrmemdup(r->pool, pro, len);
- /* XXX ap_update_connection_status(conn->id, "Protocol", r->protocol); */
-
/* Avoid sscanf in the common case */
if (len == 8
&& pro[0] == 'H' && pro[1] == 'T' && pro[2] == 'T' && pro[3] == 'P'
@@ -918,7 +903,7 @@ request_rec *ap_read_request(conn_rec *conn)
request_rec *r;
apr_pool_t *p;
const char *expect;
- int access_status;
+ int access_status = HTTP_OK;
apr_bucket_brigade *tmp_bb;
apr_socket_t *csd;
apr_interval_time_t cur_timeout;
@@ -1086,7 +1071,7 @@ request_rec *ap_read_request(conn_rec *conn)
* HTTP/1.1 mentions twice (S9, S14.23) that a request MUST contain
* a Host: header, and the server MUST respond with 400 if it doesn't.
*/
- r->status = HTTP_BAD_REQUEST;
+ access_status = HTTP_BAD_REQUEST;
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00569)
"client sent HTTP/1.1 request without hostname "
"(see RFC2616 section 14.23): %s", r->uri);
@@ -1102,14 +1087,8 @@ request_rec *ap_read_request(conn_rec *conn)
ap_add_input_filter_handle(ap_http_input_filter_handle,
NULL, r, r->connection);
- if (r->status != HTTP_OK) {
- ap_send_error_response(r, 0);
- ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
- ap_run_log_transaction(r);
- goto traceout;
- }
-
- if ((access_status = ap_run_post_read_request(r))) {
+ if (access_status != HTTP_OK
+ || (access_status = ap_run_post_read_request(r))) {
ap_die(access_status, r);
ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);
ap_run_log_transaction(r);
diff --git a/server/provider.c b/server/provider.c
index a102dd85..cf307e7c 100644
--- a/server/provider.c
+++ b/server/provider.c
@@ -42,7 +42,7 @@ AP_DECLARE(apr_status_t) ap_register_provider(apr_pool_t *pool,
if (global_providers == NULL) {
global_providers = apr_hash_make(pool);
- global_providers_names = apr_hash_make(pool);;
+ global_providers_names = apr_hash_make(pool);
apr_pool_cleanup_register(pool, NULL, cleanup_global_providers,
apr_pool_cleanup_null);
}
diff --git a/server/util.c b/server/util.c
index 75e91a7b..d77719eb 100644
--- a/server/util.c
+++ b/server/util.c
@@ -62,6 +62,11 @@
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
+#ifdef HAVE_SYS_LOADAVG_H
+#include <sys/loadavg.h>
+#endif
+
+#include "ap_mpm.h"
/* A bunch of functions in util.c scan strings looking for certain characters.
* To make that more efficient we encode a lookup table. The test_char_table
@@ -273,8 +278,10 @@ AP_DECLARE(ap_regex_t *) ap_pregcomp(apr_pool_t *p, const char *pattern,
int cflags)
{
ap_regex_t *preg = apr_palloc(p, sizeof *preg);
-
- if (ap_regcomp(preg, pattern, cflags)) {
+ int err = ap_regcomp(preg, pattern, cflags);
+ if (err) {
+ if (err == AP_REG_ESPACE)
+ ap_abort_on_oom();
return NULL;
}
@@ -425,7 +432,7 @@ static apr_status_t regsub_core(apr_pool_t *p, char **result,
*result = dst = apr_palloc(p, len + 1);
}
else {
- if (vb->buf && vb->strlen == AP_VARBUF_UNKNOWN)
+ if (vb->strlen == AP_VARBUF_UNKNOWN)
vb->strlen = strlen(vb->buf);
ap_varbuf_grow(vb, vb->strlen + len);
dst = vb->buf + vb->strlen;
@@ -1093,11 +1100,22 @@ AP_DECLARE(apr_status_t) ap_varbuf_cfg_getline(struct ap_varbuf *vb,
apr_size_t max_len)
{
apr_status_t rc;
+ apr_size_t new_len;
vb->strlen = 0;
*vb->buf = '\0';
+ if (vb->strlen == AP_VARBUF_UNKNOWN)
+ vb->strlen = strlen(vb->buf);
+ if (vb->avail - vb->strlen < 3) {
+ new_len = vb->avail * 2;
+ if (new_len > max_len)
+ new_len = max_len;
+ else if (new_len < 3)
+ new_len = 3;
+ ap_varbuf_grow(vb, new_len);
+ }
+
for (;;) {
- apr_size_t new_len;
rc = ap_cfg_getline_core(vb->buf + vb->strlen, vb->avail - vb->strlen, cfp);
if (rc == APR_ENOSPC || rc == APR_SUCCESS)
vb->strlen += strlen(vb->buf + vb->strlen);
@@ -1940,6 +1958,18 @@ AP_DECLARE(apr_size_t) ap_escape_errorlog_item(char *dest, const char *source,
return (d - (unsigned char *)dest);
}
+AP_DECLARE(void) ap_bin2hex(const void *src, apr_size_t srclen, char *dest)
+{
+ const unsigned char *in = src;
+ apr_size_t i;
+
+ for (i = 0; i < srclen; i++) {
+ *dest++ = c2x_table[in[i] >> 4];
+ *dest++ = c2x_table[in[i] & 0xf];
+ }
+ *dest = '\0';
+}
+
AP_DECLARE(int) ap_is_directory(apr_pool_t *p, const char *path)
{
apr_finfo_t finfo;
@@ -2583,6 +2613,8 @@ AP_DECLARE(void) ap_varbuf_grow(struct ap_varbuf *vb, apr_size_t new_len)
struct ap_varbuf_info *new_info;
char *new;
+ AP_DEBUG_ASSERT(vb->strlen == AP_VARBUF_UNKNOWN || vb->avail >= vb->strlen);
+
if (new_len <= vb->avail)
return;
@@ -2702,9 +2734,10 @@ AP_DECLARE(char *) ap_varbuf_pdup(apr_pool_t *p, struct ap_varbuf *buf,
i++;
}
if (buf->avail && buf->strlen) {
+ if (buf->strlen == AP_VARBUF_UNKNOWN)
+ buf->strlen = strlen(buf->buf);
vec[i].iov_base = (void *)buf->buf;
- vec[i].iov_len = (buf->strlen == AP_VARBUF_UNKNOWN) ? buf->avail
- : buf->strlen;
+ vec[i].iov_len = buf->strlen;
i++;
}
if (append) {
@@ -2772,3 +2805,84 @@ AP_DECLARE(void *) ap_realloc(void *ptr, size_t size)
ap_abort_on_oom();
return p;
}
+
+AP_DECLARE(void) ap_get_sload(ap_sload_t *ld)
+{
+ int i, j, server_limit, thread_limit;
+ int ready = 0;
+ int busy = 0;
+ int total;
+ ap_generation_t mpm_generation;
+
+ /* preload errored fields, we overwrite */
+ ld->idle = -1;
+ ld->busy = -1;
+ ld->bytes_served = 0;
+ ld->access_count = 0;
+
+ ap_mpm_query(AP_MPMQ_GENERATION, &mpm_generation);
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit);
+
+ for (i = 0; i < server_limit; i++) {
+ process_score *ps;
+ ps = ap_get_scoreboard_process(i);
+
+ for (j = 0; j < thread_limit; j++) {
+ int res;
+ worker_score *ws = NULL;
+ ws = &ap_scoreboard_image->servers[i][j];
+ res = ws->status;
+
+ if (!ps->quiescing && ps->pid) {
+ if (res == SERVER_READY && ps->generation == mpm_generation) {
+ ready++;
+ }
+ else if (res != SERVER_DEAD &&
+ res != SERVER_STARTING && res != SERVER_IDLE_KILL &&
+ ps->generation == mpm_generation) {
+ busy++;
+ }
+ }
+
+ if (ap_extended_status && !ps->quiescing && ps->pid) {
+ if (ws->access_count != 0
+ || (res != SERVER_READY && res != SERVER_DEAD)) {
+ ld->access_count += ws->access_count;
+ ld->bytes_served += ws->bytes_served;
+ }
+ }
+ }
+ }
+ total = busy + ready;
+ if (total) {
+ ld->idle = ready * 100 / total;
+ ld->busy = busy * 100 / total;
+ }
+}
+
+AP_DECLARE(void) ap_get_loadavg(ap_loadavg_t *ld)
+{
+ /* preload errored fields, we overwrite */
+ ld->loadavg = -1.0;
+ ld->loadavg5 = -1.0;
+ ld->loadavg15 = -1.0;
+
+#if HAVE_GETLOADAVG
+ {
+ double la[3];
+ int num;
+
+ num = getloadavg(la, 3);
+ if (num > 0) {
+ ld->loadavg = (float)la[0];
+ }
+ if (num > 1) {
+ ld->loadavg5 = (float)la[1];
+ }
+ if (num > 2) {
+ ld->loadavg15 = (float)la[2];
+ }
+ }
+#endif
+}
diff --git a/server/util_expr_eval.c b/server/util_expr_eval.c
index 69959310..b350cfc7 100644
--- a/server/util_expr_eval.c
+++ b/server/util_expr_eval.c
@@ -968,6 +968,8 @@ static const char *req_table_func(ap_expr_eval_ctx_t *ctx, const void *data,
t = ctx->r->notes;
else if (name[3] == 'e') /* reqenv */
t = ctx->r->subprocess_env;
+ else if (name[3] == '_') /* req_novary */
+ t = ctx->r->headers_in;
else { /* req, http */
t = ctx->r->headers_in;
add_vary(ctx, arg);
@@ -1566,6 +1568,7 @@ static const struct expr_provider_single string_func_providers[] = {
{ req_table_func, "http", NULL, 0 },
{ req_table_func, "note", NULL, 0 },
{ req_table_func, "reqenv", NULL, 0 },
+ { req_table_func, "req_novary", NULL, 0 },
{ tolower_func, "tolower", NULL, 0 },
{ toupper_func, "toupper", NULL, 0 },
{ escape_func, "escape", NULL, 0 },
diff --git a/server/util_md5.c b/server/util_md5.c
index 83bfa757..148c60ce 100644
--- a/server/util_md5.c
+++ b/server/util_md5.c
@@ -52,11 +52,9 @@
AP_DECLARE(char *) ap_md5_binary(apr_pool_t *p, const unsigned char *buf, int length)
{
- const char *hex = "0123456789abcdef";
apr_md5_ctx_t my_md5;
unsigned char hash[APR_MD5_DIGESTSIZE];
- char *r, result[33]; /* (MD5_DIGESTSIZE * 2) + 1 */
- int i;
+ char result[2 * APR_MD5_DIGESTSIZE + 1];
/*
* Take the MD5 hash of the string argument.
@@ -69,11 +67,7 @@ AP_DECLARE(char *) ap_md5_binary(apr_pool_t *p, const unsigned char *buf, int le
apr_md5_update(&my_md5, buf, (unsigned int)length);
apr_md5_final(hash, &my_md5);
- for (i = 0, r = result; i < APR_MD5_DIGESTSIZE; i++) {
- *r++ = hex[hash[i] >> 4];
- *r++ = hex[hash[i] & 0xF];
- }
- *r = '\0';
+ ap_bin2hex(hash, APR_MD5_DIGESTSIZE, result);
return apr_pstrndup(p, result, APR_MD5_DIGESTSIZE*2);
}
diff --git a/server/util_pcre.c b/server/util_pcre.c
index 2d157c0c..1e83cad0 100644
--- a/server/util_pcre.c
+++ b/server/util_pcre.c
@@ -123,6 +123,7 @@ AP_DECLARE(int) ap_regcomp(ap_regex_t * preg, const char *pattern, int cflags)
{
const char *errorptr;
int erroffset;
+ int errcode = 0;
int options = 0;
if ((cflags & AP_REG_ICASE) != 0)
@@ -133,11 +134,18 @@ AP_DECLARE(int) ap_regcomp(ap_regex_t * preg, const char *pattern, int cflags)
options |= PCRE_DOTALL;
preg->re_pcre =
- pcre_compile(pattern, options, &errorptr, &erroffset, NULL);
+ pcre_compile2(pattern, options, &errcode, &errorptr, &erroffset, NULL);
preg->re_erroffset = erroffset;
- if (preg->re_pcre == NULL)
+ if (preg->re_pcre == NULL) {
+ /*
+ * There doesn't seem to be constants defined for compile time error
+ * codes. 21 is "failed to get memory" according to pcreapi(3).
+ */
+ if (errcode == 21)
+ return AP_REG_ESPACE;
return AP_REG_INVARG;
+ }
pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
PCRE_INFO_CAPTURECOUNT, &(preg->re_nsub));
diff --git a/server/util_script.c b/server/util_script.c
index 703d1600..5708c086 100644
--- a/server/util_script.c
+++ b/server/util_script.c
@@ -122,7 +122,7 @@ AP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t)
*whack++ = '_';
}
while (*whack != '=') {
- if (!apr_isalnum(*whack) && *whack != '_') {
+ if (!apr_isalnum(*whack)) {
*whack = '_';
}
++whack;
@@ -591,11 +591,11 @@ AP_DECLARE(int) ap_scan_script_header_err_core_ex(request_rec *r, char *buffer,
r->status = cgi_status = atoi(l);
if (!ap_is_HTTP_VALID_RESPONSE(cgi_status))
ap_log_rerror(SCRIPT_LOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r,
- "Invalid status line from script '%s': %s",
+ "Invalid status line from script '%s': %.30s",
apr_filepath_name_get(r->filename), l);
else
ap_log_rerror(SCRIPT_LOG_MARK, APLOG_TRACE1, 0, r,
- "Status line from script '%s': %s",
+ "Status line from script '%s': %.30s",
apr_filepath_name_get(r->filename), l);
r->status_line = apr_pstrdup(r->pool, l);
}
diff --git a/server/vhost.c b/server/vhost.c
index 302e4084..fd7c0ad6 100644
--- a/server/vhost.c
+++ b/server/vhost.c
@@ -754,8 +754,9 @@ static void fix_hostname(request_rec *r)
bad:
r->status = HTTP_BAD_REQUEST;
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00550)
- "Client sent malformed Host header");
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00550)
+ "Client sent malformed Host header: %s",
+ r->hostname);
return;
}