lighttpd 1.4.x https://www.lighttpd.net/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1687 lines
56 KiB

#include "first.h"
#include "base.h"
#include "burl.h"
#include "fdevent.h"
#include "keyvalue.h"
#include "log.h"
#include "stream.h"
#include "configparser.h"
#include "configfile.h"
#include "stat_cache.h"
#include "sys-crypto.h"
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <glob.h>
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
#if defined(HAVE_MYSQL) || (defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER))
static void config_warn_authn_module (server *srv, const char *module, size_t len) {
for (size_t i = 0; i < srv->config_context->used; ++i) {
const data_config *config = (data_config const*)srv->config_context->data[i];
const data_unset *du = array_get_element(config->value, "auth.backend");
if (NULL != du && du->type == TYPE_STRING) {
data_string *ds = (data_string *)du;
if (buffer_is_equal_string(ds->value, module, len)) {
buffer_copy_string_len(srv->tmp_buf, CONST_STR_LEN("mod_authn_"));
buffer_append_string_len(srv->tmp_buf, module, len);
array_insert_value(srv->srvconf.modules, CONST_BUF_LEN(srv->tmp_buf));
log_error_write(srv, __FILE__, __LINE__, "SSSsSSS", "Warning: please add \"mod_authn_", module, "\" to server.modules list in lighttpd.conf. A future release of lighttpd 1.4.x will not automatically load mod_authn_", module, "and lighttpd will fail to start up since your lighttpd.conf uses auth.backend = \"", module, "\".");
return;
}
}
}
}
#endif
#ifdef USE_OPENSSL_CRYPTO
static void config_warn_openssl_module (server *srv) {
for (size_t i = 0; i < srv->config_context->used; ++i) {
const data_config *config = (data_config const*)srv->config_context->data[i];
for (size_t j = 0; j < config->value->used; ++j) {
data_unset *du = config->value->data[j];
if (0 == strncmp(du->key->ptr, "ssl.", sizeof("ssl.")-1)) {
/* mod_openssl should be loaded after mod_extforward */
array_insert_value(srv->srvconf.modules, CONST_STR_LEN("mod_openssl"));
log_error_write(srv, __FILE__, __LINE__, "S", "Warning: please add \"mod_openssl\" to server.modules list in lighttpd.conf. A future release of lighttpd 1.4.x *will not* automatically load mod_openssl and lighttpd *will not* use SSL/TLS where your lighttpd.conf contains ssl.* directives");
return;
}
}
}
}
#endif
static int config_http_parseopts (server *srv, array *a) {
unsigned short int opts = srv->srvconf.http_url_normalize;
unsigned short int decode_2f = 1;
int rc = 1;
if (!array_is_kvstring(a)) {
log_error_write(srv, __FILE__, __LINE__, "s",
"unexpected value for server.http-parseopts; "
"expected list of \"key\" => \"[enable|disable]\"");
return 0;
}
for (size_t i = 0; i < a->used; ++i) {
const data_string * const ds = (data_string *)a->data[i];
unsigned short int opt;
int val = 0;
if (buffer_is_equal_string(ds->value, CONST_STR_LEN("enable")))
val = 1;
else if (buffer_is_equal_string(ds->value, CONST_STR_LEN("disable")))
val = 0;
else {
log_error_write(srv, __FILE__, __LINE__, "sbsbs",
"unrecognized value for server.http-parseopts:",
ds->key, "=>", ds->value,
"(expect \"[enable|disable]\")");
rc = 0;
}
if (buffer_is_equal_string(ds->key, CONST_STR_LEN("url-normalize")))
opt = HTTP_PARSEOPT_URL_NORMALIZE;
else if (buffer_is_equal_string(ds->key, CONST_STR_LEN("url-normalize-unreserved")))
opt = HTTP_PARSEOPT_URL_NORMALIZE_UNRESERVED;
else if (buffer_is_equal_string(ds->key, CONST_STR_LEN("url-normalize-required")))
opt = HTTP_PARSEOPT_URL_NORMALIZE_REQUIRED;
else if (buffer_is_equal_string(ds->key, CONST_STR_LEN("url-ctrls-reject")))
opt = HTTP_PARSEOPT_URL_NORMALIZE_CTRLS_REJECT;
else if (buffer_is_equal_string(ds->key, CONST_STR_LEN("url-path-backslash-trans")))
opt = HTTP_PARSEOPT_URL_NORMALIZE_PATH_BACKSLASH_TRANS;
else if (buffer_is_equal_string(ds->key, CONST_STR_LEN("url-path-2f-decode")))
opt = HTTP_PARSEOPT_URL_NORMALIZE_PATH_2F_DECODE;
else if (buffer_is_equal_string(ds->key, CONST_STR_LEN("url-path-2f-reject")))
opt = HTTP_PARSEOPT_URL_NORMALIZE_PATH_2F_REJECT;
else if (buffer_is_equal_string(ds->key, CONST_STR_LEN("url-path-dotseg-remove")))
opt = HTTP_PARSEOPT_URL_NORMALIZE_PATH_DOTSEG_REMOVE;
else if (buffer_is_equal_string(ds->key, CONST_STR_LEN("url-path-dotseg-reject")))
opt = HTTP_PARSEOPT_URL_NORMALIZE_PATH_DOTSEG_REJECT;
else if (buffer_is_equal_string(ds->key, CONST_STR_LEN("url-query-20-plus")))
opt = HTTP_PARSEOPT_URL_NORMALIZE_QUERY_20_PLUS;
else if (buffer_is_equal_string(ds->key, CONST_STR_LEN("header-strict"))) {
srv->srvconf.http_header_strict = val;
continue;
}
else if (buffer_is_equal_string(ds->key, CONST_STR_LEN("host-strict"))) {
srv->srvconf.http_host_strict = val;
continue;
}
else if (buffer_is_equal_string(ds->key, CONST_STR_LEN("host-normalize"))) {
srv->srvconf.http_host_normalize = val;
continue;
}
else if (buffer_is_equal_string(ds->key, CONST_STR_LEN("method-get-body"))) {
srv->srvconf.http_method_get_body = val;
continue;
}
else {
log_error_write(srv, __FILE__, __LINE__, "sb",
"unrecognized key for server.http-parseopts:",
ds->key);
rc = 0;
continue;
}
if (val)
opts |= opt;
else {
opts &= ~opt;
if (opt == HTTP_PARSEOPT_URL_NORMALIZE) {
opts = 0;
break;
}
if (opt == HTTP_PARSEOPT_URL_NORMALIZE_PATH_2F_DECODE) {
decode_2f = 0;
}
}
}
if (opts != 0) {
opts |= HTTP_PARSEOPT_URL_NORMALIZE;
if ((opts & (HTTP_PARSEOPT_URL_NORMALIZE_PATH_2F_DECODE
|HTTP_PARSEOPT_URL_NORMALIZE_PATH_2F_REJECT))
== (HTTP_PARSEOPT_URL_NORMALIZE_PATH_2F_DECODE
|HTTP_PARSEOPT_URL_NORMALIZE_PATH_2F_REJECT)) {
log_error_write(srv, __FILE__, __LINE__, "s",
"conflicting options in server.http-parseopts:"
"url-path-2f-decode, url-path-2f-reject");
rc = 0;
}
if ((opts & (HTTP_PARSEOPT_URL_NORMALIZE_PATH_DOTSEG_REMOVE
|HTTP_PARSEOPT_URL_NORMALIZE_PATH_DOTSEG_REJECT))
== (HTTP_PARSEOPT_URL_NORMALIZE_PATH_DOTSEG_REMOVE
|HTTP_PARSEOPT_URL_NORMALIZE_PATH_DOTSEG_REJECT)) {
log_error_write(srv, __FILE__, __LINE__, "s",
"conflicting options in server.http-parseopts:"
"url-path-dotseg-remove, url-path-dotseg-reject");
rc = 0;
}
if (!(opts & (HTTP_PARSEOPT_URL_NORMALIZE_UNRESERVED
|HTTP_PARSEOPT_URL_NORMALIZE_REQUIRED))) {
opts |= HTTP_PARSEOPT_URL_NORMALIZE_UNRESERVED;
if (decode_2f
&& !(opts & HTTP_PARSEOPT_URL_NORMALIZE_PATH_2F_REJECT))
opts |= HTTP_PARSEOPT_URL_NORMALIZE_PATH_2F_DECODE;
}
}
srv->srvconf.http_url_normalize = opts;
return rc;
}
static int config_insert(server *srv) {
size_t i;
int ret = 0;
buffer *stat_cache_string;
array *http_parseopts;
unsigned int chunk_sz = 0;
config_values_t cv[] = {
{ "server.bind", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 0 */
{ "server.errorlog", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 1 */
{ "server.errorfile-prefix", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
{ "server.chroot", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 3 */
{ "server.username", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 4 */
{ "server.groupname", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 5 */
{ "server.port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 6 */
{ "server.tag", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 7 */
{ "server.use-ipv6", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
{ "server.modules", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_SERVER }, /* 9 */
{ "server.event-handler", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 10 */
{ "server.pid-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 11 */
{ "server.max-request-size", NULL, T_CONFIG_INT, T_CONFIG_SCOPE_CONNECTION }, /* 12 */
{ "server.max-worker", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 13 */
{ "server.document-root", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 14 */
{ "server.force-lowercase-filenames", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 15 */
{ "debug.log-condition-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 16 */
{ "server.max-keep-alive-requests", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 17 */
{ "server.name", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 18 */
{ "server.max-keep-alive-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 19 */
{ "server.max-read-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 20 */
{ "server.max-write-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 21 */
[core] server.error-handler new directive for error pages (fixes #2702) server.error-handler preserves HTTP status error code when error page is static, and allows dynamic handlers to change HTTP status code when error page is provided by dynamic handler. server.error-handler intercepts all HTTP status codes >= 400 except when the content is generated by a dynamic handler (cgi, ssi, fastcgi, scgi, proxy, lua). The request method is unconditionally changed to GET for the request to service the error handler, and the original request method is later restored (for logging purposes). request body from the original request, if present, is discarded. server.error-handler is somewhat similar to server.error-handler-404, but server.error-handler-404 is now deprecated, intercepts only 404 and 403 HTTP status codes, and returns 200 OK for static error pages, a source of confusion for some admins. On the other hand, the new server.error-handler, when set, will intercept all HTTP status error codes >= 400. server.error-handler takes precedence over server.error-handler-404 when both are set. NOTE: a major difference between server.error-handler and the now-deprecated server.error-handler-404 is that the values of the non-standard CGI environment variables REQUEST_URI and REDIRECT_URI have been swapped. Since REDIRECT_STATUS is the original HTTP status code, REDIRECT_URI is now the original request, and REQUEST_URI is the current request (e.g. the URI/URL to the error handler). The prior behavior -- which reversed REQUEST_URI and REDIRECT_URI values from those described above -- is preserved for server.error-handler-404. Additionally, REDIRECT_STATUS is now available to mod_magnet, which continues to have access to request.uri and request.orig_uri. See further discussion at https://redmine.lighttpd.net/issues/2702 and https://redmine.lighttpd.net/issues/1828 github: closes #36
6 years ago
{ "server.error-handler", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 22 */
{ "server.max-fds", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 23 */
#ifdef HAVE_LSTAT
{ "server.follow-symlink", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 24 */
#else
{ "server.follow-symlink",
"Your system lacks lstat(). We can not differ symlinks from files."
"Please remove server.follow-symlinks from your config.",
T_CONFIG_UNSUPPORTED, T_CONFIG_SCOPE_UNSET },
#endif
{ "server.kbytes-per-second", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 25 */
{ "connection.kbytes-per-second", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 26 */
{ "mimetype.use-xattr", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 27 */
{ "mimetype.assign", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 28 */
{ "unused-slot-moved-to-mod-openssl", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 29 */
{ "ssl.engine", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 30 */
{ "debug.log-file-not-found", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 31 */
{ "debug.log-request-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 32 */
{ "debug.log-response-header", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 33 */
{ "debug.log-request-header", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 34 */
{ "unused-slot-moved-to-mod-openssl", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 35 */
{ "server.protocol-http11", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 36 */
{ "debug.log-request-header-on-error", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 37 */
{ "debug.log-state-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 38 */
{ "unused-slot-moved-to-mod-openssl", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 39 */
{ "server.errorlog-use-syslog", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 40 */
{ "server.range-requests", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 41 */
{ "server.stat-cache-engine", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 42 */
{ "server.max-connections", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 43 */
{ "server.network-backend", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 44 */
{ "server.upload-dirs", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_SERVER }, /* 45 */
{ "server.core-files", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 46 */
{ "server.compat-module-load", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 47 */
{ "server.chunkqueue-chunk-sz", NULL, T_CONFIG_INT, T_CONFIG_SCOPE_SERVER }, /* 48 */
{ "etag.use-inode", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 49 */
{ "etag.use-mtime", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 50 */
{ "etag.use-size", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 51 */
{ "server.reject-expect-100-with-417", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 52 */
{ "debug.log-timeouts", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 53 */
{ "server.defer-accept", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 54 */
{ "server.breakagelog", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 55 */
{ "unused-slot-moved-to-mod-openssl", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 56 */
{ "unused-slot-moved-to-mod-openssl", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 57 */
{ "unused-slot-moved-to-mod-openssl", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 58 */
{ "unused-slot-moved-to-mod-openssl", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 59 */
{ "unused-slot-moved-to-mod-openssl", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 60 */
{ "server.set-v6only", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 61 */
{ "unused-slot-moved-to-mod-openssl", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 62 */
{ "unused-slot-moved-to-mod-openssl", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 63 */
{ "unused-slot-moved-to-mod-openssl", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 64 */
{ "unused-slot-moved-to-mod-openssl", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 65 */
{ "unused-slot-moved-to-mod-openssl", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 66 */
{ "unused-slot-moved-to-mod-openssl", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 67 */
{ "server.upload-temp-file-size", NULL, T_CONFIG_INT, T_CONFIG_SCOPE_SERVER }, /* 68 */
{ "mimetype.xattr-name", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 69 */
{ "server.listen-backlog", NULL, T_CONFIG_INT, T_CONFIG_SCOPE_CONNECTION }, /* 70 */
[core] server.error-handler new directive for error pages (fixes #2702) server.error-handler preserves HTTP status error code when error page is static, and allows dynamic handlers to change HTTP status code when error page is provided by dynamic handler. server.error-handler intercepts all HTTP status codes >= 400 except when the content is generated by a dynamic handler (cgi, ssi, fastcgi, scgi, proxy, lua). The request method is unconditionally changed to GET for the request to service the error handler, and the original request method is later restored (for logging purposes). request body from the original request, if present, is discarded. server.error-handler is somewhat similar to server.error-handler-404, but server.error-handler-404 is now deprecated, intercepts only 404 and 403 HTTP status codes, and returns 200 OK for static error pages, a source of confusion for some admins. On the other hand, the new server.error-handler, when set, will intercept all HTTP status error codes >= 400. server.error-handler takes precedence over server.error-handler-404 when both are set. NOTE: a major difference between server.error-handler and the now-deprecated server.error-handler-404 is that the values of the non-standard CGI environment variables REQUEST_URI and REDIRECT_URI have been swapped. Since REDIRECT_STATUS is the original HTTP status code, REDIRECT_URI is now the original request, and REQUEST_URI is the current request (e.g. the URI/URL to the error handler). The prior behavior -- which reversed REQUEST_URI and REDIRECT_URI values from those described above -- is preserved for server.error-handler-404. Additionally, REDIRECT_STATUS is now available to mod_magnet, which continues to have access to request.uri and request.orig_uri. See further discussion at https://redmine.lighttpd.net/issues/2702 and https://redmine.lighttpd.net/issues/1828 github: closes #36
6 years ago
{ "server.error-handler-404", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 71 */
[config] opts for http header parsing strictness (fixes #551, fixes #1086, fixes #1184, fixes #2143, #2258, #2281, fixes #946, fixes #1330, fixes #602, #1016) server.http-parseopt-header-strict = "enable" server.http-parseopt-host-strict = "enable" (implies host-normalize) server.http-parseopt-host-normalize = "disable" defaults retain current behavior, which is strict header parsing and strict host parsing, with enhancement to normalize IPv4 address and port number strings. For lighttpd tests, these need to be enabled (and are by default) For marginally faster HTTP header parsing for benchmarks, disable these. To allow - underscores in hostname - hypen ('-') at beginning of hostname - all-numeric TLDs server.http-parseopt-host-strict = "disable" x-ref: "lighttpd doesn't allow underscores in host names" https://redmine.lighttpd.net/issues/551 "hyphen in hostname" https://redmine.lighttpd.net/issues/1086 "a numeric tld" https://redmine.lighttpd.net/issues/1184 "Numeric tld's" https://redmine.lighttpd.net/issues/2143 "Bad Request" https://redmine.lighttpd.net/issues/2258 "400 Bad Request when using Numeric TLDs" https://redmine.lighttpd.net/issues/2281 To allow a variety of numerical formats to be converted to IP addresses server.http-parseopt-host-strict = "disable" server.http-parseopt-host-normalize = "enable" x-ref: "URL encoding leads to "400 - Bad Request"" https://redmine.lighttpd.net/issues/946 "400 Bad Request when using IP's numeric value ("ip2long()")" https://redmine.lighttpd.net/issues/1330 To allow most 8-bit and 7-bit chars in headers server.http-parseopt-header-strict = "disable" (not recommended) x-ref: "Russian letters not alowed?" https://redmine.lighttpd.net/issues/602 "header Content-Disposition with russian '?' (CP1251, ascii code 255) causes error" https://redmine.lighttpd.net/issues/1016
6 years ago
{ "server.http-parseopt-header-strict",NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 72 */
{ "server.http-parseopt-host-strict", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 73 */
{ "server.http-parseopt-host-normalize",NULL,T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 74 */
{ "server.bsd-accept-filter", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 75 */
{ "server.stream-request-body", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 76 */
{ "server.stream-response-body", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 77 */
{ "server.max-request-field-size", NULL, T_CONFIG_INT, T_CONFIG_SCOPE_SERVER }, /* 78 */
{ "server.error-intercept", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 79 */
{ "server.syslog-facility", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 80 */
{ "server.socket-perms", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 81 */
{ "server.http-parseopts", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_SERVER }, /* 82 */
{ "server.systemd-socket-activation", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 83 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
/* all T_CONFIG_SCOPE_SERVER options */
cv[0].destination = srv->srvconf.bindhost;
cv[1].destination = srv->srvconf.errorlog_file;
cv[3].destination = srv->srvconf.changeroot;
cv[4].destination = srv->srvconf.username;
cv[5].destination = srv->srvconf.groupname;
cv[6].destination = &(srv->srvconf.port);
cv[9].destination = srv->srvconf.modules;
cv[10].destination = srv->srvconf.event_handler;
cv[11].destination = srv->srvconf.pid_file;
cv[13].destination = &(srv->srvconf.max_worker);
cv[23].destination = &(srv->srvconf.max_fds);
cv[37].destination = &(srv->srvconf.log_request_header_on_error);
cv[38].destination = &(srv->srvconf.log_state_handling);
cv[40].destination = &(srv->srvconf.errorlog_use_syslog);
stat_cache_string = buffer_init();
cv[42].destination = stat_cache_string;
cv[43].destination = &(srv->srvconf.max_conns);
cv[44].destination = srv->srvconf.network_backend;
cv[45].destination = srv->srvconf.upload_tempdirs;
cv[46].destination = &(srv->srvconf.enable_cores);
cv[47].destination = &(srv->srvconf.compat_module_load);
cv[48].destination = &chunk_sz;
cv[52].destination = &(srv->srvconf.reject_expect_100_with_417);
cv[55].destination = srv->srvconf.breakagelog_file;
cv[68].destination = &(srv->srvconf.upload_temp_file_size);
cv[69].destination = srv->srvconf.xattr_name;
[config] opts for http header parsing strictness (fixes #551, fixes #1086, fixes #1184, fixes #2143, #2258, #2281, fixes #946, fixes #1330, fixes #602, #1016) server.http-parseopt-header-strict = "enable" server.http-parseopt-host-strict = "enable" (implies host-normalize) server.http-parseopt-host-normalize = "disable" defaults retain current behavior, which is strict header parsing and strict host parsing, with enhancement to normalize IPv4 address and port number strings. For lighttpd tests, these need to be enabled (and are by default) For marginally faster HTTP header parsing for benchmarks, disable these. To allow - underscores in hostname - hypen ('-') at beginning of hostname - all-numeric TLDs server.http-parseopt-host-strict = "disable" x-ref: "lighttpd doesn't allow underscores in host names" https://redmine.lighttpd.net/issues/551 "hyphen in hostname" https://redmine.lighttpd.net/issues/1086 "a numeric tld" https://redmine.lighttpd.net/issues/1184 "Numeric tld's" https://redmine.lighttpd.net/issues/2143 "Bad Request" https://redmine.lighttpd.net/issues/2258 "400 Bad Request when using Numeric TLDs" https://redmine.lighttpd.net/issues/2281 To allow a variety of numerical formats to be converted to IP addresses server.http-parseopt-host-strict = "disable" server.http-parseopt-host-normalize = "enable" x-ref: "URL encoding leads to "400 - Bad Request"" https://redmine.lighttpd.net/issues/946 "400 Bad Request when using IP's numeric value ("ip2long()")" https://redmine.lighttpd.net/issues/1330 To allow most 8-bit and 7-bit chars in headers server.http-parseopt-header-strict = "disable" (not recommended) x-ref: "Russian letters not alowed?" https://redmine.lighttpd.net/issues/602 "header Content-Disposition with russian '?' (CP1251, ascii code 255) causes error" https://redmine.lighttpd.net/issues/1016
6 years ago
cv[72].destination = &(srv->srvconf.http_header_strict);
cv[73].destination = &(srv->srvconf.http_host_strict);
cv[74].destination = &(srv->srvconf.http_host_normalize);
cv[78].destination = &(srv->srvconf.max_request_field_size);
cv[80].destination = srv->srvconf.syslog_facility;
http_parseopts = array_init();
cv[82].destination = http_parseopts;
cv[83].destination = &(srv->srvconf.systemd_socket_activation);
srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
force_assert(srv->config_storage);
force_assert(srv->config_context->used); /* static analysis hint for ccc
-analyzer */
for (i = 0; i < srv->config_context->used; i++) {
data_config * const config = (data_config *)srv->config_context->data[i];
specific_config *s;
s = calloc(1, sizeof(specific_config));
force_assert(s);
s->document_root = buffer_init();
s->mimetypes = array_init();
s->server_name = buffer_init();
s->error_handler = buffer_init();
[core] server.error-handler new directive for error pages (fixes #2702) server.error-handler preserves HTTP status error code when error page is static, and allows dynamic handlers to change HTTP status code when error page is provided by dynamic handler. server.error-handler intercepts all HTTP status codes >= 400 except when the content is generated by a dynamic handler (cgi, ssi, fastcgi, scgi, proxy, lua). The request method is unconditionally changed to GET for the request to service the error handler, and the original request method is later restored (for logging purposes). request body from the original request, if present, is discarded. server.error-handler is somewhat similar to server.error-handler-404, but server.error-handler-404 is now deprecated, intercepts only 404 and 403 HTTP status codes, and returns 200 OK for static error pages, a source of confusion for some admins. On the other hand, the new server.error-handler, when set, will intercept all HTTP status error codes >= 400. server.error-handler takes precedence over server.error-handler-404 when both are set. NOTE: a major difference between server.error-handler and the now-deprecated server.error-handler-404 is that the values of the non-standard CGI environment variables REQUEST_URI and REDIRECT_URI have been swapped. Since REDIRECT_STATUS is the original HTTP status code, REDIRECT_URI is now the original request, and REQUEST_URI is the current request (e.g. the URI/URL to the error handler). The prior behavior -- which reversed REQUEST_URI and REDIRECT_URI values from those described above -- is preserved for server.error-handler-404. Additionally, REDIRECT_STATUS is now available to mod_magnet, which continues to have access to request.uri and request.orig_uri. See further discussion at https://redmine.lighttpd.net/issues/2702 and https://redmine.lighttpd.net/issues/1828 github: closes #36
6 years ago
s->error_handler_404 = buffer_init();
s->server_tag = buffer_init();
s->errorfile_prefix = buffer_init();
#if defined(__FreeBSD__) || defined(__NetBSD__) \
|| defined(__OpenBSD__) || defined(__DragonFly__)
s->bsd_accept_filter = (i == 0)
? buffer_init()
: buffer_init_buffer(srv->config_storage[0]->bsd_accept_filter);
#endif
s->socket_perms = (i == 0 || buffer_string_is_empty(srv->config_storage[0]->socket_perms))
? buffer_init()
: buffer_init_buffer(srv->config_storage[0]->socket_perms);
s->max_keep_alive_requests = 100;
s->max_keep_alive_idle = 5;
s->max_read_idle = 60;
s->max_write_idle = 360;
s->max_request_size = 0;
s->use_xattr = 0;
s->ssl_enabled = 0;
s->use_ipv6 = (i == 0) ? 0 : srv->config_storage[0]->use_ipv6;
s->set_v6only = (i == 0) ? 1 : srv->config_storage[0]->set_v6only;
s->defer_accept = (i == 0) ? 0 : srv->config_storage[0]->defer_accept;
s->follow_symlink = 1;
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 = (i == 0) ? 2 : 0; /* we wan't to detect later if user changed this for global section */
s->global_kbytes_per_second = 0;
s->global_bytes_per_second_cnt = 0;
s->global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt;
s->listen_backlog = (0 == i ? 1024 : srv->config_storage[0]->listen_backlog);
s->stream_request_body = 0;
s->stream_response_body = 0;
s->error_intercept = 0;
/* all T_CONFIG_SCOPE_CONNECTION options */
cv[2].destination = s->errorfile_prefix;
cv[7].destination = s->server_tag;
cv[8].destination = &(s->use_ipv6);
cv[12].destination = &(s->max_request_size);
cv[14].destination = s->document_root;
cv[15].destination = &(s->force_lowercase_filenames);
cv[16].destination = &(s->log_condition_handling);
cv[17].destination = &(s->max_keep_alive_requests);
cv[18].destination = s->server_name;
cv[19].destination = &(s->max_keep_alive_idle);
cv[20].destination = &(s->max_read_idle);
cv[21].destination = &(s->max_write_idle);
cv[22].destination = s->error_handler;
cv[24].destination = &(s->follow_symlink);
cv[25].destination = &(s->global_kbytes_per_second);
cv[26].destination = &(s->kbytes_per_second);
cv[27].destination = &(s->use_xattr);
cv[28].destination = s->mimetypes;
/*cv[29].destination = s->unused;*/
cv[30].destination = &(s->ssl_enabled);
cv[31].destination = &(s->log_file_not_found);
cv[32].destination = &(s->log_request_handling);
cv[33].destination = &(s->log_response_header);
cv[34].destination = &(s->log_request_header);
/*cv[35].destination = &(s->unused);*/
cv[36].destination = &(s->allow_http11);
/*cv[39].destination = s->unused;*/
cv[41].destination = &(s->range_requests);
/*cv[47].destination = s->unused;*/
/*cv[48].destination = &(s->unused);*/
cv[49].destination = &(s->etag_use_inode);
cv[50].destination = &(s->etag_use_mtime);
cv[51].destination = &(s->etag_use_size);
cv[53].destination = &(s->log_timeouts);
cv[54].destination = &(s->defer_accept);
/*cv[56].destination = &(s->unused);*/
/*cv[57].destination = &(s->unused);*/
/*cv[58].destination = &(s->unused);*/
/*cv[59].destination = s->unused;*/
/*cv[60].destination = &(s->unused);*/
cv[61].destination = &(s->set_v6only);
/*cv[62].destination = &(s->unused);*/
/*cv[63].destination = s->unused;*/
/*cv[64].destination = s->unused;*/
/*cv[65].destination = &(s->unused);*/
/*cv[66].destination = &(s->unused);*/
/*cv[67].destination = &(s->unused);*/
cv[70].destination = &(s->listen_backlog);
[core] server.error-handler new directive for error pages (fixes #2702) server.error-handler preserves HTTP status error code when error page is static, and allows dynamic handlers to change HTTP status code when error page is provided by dynamic handler. server.error-handler intercepts all HTTP status codes >= 400 except when the content is generated by a dynamic handler (cgi, ssi, fastcgi, scgi, proxy, lua). The request method is unconditionally changed to GET for the request to service the error handler, and the original request method is later restored (for logging purposes). request body from the original request, if present, is discarded. server.error-handler is somewhat similar to server.error-handler-404, but server.error-handler-404 is now deprecated, intercepts only 404 and 403 HTTP status codes, and returns 200 OK for static error pages, a source of confusion for some admins. On the other hand, the new server.error-handler, when set, will intercept all HTTP status error codes >= 400. server.error-handler takes precedence over server.error-handler-404 when both are set. NOTE: a major difference between server.error-handler and the now-deprecated server.error-handler-404 is that the values of the non-standard CGI environment variables REQUEST_URI and REDIRECT_URI have been swapped. Since REDIRECT_STATUS is the original HTTP status code, REDIRECT_URI is now the original request, and REQUEST_URI is the current request (e.g. the URI/URL to the error handler). The prior behavior -- which reversed REQUEST_URI and REDIRECT_URI values from those described above -- is preserved for server.error-handler-404. Additionally, REDIRECT_STATUS is now available to mod_magnet, which continues to have access to request.uri and request.orig_uri. See further discussion at https://redmine.lighttpd.net/issues/2702 and https://redmine.lighttpd.net/issues/1828 github: closes #36
6 years ago
cv[71].destination = s->error_handler_404;
#if defined(__FreeBSD__) || defined(__NetBSD__) \
|| defined(__OpenBSD__) || defined(__DragonFly__)
cv[75].destination = s->bsd_accept_filter;
#endif
cv[76].destination = &(s->stream_request_body);
cv[77].destination = &(s->stream_response_body);
cv[79].destination = &(s->error_intercept);
cv[81].destination = s->socket_perms;
srv->config_storage[i] = s;
if (0 != (ret = config_insert_values_global(srv, config->value, cv, i == 0 ? T_CONFIG_SCOPE_SERVER : T_CONFIG_SCOPE_CONNECTION))) {
break;
}
if (s->stream_request_body & FDEVENT_STREAM_REQUEST_BUFMIN) {
s->stream_request_body |= FDEVENT_STREAM_REQUEST;
}
if (s->stream_response_body & FDEVENT_STREAM_RESPONSE_BUFMIN) {
s->stream_response_body |= FDEVENT_STREAM_RESPONSE;
}
if (!array_is_kvstring(s->mimetypes)) {
log_error_write(srv, __FILE__, __LINE__, "s",
"unexpected value for mimetype.assign; expected list of \"ext\" => \"mimetype\"");
}
if (!buffer_string_is_empty(s->server_tag)) {
for (char *t = strchr(s->server_tag->ptr,'\n'); NULL != t; t = strchr(t+2,'\n')) {
/* not expecting admin to define multi-line server.tag,
* but ensure server_tag has proper header continuation,
* if needed */
off_t off = t - s->server_tag->ptr;
size_t len;
if (t[1] == ' ' || t[1] == '\t') continue;
len = buffer_string_length(s->server_tag);
buffer_string_prepare_append(s->server_tag, 1);
t = s->server_tag->ptr+off;
memmove(t+2, t+1, len - off - 1);
t[1] = ' ';
buffer_commit(s->server_tag, 1);
}
}
if (0 == i) {
if (!config_http_parseopts(srv, http_parseopts)) {
ret = HANDLER_ERROR;
break;
}
}
if (srv->srvconf.http_url_normalize
&& COMP_HTTP_QUERY_STRING == config->comp) {
switch(config->cond) {
case CONFIG_COND_NE:
case CONFIG_COND_EQ:
/* (can use this routine as long as it does not perform
* any regex-specific normalization of first arg) */
pcre_keyvalue_burl_normalize_key(config->string, srv->tmp_buf);
break;
case CONFIG_COND_NOMATCH:
case CONFIG_COND_MATCH:
pcre_keyvalue_burl_normalize_key(config->string, srv->tmp_buf);
if (!data_config_pcre_compile(config)) {
ret = HANDLER_ERROR;
}
break;
default:
break;
}
if (HANDLER_ERROR == ret) break;
}
#ifndef USE_OPENSSL_CRYPTO
if (s->ssl_enabled) {
log_error_write(srv, __FILE__, __LINE__, "s",
"ssl support is missing, recompile with e.g. --with-openssl");
ret = HANDLER_ERROR;
break;
}
#endif
}
array_free(http_parseopts);
[config] opts for http header parsing strictness (fixes #551, fixes #1086, fixes #1184, fixes #2143, #2258, #2281, fixes #946, fixes #1330, fixes #602, #1016) server.http-parseopt-header-strict = "enable" server.http-parseopt-host-strict = "enable" (implies host-normalize) server.http-parseopt-host-normalize = "disable" defaults retain current behavior, which is strict header parsing and strict host parsing, with enhancement to normalize IPv4 address and port number strings. For lighttpd tests, these need to be enabled (and are by default) For marginally faster HTTP header parsing for benchmarks, disable these. To allow - underscores in hostname - hypen ('-') at beginning of hostname - all-numeric TLDs server.http-parseopt-host-strict = "disable" x-ref: "lighttpd doesn't allow underscores in host names" https://redmine.lighttpd.net/issues/551 "hyphen in hostname" https://redmine.lighttpd.net/issues/1086 "a numeric tld" https://redmine.lighttpd.net/issues/1184 "Numeric tld's" https://redmine.lighttpd.net/issues/2143 "Bad Request" https://redmine.lighttpd.net/issues/2258 "400 Bad Request when using Numeric TLDs" https://redmine.lighttpd.net/issues/2281 To allow a variety of numerical formats to be converted to IP addresses server.http-parseopt-host-strict = "disable" server.http-parseopt-host-normalize = "enable" x-ref: "URL encoding leads to "400 - Bad Request"" https://redmine.lighttpd.net/issues/946 "400 Bad Request when using IP's numeric value ("ip2long()")" https://redmine.lighttpd.net/issues/1330 To allow most 8-bit and 7-bit chars in headers server.http-parseopt-header-strict = "disable" (not recommended) x-ref: "Russian letters not alowed?" https://redmine.lighttpd.net/issues/602 "header Content-Disposition with russian '?' (CP1251, ascii code 255) causes error" https://redmine.lighttpd.net/issues/1016
6 years ago
{
specific_config *s = srv->config_storage[0];
s->http_parseopts= /*(global, but stored in con->conf.http_parseopts)*/
(srv->srvconf.http_header_strict ?(HTTP_PARSEOPT_HEADER_STRICT) :0)
|(srv->srvconf.http_host_strict ?(HTTP_PARSEOPT_HOST_STRICT
|HTTP_PARSEOPT_HOST_NORMALIZE):0)
|(srv->srvconf.http_host_normalize ?(HTTP_PARSEOPT_HOST_NORMALIZE):0)
|(srv->srvconf.http_method_get_body?(HTTP_PARSEOPT_METHOD_GET_BODY):0);
s->http_parseopts |= srv->srvconf.http_url_normalize;
if (s->log_request_handling || s->log_request_header)
srv->srvconf.log_request_header_on_error = 1;
[config] opts for http header parsing strictness (fixes #551, fixes #1086, fixes #1184, fixes #2143, #2258, #2281, fixes #946, fixes #1330, fixes #602, #1016) server.http-parseopt-header-strict = "enable" server.http-parseopt-host-strict = "enable" (implies host-normalize) server.http-parseopt-host-normalize = "disable" defaults retain current behavior, which is strict header parsing and strict host parsing, with enhancement to normalize IPv4 address and port number strings. For lighttpd tests, these need to be enabled (and are by default) For marginally faster HTTP header parsing for benchmarks, disable these. To allow - underscores in hostname - hypen ('-') at beginning of hostname - all-numeric TLDs server.http-parseopt-host-strict = "disable" x-ref: "lighttpd doesn't allow underscores in host names" https://redmine.lighttpd.net/issues/551 "hyphen in hostname" https://redmine.lighttpd.net/issues/1086 "a numeric tld" https://redmine.lighttpd.net/issues/1184 "Numeric tld's" https://redmine.lighttpd.net/issues/2143 "Bad Request" https://redmine.lighttpd.net/issues/2258 "400 Bad Request when using Numeric TLDs" https://redmine.lighttpd.net/issues/2281 To allow a variety of numerical formats to be converted to IP addresses server.http-parseopt-host-strict = "disable" server.http-parseopt-host-normalize = "enable" x-ref: "URL encoding leads to "400 - Bad Request"" https://redmine.lighttpd.net/issues/946 "400 Bad Request when using IP's numeric value ("ip2long()")" https://redmine.lighttpd.net/issues/1330 To allow most 8-bit and 7-bit chars in headers server.http-parseopt-header-strict = "disable" (not recommended) x-ref: "Russian letters not alowed?" https://redmine.lighttpd.net/issues/602 "header Content-Disposition with russian '?' (CP1251, ascii code 255) causes error" https://redmine.lighttpd.net/issues/1016
6 years ago
}
if (0 != chunk_sz) {
chunkqueue_set_chunk_size(chunk_sz);
}
if (0 != stat_cache_choose_engine(srv, stat_cache_string)) {
ret = HANDLER_ERROR;
}
buffer_free(stat_cache_string);
if (!array_is_vlist(srv->srvconf.upload_tempdirs)) {
log_error_write(srv, __FILE__, __LINE__, "s",
"unexpected value for server.upload-dirs; expected list of \"path\" strings");
ret = HANDLER_ERROR;
}
if (!array_is_vlist(srv->srvconf.modules)) {
log_error_write(srv, __FILE__, __LINE__, "s",
"unexpected value for server.modules; expected list of \"mod_xxxxxx\" strings");
ret = HANDLER_ERROR;
} else if (srv->srvconf.compat_module_load) {
data_string *ds;
int prepend_mod_indexfile = 1;
int append_mod_dirlisting = 1;
int append_mod_staticfile = 1;
int append_mod_authn_file = 1;
int append_mod_authn_ldap = 1;
int append_mod_authn_mysql = 1;
int append_mod_openssl = 1;
int contains_mod_auth = 0;
/* prepend default modules */
for (i = 0; i < srv->srvconf.modules->used; i++) {
ds = (data_string *)srv->srvconf.modules->data[i];
if (buffer_is_equal_string(ds->value, CONST_STR_LEN("mod_indexfile"))) {
prepend_mod_indexfile = 0;
}
if (buffer_is_equal_string(ds->value, CONST_STR_LEN("mod_staticfile"))) {
append_mod_staticfile = 0;
}
if (buffer_is_equal_string(ds->value, CONST_STR_LEN("mod_dirlisting"))) {
append_mod_dirlisting = 0;
}
if (buffer_is_equal_string(ds->value, CONST_STR_LEN("mod_openssl"))) {
append_mod_openssl = 0;
}
if (buffer_is_equal_string(ds->value, CONST_STR_LEN("mod_authn_file"))) {
append_mod_authn_file = 0;
}
if (buffer_is_equal_string(ds->value, CONST_STR_LEN("mod_authn_ldap"))) {
append_mod_authn_ldap = 0;
}
if (buffer_is_equal_string(ds->value, CONST_STR_LEN("mod_authn_mysql"))) {
append_mod_authn_mysql = 0;
}
if (buffer_is_equal_string(ds->value, CONST_STR_LEN("mod_auth"))) {
contains_mod_auth = 1;
}
if (0 == prepend_mod_indexfile &&
0 == append_mod_dirlisting &&
0 == append_mod_staticfile &&
0 == append_mod_openssl &&
0 == append_mod_authn_file &&
0 == append_mod_authn_ldap &&