diff options
author | Arno Töll <arno@debian.org> | 2013-02-28 21:57:03 +0100 |
---|---|---|
committer | Arno Töll <arno@debian.org> | 2013-02-28 21:57:03 +0100 |
commit | 1697a801fb875664f7b269260511f5f4126a5e83 (patch) | |
tree | 89da4a9495e2ba6d6cb4e4dbae4184c7238a985a /server | |
parent | 5c4fba3ffbe778bdffe10a93d04821579601a020 (diff) | |
download | apache2-1697a801fb875664f7b269260511f5f4126a5e83.tar.gz |
Imported Upstream version 2.4.4upstream/2.4.4
Diffstat (limited to 'server')
-rw-r--r-- | server/Makefile.in | 2 | ||||
-rw-r--r-- | server/config.c | 12 | ||||
-rw-r--r-- | server/core.c | 19 | ||||
-rw-r--r-- | server/error_bucket.c | 2 | ||||
-rw-r--r-- | server/gen_test_char.c | 4 | ||||
-rw-r--r-- | server/listen.c | 5 | ||||
-rw-r--r-- | server/log.c | 10 | ||||
-rw-r--r-- | server/mpm/event/event.c | 6 | ||||
-rw-r--r-- | server/mpm/netware/mpm_netware.c | 4 | ||||
-rw-r--r-- | server/mpm/prefork/prefork.c | 13 | ||||
-rw-r--r-- | server/mpm/winnt/child.c | 5 | ||||
-rw-r--r-- | server/mpm/winnt/mpm_winnt.c | 42 | ||||
-rw-r--r-- | server/mpm/winnt/mpm_winnt.h | 2 | ||||
-rw-r--r-- | server/mpm/winnt/service.c | 4 | ||||
-rw-r--r-- | server/protocol.c | 29 | ||||
-rw-r--r-- | server/provider.c | 2 | ||||
-rw-r--r-- | server/util.c | 126 | ||||
-rw-r--r-- | server/util_expr_eval.c | 3 | ||||
-rw-r--r-- | server/util_md5.c | 10 | ||||
-rw-r--r-- | server/util_pcre.c | 12 | ||||
-rw-r--r-- | server/util_script.c | 6 | ||||
-rw-r--r-- | server/vhost.c | 5 |
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; } |