summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorArno Töll <arno@debian.org>2012-11-21 23:03:47 +0100
committerArno Töll <arno@debian.org>2012-11-21 23:03:47 +0100
commita4197a3a45fd2b20d05c079d49af9fbef5fd4e2e (patch)
tree6777fddb60ecea91715e0ce39298a8366c27a40d /src
parent0f22664a8c9f92c8b7d5dd05772bacf7caecbd52 (diff)
downloadlighttpd-a4197a3a45fd2b20d05c079d49af9fbef5fd4e2e.tar.gz
Imported Upstream version 1.4.16upstream/1.4.16
Diffstat (limited to 'src')
-rw-r--r--src/base.h6
-rw-r--r--src/configfile.c26
-rw-r--r--src/connections.c14
-rw-r--r--src/etag.c24
-rw-r--r--src/etag.h4
-rw-r--r--src/http_auth.c25
-rw-r--r--src/mod_access.c37
-rw-r--r--src/mod_accesslog.c2
-rw-r--r--src/mod_fastcgi.c100
-rw-r--r--src/mod_scgi.c6
-rw-r--r--src/mod_ssi.c2
-rw-r--r--src/mod_staticfile.c19
-rw-r--r--src/mod_status.c11
-rw-r--r--src/mod_webdav.c4
-rw-r--r--src/proc_open.c2
-rw-r--r--src/request.c33
-rw-r--r--src/server.c16
-rw-r--r--src/spawn-fcgi.c2
-rw-r--r--src/stat_cache.c6
19 files changed, 248 insertions, 91 deletions
diff --git a/src/base.h b/src/base.h
index a647f08..bff7f91 100644
--- a/src/base.h
+++ b/src/base.h
@@ -25,6 +25,7 @@
#include "fdevent.h"
#include "sys-socket.h"
#include "splaytree.h"
+#include "etag.h"
#if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H
@@ -269,6 +270,9 @@ typedef struct {
unsigned short use_ipv6;
unsigned short is_ssl;
unsigned short allow_http11;
+ unsigned short etag_use_inode;
+ unsigned short etag_use_mtime;
+ unsigned short etag_use_size;
unsigned short force_lowercase_filenames; /* if the FS is case-insensitive, force all files to lower-case */
unsigned short max_request_size;
@@ -410,6 +414,8 @@ typedef struct {
SSL *ssl;
buffer *ssl_error_want_reuse_buffer;
#endif
+ /* etag handling */
+ etag_flags_t etag_flags;
} connection;
typedef struct {
diff --git a/src/configfile.c b/src/configfile.c
index 5ff3261..921109f 100644
--- a/src/configfile.c
+++ b/src/configfile.c
@@ -89,7 +89,9 @@ static int config_insert(server *srv) {
{ "server.core-files", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 45 */
{ "ssl.cipher-list", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 46 */
{ "ssl.use-sslv2", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 47 */
-
+ { "etag.use-inode", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 48 */
+ { "etag.use-mtime", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 49 */
+ { "etag.use-size", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 50 */
{ "server.host", "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
{ "server.docroot", "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
{ "server.virtual-root", "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
@@ -162,6 +164,9 @@ static int config_insert(server *srv) {
#endif
s->kbytes_per_second = 0;
s->allow_http11 = 1;
+ s->etag_use_inode = 1;
+ s->etag_use_mtime = 1;
+ s->etag_use_size = 1;
s->range_requests = 1;
s->force_lowercase_filenames = 0;
s->global_kbytes_per_second = 0;
@@ -206,6 +211,9 @@ static int config_insert(server *srv) {
cv[46].destination = s->ssl_cipher_list;
cv[47].destination = &(s->ssl_use_sslv2);
+ cv[48].destination = &(s->etag_use_inode);
+ cv[49].destination = &(s->etag_use_mtime);
+ cv[50].destination = &(s->etag_use_size);
srv->config_storage[i] = s;
@@ -280,8 +288,10 @@ int config_setup_connection(server *srv, connection *con) {
PATCH(ssl_ca_file);
PATCH(ssl_cipher_list);
PATCH(ssl_use_sslv2);
-
-
+ PATCH(etag_use_inode);
+ PATCH(etag_use_mtime);
+ PATCH(etag_use_size);
+
return 0;
}
@@ -323,6 +333,12 @@ int config_patch_connection(server *srv, connection *con, comp_key_t comp) {
PATCH(max_read_idle);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("mimetype.use-xattr"))) {
PATCH(use_xattr);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("etag.use-inode"))) {
+ PATCH(etag_use_inode);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("etag.use-mtime"))) {
+ PATCH(etag_use_mtime);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("etag.use-size"))) {
+ PATCH(etag_use_size);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.pemfile"))) {
PATCH(ssl_pemfile);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.ca-file"))) {
@@ -365,6 +381,10 @@ int config_patch_connection(server *srv, connection *con, comp_key_t comp) {
}
}
+ con->etag_flags = (con->conf.etag_use_mtime ? ETAG_USE_MTIME : 0) |
+ (con->conf.etag_use_inode ? ETAG_USE_INODE : 0) |
+ (con->conf.etag_use_size ? ETAG_USE_SIZE : 0);
+
return 0;
}
#undef PATCH
diff --git a/src/connections.c b/src/connections.c
index 806e4b6..2f715ef 100644
--- a/src/connections.c
+++ b/src/connections.c
@@ -1252,6 +1252,16 @@ connection *connection_accept(server *srv, server_socket *srv_socket) {
socklen_t cnt_len;
/* accept it and register the fd */
+ /**
+ * check if we can still open a new connections
+ *
+ * see #1216
+ */
+
+ if (srv->conns->used >= srv->max_conns) {
+ return NULL;
+ }
+
cnt_len = sizeof(cnt_addr);
if (-1 == (cnt = accept(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len))) {
@@ -1265,6 +1275,9 @@ connection *connection_accept(server *srv, server_socket *srv_socket) {
case ECONNABORTED: /* this is a FreeBSD thingy */
/* we were stopped _after_ we had a connection */
break;
+ case EMFILE:
+ /* out of fds */
+ break;
default:
log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), errno);
}
@@ -1432,6 +1445,7 @@ int connection_state_machine(server *srv, connection *con) {
} else if (con->in_error_handler) {
/* error-handler is back and has generated content */
/* if Status: was set, take it otherwise use 200 */
+ con->http_status = con->error_handler_saved_status;
}
if (con->http_status == 0) con->http_status = 200;
diff --git a/src/etag.c b/src/etag.c
index 4f7e95b..91207ca 100644
--- a/src/etag.c
+++ b/src/etag.c
@@ -8,12 +8,24 @@ int etag_is_equal(buffer *etag, const char *matches) {
return 0;
}
-int etag_create(buffer *etag, struct stat *st) {
- buffer_copy_off_t(etag, st->st_ino);
- buffer_append_string_len(etag, CONST_STR_LEN("-"));
- buffer_append_off_t(etag, st->st_size);
- buffer_append_string_len(etag, CONST_STR_LEN("-"));
- buffer_append_long(etag, st->st_mtime);
+int etag_create(buffer *etag, struct stat *st,etag_flags_t flags) {
+ if (0 == flags) return 0;
+
+ buffer_reset(etag);
+
+ if (flags & ETAG_USE_INODE) {
+ buffer_append_off_t(etag, st->st_ino);
+ buffer_append_string_len(etag, CONST_STR_LEN("-"));
+ }
+
+ if (flags & ETAG_USE_SIZE) {
+ buffer_append_off_t(etag, st->st_size);
+ buffer_append_string_len(etag, CONST_STR_LEN("-"));
+ }
+
+ if (flags & ETAG_USE_MTIME) {
+ buffer_append_long(etag, st->st_mtime);
+ }
return 0;
}
diff --git a/src/etag.h b/src/etag.h
index 4856cab..5fefe0f 100644
--- a/src/etag.h
+++ b/src/etag.h
@@ -7,8 +7,10 @@
#include "buffer.h"
+typedef enum { ETAG_USE_INODE = 1, ETAG_USE_MTIME = 2, ETAG_USE_SIZE = 4 } etag_flags_t;
+
int etag_is_equal(buffer *etag, const char *matches);
-int etag_create(buffer *etag, struct stat *st);
+int etag_create(buffer *etag, struct stat *st, etag_flags_t flags);
int etag_mutate(buffer *mut, buffer *etag);
diff --git a/src/http_auth.c b/src/http_auth.c
index fc125cf..abb69f5 100644
--- a/src/http_auth.c
+++ b/src/http_auth.c
@@ -830,7 +830,13 @@ int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p,
username = buffer_init();
- base64_decode(username, realm_str);
+ if (!base64_decode(username, realm_str)) {
+ buffer_free(username);
+
+ log_error_write(srv, __FILE__, __LINE__, "sb", "decodeing base64-string failed", username);
+
+ return 0;
+ }
/* r2 == user:password */
if (NULL == (pw = strchr(username->ptr, ':'))) {
@@ -967,7 +973,7 @@ int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p
for (c = b->ptr; *c; c++) {
/* skip whitespaces */
while (*c == ' ' || *c == '\t') c++;
- if (!c) break;
+ if (!*c) break;
for (i = 0; dkv[i].key; i++) {
if ((0 == strncmp(c, dkv[i].key, dkv[i].key_len))) {
@@ -1016,6 +1022,21 @@ int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p
log_error_write(srv, __FILE__, __LINE__, "s",
"digest: missing field");
+
+ buffer_free(b);
+ return -1;
+ }
+
+ /**
+ * protect the md5-sess against missing cnonce and nonce
+ */
+ if (algorithm &&
+ 0 == strcasecmp(algorithm, "md5-sess") &&
+ (!nonce || !cnonce)) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "digest: (md5-sess: missing field");
+
+ buffer_free(b);
return -1;
}
diff --git a/src/mod_access.c b/src/mod_access.c
index 3fc0599..f100c80 100644
--- a/src/mod_access.c
+++ b/src/mod_access.c
@@ -111,6 +111,15 @@ static int mod_access_patch_connection(server *srv, connection *con, plugin_data
}
#undef PATCH
+/**
+ * URI handler
+ *
+ * we will get called twice:
+ * - after the clean up of the URL and
+ * - after the pathinfo checks are done
+ *
+ * this handles the issue of trailing slashes
+ */
URIHANDLER_FUNC(mod_access_uri_handler) {
plugin_data *p = p_d;
int s_len;
@@ -122,28 +131,41 @@ URIHANDLER_FUNC(mod_access_uri_handler) {
s_len = con->uri.path->used - 1;
+ if (con->conf.log_request_handling) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "-- mod_access_uri_handler called");
+ }
+
for (k = 0; k < p->conf.access_deny->used; k++) {
data_string *ds = (data_string *)p->conf.access_deny->data[k];
int ct_len = ds->value->used - 1;
+ int denied = 0;
- if (ct_len > s_len) continue;
+ if (ct_len > s_len) continue;
if (ds->value->used == 0) continue;
/* if we have a case-insensitive FS we have to lower-case the URI here too */
if (con->conf.force_lowercase_filenames) {
if (0 == strncasecmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
- con->http_status = 403;
-
- return HANDLER_FINISHED;
+ denied = 1;
}
} else {
if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
- con->http_status = 403;
+ denied = 1;
+ }
+ }
- return HANDLER_FINISHED;
+ if (denied) {
+ con->http_status = 403;
+
+ if (con->conf.log_request_handling) {
+ log_error_write(srv, __FILE__, __LINE__, "sb",
+ "url denied as we match:", ds->value);
}
+
+ return HANDLER_FINISHED;
}
}
@@ -158,7 +180,8 @@ int mod_access_plugin_init(plugin *p) {
p->init = mod_access_init;
p->set_defaults = mod_access_set_defaults;
- p->handle_uri_clean = mod_access_uri_handler;
+ p->handle_uri_clean = mod_access_uri_handler;
+ p->handle_subrequest_start = mod_access_uri_handler;
p->cleanup = mod_access_free;
p->data = NULL;
diff --git a/src/mod_accesslog.c b/src/mod_accesslog.c
index 32570a1..a3516d5 100644
--- a/src/mod_accesslog.c
+++ b/src/mod_accesslog.c
@@ -507,7 +507,7 @@ SETDEFAULTS_FUNC(log_access_open) {
*
*/
- execl("/bin/sh", "sh", "-c", s->access_logfile->ptr + 1, NULL);
+ execl("/bin/sh", "sh", "-c", s->access_logfile->ptr + 1, (char *)NULL);
log_error_write(srv, __FILE__, __LINE__, "sss",
"spawning log-process failed: ", strerror(errno),
diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c
index 624c29f..2e7f339 100644
--- a/src/mod_fastcgi.c
+++ b/src/mod_fastcgi.c
@@ -69,7 +69,7 @@ typedef struct fcgi_proc {
buffer *unixsocket; /* config.socket + "-" + id */
unsigned port; /* config.port + pno */
- buffer *connection_name; /* either tcp:<host>:<port> or unix:<socket> for debuggin purposes */
+ buffer *connection_name; /* either tcp:<host>:<port> or unix:<socket> for debugging purposes */
pid_t pid; /* PID of the spawned process (0 if not spawned locally) */
@@ -80,7 +80,7 @@ typedef struct fcgi_proc {
size_t requests; /* see max_requests */
struct fcgi_proc *prev, *next; /* see first */
- time_t disabled_until; /* this proc is disabled until, use something else until than */
+ time_t disabled_until; /* this proc is disabled until, use something else until then */
int is_local;
@@ -88,7 +88,7 @@ typedef struct fcgi_proc {
PROC_STATE_UNSET, /* init-phase */
PROC_STATE_RUNNING, /* alive */
PROC_STATE_OVERLOADED, /* listen-queue is full,
- don't send something to this proc for the next 2 seconds */
+ don't send anything to this proc for the next 2 seconds */
PROC_STATE_DIED_WAIT_FOR_PID, /* */
PROC_STATE_DIED, /* marked as dead, should be restarted */
PROC_STATE_KILLED /* was killed as we don't have the load anymore */
@@ -145,7 +145,7 @@ typedef struct {
unsigned short disable_time;
/*
- * same fastcgi processes get a little bit larger
+ * some fastcgi processes get a little bit larger
* than wanted. max_requests_per_proc kills a
* process after a number of handled requests.
*
@@ -184,7 +184,7 @@ typedef struct {
* bin-path is the path to the binary
*
* check min_procs and max_procs for the number
- * of process to start-up
+ * of process to start up
*/
buffer *bin_path;
@@ -217,7 +217,7 @@ typedef struct {
unsigned short mode;
/*
- * check_local tell you if the phys file is stat()ed
+ * check_local tells you if the phys file is stat()ed
* or not. FastCGI doesn't care if the service is
* remote. If the web-server side doesn't contain
* the fastcgi-files we should not stat() for them
@@ -228,7 +228,7 @@ typedef struct {
/*
* append PATH_INFO to SCRIPT_FILENAME
*
- * php needs this if cgi.fix_pathinfo is provied
+ * php needs this if cgi.fix_pathinfo is provided
*
*/
@@ -247,7 +247,7 @@ typedef struct {
num_procs.
only if a process is killed max_id waits for the process itself
- to die and decrements its afterwards */
+ to die and decrements it afterwards */
buffer *strip_request_uri;
@@ -826,7 +826,7 @@ static int fcgi_spawn_connection(server *srv,
} else {
struct hostent *he;
- /* set a usefull default */
+ /* set a useful default */
fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
@@ -869,7 +869,7 @@ static int fcgi_spawn_connection(server *srv,
}
if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) {
- /* server is not up, spawn in */
+ /* server is not up, spawn it */
pid_t child;
int val;
@@ -1029,10 +1029,11 @@ static int fcgi_spawn_connection(server *srv,
"child exited with status",
WEXITSTATUS(status), host->bin_path);
log_error_write(srv, __FILE__, __LINE__, "s",
- "if you try do run PHP as FastCGI backend make sure you use the FastCGI enabled version.\n"
+ "If you're trying to run PHP as a FastCGI backend, make sure you're using the FastCGI-enabled version.\n"
"You can find out if it is the right one by executing 'php -v' and it should display '(cgi-fcgi)' "
- "in the output, NOT (cgi) NOR (cli)\n"
- "For more information check http://www.lighttpd.net/documentation/fastcgi.html#preparing-php-as-a-fastcgi-program");
+ "in the output, NOT '(cgi)' NOR '(cli)'.\n"
+ "For more information, check http://trac.lighttpd.net/trac/wiki/Docs%3AModFastCGI#preparing-php-as-a-fastcgi-program"
+ "If this is PHP on Gentoo, add 'fastcgi' to the USE flags.");
} else if (WIFSIGNALED(status)) {
log_error_write(srv, __FILE__, __LINE__, "sd",
"terminated by signal:",
@@ -1040,9 +1041,9 @@ static int fcgi_spawn_connection(server *srv,
if (WTERMSIG(status) == 11) {
log_error_write(srv, __FILE__, __LINE__, "s",
- "to be exact: it seg-fault, crashed, died, ... you get the idea." );
+ "to be exact: it segfaulted, crashed, died, ... you get the idea." );
log_error_write(srv, __FILE__, __LINE__, "s",
- "If this is PHP try to remove the byte-code caches for now and try again.");
+ "If this is PHP, try removing the bytecode caches for now and try again.");
}
} else {
log_error_write(srv, __FILE__, __LINE__, "sd",
@@ -1066,7 +1067,7 @@ static int fcgi_spawn_connection(server *srv,
if (p->conf.debug) {
log_error_write(srv, __FILE__, __LINE__, "sb",
- "(debug) socket is already used, won't spawn:",
+ "(debug) socket is already used; won't spawn:",
proc->connection_name);
}
}
@@ -1508,7 +1509,7 @@ static int fcgi_reconnect(server *srv, handler_ctx *hctx) {
*
* next step is resetting this attemp and setup a connection again
*
- * if we have more then 5 reconnects for the same request, die
+ * if we have more than 5 reconnects for the same request, die
*
* 2.
*
@@ -1626,7 +1627,7 @@ typedef enum {
CONNECTION_UNSET,
CONNECTION_OK,
CONNECTION_DELAYED, /* retry after event, take same host */
- CONNECTION_OVERLOADED, /* disable for 1 seconds, take another backend */
+ CONNECTION_OVERLOADED, /* disable for 1 second, take another backend */
CONNECTION_DEAD /* disable for 60 seconds, take another backend */
} connection_result_t;
@@ -1669,7 +1670,7 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h
fcgi_addr_in.sin_family = AF_INET;
if (0 == inet_aton(host->host->ptr, &(fcgi_addr_in.sin_addr))) {
log_error_write(srv, __FILE__, __LINE__, "sbs",
- "converting IP-adress failed for", host->host,
+ "converting IP address failed for", host->host,
"\nBe sure to specify an IP address here");
return -1;
@@ -1694,16 +1695,16 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h
errno == EINTR) {
if (hctx->conf.debug > 2) {
log_error_write(srv, __FILE__, __LINE__, "sb",
- "connect delayed, will continue later:", proc->connection_name);
+ "connect delayed; will continue later:", proc->connection_name);
}
return CONNECTION_DELAYED;
} else if (errno == EAGAIN) {
if (hctx->conf.debug) {
log_error_write(srv, __FILE__, __LINE__, "sbsd",
- "This means that the you have more incoming requests than your fastcgi-backend can handle in parallel. "
- "Perhaps it helps to spawn more fastcgi backend or php-children, if not decrease server.max-connections."
- "The load for this fastcgi backend", proc->connection_name, "is", proc->load);
+ "This means that you have more incoming requests than your FastCGI backend can handle in parallel."
+ "It might help to spawn more FastCGI backends or PHP children; if not, decrease server.max-connections."
+ "The load for this FastCGI backend", proc->connection_name, "is", proc->load);
}
return CONNECTION_OVERLOADED;
@@ -1881,8 +1882,6 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
if (!buffer_is_empty(con->authed_user)) {
- fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_USER"), CONST_BUF_LEN(con->authed_user));
-
/* AUTH_TYPE fix by Troy Kruthoff (tkruthoff@gmail.com)
* section 4.1.1 of RFC 3875 (cgi spec) requires the server to set a AUTH_TYPE env
* declaring the type of authentication used. (see http://tools.ietf.org/html/rfc3875#page-11)
@@ -1896,6 +1895,8 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
char *http_authorization = NULL;
data_string *ds;
+ fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_USER"), CONST_BUF_LEN(con->authed_user));
+
if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Authorization"))) {
http_authorization = ds->value->ptr;
}
@@ -2055,8 +2056,8 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
off_t written = 0;
off_t weHave = 0;
- /* we announce toWrite octects
- * now take all the request_content chunk that we need to fill this request
+ /* we announce toWrite octets
+ * now take all the request_content chunks that we need to fill this request
* */
b = chunkqueue_get_append_buffer(hctx->wb);
@@ -2356,7 +2357,7 @@ static int fastcgi_get_packet(server *srv, handler_ctx *hctx, fastcgi_response_p
}
if (packet->b->used < packet->len + 1) {
- /* we didn't got the full packet */
+ /* we didn't get the full packet */
buffer_free(packet->b);
return -1;
@@ -2439,7 +2440,6 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
b->used = r + 1; /* one extra for the fake \0 */
b->ptr[b->used - 1] = '\0';
} else {
- if (errno == EAGAIN) return 0;
log_error_write(srv, __FILE__, __LINE__, "ssdsb",
"unexpected end-of-file (perhaps the fastcgi process died):",
"pid:", proc->pid,
@@ -2558,7 +2558,7 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
if (host->mode != FCGI_AUTHORIZER ||
!(con->http_status == 0 ||
con->http_status == 200)) {
- /* send chunk-end if nesseary */
+ /* send chunk-end if necessary */
http_chunk_append_mem(srv, con, NULL, 0);
joblist_append(srv, con);
}
@@ -2653,7 +2653,7 @@ static int fcgi_restart_dead_procs(server *srv, plugin_data *p, fcgi_extension_h
if (proc->state != PROC_STATE_DIED) break;
case PROC_STATE_DIED:
- /* local proc get restarted by us,
+ /* local procs get restarted by us,
* remote ones hopefully by the admin */
if (proc->is_local) {
@@ -2774,7 +2774,7 @@ static handler_t fcgi_write_request(server *srv, handler_ctx *hctx) {
proc && proc->state != PROC_STATE_RUNNING;
proc = proc->next);
- /* all childs are dead */
+ /* all children are dead */
if (proc == NULL) {
hctx->fde_ndx = -1;
@@ -2834,7 +2834,7 @@ static handler_t fcgi_write_request(server *srv, handler_ctx *hctx) {
* -> EAGAIN */
log_error_write(srv, __FILE__, __LINE__, "ssdsd",
- "backend is overloaded, we disable it for a 2 seconds and send the request to another backend instead:",
+ "backend is overloaded; we'll disable it for 2 seconds and send the request to another backend instead:",
"reconnects:", hctx->reconnects,
"load:", host->load);
@@ -2864,7 +2864,7 @@ static handler_t fcgi_write_request(server *srv, handler_ctx *hctx) {
}
log_error_write(srv, __FILE__, __LINE__, "ssdsd",
- "backend died, we disable it for a 5 seconds and send the request to another backend instead:",
+ "backend died; we'll disable it for 5 seconds and send the request to another backend instead:",
"reconnects:", hctx->reconnects,
"load:", host->load);
@@ -2950,7 +2950,7 @@ static handler_t fcgi_write_request(server *srv, handler_ctx *hctx) {
if (hctx->wb->bytes_out == 0 &&
hctx->reconnects < 5) {
usleep(10000); /* take away the load of the webserver
- * to let the php a chance to restart
+ * to give the php a chance to restart
*/
fcgi_reconnect(srv, hctx);
@@ -2964,7 +2964,7 @@ static handler_t fcgi_write_request(server *srv, handler_ctx *hctx) {
*
*/
- log_error_write(srv, __FILE__, __LINE__, "ssdsd",
+ log_error_write(srv, __FILE__, __LINE__, "ssosd",
"[REPORT ME] connection was dropped after accept(). reconnect() denied:",
"write-offset:", hctx->wb->bytes_out,
"reconnect attempts:", hctx->reconnects);
@@ -3152,9 +3152,9 @@ static handler_t fcgi_handle_fdevent(void *s, void *ctx, int revents) {
(con->http_status == 200 ||
con->http_status == 0)) {
/*
- * If we are here in AUTHORIZER mode then a request for autorizer
- * was proceeded already, and status 200 has been returned. We need
- * now to handle autorized request.
+ * If we are here in AUTHORIZER mode then a request for authorizer
+ * was processed already, and status 200 has been returned. We need
+ * now to handle authorized request.
*/
buffer_copy_string_buffer(con->physical.doc_root, host->docroot);
@@ -3220,7 +3220,7 @@ static handler_t fcgi_handle_fdevent(void *s, void *ctx, int revents) {
}
if (con->file_started == 0) {
- /* nothing has been send out yet, try to use another child */
+ /* nothing has been sent out yet, try to use another child */
if (hctx->wb->bytes_out == 0 &&
hctx->reconnects < 5) {
@@ -3270,8 +3270,8 @@ static handler_t fcgi_handle_fdevent(void *s, void *ctx, int revents) {
hctx->state == FCGI_STATE_WRITE) {
/* we are allowed to send something out
*
- * 1. in a unfinished connect() call
- * 2. in a unfinished write() call (long POST request)
+ * 1. in an unfinished connect() call
+ * 2. in an unfinished write() call (long POST request)
*/
return mod_fastcgi_handle_subrequest(srv, con, p);
} else {
@@ -3286,8 +3286,8 @@ static handler_t fcgi_handle_fdevent(void *s, void *ctx, int revents) {
if (hctx->state == FCGI_STATE_CONNECT_DELAYED) {
/* getoptsock will catch this one (right ?)
*
- * if we are in connect we might get a EINPROGRESS
- * in the first call and a FDEVENT_HUP in the
+ * if we are in connect we might get an EINPROGRESS
+ * in the first call and an FDEVENT_HUP in the
* second round
*
* FIXME: as it is a bit ugly.
@@ -3485,7 +3485,7 @@ static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, i
return HANDLER_FINISHED;
}
- /* a note about no handler is not sent yey */
+ /* a note about no handler is not sent yet */
extension->note_is_sent = 0;
/*
@@ -3520,7 +3520,7 @@ static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, i
}
/* the prefix is the SCRIPT_NAME,
- * everthing from start to the next slash
+ * everything from start to the next slash
* this is important for check-local = "disable"
*
* if prefix = /admin.fcgi
@@ -3630,13 +3630,13 @@ TRIGGER_FUNC(mod_fastcgi_handle_trigger) {
/* perhaps we should kill a connect attempt after 10-15 seconds
*
- * currently we wait for the TCP timeout which is on Linux 180 seconds
+ * currently we wait for the TCP timeout which is 180 seconds on Linux
*
*
*
*/
- /* check all childs if they are still up */
+ /* check all children if they are still up */
for (i = 0; i < srv->config_context->used; i++) {
plugin_config *conf;
@@ -3718,11 +3718,11 @@ TRIGGER_FUNC(mod_fastcgi_handle_trigger) {
if (srv->cur_ts - proc->last_used > host->idle_timeout) {
/* a proc is idling for a long time now,
- * terminated it */
+ * terminate it */
if (p->conf.debug) {
log_error_write(srv, __FILE__, __LINE__, "ssbsd",
- "idle-timeout reached, terminating child:",
+ "idle-timeout reached; terminating child:",
"socket:", proc->connection_name,
"pid", proc->pid);
}
diff --git a/src/mod_scgi.c b/src/mod_scgi.c
index 1948260..5680091 100644
--- a/src/mod_scgi.c
+++ b/src/mod_scgi.c
@@ -803,7 +803,7 @@ static int scgi_spawn_connection(server *srv,
buffer_append_string_buffer(b, host->bin_path);
/* exec the cgi */
- execle("/bin/sh", "sh", "-c", b->ptr, NULL, env.ptr);
+ execle("/bin/sh", "sh", "-c", b->ptr, (char *)NULL, env.ptr);
log_error_write(srv, __FILE__, __LINE__, "sbs",
"execl failed for:", host->bin_path, strerror(errno));
@@ -2286,7 +2286,7 @@ static handler_t scgi_write_request(server *srv, handler_ctx *hctx) {
*
*/
- log_error_write(srv, __FILE__, __LINE__, "ssdsd",
+ log_error_write(srv, __FILE__, __LINE__, "ssosd",
"[REPORT ME] connection was dropped after accept(). reconnect() denied:",
"write-offset:", hctx->wb->bytes_out,
"reconnect attempts:", hctx->reconnects);
@@ -2536,7 +2536,7 @@ static handler_t scgi_handle_fdevent(void *s, void *ctx, int revents) {
return HANDLER_WAIT_FOR_FD;
}
- log_error_write(srv, __FILE__, __LINE__, "sdsdsd",
+ log_error_write(srv, __FILE__, __LINE__, "sosdsd",
"response not sent, request sent:", hctx->wb->bytes_out,
"connection-fd:", con->fd,
"fcgi-fd:", hctx->fd);
diff --git a/src/mod_ssi.c b/src/mod_ssi.c
index e66a6fc..6621f9d 100644
--- a/src/mod_ssi.c
+++ b/src/mod_ssi.c
@@ -702,7 +702,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p,
/* close stdin */
close(STDIN_FILENO);
- execl("/bin/sh", "sh", "-c", cmd, NULL);
+ execl("/bin/sh", "sh", "-c", cmd, (char *)NULL);
log_error_write(srv, __FILE__, __LINE__, "sss", "spawing exec failed:", strerror(errno), cmd);
diff --git a/src/mod_staticfile.c b/src/mod_staticfile.c
index 61ff373..e371410 100644
--- a/src/mod_staticfile.c
+++ b/src/mod_staticfile.c
@@ -25,6 +25,7 @@
typedef struct {
array *exclude_ext;
+ unsigned short etags_used;
} plugin_config;
typedef struct {
@@ -82,6 +83,7 @@ SETDEFAULTS_FUNC(mod_staticfile_set_defaults) {
config_values_t cv[] = {
{ "static-file.exclude-extensions", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
+ { "static-file.etags", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
@@ -94,8 +96,10 @@ SETDEFAULTS_FUNC(mod_staticfile_set_defaults) {
s = calloc(1, sizeof(plugin_config));
s->exclude_ext = array_init();
+ s->etags_used = 1;
cv[0].destination = s->exclude_ext;
+ cv[1].destination = &(s->etags_used);
p->config_storage[i] = s;
@@ -114,6 +118,7 @@ static int mod_staticfile_patch_connection(server *srv, connection *con, plugin_
plugin_config *s = p->config_storage[0];
PATCH(exclude_ext);
+ PATCH(etags_used);
/* skip the first, the global context */
for (i = 1; i < srv->config_context->used; i++) {
@@ -129,7 +134,9 @@ static int mod_staticfile_patch_connection(server *srv, connection *con, plugin_
if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.exclude-extensions"))) {
PATCH(exclude_ext);
- }
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.etags"))) {
+ PATCH(etags_used);
+ }
}
}
@@ -446,11 +453,13 @@ URIHANDLER_FUNC(mod_staticfile_subrequest) {
response_header_overwrite(srv, con, CONST_STR_LEN("Accept-Ranges"), CONST_STR_LEN("bytes"));
if (allow_caching) {
- if (NULL == array_get_element(con->response.headers, "ETag")) {
- /* generate e-tag */
- etag_mutate(con->physical.etag, sce->etag);
+ if (p->conf.etags_used && con->etag_flags != 0 && !buffer_is_empty(sce->etag)) {
+ if (NULL == array_get_element(con->response.headers, "ETag")) {
+ /* generate e-tag */
+ etag_mutate(con->physical.etag, sce->etag);
- response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
+ response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
+ }
}
/* prepare header */
diff --git a/src/mod_status.c b/src/mod_status.c
index 2a4003a..e64cb29 100644
--- a/src/mod_status.c
+++ b/src/mod_status.c
@@ -220,6 +220,7 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
BUFFER_APPEND_STRING_CONST(b,
" <style type=\"text/css\">\n"
" table.status { border: black solid thin; }\n"
+ " td { white-space: nowrap; }\n"
" td.int { background-color: #f0f0f0; text-align: right }\n"
" td.string { background-color: #f0f0f0; text-align: left }\n"
" th.status { background-color: black; color: white; font-weight: bold; }\n"
@@ -520,6 +521,16 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.path), ENCODING_HTML);
}
+ if (!buffer_is_empty(c->uri.query)) {
+ BUFFER_APPEND_STRING_CONST(b, "?");
+ buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.query), ENCODING_HTML);
+ }
+
+ if (!buffer_is_empty(c->request.orig_uri)) {
+ BUFFER_APPEND_STRING_CONST(b, " (");
+ buffer_append_string_encoded(b, CONST_BUF_LEN(c->request.orig_uri), ENCODING_HTML);
+ BUFFER_APPEND_STRING_CONST(b, ")");
+ }
BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
buffer_append_string_buffer(b, c->physical.path);
diff --git a/src/mod_webdav.c b/src/mod_webdav.c
index d7bab2f..1432618 100644
--- a/src/mod_webdav.c
+++ b/src/mod_webdav.c
@@ -1035,7 +1035,7 @@ static int webdav_parse_chunkqueue(server *srv, connection *con, plugin_data *p,
}
if (XML_ERR_OK != (err = xmlParseChunk(ctxt, c->file.mmap.start + c->offset, weHave, 0))) {
- log_error_write(srv, __FILE__, __LINE__, "sddd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
+ log_error_write(srv, __FILE__, __LINE__, "sodd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
}
c->offset += weHave;
@@ -1053,7 +1053,7 @@ static int webdav_parse_chunkqueue(server *srv, connection *con, plugin_data *p,
}
if (XML_ERR_OK != (err = xmlParseChunk(ctxt, c->mem->ptr + c->offset, weHave, 0))) {
- log_error_write(srv, __FILE__, __LINE__, "sddd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
+ log_error_write(srv, __FILE__, __LINE__, "sodd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
}
c->offset += weHave;
diff --git a/src/proc_open.c b/src/proc_open.c
index ad2650d..1f55b61 100644
--- a/src/proc_open.c
+++ b/src/proc_open.c
@@ -255,7 +255,7 @@ int proc_open(proc_handler_t *proc, const char *command) {
*/
proc_close_parents(proc);
- execl(shell, shell, "-c", command, NULL);
+ execl(shell, shell, "-c", command, (char *)NULL);
_exit(127);
} else if (child < 0) {
diff --git a/src/request.c b/src/request.c
index f76252e..92660a0 100644
--- a/src/request.c
+++ b/src/request.c
@@ -284,8 +284,6 @@ int http_request_parse(server *srv, connection *con) {
int done = 0;
- data_string *ds = NULL;
-
/*
* Request: "^(GET|POST|HEAD) ([^ ]+(\\?[^ ]+|)) (HTTP/1\\.[01])$"
* Option : "^([-a-zA-Z]+): (.+)$"
@@ -715,12 +713,24 @@ int http_request_parse(server *srv, connection *con) {
switch(*cur) {
case '\r':
if (con->parse_request->ptr[i+1] == '\n') {
+ data_string *ds = NULL;
+
/* End of Headerline */
con->parse_request->ptr[i] = '\0';
con->parse_request->ptr[i+1] = '\0';
if (in_folding) {
- if (!ds) {
+ buffer *key_b;
+ /**
+ * we use a evil hack to handle the line-folding
+ *
+ * As array_insert_unique() deletes 'ds' in the case of a duplicate
+ * ds points somewhere and we get a evil crash. As a solution we keep the old
+ * "key" and get the current value from the hash and append us
+ *
+ * */
+
+ if (!key || !key_len) {
/* 400 */
if (srv->srvconf.log_request_header_on_error) {
@@ -737,7 +747,15 @@ int http_request_parse(server *srv, connection *con) {
con->response.keep_alive = 0;
return 0;
}
- buffer_append_string(ds->value, value);
+
+ key_b = buffer_init();
+ buffer_copy_string_len(key_b, key, key_len);
+
+ if (NULL != (ds = (data_string *)array_get_element(con->request.headers, key_b->ptr))) {
+ buffer_append_string(ds->value, value);
+ }
+
+ buffer_free(key_b);
} else {
int s_len;
key = con->parse_request->ptr + first;
@@ -969,7 +987,12 @@ int http_request_parse(server *srv, connection *con) {
first = i+1;
is_key = 1;
value = 0;
- key_len = 0;
+#if 0
+ /**
+ * for Bug 1230 keep the key_len a live
+ */
+ key_len = 0;
+#endif
in_folding = 0;
} else {
if (srv->srvconf.log_request_header_on_error) {
diff --git a/src/server.c b/src/server.c
index 37b7cb4..7eaae3e 100644
--- a/src/server.c
+++ b/src/server.c
@@ -775,6 +775,22 @@ int main (int argc, char **argv) {
return -1;
}
+ /**
+ * we are not root can can't increase the fd-limit, but we can reduce it
+ */
+ if (srv->srvconf.max_fds && srv->srvconf.max_fds < rlim.rlim_cur) {
+ /* set rlimits */
+
+ rlim.rlim_cur = srv->srvconf.max_fds;
+
+ if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
+ log_error_write(srv, __FILE__, __LINE__,
+ "ss", "couldn't set 'max filedescriptors'",
+ strerror(errno));
+ return -1;
+ }
+ }
+
if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
} else {
diff --git a/src/spawn-fcgi.c b/src/spawn-fcgi.c
index c40d8f9..0aaac14 100644
--- a/src/spawn-fcgi.c
+++ b/src/spawn-fcgi.c
@@ -169,7 +169,7 @@ int fcgi_spawn_connection(char *appPath, char *addr, unsigned short port, const
strcat(b, appPath);
/* exec the cgi */
- execl("/bin/sh", "sh", "-c", b, NULL);
+ execl("/bin/sh", "sh", "-c", b, (char *)NULL);
exit(errno);
diff --git a/src/stat_cache.c b/src/stat_cache.c
index 283ead9..6fbf1ba 100644
--- a/src/stat_cache.c
+++ b/src/stat_cache.c
@@ -608,14 +608,14 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
break;
}
}
- etag_create(sce->etag, &(sce->st));
+ etag_create(sce->etag, &(sce->st), con->etag_flags);
#ifdef HAVE_XATTR
- if (buffer_is_empty(sce->content_type)) {
+ if (con->conf.use_xattr && buffer_is_empty(sce->content_type)) {
stat_cache_attr_get(sce->content_type, name->ptr);
}
#endif
} else if (S_ISDIR(st.st_mode)) {
- etag_create(sce->etag, &(sce->st));
+ etag_create(sce->etag, &(sce->st), con->etag_flags);
}
#ifdef HAVE_FAM_H