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.

1372 lines
37 KiB

#include "first.h"
#include "base.h"
#include "fdevent.h"
#include "log.h"
#include "buffer.h"
#include "http_header.h"
#include "stat_cache.h"
#include "plugin.h"
#include "response.h"
#include "mod_ssi.h"
#include "sys-socket.h"
#include <sys/types.h>
#include <sys/stat.h>
#include "sys-strings.h"
#include <sys/wait.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
fallback to lseek()/read() if mmap() fails (#fixes 2666) fallback to lseek()/read() if mmap() fails (#fixes 2666) e.g. when mmap() is used on lighttpd-controlled temporary files used POST request body (mod_cgi) and PUT file upload (mod_webdav) replace use of stream_open() on potentially untrusted files (protect against SIGBUS if a file is modified while map is read) Note: stream.[ch] may be removed in a future release For now, stream.[ch] will read entire file into memory if mmap fails and so it should only be used on trusted files, e.g. config files. http_auth basic and digest files are typically small and so buffered stdio fopen(), fgets(), fclose() will likely be approximately as fast as mmap. mod_dirlisting header and readme files are typically small and so open(), read(), close() will typically be approximately as fast as mmap mod_ssi will likely be much faster, now buffering SSI page construction rather than a potentially huge number of file open() calls, one for each tiny chunk of text between SSI directives. mod_webdav COPY and MOVE may be slower due to removal of mmap, but are now more resilient to partial writes. x-ref: &#34;handle filesystems without mmap() support&#34; https://redmine.lighttpd.net/issues/2666 &#34;WebDAV upload-&gt; mmap failed: operation not permitted&#34; https://redmine.lighttpd.net/issues/962 &#34;Lighttpd 1.4.20 Crash (SIGBUS in mod_compress)&#34; https://redmine.lighttpd.net/issues/1879 &#34;Crash SIGBUS&#34; https://redmine.lighttpd.net/issues/2391 github: closes #57
6 years ago
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#ifdef HAVE_PWD_H
# include <pwd.h>
#endif
#ifdef HAVE_SYS_FILIO_H
# include <sys/filio.h>
#endif
#include "etag.h"
static handler_ctx * handler_ctx_init(plugin_data *p) {
handler_ctx *hctx = calloc(1, sizeof(*hctx));
force_assert(hctx);
hctx->timefmt = p->timefmt;
hctx->stat_fn = p->stat_fn;
hctx->ssi_vars = p->ssi_vars;
hctx->ssi_cgi_env = p->ssi_cgi_env;
memcpy(&hctx->conf, &p->conf, sizeof(plugin_config));
return hctx;
}
static void handler_ctx_free(handler_ctx *hctx) {
free(hctx);
}
/* The newest modified time of included files for include statement */
static volatile time_t include_file_last_mtime = 0;
/* init the plugin data */
INIT_FUNC(mod_ssi_init) {
plugin_data *p;
p = calloc(1, sizeof(*p));
p->timefmt = buffer_init();
p->stat_fn = buffer_init();
p->ssi_vars = array_init();
p->ssi_cgi_env = array_init();
return p;
}
/* detroy the plugin data */
FREE_FUNC(mod_ssi_free) {
plugin_data *p = p_d;
UNUSED(srv);
if (!p) return HANDLER_GO_ON;
if (p->config_storage) {
size_t i;
for (i = 0; i < srv->config_context->used; i++) {
plugin_config *s = p->config_storage[i];
if (NULL == s) continue;
array_free(s->ssi_extension);
buffer_free(s->content_type);
free(s);
}
free(p->config_storage);
}
array_free(p->ssi_vars);
array_free(p->ssi_cgi_env);
buffer_free(p->timefmt);
buffer_free(p->stat_fn);
free(p);
return HANDLER_GO_ON;
}
/* handle plugin config and check values */
SETDEFAULTS_FUNC(mod_ssi_set_defaults) {
plugin_data *p = p_d;
size_t i = 0;
config_values_t cv[] = {
{ "ssi.extension", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
{ "ssi.content-type", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
[mod_ssi] config ssi.conditional-requests Summary: A new SSI directive, &#34;ssi.conditional-requests&#34;, allows to inform lighttpd which SSI pages should be considered as cacheable and which should not. In particular, the &#34;ETag&#34; &amp; &#34;Last-Modified&#34; headers will only be sent for those SSI pages for which the directive is enabled. Long description: &#34;ETag&#34; and &#34;Last-Modified&#34; headers were being sent for all SSI pages, regardless of whether they were cacheable or not. And yet, there was no cache validation at all for any SSI page. This commit fixes these two minor issues by adding a new directive, &#34;ssi.conditional-requests&#34;, which allows to specify which SSI pages are cacheable and which are not, and by adding cache validation to those SSI pages which are cacheable. And since sending ETags for non-cacheable documents is not appropriate, they are no longuer computed nor sent for those SSI pages which are not cacheable. Regarding the &#34;Last-Modified&#34; header for non-cacheable documents, the standards allow to either send the current date and time for that header or to simply skip it. The approach chosen is to not send it for non-cacheable SSI pages. &#34;ETag&#34; and &#34;Last-Modified&#34; headers are therefore only sent for an SSI page if ssi.conditional-requests is enabled for that page. The ssi.conditional-requests directive can be enabled or disabled globally and/or in any context. It is disabled by default. An index.shtml which only includes deterministic SSI commands such as: &lt;!--#echo var=&#34;LAST_MODIFIED&#34;--&gt; is a trivial example of a dynamic SSI page that is cacheable.
6 years ago
{ "ssi.conditional-requests", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
{ "ssi.exec", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
{ "ssi.recursion-max", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 4 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
if (!p) return HANDLER_ERROR;
p->config_storage = calloc(srv->config_context->used, sizeof(plugin_config *));
for (i = 0; i < srv->config_context->used; i++) {
data_config const* config = (data_config const*)srv->config_context->data[i];
plugin_config *s;
s = calloc(1, sizeof(plugin_config));
s->ssi_extension = array_init();
s->content_type = buffer_init();
[mod_ssi] config ssi.conditional-requests Summary: A new SSI directive, &#34;ssi.conditional-requests&#34;, allows to inform lighttpd which SSI pages should be considered as cacheable and which should not. In particular, the &#34;ETag&#34; &amp; &#34;Last-Modified&#34; headers will only be sent for those SSI pages for which the directive is enabled. Long description: &#34;ETag&#34; and &#34;Last-Modified&#34; headers were being sent for all SSI pages, regardless of whether they were cacheable or not. And yet, there was no cache validation at all for any SSI page. This commit fixes these two minor issues by adding a new directive, &#34;ssi.conditional-requests&#34;, which allows to specify which SSI pages are cacheable and which are not, and by adding cache validation to those SSI pages which are cacheable. And since sending ETags for non-cacheable documents is not appropriate, they are no longuer computed nor sent for those SSI pages which are not cacheable. Regarding the &#34;Last-Modified&#34; header for non-cacheable documents, the standards allow to either send the current date and time for that header or to simply skip it. The approach chosen is to not send it for non-cacheable SSI pages. &#34;ETag&#34; and &#34;Last-Modified&#34; headers are therefore only sent for an SSI page if ssi.conditional-requests is enabled for that page. The ssi.conditional-requests directive can be enabled or disabled globally and/or in any context. It is disabled by default. An index.shtml which only includes deterministic SSI commands such as: &lt;!--#echo var=&#34;LAST_MODIFIED&#34;--&gt; is a trivial example of a dynamic SSI page that is cacheable.
6 years ago
s->conditional_requests = 0;
s->ssi_exec = 1;
s->ssi_recursion_max = 0;
cv[0].destination = s->ssi_extension;
cv[1].destination = s->content_type;
[mod_ssi] config ssi.conditional-requests Summary: A new SSI directive, &#34;ssi.conditional-requests&#34;, allows to inform lighttpd which SSI pages should be considered as cacheable and which should not. In particular, the &#34;ETag&#34; &amp; &#34;Last-Modified&#34; headers will only be sent for those SSI pages for which the directive is enabled. Long description: &#34;ETag&#34; and &#34;Last-Modified&#34; headers were being sent for all SSI pages, regardless of whether they were cacheable or not. And yet, there was no cache validation at all for any SSI page. This commit fixes these two minor issues by adding a new directive, &#34;ssi.conditional-requests&#34;, which allows to specify which SSI pages are cacheable and which are not, and by adding cache validation to those SSI pages which are cacheable. And since sending ETags for non-cacheable documents is not appropriate, they are no longuer computed nor sent for those SSI pages which are not cacheable. Regarding the &#34;Last-Modified&#34; header for non-cacheable documents, the standards allow to either send the current date and time for that header or to simply skip it. The approach chosen is to not send it for non-cacheable SSI pages. &#34;ETag&#34; and &#34;Last-Modified&#34; headers are therefore only sent for an SSI page if ssi.conditional-requests is enabled for that page. The ssi.conditional-requests directive can be enabled or disabled globally and/or in any context. It is disabled by default. An index.shtml which only includes deterministic SSI commands such as: &lt;!--#echo var=&#34;LAST_MODIFIED&#34;--&gt; is a trivial example of a dynamic SSI page that is cacheable.
6 years ago
cv[2].destination = &(s->conditional_requests);
cv[3].destination = &(s->ssi_exec);
cv[4].destination = &(s->ssi_recursion_max);
p->config_storage[i] = s;
if (0 != config_insert_values_global(srv, config->value, cv, i == 0 ? T_CONFIG_SCOPE_SERVER : T_CONFIG_SCOPE_CONNECTION)) {
return HANDLER_ERROR;
}
if (!array_is_vlist(s->ssi_extension)) {
log_error_write(srv, __FILE__, __LINE__, "s",
"unexpected value for ssi.extension; expected list of \"ext\"");
return HANDLER_ERROR;
}
}
return HANDLER_GO_ON;
}
fallback to lseek()/read() if mmap() fails (#fixes 2666) fallback to lseek()/read() if mmap() fails (#fixes 2666) e.g. when mmap() is used on lighttpd-controlled temporary files used POST request body (mod_cgi) and PUT file upload (mod_webdav) replace use of stream_open() on potentially untrusted files (protect against SIGBUS if a file is modified while map is read) Note: stream.[ch] may be removed in a future release For now, stream.[ch] will read entire file into memory if mmap fails and so it should only be used on trusted files, e.g. config files. http_auth basic and digest files are typically small and so buffered stdio fopen(), fgets(), fclose() will likely be approximately as fast as mmap. mod_dirlisting header and readme files are typically small and so open(), read(), close() will typically be approximately as fast as mmap mod_ssi will likely be much faster, now buffering SSI page construction rather than a potentially huge number of file open() calls, one for each tiny chunk of text between SSI directives. mod_webdav COPY and MOVE may be slower due to removal of mmap, but are now more resilient to partial writes. x-ref: &#34;handle filesystems without mmap() support&#34; https://redmine.lighttpd.net/issues/2666 &#34;WebDAV upload-&gt; mmap failed: operation not permitted&#34; https://redmine.lighttpd.net/issues/962 &#34;Lighttpd 1.4.20 Crash (SIGBUS in mod_compress)&#34; https://redmine.lighttpd.net/issues/1879 &#34;Crash SIGBUS&#34; https://redmine.lighttpd.net/issues/2391 github: closes #57
6 years ago
static int ssi_env_add(void *venv, const char *key, size_t klen, const char *val, size_t vlen) {
array_insert_key_value((array *)venv, key, klen, val, vlen);
return 0;
}
static int build_ssi_cgi_vars(server *srv, connection *con, handler_ctx *p) {
http_cgi_opts opts = { 0, 0, NULL, NULL };
/* temporarily remove Authorization from request headers
* so that Authorization does not end up in SSI environment */
buffer *vb_auth = http_header_request_get(con, HTTP_HEADER_AUTHORIZATION, CONST_STR_LEN("Authorization"));
buffer b_auth;
if (vb_auth) {
memcpy(&b_auth, vb_auth, sizeof(buffer));
memset(vb_auth, 0, sizeof(buffer));
}
array_reset_data_strings(p->ssi_cgi_env);
[mod_ssi] Add SSI vars SCRIPT_{URI,URL} and REQUEST_SCHEME (fixes #2721) This is a proposal to add to lighttpd the famous SSI variables SCRIPT_URI and SCRIPT_URL (known to Apache users), as well as a bonus ENV variable called REQUEST_SCHEME. SCRIPT_URI and SCRIPT_URL will be available as SSI variables from within documents handled by mod_ssi. They can be used like any other SSI var with the &#34;#echo var&#34; command: &lt;!--#echo var=&#34;SCRIPT_URI&#34;--&gt; &lt;!--#echo var=&#34;SCRIPT_URL&#34;--&gt; Webmasters willing to display links to the W3C Validator will be able to use: &lt;a href=&#34;http://validator.w3.org/check?uri=&lt;!--#echo var=&#34;SCRIPT_URI&#34;--&gt;&#34;&gt;…&lt;/a&gt; instead of the generic http://validator.w3.org/check?uri=referer link which does not work on some (most?) browsers which do not send referers when the link itself resides in a document sent through https. REQUEST_SCHEME will be available both as an environment variable. It is defined as &#34;http&#34; or &#34;https&#34;, depending on the scheme of the connection. It is safe to use this name as it does not conflict with any existing variable on Apache or Nginx. This is slightly different from the HTTPS var which is often added by webadmins on their server&#39;s configuration. EDIT: Some Apache modules also define REQUEST_SCHEME with the same possible values as this proposal. From: fbrosson &lt;fbrosson@users.noreply.github.com&gt; git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@3124 152afb58-edef-0310-8abb-c4023f1b3aa9
6 years ago
if (0 != http_cgi_headers(srv, con, &opts, ssi_env_add, p->ssi_cgi_env)) {
con->http_status = 400;
return -1;
[mod_ssi] Add SSI vars SCRIPT_{URI,URL} and REQUEST_SCHEME (fixes #2721) This is a proposal to add to lighttpd the famous SSI variables SCRIPT_URI and SCRIPT_URL (known to Apache users), as well as a bonus ENV variable called REQUEST_SCHEME. SCRIPT_URI and SCRIPT_URL will be available as SSI variables from within documents handled by mod_ssi. They can be used like any other SSI var with the &#34;#echo var&#34; command: &lt;!--#echo var=&#34;SCRIPT_URI&#34;--&gt; &lt;!--#echo var=&#34;SCRIPT_URL&#34;--&gt; Webmasters willing to display links to the W3C Validator will be able to use: &lt;a href=&#34;http://validator.w3.org/check?uri=&lt;!--#echo var=&#34;SCRIPT_URI&#34;--&gt;&#34;&gt;…&lt;/a&gt; instead of the generic http://validator.w3.org/check?uri=referer link which does not work on some (most?) browsers which do not send referers when the link itself resides in a document sent through https. REQUEST_SCHEME will be available both as an environment variable. It is defined as &#34;http&#34; or &#34;https&#34;, depending on the scheme of the connection. It is safe to use this name as it does not conflict with any existing variable on Apache or Nginx. This is slightly different from the HTTPS var which is often added by webadmins on their server&#39;s configuration. EDIT: Some Apache modules also define REQUEST_SCHEME with the same possible values as this proposal. From: fbrosson &lt;fbrosson@users.noreply.github.com&gt; git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@3124 152afb58-edef-0310-8abb-c4023f1b3aa9
6 years ago
}
if (vb_auth) {
memcpy(vb_auth, &b_auth, sizeof(buffer));
}
return 0;
}
static int mod_ssi_process_file(server *srv, connection *con, handler_ctx *p, struct stat *st);
static int process_ssi_stmt(server *srv, connection *con, handler_ctx *p, const char **l, size_t n, struct stat *st) {
fallback to lseek()/read() if mmap() fails (#fixes 2666) fallback to lseek()/read() if mmap() fails (#fixes 2666) e.g. when mmap() is used on lighttpd-controlled temporary files used POST request body (mod_cgi) and PUT file upload (mod_webdav) replace use of stream_open() on potentially untrusted files (protect against SIGBUS if a file is modified while map is read) Note: stream.[ch] may be removed in a future release For now, stream.[ch] will read entire file into memory if mmap fails and so it should only be used on trusted files, e.g. config files. http_auth basic and digest files are typically small and so buffered stdio fopen(), fgets(), fclose() will likely be approximately as fast as mmap. mod_dirlisting header and readme files are typically small and so open(), read(), close() will typically be approximately as fast as mmap mod_ssi will likely be much faster, now buffering SSI page construction rather than a potentially huge number of file open() calls, one for each tiny chunk of text between SSI directives. mod_webdav COPY and MOVE may be slower due to removal of mmap, but are now more resilient to partial writes. x-ref: &#34;handle filesystems without mmap() support&#34; https://redmine.lighttpd.net/issues/2666 &#34;WebDAV upload-&gt; mmap failed: operation not permitted&#34; https://redmine.lighttpd.net/issues/962 &#34;Lighttpd 1.4.20 Crash (SIGBUS in mod_compress)&#34; https://redmine.lighttpd.net/issues/1879 &#34;Crash SIGBUS&#34; https://redmine.lighttpd.net/issues/2391 github: closes #57
6 years ago
/**
* <!--#element attribute=value attribute=value ... -->
*
* config DONE
* errmsg -- missing
* sizefmt DONE
* timefmt DONE
* echo DONE
* var DONE
* encoding -- missing
* exec DONE
* cgi -- never
* cmd DONE
* fsize DONE
* file DONE
* virtual DONE
* flastmod DONE
* file DONE
* virtual DONE
* include DONE
* file DONE
* virtual DONE
* printenv DONE
* set DONE
* var DONE
* value DONE
*
* if DONE
* elif DONE
* else DONE
* endif DONE
*
*
* expressions
* AND, OR DONE
* comp DONE
* ${...} -- missing
* $... DONE
* '...' DONE
* ( ... ) DONE
*
*
*
* ** all DONE **
* DATE_GMT
* The current date in Greenwich Mean Time.
* DATE_LOCAL
* The current date in the local time zone.
* DOCUMENT_NAME
* The filename (excluding directories) of the document requested by the user.
* DOCUMENT_URI
* The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document.
* LAST_MODIFIED
* The last modification date of the document requested by the user.
* USER_NAME
* Contains the owner of the file which included it.
*
*/
size_t i, ssicmd = 0;
char buf[255];
buffer *b = NULL;
static const struct {
const char *var;
enum { SSI_UNSET, SSI_ECHO, SSI_FSIZE, SSI_INCLUDE, SSI_FLASTMOD,
SSI_CONFIG, SSI_PRINTENV, SSI_SET, SSI_IF, SSI_ELIF,
SSI_ELSE, SSI_ENDIF, SSI_EXEC, SSI_COMMENT } type;
} ssicmds[] = {
{ "echo", SSI_ECHO },
{ "include", SSI_INCLUDE },
{ "flastmod", SSI_FLASTMOD },
{ "fsize", SSI_FSIZE },
{ "config", SSI_CONFIG },
{ "printenv", SSI_PRINTENV },
{ "set", SSI_SET },
{ "if", SSI_IF },
{ "elif", SSI_ELIF },
{ "endif", SSI_ENDIF },
{ "else", SSI_ELSE },
{ "exec", SSI_EXEC },
{ "comment", SSI_COMMENT },
{ NULL, SSI_UNSET }
};
for (i = 0; ssicmds[i].var; i++) {
if (0 == strcmp(l[1], ssicmds[i].var)) {
ssicmd = ssicmds[i].type;
break;
}
}
switch(ssicmd) {
case SSI_ECHO: {
/* echo */
int var = 0;
/* int enc = 0; */
const char *var_val = NULL;
static const struct {
const char *var;
[mod_ssi] Add SSI vars SCRIPT_{URI,URL} and REQUEST_SCHEME (fixes #2721) This is a proposal to add to lighttpd the famous SSI variables SCRIPT_URI and SCRIPT_URL (known to Apache users), as well as a bonus ENV variable called REQUEST_SCHEME. SCRIPT_URI and SCRIPT_URL will be available as SSI variables from within documents handled by mod_ssi. They can be used like any other SSI var with the &#34;#echo var&#34; command: &lt;!--#echo var=&#34;SCRIPT_URI&#34;--&gt; &lt;!--#echo var=&#34;SCRIPT_URL&#34;--&gt; Webmasters willing to display links to the W3C Validator will be able to use: &lt;a href=&#34;http://validator.w3.org/check?uri=&lt;!--#echo var=&#34;SCRIPT_URI&#34;--&gt;&#34;&gt;…&lt;/a&gt; instead of the generic http://validator.w3.org/check?uri=referer link which does not work on some (most?) browsers which do not send referers when the link itself resides in a document sent through https. REQUEST_SCHEME will be available both as an environment variable. It is defined as &#34;http&#34; or &#34;https&#34;, depending on the scheme of the connection. It is safe to use this name as it does not conflict with any existing variable on Apache or Nginx. This is slightly different from the HTTPS var which is often added by webadmins on their server&#39;s configuration. EDIT: Some Apache modules also define REQUEST_SCHEME with the same possible values as this proposal. From: fbrosson &lt;fbrosson@users.noreply.github.com&gt; git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@3124 152afb58-edef-0310-8abb-c4023f1b3aa9
6 years ago
enum {
SSI_ECHO_UNSET,
SSI_ECHO_DATE_GMT,
SSI_ECHO_DATE_LOCAL,
SSI_ECHO_DOCUMENT_NAME,
SSI_ECHO_DOCUMENT_URI,
SSI_ECHO_LAST_MODIFIED,
SSI_ECHO_USER_NAME,
SSI_ECHO_SCRIPT_URI,
SSI_ECHO_SCRIPT_URL,
} type;
} echovars[] = {
{ "DATE_GMT", SSI_ECHO_DATE_GMT },
{ "DATE_LOCAL", SSI_ECHO_DATE_LOCAL },
{ "DOCUMENT_NAME", SSI_ECHO_DOCUMENT_NAME },
{ "DOCUMENT_URI", SSI_ECHO_DOCUMENT_URI },
{ "LAST_MODIFIED", SSI_ECHO_LAST_MODIFIED },
{ "USER_NAME", SSI_ECHO_USER_NAME },
[mod_ssi] Add SSI vars SCRIPT_{URI,URL} and REQUEST_SCHEME (fixes #2721) This is a proposal to add to lighttpd the famous SSI variables SCRIPT_URI and SCRIPT_URL (known to Apache users), as well as a bonus ENV variable called REQUEST_SCHEME. SCRIPT_URI and SCRIPT_URL will be available as SSI variables from within documents handled by mod_ssi. They can be used like any other SSI var with the &#34;#echo var&#34; command: &lt;!--#echo var=&#34;SCRIPT_URI&#34;--&gt; &lt;!--#echo var=&#34;SCRIPT_URL&#34;--&gt; Webmasters willing to display links to the W3C Validator will be able to use: &lt;a href=&#34;http://validator.w3.org/check?uri=&lt;!--#echo var=&#34;SCRIPT_URI&#34;--&gt;&#34;&gt;…&lt;/a&gt; instead of the generic http://validator.w3.org/check?uri=referer link which does not work on some (most?) browsers which do not send referers when the link itself resides in a document sent through https. REQUEST_SCHEME will be available both as an environment variable. It is defined as &#34;http&#34; or &#34;https&#34;, depending on the scheme of the connection. It is safe to use this name as it does not conflict with any existing variable on Apache or Nginx. This is slightly different from the HTTPS var which is often added by webadmins on their server&#39;s configuration. EDIT: Some Apache modules also define REQUEST_SCHEME with the same possible values as this proposal. From: fbrosson &lt;fbrosson@users.noreply.github.com&gt; git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@3124 152afb58-edef-0310-8abb-c4023f1b3aa9
6 years ago
{ "SCRIPT_URI", SSI_ECHO_SCRIPT_URI },
{ "SCRIPT_URL", SSI_ECHO_SCRIPT_URL },
{ NULL, SSI_ECHO_UNSET }
};
/*
static const struct {
const char *var;
enum { SSI_ENC_UNSET, SSI_ENC_URL, SSI_ENC_NONE, SSI_ENC_ENTITY } type;
} encvars[] = {
{ "url", SSI_ENC_URL },
{ "none", SSI_ENC_NONE },
{ "entity", SSI_ENC_ENTITY },
{ NULL, SSI_ENC_UNSET }
};
*/
for (i = 2; i < n; i += 2) {
if (0 == strcmp(l[i], "var")) {
int j;
var_val = l[i+1];
for (j = 0; echovars[j].var; j++) {
if (0 == strcmp(l[i+1], echovars[j].var)) {
var = echovars[j].type;
break;
}
}
} else if (0 == strcmp(l[i], "encoding")) {
/*
int j;
for (j = 0; encvars[j].var; j++) {
if (0 == strcmp(l[i+1], encvars[j].var)) {
enc = encvars[j].type;
break;
}
}
*/
} else {
log_error_write(srv, __FILE__, __LINE__, "sss",
"ssi: unknown attribute for ",
l[1], l[i]);
}
}
if (p->if_is_false) break;
if (!var_val) {
log_error_write(srv, __FILE__, __LINE__, "sss",
"ssi: ",
l[1], "var is missing");
break;
}
switch(var) {
case SSI_ECHO_USER_NAME: {
struct passwd *pw;
b = srv->tmp_buf;
#ifdef HAVE_PWD_H
fallback to lseek()/read() if mmap() fails (#fixes 2666) fallback to lseek()/read() if mmap() fails (#fixes 2666) e.g. when mmap() is used on lighttpd-controlled temporary files used POST request body (mod_cgi) and PUT file upload (mod_webdav) replace use of stream_open() on potentially untrusted files (protect against SIGBUS if a file is modified while map is read) Note: stream.[ch] may be removed in a future release For now, stream.[ch] will read entire file into memory if mmap fails and so it should only be used on trusted files, e.g. config files. http_auth basic and digest files are typically small and so buffered stdio fopen(), fgets(), fclose() will likely be approximately as fast as mmap. mod_dirlisting header and readme files are typically small and so open(), read(), close() will typically be approximately as fast as mmap mod_ssi will likely be much faster, now buffering SSI page construction rather than a potentially huge number of file open() calls, one for each tiny chunk of text between SSI directives. mod_webdav COPY and MOVE may be slower due to removal of mmap, but are now more resilient to partial writes. x-ref: &#34;handle filesystems without mmap() support&#34; https://redmine.lighttpd.net/issues/2666 &#34;WebDAV upload-&gt; mmap failed: operation not permitted&#34; https://redmine.lighttpd.net/issues/962 &#34;Lighttpd 1.4.20 Crash (SIGBUS in mod_compress)&#34; https://redmine.lighttpd.net/issues/1879 &#34;Crash SIGBUS&#34; https://redmine.lighttpd.net/issues/2391 github: closes #57
6 years ago
if (NULL == (pw = getpwuid(st->st_uid))) {
buffer_copy_int(b, st->st_uid);
} else {
buffer_copy_string(b, pw->pw_name);
}
#else
fallback to lseek()/read() if mmap() fails (#fixes 2666) fallback to lseek()/read() if mmap() fails (#fixes 2666) e.g. when mmap() is used on lighttpd-controlled temporary files used POST request body (mod_cgi) and PUT file upload (mod_webdav) replace use of stream_open() on potentially untrusted files (protect against SIGBUS if a file is modified while map is read) Note: stream.[ch] may be removed in a future release For now, stream.[ch] will read entire file into memory if mmap fails and so it should only be used on trusted files, e.g. config files. http_auth basic and digest files are typically small and so buffered stdio fopen(), fgets(), fclose() will likely be approximately as fast as mmap. mod_dirlisting header and readme files are typically small and so open(), read(), close() will typically be approximately as fast as mmap mod_ssi will likely be much faster, now buffering SSI page construction rather than a potentially huge number of file open() calls, one for each tiny chunk of text between SSI directives. mod_webdav COPY and MOVE may be slower due to removal of mmap, but are now more resilient to partial writes. x-ref: &#34;handle filesystems without mmap() support&#34; https://redmine.lighttpd.net/issues/2666 &#34;WebDAV upload-&gt; mmap failed: operation not permitted&#34; https://redmine.lighttpd.net/issues/962 &#34;Lighttpd 1.4.20 Crash (SIGBUS in mod_compress)&#34; https://redmine.lighttpd.net/issues/1879 &#34;Crash SIGBUS&#34; https://redmine.lighttpd.net/issues/2391 github: closes #57
6 years ago
buffer_copy_int(b, st->st_uid);
#endif
chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(b));
break;
}
[mod_ssi] Add SSI vars SCRIPT_{URI,URL} and REQUEST_SCHEME (fixes #2721) This is a proposal to add to lighttpd the famous SSI variables SCRIPT_URI and SCRIPT_URL (known to Apache users), as well as a bonus ENV variable called REQUEST_SCHEME. SCRIPT_URI and SCRIPT_URL will be available as SSI variables from within documents handled by mod_ssi. They can be used like any other SSI var with the &#34;#echo var&#34; command: &lt;!--#echo var=&#34;SCRIPT_URI&#34;--&gt; &lt;!--#echo var=&#34;SCRIPT_URL&#34;--&gt; Webmasters willing to display links to the W3C Validator will be able to use: &lt;a href=&#34;http://validator.w3.org/check?uri=&lt;!--#echo var=&#34;SCRIPT_URI&#34;--&gt;&#34;&gt;…&lt;/a&gt; instead of the generic http://validator.w3.org/check?uri=referer link which does not work on some (most?) browsers which do not send referers when the link itself resides in a document sent through https. REQUEST_SCHEME will be available both as an environment variable. It is defined as &#34;http&#34; or &#34;https&#34;, depending on the scheme of the connection. It is safe to use this name as it does not conflict with any existing variable on Apache or Nginx. This is slightly different from the HTTPS var which is often added by webadmins on their server&#39;s configuration. EDIT: Some Apache modules also define REQUEST_SCHEME with the same possible values as this proposal. From: fbrosson &lt;fbrosson@users.noreply.github.com&gt; git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@3124 152afb58-edef-0310-8abb-c4023f1b3aa9
6 years ago
case SSI_ECHO_LAST_MODIFIED: {
fallback to lseek()/read() if mmap() fails (#fixes 2666) fallback to lseek()/read() if mmap() fails (#fixes 2666) e.g. when mmap() is used on lighttpd-controlled temporary files used POST request body (mod_cgi) and PUT file upload (mod_webdav) replace use of stream_open() on potentially untrusted files (protect against SIGBUS if a file is modified while map is read) Note: stream.[ch] may be removed in a future release For now, stream.[ch] will read entire file into memory if mmap fails and so it should only be used on trusted files, e.g. config files. http_auth basic and digest files are typically small and so buffered stdio fopen(), fgets(), fclose() will likely be approximately as fast as mmap. mod_dirlisting header and readme files are typically small and so open(), read(), close() will typically be approximately as fast as mmap mod_ssi will likely be much faster, now buffering SSI page construction rather than a potentially huge number of file open() calls, one for each tiny chunk of text between SSI directives. mod_webdav COPY and MOVE may be slower due to removal of mmap, but are now more resilient to partial writes. x-ref: &#34;handle filesystems without mmap() support&#34; https://redmine.lighttpd.net/issues/2666 &#34;WebDAV upload-&gt; mmap failed: operation not permitted&#34; https://redmine.lighttpd.net/issues/962 &#34;Lighttpd 1.4.20 Crash (SIGBUS in mod_compress)&#34; https://redmine.lighttpd.net/issues/1879 &#34;Crash SIGBUS&#34; https://redmine.lighttpd.net/issues/2391 github: closes #57
6 years ago
time_t t = st->st_mtime;
if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("(none)"));
} else {
chunkqueue_append_mem(con->write_queue, buf, strlen(buf));
}
break;
}
case SSI_ECHO_DATE_LOCAL: {
time_t t = time(NULL);
if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("(none)"));
} else {
chunkqueue_append_mem(con->write_queue, buf, strlen(buf));
}
break;
}
case SSI_ECHO_DATE_GMT: {
time_t t = time(NULL);
if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, gmtime(&t))) {
chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("(none)"));
} else {
chunkqueue_append_mem(con->write_queue, buf, strlen(buf));
}
break;
}
case SSI_ECHO_DOCUMENT_NAME: {
char *sl;
if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) {
chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(con->physical.path));
} else {
chunkqueue_append_mem(con->write_queue, sl + 1, strlen(sl + 1));
}
break;
}
case SSI_ECHO_DOCUMENT_URI: {
chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(con->uri.path));
break;
}
[mod_ssi] Add SSI vars SCRIPT_{URI,URL} and REQUEST_SCHEME (fixes #2721) This is a proposal to add to lighttpd the famous SSI variables SCRIPT_URI and SCRIPT_URL (known to Apache users), as well as a bonus ENV variable called REQUEST_SCHEME. SCRIPT_URI and SCRIPT_URL will be available as SSI variables from within documents handled by mod_ssi. They can be used like any other SSI var with the &#34;#echo var&#34; command: &lt;!--#echo var=&#34;SCRIPT_URI&#34;--&gt; &lt;!--#echo var=&#34;SCRIPT_URL&#34;--&gt; Webmasters willing to display links to the W3C Validator will be able to use: &lt;a href=&#34;http://validator.w3.org/check?uri=&lt;!--#echo var=&#34;SCRIPT_URI&#34;--&gt;&#34;&gt;…&lt;/a&gt; instead of the generic http://validator.w3.org/check?uri=referer link which does not work on some (most?) browsers which do not send referers when the link itself resides in a document sent through https. REQUEST_SCHEME will be available both as an environment variable. It is defined as &#34;http&#34; or &#34;https&#34;, depending on the scheme of the connection. It is safe to use this name as it does not conflict with any existing variable on Apache or Nginx. This is slightly different from the HTTPS var which is often added by webadmins on their server&#39;s configuration. EDIT: Some Apache modules also define REQUEST_SCHEME with the same possible values as this proposal. From: fbrosson &lt;fbrosson@users.noreply.github.com&gt; git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@3124 152afb58-edef-0310-8abb-c4023f1b3aa9
6 years ago
case SSI_ECHO_SCRIPT_URI: {
if (!buffer_string_is_empty(con->uri.scheme) && !buffer_string_is_empty(con->uri.authority)) {
chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(con->uri.scheme));
chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("://"));
chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(con->uri.authority));
chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(con->request.uri));
if (!buffer_string_is_empty(con->uri.query)) {
chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("?"));
chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(con->uri.query));
}
}
break;
}
case SSI_ECHO_SCRIPT_URL: {
chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(con->request.uri));
if (!buffer_string_is_empty(con->uri.query)) {
chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("?"));
chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(con->uri.query));
}
break;
}
default: {
data_string *ds;
/* check if it is a cgi-var or a ssi-var */
if (NULL != (ds = (data_string *)array_get_element_klen(p->ssi_cgi_env, var_val, strlen(var_val))) ||
NULL != (ds = (data_string *)array_get_element_klen(p->ssi_vars, var_val, strlen(var_val)))) {
chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(ds->value));
} else {
chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("(none)"));
}
break;
}
}
break;
}
case SSI_INCLUDE:
case SSI_FLASTMOD:
case SSI_FSIZE: {
const char * file_path = NULL, *virt_path = NULL;
fallback to lseek()/read() if mmap() fails (#fixes 2666) fallback to lseek()/read() if mmap() fails (#fixes 2666) e.g. when mmap() is used on lighttpd-controlled temporary files used POST request body (mod_cgi) and PUT file upload (mod_webdav) replace use of stream_open() on potentially untrusted files (protect against SIGBUS if a file is modified while map is read) Note: stream.[ch] may be removed in a future release For now, stream.[ch] will read entire file into memory if mmap fails and so it should only be used on trusted files, e.g. config files. http_auth basic and digest files are typically small and so buffered stdio fopen(), fgets(), fclose() will likely be approximately as fast as mmap. mod_dirlisting header and readme files are typically small and so open(), read(), close() will typically be approximately as fast as mmap mod_ssi will likely be much faster, now buffering SSI page construction rather than a potentially huge number of file open() calls, one for each tiny chunk of text between SSI directives. mod_webdav COPY and MOVE may be slower due to removal of mmap, but are now more resilient to partial writes. x-ref: &#34;handle filesystems without mmap() support&#34; https://redmine.lighttpd.net/issues/2666 &#34;WebDAV upload-&gt; mmap failed: operation not permitted&#34; https://redmine.lighttpd.net/issues/962 &#34;Lighttpd 1.4.20 Crash (SIGBUS in mod_compress)&#34; https://redmine.lighttpd.net/issues/1879 &#34;Crash SIGBUS&#34; https://redmine.lighttpd.net/issues/2391 github: closes #57
6 years ago
struct stat stb;
char *sl;
for (i = 2; i < n; i += 2) {
if (0 == strcmp(l[i], "file")) {
file_path = l[i+1];
} else if (0 == strcmp(l[i], "virtual")) {
virt_path = l[i+1];
} else {
log_error_write(srv, __FILE__, __LINE__, "sss",
"ssi: unknown attribute for ",
l[1], l[i]);
}
}
if (!file_path && !virt_path) {
log_error_write(srv, __FILE__, __LINE__, "sss",
"ssi: ",
l[1], "file or virtual are missing");
break;
}
if (file_path && virt_path) {
log_error_write(srv, __FILE__, __LINE__, "sss",
"ssi: ",
l[1], "only one of file and virtual is allowed here");
break;
}
if (p->if_is_false) break;
if (file_path) {
/* current doc-root */
if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) {
buffer_copy_string_len(p->stat_fn, CONST_STR_LEN("/"));
} else {
buffer_copy_string_len(p->stat_fn, con->physical.path->ptr, sl - con->physical.path->ptr + 1);
}
buffer_copy_string(srv->tmp_buf, file_path);
buffer_urldecode_path(srv->tmp_buf);
if (!buffer_is_valid_UTF8(srv->tmp_buf)) {
log_error_write(srv, __FILE__, __LINE__, "sb",
"SSI invalid UTF-8 after url-decode:", srv->tmp_buf);
break;
}
buffer_path_simplify(srv->tmp_buf, srv->tmp_buf);
buffer_append_string_buffer(p->stat_fn, srv->tmp_buf);
} else {
/* virtual */
size_t remain;
if (virt_path[0] == '/') {
buffer_copy_string(srv->tmp_buf, virt_path);
} else {
/* there is always a / */
sl = strrchr(con->uri.path->ptr, '/');
buffer_copy_string_len(srv->tmp_buf, con->uri.path->ptr, sl - con->uri.path->ptr + 1);
buffer_append_string(srv->tmp_buf, virt_path);
}
buffer_urldecode_path(srv->tmp_buf);
if (!buffer_is_valid_UTF8(srv->tmp_buf)) {
log_error_write(srv, __FILE__, __LINE__, "sb",
"SSI invalid UTF-8 after url-decode:", srv->tmp_buf);
break;
}
buffer_path_simplify(srv->tmp_buf, srv->tmp_buf);
/* we have an uri */
/* Destination physical path (similar to code in mod_webdav.c)
* src con->physical.path might have been remapped with mod_alias, mod_userdir.
* (but neither modifies con->physical.rel_path)
* Find matching prefix to support relative paths to current physical path.
* Aliasing of paths underneath current con->physical.basedir might not work.
* Likewise, mod_rewrite URL rewriting might thwart this comparison.
* Use mod_redirect instead of mod_alias to remap paths *under* this basedir.
* Use mod_redirect instead of mod_rewrite on *any* parts of path to basedir.
* (Related, use mod_auth to protect this basedir, but avoid attempting to
* use mod_auth on paths underneath this basedir, as target path is not
* validated with mod_auth)
*/
/* find matching URI prefix
* check if remaining con->physical.rel_path matches suffix
* of con->physical.basedir so that we can use it to
* remap Destination physical path */
{
const char *sep, *sep2;
sep = con->uri.path->ptr;
sep2 = srv->tmp_buf->ptr;
for (i = 0; sep[i] && sep[i] == sep2[i]; ++i) ;
while (i != 0 && sep[--i] != '/') ; /* find matching directory path */
}
if (con->conf.force_lowercase_filenames) {
buffer_to_lower(srv->tmp_buf);
}
remain = buffer_string_length(con->uri.path) - i;
if (!con->conf.force_lowercase_filenames
? buffer_is_equal_right_len(con->physical.path, con->physical.rel_path, remain)
:(buffer_string_length(con->physical.path) >= remain
&& 0 == strncasecmp(con->physical.path->ptr+buffer_string_length(con->physical.path)-remain, con->physical.rel_path->ptr+i, remain))) {
buffer_copy_string_len(p->stat_fn, con->physical.path->ptr, buffer_string_length(con->physical.path)-remain);
buffer_append_string_len(p->stat_fn, srv->tmp_buf->ptr+i, buffer_string_length(srv->tmp_buf)-i);
} else {
/* unable to perform physical path remap here;
* assume doc_root/rel_path and no remapping */
buffer_copy_buffer(p->stat_fn, con->physical.doc_root);
buffer_append_string_buffer(p->stat_fn, srv->tmp_buf);
}
}
if (!con->conf.follow_symlink
&& 0 != stat_cache_path_contains_symlink(srv, p->stat_fn)) {
break;
}
int fd = stat_cache_open_rdonly_fstat(p->stat_fn, &stb, con->conf.follow_symlink);
if (fd > 0) {
fallback to lseek()/read() if mmap() fails (#fixes 2666) fallback to lseek()/read() if mmap() fails (#fixes 2666) e.g. when mmap() is used on lighttpd-controlled temporary files used POST request body (mod_cgi) and PUT file upload (mod_webdav) replace use of stream_open() on potentially untrusted files (protect against SIGBUS if a file is modified while map is read) Note: stream.[ch] may be removed in a future release For now, stream.[ch] will read entire file into memory if mmap fails and so it should only be used on trusted files, e.g. config files. http_auth basic and digest files are typically small and so buffered stdio fopen(), fgets(), fclose() will likely be approximately as fast as mmap. mod_dirlisting header and readme files are typically small and so open(), read(), close() will typically be approximately as fast as mmap mod_ssi will likely be much faster, now buffering SSI page construction rather than a potentially huge number of file open() calls, one for each tiny chunk of text between SSI directives. mod_webdav COPY and MOVE may be slower due to removal of mmap, but are now more resilient to partial writes. x-ref: &#34;handle filesystems without mmap() support&#34; https://redmine.lighttpd.net/issues/2666 &#34;WebDAV upload-&gt; mmap failed: operation not permitted&#34; https://redmine.lighttpd.net/issues/962 &#34;Lighttpd 1.4.20 Crash (SIGBUS in mod_compress)&#34; https://redmine.lighttpd.net/issues/1879 &#34;Crash SIGBUS&#34; https://redmine.lighttpd.net/issues/2391 github: closes #57
6 years ago
time_t t = stb.st_mtime;
switch (ssicmd) {
case SSI_FSIZE:
b = srv->tmp_buf;
if (p->sizefmt) {
int j = 0;
const char *abr[] = { " B", " kB", " MB", " GB", " TB", NULL };
fallback to lseek()/read() if mmap() fails (#fixes 2666) fallback to lseek()/read() if mmap() fails (#fixes 2666) e.g. when mmap() is used on lighttpd-controlled temporary files used POST request body (mod_cgi) and PUT file upload (mod_webdav) replace use of stream_open() on potentially untrusted files (protect against SIGBUS if a file is modified while map is read) Note: stream.[ch] may be removed in a future release For now, stream.[ch] will read entire file into memory if mmap fails and so it should only be used on trusted files, e.g. config files. http_auth basic and digest files are typically small and so buffered stdio fopen(), fgets(), fclose() will likely be approximately as fast as mmap. mod_dirlisting header and readme files are typically small and so open(), read(), close() will typically be approximately as fast as mmap mod_ssi will likely be much faster, now buffering SSI page construction rather than a potentially huge number of file open() calls, one for each tiny chunk of text between SSI directives. mod_webdav COPY and MOVE may be slower due to removal of mmap, but are now more resilient to partial writes. x-ref: &#34;handle filesystems without mmap() support&#34; https://redmine.lighttpd.net/issues/2666 &#34;WebDAV upload-&gt; mmap failed: operation not permitted&#34; https://redmine.lighttpd.net/issues/962 &#34;Lighttpd 1.4.20 Crash (SIGBUS in mod_compress)&#34; https://redmine.lighttpd.net/issues/1879 &#34;Crash SIGBUS&#34; https://redmine.lighttpd.net/issues/2391 github: closes #57
6 years ago
off_t s = stb.st_size;
for (j = 0; s > 1024 && abr[j+1]; s /= 1024, j++);
fix buffer, chunk and http_chunk API * remove unused structs and functions (buffer_array, read_buffer) * change return type from int to void for many functions, as the return value (indicating error/success) was never checked, and the function would only fail on programming errors and not on invalid input; changed functions to use force_assert instead of returning an error. * all &#34;len&#34; parameters now are the real size of the memory to be read. the length of strings is given always without the terminating 0. * the &#34;buffer&#34; struct still counts the terminating 0 in -&gt;used, provide buffer_string_length() to get the length of a string in a buffer. unset config &#34;strings&#34; have used == 0, which is used in some places to distinguish unset values from &#34;&#34; (empty string) values. * most buffer usages should now use it as string container. * optimise some buffer copying by &#34;moving&#34; data to other buffers * use (u)intmax_t for generic int-to-string functions * remove unused enum values: UNUSED_CHUNK, ENCODING_UNSET * converted BUFFER_APPEND_SLASH to inline function (no macro feature needed) * refactor: create chunkqueue_steal: moving (partial) chunks into another queue * http_chunk: added separate function to terminate chunked body instead of magic handling in http_chunk_append_mem(). http_chunk_append_* now handle empty chunks, and never terminate the chunked body. From: Stefan Bühler &lt;stbuehler@web.de&gt; git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2975 152afb58-edef-0310-8abb-c4023f1b3aa9
7 years ago
buffer_copy_int(b, s);
buffer_append_string(b, abr[j]);
} else {
fallback to lseek()/read() if mmap() fails (#fixes 2666) fallback to lseek()/read() if mmap() fails (#fixes 2666) e.g. when mmap() is used on lighttpd-controlled temporary files used POST request body (mod_cgi) and PUT file upload (mod_webdav) replace use of stream_open() on potentially untrusted files (protect against SIGBUS if a file is modified while map is read) Note: stream.[ch] may be removed in a future release For now, stream.[ch] will read entire file into memory if mmap fails and so it should only be used on trusted files, e.g. config files. http_auth basic and digest files are typically small and so buffered stdio fopen(), fgets(), fclose() will likely be approximately as fast as mmap. mod_dirlisting header and readme files are typically small and so open(), read(), close() will typically be approximately as fast as mmap mod_ssi will likely be much faster, now buffering SSI page construction rather than a potentially huge number of file open() calls, one for each tiny chunk of text between SSI directives. mod_webdav COPY and MOVE may be slower due to removal of mmap, but are now more resilient to partial writes. x-ref: &#34;handle filesystems without mmap() support&#34; https://redmine.lighttpd.net/issues/2666 &#34;WebDAV upload-&gt; mmap failed: operation not permitted&#34; https://redmine.lighttpd.net/issues/962 &#34;Lighttpd 1.4.20 Crash (SIGBUS in mod_compress)&#34; https://redmine.lighttpd.net/issues/1879 &#34;Crash SIGBUS&#34; https://redmine.lighttpd.net/issues/2391 github: closes #57
6 years ago
buffer_copy_int(b, stb.st_size);
}
chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(b));
break;
case SSI_FLASTMOD:
if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("(none)"));
} else {
chunkqueue_append_mem(con->write_queue, buf, strlen(buf));
}
break;
case SSI_INCLUDE:
/* Keep the newest mtime of included files */
fallback to lseek()/read() if mmap() fails (#fixes 2666) fallback to lseek()/read() if mmap() fails (#fixes 2666) e.g. when mmap() is used on lighttpd-controlled temporary files used POST request body (mod_cgi) and PUT file upload (mod_webdav) replace use of stream_open() on potentially untrusted files (protect against SIGBUS if a file is modified while map is read) Note: stream.[ch] may be removed in a future release For now, stream.[ch] will read entire file into memory if mmap fails and so it should only be used on trusted files, e.g. config files. http_auth basic and digest files are typically small and so buffered stdio fopen(), fgets(), fclose() will likely be approximately as fast as mmap. mod_dirlisting header and readme files are typically small and so open(), read(), close() will typically be approximately as fast as mmap mod_ssi will likely be much faster, now buffering SSI page construction rather than a potentially huge number of file open() calls, one for each tiny chunk of text between SSI directives. mod_webdav COPY and MOVE may be slower due to removal of mmap, but are now more resilient to partial writes. x-ref: &#34;handle filesystems without mmap() support&#34; https://redmine.lighttpd.net/issues/2666 &#34;WebDAV upload-&gt; mmap failed: operation not permitted&#34; https://redmine.lighttpd.net/issues/962 &#34;Lighttpd 1.4.20 Crash (SIGBUS in mod_compress)&#34; https://redmine.lighttpd.net/issues/1879 &#34;Crash SIGBUS&#34; https://redmine.lighttpd.net/issues/2391 github: closes #57
6 years ago
if (stb.st_mtime > include_file_last_mtime)
include_file_last_mtime = stb.st_mtime;
if (file_path || 0 == p->conf.ssi_recursion_max) {
/* don't process if #include file="..." is used */
chunkqueue_append_file_fd(con->write_queue, p->stat_fn, fd, 0, stb.st_size);
fd = -1;
} else {
buffer *upsave, *ppsave, *prpsave;