2016-03-19 15:14:35 +00:00
|
|
|
#include "first.h"
|
|
|
|
|
2009-10-11 14:31:42 +00:00
|
|
|
#include <sys/types.h>
|
2018-03-25 07:45:05 +00:00
|
|
|
#include <stdlib.h>
|
2009-10-11 14:31:42 +00:00
|
|
|
#include <string.h>
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
|
|
|
|
#include "gw_backend.h"
|
|
|
|
typedef gw_plugin_config plugin_config;
|
|
|
|
typedef gw_plugin_data plugin_data;
|
|
|
|
typedef gw_handler_ctx handler_ctx;
|
|
|
|
|
|
|
|
#include "buffer.h"
|
|
|
|
#include "fdevent.h"
|
2021-03-05 00:11:40 +00:00
|
|
|
#include "http_cgi.h"
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
#include "http_chunk.h"
|
|
|
|
#include "log.h"
|
2021-08-02 09:11:36 +00:00
|
|
|
#include "request.h"
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
#include "status_counter.h"
|
2009-10-11 14:31:42 +00:00
|
|
|
|
2020-12-21 02:32:50 +00:00
|
|
|
#include "compat/fastcgi.h"
|
2009-10-11 14:31:42 +00:00
|
|
|
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
#if GW_RESPONDER != FCGI_RESPONDER
|
|
|
|
#error "mismatched defines: (GW_RESPONDER != FCGI_RESPONDER)"
|
2005-02-20 14:27:00 +00:00
|
|
|
#endif
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
#if GW_AUTHORIZER != FCGI_AUTHORIZER
|
|
|
|
#error "mismatched defines: (GW_AUTHORIZER != FCGI_AUTHORIZER)"
|
|
|
|
#endif
|
|
|
|
#if GW_FILTER != FCGI_FILTER
|
|
|
|
#error "mismatched defines: (GW_FILTER != FCGI_FILTER)"
|
2005-02-20 14:27:00 +00:00
|
|
|
#endif
|
2016-04-01 01:59:32 +00:00
|
|
|
|
2019-11-13 05:40:28 +00:00
|
|
|
static void mod_fastcgi_merge_config_cpv(plugin_config * const pconf, const config_plugin_value_t * const cpv) {
|
|
|
|
switch (cpv->k_id) { /* index into static config_plugin_keys_t cpk[] */
|
|
|
|
case 0: /* fastcgi.server */
|
|
|
|
if (cpv->vtype == T_CONFIG_LOCAL) {
|
|
|
|
gw_plugin_config * const gw = cpv->v.v;
|
|
|
|
pconf->exts = gw->exts;
|
|
|
|
pconf->exts_auth = gw->exts_auth;
|
|
|
|
pconf->exts_resp = gw->exts_resp;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1: /* fastcgi.balance */
|
|
|
|
/*if (cpv->vtype == T_CONFIG_LOCAL)*//*always true here for this param*/
|
|
|
|
pconf->balance = (int)cpv->v.u;
|
|
|
|
break;
|
|
|
|
case 2: /* fastcgi.debug */
|
|
|
|
pconf->debug = (int)cpv->v.u;
|
|
|
|
break;
|
|
|
|
case 3: /* fastcgi.map-extensions */
|
|
|
|
pconf->ext_mapping = cpv->v.a;
|
|
|
|
break;
|
|
|
|
default:/* should not happen */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2016-09-19 00:23:59 +00:00
|
|
|
|
2019-11-13 05:40:28 +00:00
|
|
|
static void mod_fastcgi_merge_config(plugin_config * const pconf, const config_plugin_value_t *cpv) {
|
|
|
|
do {
|
|
|
|
mod_fastcgi_merge_config_cpv(pconf, cpv);
|
|
|
|
} while ((++cpv)->k_id != -1);
|
|
|
|
}
|
2016-10-25 21:44:45 +00:00
|
|
|
|
2020-01-13 02:51:12 +00:00
|
|
|
static void mod_fastcgi_patch_config(request_st * const r, plugin_data * const p) {
|
2019-11-13 05:40:28 +00:00
|
|
|
memcpy(&p->conf, &p->defaults, sizeof(plugin_config));
|
|
|
|
for (int i = 1, used = p->nconfig; i < used; ++i) {
|
2020-01-13 02:51:12 +00:00
|
|
|
if (config_check_cond(r, (uint32_t)p->cvlist[i].k_id))
|
2019-11-13 05:40:28 +00:00
|
|
|
mod_fastcgi_merge_config(&p->conf,p->cvlist + p->cvlist[i].v.u2[0]);
|
|
|
|
}
|
|
|
|
}
|
2016-10-25 21:44:45 +00:00
|
|
|
|
2019-11-13 05:40:28 +00:00
|
|
|
SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
|
|
|
|
static const config_plugin_keys_t cpk[] = {
|
|
|
|
{ CONST_STR_LEN("fastcgi.server"),
|
2019-12-08 00:15:55 +00:00
|
|
|
T_CONFIG_ARRAY_KVARRAY,
|
2019-11-13 05:40:28 +00:00
|
|
|
T_CONFIG_SCOPE_CONNECTION }
|
|
|
|
,{ CONST_STR_LEN("fastcgi.balance"),
|
|
|
|
T_CONFIG_STRING,
|
|
|
|
T_CONFIG_SCOPE_CONNECTION }
|
|
|
|
,{ CONST_STR_LEN("fastcgi.debug"),
|
|
|
|
T_CONFIG_INT,
|
|
|
|
T_CONFIG_SCOPE_CONNECTION }
|
|
|
|
,{ CONST_STR_LEN("fastcgi.map-extensions"),
|
2019-12-08 00:15:55 +00:00
|
|
|
T_CONFIG_ARRAY_KVSTRING,
|
2019-11-13 05:40:28 +00:00
|
|
|
T_CONFIG_SCOPE_CONNECTION }
|
|
|
|
,{ NULL, 0,
|
|
|
|
T_CONFIG_UNSET,
|
|
|
|
T_CONFIG_SCOPE_UNSET }
|
|
|
|
};
|
|
|
|
|
|
|
|
plugin_data * const p = p_d;
|
|
|
|
if (!config_plugin_values_init(srv, p, cpk, "mod_fastcgi"))
|
|
|
|
return HANDLER_ERROR;
|
|
|
|
|
|
|
|
/* process and validate config directives
|
|
|
|
* (init i to 0 if global context; to 1 to skip empty global context) */
|
|
|
|
for (int i = !p->cvlist[0].v.u2[1]; i < p->nconfig; ++i) {
|
|
|
|
config_plugin_value_t *cpv = p->cvlist + p->cvlist[i].v.u2[0];
|
|
|
|
for (; -1 != cpv->k_id; ++cpv) {
|
|
|
|
switch (cpv->k_id) {
|
|
|
|
case 0:{/* fastcgi.server */
|
|
|
|
gw_plugin_config *gw = calloc(1, sizeof(gw_plugin_config));
|
|
|
|
force_assert(gw);
|
|
|
|
if (!gw_set_defaults_backend(srv, p, cpv->v.a, gw, 0,
|
|
|
|
cpk[cpv->k_id].k)) {
|
|
|
|
gw_plugin_config_free(gw);
|
|
|
|
return HANDLER_ERROR;
|
|
|
|
}
|
|
|
|
cpv->v.v = gw;
|
|
|
|
cpv->vtype = T_CONFIG_LOCAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 1: /* fastcgi.balance */
|
|
|
|
cpv->v.u = (unsigned int)gw_get_defaults_balance(srv, cpv->v.b);
|
|
|
|
break;
|
|
|
|
case 2: /* fastcgi.debug */
|
|
|
|
case 3: /* fastcgi.map-extensions */
|
|
|
|
break;
|
|
|
|
default:/* should not happen */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* default is 0 */
|
|
|
|
/*p->defaults.balance = (unsigned int)gw_get_defaults_balance(srv, NULL);*/
|
|
|
|
|
|
|
|
/* initialize p->defaults from global config context */
|
|
|
|
if (p->nconfig > 0 && p->cvlist->v.u2[1]) {
|
|
|
|
const config_plugin_value_t *cpv = p->cvlist + p->cvlist->v.u2[0];
|
|
|
|
if (-1 != cpv->k_id)
|
|
|
|
mod_fastcgi_merge_config(&p->defaults, cpv);
|
|
|
|
}
|
|
|
|
|
|
|
|
return HANDLER_GO_ON;
|
2005-02-20 14:27:00 +00:00
|
|
|
}
|
|
|
|
|
2019-11-13 05:40:28 +00:00
|
|
|
|
consistent, shared code to create CGI env
consolidated from CGI, FastCGI, SCGI, SSI
Note: due to prior inconsistencies between the code in mod_cgi,
mod_fastcgi, mod_scgi, and mod_ssi, there are some minor behavior
changes.
CONTENT_LENGTH is now always set, even if 0
(though CONTENT_LENGTH is never set for FASTCGI_AUTHORIZER)
PATH_INFO is created only if present, not if empty.
(mod_fastcgi and mod_ssi previously set PATH_INFO="" (blank value))
PATH_TRANSLATED is now set if PATH_INFO is present
(previously missing from mod_cgi and mod_ssi)
mod_ssi now sets DOCUMENT_ROOT to con->physical.basedir, like others
(previously, mod_ssi set DOCUMENT_ROOT to con->physical.doc_root,
which matched con->physical.basedir unless mod_alias changed basedir)
mod_ssi now sets REQUEST_URI to con->request.orig_uri, like others
(previously, mod_ssi set REQUEST_URI to con->request.uri, which
matched con->request.orig_uri except after redirects, error docs)
2016-10-10 17:37:36 +00:00
|
|
|
static int fcgi_env_add(void *venv, const char *key, size_t key_len, const char *val, size_t val_len) {
|
|
|
|
buffer *env = venv;
|
2015-02-08 19:10:39 +00:00
|
|
|
char len_enc[8];
|
|
|
|
size_t len_enc_len = 0;
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2020-11-09 22:19:10 +00:00
|
|
|
if (!key || (!val && val_len)) return -1;
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2007-09-05 11:28:35 +00:00
|
|
|
/**
|
|
|
|
* field length can be 31bit max
|
|
|
|
*
|
|
|
|
* HINT: this can't happen as FCGI_MAX_LENGTH is only 16bit
|
|
|
|
*/
|
2015-02-08 19:10:39 +00:00
|
|
|
force_assert(key_len < 0x7fffffffu);
|
|
|
|
force_assert(val_len < 0x7fffffffu);
|
2007-09-05 11:28:35 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
if (key_len > 127) {
|
2021-03-16 05:05:47 +00:00
|
|
|
len_enc[0] = ((key_len >> 24) & 0xff) | 0x80;
|
|
|
|
len_enc[1] = (key_len >> 16) & 0xff;
|
|
|
|
len_enc[2] = (key_len >> 8) & 0xff;
|
|
|
|
len_enc_len += 3;
|
2005-02-20 14:27:00 +00:00
|
|
|
}
|
2021-03-16 05:05:47 +00:00
|
|
|
len_enc[len_enc_len++] = key_len & 0xff;
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
if (val_len > 127) {
|
2015-02-08 19:10:39 +00:00
|
|
|
len_enc[len_enc_len++] = ((val_len >> 24) & 0xff) | 0x80;
|
|
|
|
len_enc[len_enc_len++] = (val_len >> 16) & 0xff;
|
|
|
|
len_enc[len_enc_len++] = (val_len >> 8) & 0xff;
|
2005-02-20 14:27:00 +00:00
|
|
|
}
|
2021-03-16 05:05:47 +00:00
|
|
|
len_enc[len_enc_len++] = val_len & 0xff;
|
|
|
|
|
|
|
|
const size_t len = len_enc_len + key_len + val_len;
|
|
|
|
const size_t fmax =
|
|
|
|
FCGI_MAX_LENGTH + sizeof(FCGI_BeginRequestRecord) + sizeof(FCGI_Header);
|
[multiple] reduce redundant NULL buffer checks
This commit is a large set of code changes and results in removal of
hundreds, perhaps thousands, of CPU instructions, a portion of which
are on hot code paths.
Most (buffer *) used by lighttpd are not NULL, especially since buffers
were inlined into numerous larger structs such as request_st and chunk.
In the small number of instances where that is not the case, a NULL
check is often performed earlier in a function where that buffer is
later used with a buffer_* func. In the handful of cases that remained,
a NULL check was added, e.g. with r->http_host and r->conf.server_tag.
- check for empty strings at config time and set value to NULL if blank
string will be ignored at runtime; at runtime, simple pointer check
for NULL can be used to check for a value that has been set and is not
blank ("")
- use buffer_is_blank() instead of buffer_string_is_empty(),
and use buffer_is_unset() instead of buffer_is_empty(),
where buffer is known not to be NULL so that NULL check can be skipped
- use buffer_clen() instead of buffer_string_length() when buffer is
known not to be NULL (to avoid NULL check at runtime)
- use buffer_truncate() instead of buffer_string_set_length() to
truncate string, and use buffer_extend() to extend
Examples where buffer known not to be NULL:
- cpv->v.b from config_plugin_values_init is not NULL if T_CONFIG_BOOL
(though we might set it to NULL if buffer_is_blank(cpv->v.b))
- address of buffer is arg (&foo)
(compiler optimizer detects this in most, but not all, cases)
- buffer is checked for NULL earlier in func
- buffer is accessed in same scope without a NULL check (e.g. b->ptr)
internal behavior change:
callers must not pass a NULL buffer to some funcs.
- buffer_init_buffer() requires non-null args
- buffer_copy_buffer() requires non-null args
- buffer_append_string_buffer() requires non-null args
- buffer_string_space() requires non-null arg
2021-06-09 02:57:36 +00:00
|
|
|
if (len > fmax - buffer_clen(env))
|
2021-03-16 05:05:47 +00:00
|
|
|
return -1; /* we can't append more headers, ignore it */
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2021-03-25 01:39:08 +00:00
|
|
|
buffer_append_str3(env, len_enc, len_enc_len, key, key_len, val, val_len);
|
2005-02-20 14:27:00 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
static void fcgi_header(FCGI_Header * header, unsigned char type, int request_id, int contentLength, unsigned char paddingLength) {
|
2014-02-16 13:08:20 +00:00
|
|
|
force_assert(contentLength <= FCGI_MAX_LENGTH);
|
2007-09-05 11:22:32 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
header->version = FCGI_VERSION_1;
|
|
|
|
header->type = type;
|
|
|
|
header->requestIdB0 = request_id & 0xff;
|
|
|
|
header->requestIdB1 = (request_id >> 8) & 0xff;
|
|
|
|
header->contentLengthB0 = contentLength & 0xff;
|
|
|
|
header->contentLengthB1 = (contentLength >> 8) & 0xff;
|
|
|
|
header->paddingLength = paddingLength;
|
|
|
|
header->reserved = 0;
|
|
|
|
}
|
|
|
|
|
2019-11-26 07:13:05 +00:00
|
|
|
static handler_t fcgi_stdin_append(handler_ctx *hctx) {
|
2016-06-10 04:04:10 +00:00
|
|
|
FCGI_Header header;
|
2020-09-29 20:50:39 +00:00
|
|
|
chunkqueue * const req_cq = &hctx->r->reqbody_queue;
|
2016-06-10 04:04:10 +00:00
|
|
|
off_t offset, weWant;
|
2020-11-12 22:19:31 +00:00
|
|
|
off_t req_cqlen = chunkqueue_length(req_cq);
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
int request_id = hctx->request_id;
|
2020-11-12 22:19:31 +00:00
|
|
|
if (req_cqlen > MAX_WRITE_LIMIT) req_cqlen = MAX_WRITE_LIMIT;
|
2016-06-10 04:04:10 +00:00
|
|
|
|
|
|
|
/* something to send ? */
|
|
|
|
for (offset = 0; offset != req_cqlen; offset += weWant) {
|
|
|
|
weWant = req_cqlen - offset > FCGI_MAX_LENGTH ? FCGI_MAX_LENGTH : req_cqlen - offset;
|
|
|
|
|
2017-05-07 21:04:01 +00:00
|
|
|
if (-1 != hctx->wb_reqlen) {
|
|
|
|
if (hctx->wb_reqlen >= 0) {
|
|
|
|
hctx->wb_reqlen += sizeof(header);
|
|
|
|
} else {
|
|
|
|
hctx->wb_reqlen -= sizeof(header);
|
|
|
|
}
|
|
|
|
}
|
2016-06-10 04:04:10 +00:00
|
|
|
|
2018-12-13 01:00:07 +00:00
|
|
|
fcgi_header(&(header), FCGI_STDIN, request_id, weWant, 0);
|
2020-09-29 20:50:39 +00:00
|
|
|
(chunkqueue_is_empty(&hctx->wb) || hctx->wb.first->type == MEM_CHUNK) /* else FILE_CHUNK for temp file */
|
|
|
|
? chunkqueue_append_mem(&hctx->wb, (const char *)&header, sizeof(header))
|
|
|
|
: chunkqueue_append_mem_min(&hctx->wb, (const char *)&header, sizeof(header));
|
|
|
|
chunkqueue_steal(&hctx->wb, req_cq, weWant);
|
2020-01-07 02:50:50 +00:00
|
|
|
/*(hctx->wb_reqlen already includes reqbody_length)*/
|
2016-06-10 04:04:10 +00:00
|
|
|
}
|
|
|
|
|
2020-09-29 20:50:39 +00:00
|
|
|
if (hctx->wb.bytes_in == hctx->wb_reqlen) {
|
2016-06-10 04:04:10 +00:00
|
|
|
/* terminate STDIN */
|
2017-05-07 21:04:01 +00:00
|
|
|
/* (future: must defer ending FCGI_STDIN
|
|
|
|
* if might later upgrade protocols
|
|
|
|
* and then have more data to send) */
|
2016-06-10 04:04:10 +00:00
|
|
|
fcgi_header(&(header), FCGI_STDIN, request_id, 0, 0);
|
2020-09-29 20:50:39 +00:00
|
|
|
chunkqueue_append_mem(&hctx->wb, (const char *)&header, sizeof(header));
|
2016-06-10 04:04:10 +00:00
|
|
|
hctx->wb_reqlen += (int)sizeof(header);
|
|
|
|
}
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
|
|
|
|
return HANDLER_GO_ON;
|
2016-06-10 04:04:10 +00:00
|
|
|
}
|
|
|
|
|
2019-11-26 07:13:05 +00:00
|
|
|
static handler_t fcgi_create_env(handler_ctx *hctx) {
|
2005-02-20 14:27:00 +00:00
|
|
|
FCGI_BeginRequestRecord beginRecord;
|
|
|
|
FCGI_Header header;
|
2017-06-30 03:50:59 +00:00
|
|
|
int request_id;
|
2006-10-04 13:26:23 +00:00
|
|
|
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
gw_host *host = hctx->host;
|
2020-01-13 02:51:12 +00:00
|
|
|
request_st * const r = hctx->r;
|
2006-10-04 13:26:23 +00:00
|
|
|
|
consistent, shared code to create CGI env
consolidated from CGI, FastCGI, SCGI, SSI
Note: due to prior inconsistencies between the code in mod_cgi,
mod_fastcgi, mod_scgi, and mod_ssi, there are some minor behavior
changes.
CONTENT_LENGTH is now always set, even if 0
(though CONTENT_LENGTH is never set for FASTCGI_AUTHORIZER)
PATH_INFO is created only if present, not if empty.
(mod_fastcgi and mod_ssi previously set PATH_INFO="" (blank value))
PATH_TRANSLATED is now set if PATH_INFO is present
(previously missing from mod_cgi and mod_ssi)
mod_ssi now sets DOCUMENT_ROOT to con->physical.basedir, like others
(previously, mod_ssi set DOCUMENT_ROOT to con->physical.doc_root,
which matched con->physical.basedir unless mod_alias changed basedir)
mod_ssi now sets REQUEST_URI to con->request.orig_uri, like others
(previously, mod_ssi set REQUEST_URI to con->request.uri, which
matched con->request.orig_uri except after redirects, error docs)
2016-10-10 17:37:36 +00:00
|
|
|
http_cgi_opts opts = {
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
(hctx->gw_mode == FCGI_AUTHORIZER),
|
consistent, shared code to create CGI env
consolidated from CGI, FastCGI, SCGI, SSI
Note: due to prior inconsistencies between the code in mod_cgi,
mod_fastcgi, mod_scgi, and mod_ssi, there are some minor behavior
changes.
CONTENT_LENGTH is now always set, even if 0
(though CONTENT_LENGTH is never set for FASTCGI_AUTHORIZER)
PATH_INFO is created only if present, not if empty.
(mod_fastcgi and mod_ssi previously set PATH_INFO="" (blank value))
PATH_TRANSLATED is now set if PATH_INFO is present
(previously missing from mod_cgi and mod_ssi)
mod_ssi now sets DOCUMENT_ROOT to con->physical.basedir, like others
(previously, mod_ssi set DOCUMENT_ROOT to con->physical.doc_root,
which matched con->physical.basedir unless mod_alias changed basedir)
mod_ssi now sets REQUEST_URI to con->request.orig_uri, like others
(previously, mod_ssi set REQUEST_URI to con->request.uri, which
matched con->request.orig_uri except after redirects, error docs)
2016-10-10 17:37:36 +00:00
|
|
|
host->break_scriptfilename_for_php,
|
|
|
|
host->docroot,
|
|
|
|
host->strip_request_uri
|
|
|
|
};
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2020-09-29 20:50:39 +00:00
|
|
|
size_t rsz = (size_t)(r->read_queue.bytes_out - hctx->wb.bytes_in);
|
|
|
|
if (rsz >= 65536) rsz = r->rqst_header_len;
|
|
|
|
buffer * const b = chunkqueue_prepend_buffer_open_sz(&hctx->wb, rsz);
|
2018-11-12 05:33:06 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
/* send FCGI_BEGIN_REQUEST */
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2017-06-30 03:50:59 +00:00
|
|
|
if (hctx->request_id == 0) {
|
|
|
|
hctx->request_id = 1; /* always use id 1 as we don't use multiplexing */
|
|
|
|
} else {
|
2020-01-13 02:51:12 +00:00
|
|
|
log_error(r->conf.errh, __FILE__, __LINE__,
|
2019-11-25 06:54:08 +00:00
|
|
|
"fcgi-request is already in use: %d", hctx->request_id);
|
2017-06-30 03:50:59 +00:00
|
|
|
}
|
|
|
|
request_id = hctx->request_id;
|
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
fcgi_header(&(beginRecord.header), FCGI_BEGIN_REQUEST, request_id, sizeof(beginRecord.body), 0);
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
beginRecord.body.roleB0 = hctx->gw_mode;
|
2005-02-20 14:27:00 +00:00
|
|
|
beginRecord.body.roleB1 = 0;
|
|
|
|
beginRecord.body.flags = 0;
|
|
|
|
memset(beginRecord.body.reserved, 0, sizeof(beginRecord.body.reserved));
|
2018-10-29 07:44:24 +00:00
|
|
|
fcgi_header(&header, FCGI_PARAMS, request_id, 0, 0); /*(set aside space to fill in later)*/
|
2021-03-25 01:39:08 +00:00
|
|
|
buffer_append_str2(b, (const char *)&beginRecord, sizeof(beginRecord),
|
|
|
|
(const char *)&header, sizeof(header));
|
2018-10-29 07:44:24 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
/* send FCGI_PARAMS */
|
|
|
|
|
2020-01-13 02:51:12 +00:00
|
|
|
if (0 != http_cgi_headers(r, &opts, fcgi_env_add, b)) {
|
|
|
|
r->http_status = 400;
|
|
|
|
r->handler_module = NULL;
|
2018-11-23 05:37:38 +00:00
|
|
|
buffer_clear(b);
|
2020-09-29 20:50:39 +00:00
|
|
|
chunkqueue_remove_finished_chunks(&hctx->wb);
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
return HANDLER_FINISHED;
|
2005-02-20 14:27:00 +00:00
|
|
|
} else {
|
2018-10-29 07:44:24 +00:00
|
|
|
fcgi_header(&(header), FCGI_PARAMS, request_id,
|
[multiple] reduce redundant NULL buffer checks
This commit is a large set of code changes and results in removal of
hundreds, perhaps thousands, of CPU instructions, a portion of which
are on hot code paths.
Most (buffer *) used by lighttpd are not NULL, especially since buffers
were inlined into numerous larger structs such as request_st and chunk.
In the small number of instances where that is not the case, a NULL
check is often performed earlier in a function where that buffer is
later used with a buffer_* func. In the handful of cases that remained,
a NULL check was added, e.g. with r->http_host and r->conf.server_tag.
- check for empty strings at config time and set value to NULL if blank
string will be ignored at runtime; at runtime, simple pointer check
for NULL can be used to check for a value that has been set and is not
blank ("")
- use buffer_is_blank() instead of buffer_string_is_empty(),
and use buffer_is_unset() instead of buffer_is_empty(),
where buffer is known not to be NULL so that NULL check can be skipped
- use buffer_clen() instead of buffer_string_length() when buffer is
known not to be NULL (to avoid NULL check at runtime)
- use buffer_truncate() instead of buffer_string_set_length() to
truncate string, and use buffer_extend() to extend
Examples where buffer known not to be NULL:
- cpv->v.b from config_plugin_values_init is not NULL if T_CONFIG_BOOL
(though we might set it to NULL if buffer_is_blank(cpv->v.b))
- address of buffer is arg (&foo)
(compiler optimizer detects this in most, but not all, cases)
- buffer is checked for NULL earlier in func
- buffer is accessed in same scope without a NULL check (e.g. b->ptr)
internal behavior change:
callers must not pass a NULL buffer to some funcs.
- buffer_init_buffer() requires non-null args
- buffer_copy_buffer() requires non-null args
- buffer_append_string_buffer() requires non-null args
- buffer_string_space() requires non-null arg
2021-06-09 02:57:36 +00:00
|
|
|
buffer_clen(b) - sizeof(FCGI_BeginRequestRecord) - sizeof(FCGI_Header), 0);
|
2018-10-29 07:44:24 +00:00
|
|
|
memcpy(b->ptr+sizeof(FCGI_BeginRequestRecord), (const char *)&header, sizeof(header));
|
2015-02-08 19:10:36 +00:00
|
|
|
|
|
|
|
fcgi_header(&(header), FCGI_PARAMS, request_id, 0, 0);
|
|
|
|
buffer_append_string_len(b, (const char *)&header, sizeof(header));
|
|
|
|
|
[multiple] reduce redundant NULL buffer checks
This commit is a large set of code changes and results in removal of
hundreds, perhaps thousands, of CPU instructions, a portion of which
are on hot code paths.
Most (buffer *) used by lighttpd are not NULL, especially since buffers
were inlined into numerous larger structs such as request_st and chunk.
In the small number of instances where that is not the case, a NULL
check is often performed earlier in a function where that buffer is
later used with a buffer_* func. In the handful of cases that remained,
a NULL check was added, e.g. with r->http_host and r->conf.server_tag.
- check for empty strings at config time and set value to NULL if blank
string will be ignored at runtime; at runtime, simple pointer check
for NULL can be used to check for a value that has been set and is not
blank ("")
- use buffer_is_blank() instead of buffer_string_is_empty(),
and use buffer_is_unset() instead of buffer_is_empty(),
where buffer is known not to be NULL so that NULL check can be skipped
- use buffer_clen() instead of buffer_string_length() when buffer is
known not to be NULL (to avoid NULL check at runtime)
- use buffer_truncate() instead of buffer_string_set_length() to
truncate string, and use buffer_extend() to extend
Examples where buffer known not to be NULL:
- cpv->v.b from config_plugin_values_init is not NULL if T_CONFIG_BOOL
(though we might set it to NULL if buffer_is_blank(cpv->v.b))
- address of buffer is arg (&foo)
(compiler optimizer detects this in most, but not all, cases)
- buffer is checked for NULL earlier in func
- buffer is accessed in same scope without a NULL check (e.g. b->ptr)
internal behavior change:
callers must not pass a NULL buffer to some funcs.
- buffer_init_buffer() requires non-null args
- buffer_copy_buffer() requires non-null args
- buffer_append_string_buffer() requires non-null args
- buffer_string_space() requires non-null arg
2021-06-09 02:57:36 +00:00
|
|
|
hctx->wb_reqlen = buffer_clen(b);
|
2020-09-29 20:50:39 +00:00
|
|
|
chunkqueue_prepend_buffer_commit(&hctx->wb);
|
2015-02-08 19:10:36 +00:00
|
|
|
}
|
2005-09-26 08:56:39 +00:00
|
|
|
|
2020-01-13 02:51:12 +00:00
|
|
|
if (r->reqbody_length) {
|
2020-09-29 20:50:39 +00:00
|
|
|
/*chunkqueue_append_chunkqueue(&hctx->wb, &r->reqbody_queue);*/
|
2020-01-13 02:51:12 +00:00
|
|
|
if (r->reqbody_length > 0)
|
|
|
|
hctx->wb_reqlen += r->reqbody_length;/* (eventual) (minimal) total request size, not necessarily including all fcgi_headers around content length yet */
|
2017-05-07 21:04:01 +00:00
|
|
|
else /* as-yet-unknown total request size (Transfer-Encoding: chunked)*/
|
|
|
|
hctx->wb_reqlen = -hctx->wb_reqlen;
|
|
|
|
}
|
2019-11-26 07:13:05 +00:00
|
|
|
fcgi_stdin_append(hctx);
|
2005-09-26 08:56:39 +00:00
|
|
|
|
2019-11-28 15:27:01 +00:00
|
|
|
status_counter_inc(CONST_STR_LEN("fastcgi.requests"));
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
return HANDLER_GO_ON;
|
2005-02-20 14:27:00 +00:00
|
|
|
}
|
|
|
|
|
2005-09-08 10:00:32 +00:00
|
|
|
typedef struct {
|
2016-06-10 04:04:10 +00:00
|
|
|
unsigned int len;
|
2005-09-08 10:00:32 +00:00
|
|
|
int type;
|
|
|
|
int padding;
|
2016-06-10 04:04:10 +00:00
|
|
|
int request_id;
|
2005-09-08 10:00:32 +00:00
|
|
|
} fastcgi_response_packet;
|
|
|
|
|
2019-11-25 06:54:08 +00:00
|
|
|
static int fastcgi_get_packet(handler_ctx *hctx, fastcgi_response_packet *packet) {
|
2018-11-05 04:12:55 +00:00
|
|
|
FCGI_Header header;
|
|
|
|
off_t rblen = chunkqueue_length(hctx->rb);
|
|
|
|
if (rblen < (off_t)sizeof(FCGI_Header)) {
|
|
|
|
/* no header */
|
|
|
|
if (hctx->conf.debug && 0 != rblen) {
|
2020-01-13 02:51:12 +00:00
|
|
|
log_error(hctx->r->conf.errh, __FILE__, __LINE__,
|
2019-11-25 06:54:08 +00:00
|
|
|
"FastCGI: header too small: %lld bytes < %zu bytes, "
|
|
|
|
"waiting for more data", (long long)rblen, sizeof(FCGI_Header));
|
2018-11-05 04:12:55 +00:00
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
2020-09-23 14:05:04 +00:00
|
|
|
char *ptr = (char *)&header;
|
|
|
|
uint32_t rd = sizeof(FCGI_Header);
|
|
|
|
if (chunkqueue_peek_data(hctx->rb, &ptr, &rd, hctx->r->conf.errh) < 0)
|
|
|
|
return -1;
|
|
|
|
if (rd != sizeof(FCGI_Header))
|
|
|
|
return -1;
|
|
|
|
if (ptr != (char *)&header) /* copy into aligned struct */
|
|
|
|
memcpy(&header, ptr, sizeof(FCGI_Header));
|
2005-09-08 10:00:32 +00:00
|
|
|
|
2018-11-05 04:12:55 +00:00
|
|
|
/* we have at least a header, now check how much we have to fetch */
|
|
|
|
packet->len = (header.contentLengthB0 | (header.contentLengthB1 << 8)) + header.paddingLength;
|
|
|
|
packet->request_id = (header.requestIdB0 | (header.requestIdB1 << 8));
|
|
|
|
packet->type = header.type;
|
|
|
|
packet->padding = header.paddingLength;
|
2014-02-14 21:06:00 +00:00
|
|
|
|
2018-11-05 04:12:55 +00:00
|
|
|
if (packet->len > (unsigned int)rblen-sizeof(FCGI_Header)) {
|
|
|
|
return -1; /* we didn't get the full packet */
|
2005-09-08 10:00:32 +00:00
|
|
|
}
|
|
|
|
|
2018-11-05 04:12:55 +00:00
|
|
|
chunkqueue_mark_written(hctx->rb, sizeof(FCGI_Header));
|
|
|
|
return 0;
|
|
|
|
}
|
2005-09-08 10:00:32 +00:00
|
|
|
|
2020-09-23 14:05:04 +00:00
|
|
|
static void fastcgi_get_packet_body(buffer * const b, handler_ctx * const hctx, const fastcgi_response_packet * const packet) {
|
|
|
|
/* copy content; hctx->rb must contain at least packet->len content */
|
|
|
|
/* (read entire packet and then truncate padding, if present) */
|
[multiple] reduce redundant NULL buffer checks
This commit is a large set of code changes and results in removal of
hundreds, perhaps thousands, of CPU instructions, a portion of which
are on hot code paths.
Most (buffer *) used by lighttpd are not NULL, especially since buffers
were inlined into numerous larger structs such as request_st and chunk.
In the small number of instances where that is not the case, a NULL
check is often performed earlier in a function where that buffer is
later used with a buffer_* func. In the handful of cases that remained,
a NULL check was added, e.g. with r->http_host and r->conf.server_tag.
- check for empty strings at config time and set value to NULL if blank
string will be ignored at runtime; at runtime, simple pointer check
for NULL can be used to check for a value that has been set and is not
blank ("")
- use buffer_is_blank() instead of buffer_string_is_empty(),
and use buffer_is_unset() instead of buffer_is_empty(),
where buffer is known not to be NULL so that NULL check can be skipped
- use buffer_clen() instead of buffer_string_length() when buffer is
known not to be NULL (to avoid NULL check at runtime)
- use buffer_truncate() instead of buffer_string_set_length() to
truncate string, and use buffer_extend() to extend
Examples where buffer known not to be NULL:
- cpv->v.b from config_plugin_values_init is not NULL if T_CONFIG_BOOL
(though we might set it to NULL if buffer_is_blank(cpv->v.b))
- address of buffer is arg (&foo)
(compiler optimizer detects this in most, but not all, cases)
- buffer is checked for NULL earlier in func
- buffer is accessed in same scope without a NULL check (e.g. b->ptr)
internal behavior change:
callers must not pass a NULL buffer to some funcs.
- buffer_init_buffer() requires non-null args
- buffer_copy_buffer() requires non-null args
- buffer_append_string_buffer() requires non-null args
- buffer_string_space() requires non-null arg
2021-06-09 02:57:36 +00:00
|
|
|
const uint32_t blen = buffer_clen(b);
|
2020-09-23 14:05:04 +00:00
|
|
|
if (chunkqueue_read_data(hctx->rb,
|
|
|
|
buffer_string_prepare_append(b, packet->len),
|
|
|
|
packet->len, hctx->r->conf.errh) < 0)
|
|
|
|
return; /*(should not happen; should all be in memory)*/
|
[multiple] reduce redundant NULL buffer checks
This commit is a large set of code changes and results in removal of
hundreds, perhaps thousands, of CPU instructions, a portion of which
are on hot code paths.
Most (buffer *) used by lighttpd are not NULL, especially since buffers
were inlined into numerous larger structs such as request_st and chunk.
In the small number of instances where that is not the case, a NULL
check is often performed earlier in a function where that buffer is
later used with a buffer_* func. In the handful of cases that remained,
a NULL check was added, e.g. with r->http_host and r->conf.server_tag.
- check for empty strings at config time and set value to NULL if blank
string will be ignored at runtime; at runtime, simple pointer check
for NULL can be used to check for a value that has been set and is not
blank ("")
- use buffer_is_blank() instead of buffer_string_is_empty(),
and use buffer_is_unset() instead of buffer_is_empty(),
where buffer is known not to be NULL so that NULL check can be skipped
- use buffer_clen() instead of buffer_string_length() when buffer is
known not to be NULL (to avoid NULL check at runtime)
- use buffer_truncate() instead of buffer_string_set_length() to
truncate string, and use buffer_extend() to extend
Examples where buffer known not to be NULL:
- cpv->v.b from config_plugin_values_init is not NULL if T_CONFIG_BOOL
(though we might set it to NULL if buffer_is_blank(cpv->v.b))
- address of buffer is arg (&foo)
(compiler optimizer detects this in most, but not all, cases)
- buffer is checked for NULL earlier in func
- buffer is accessed in same scope without a NULL check (e.g. b->ptr)
internal behavior change:
callers must not pass a NULL buffer to some funcs.
- buffer_init_buffer() requires non-null args
- buffer_copy_buffer() requires non-null args
- buffer_append_string_buffer() requires non-null args
- buffer_string_space() requires non-null arg
2021-06-09 02:57:36 +00:00
|
|
|
buffer_truncate(b, blen + packet->len - packet->padding);
|
2005-09-08 10:00:32 +00:00
|
|
|
}
|
2005-02-20 14:27:00 +00:00
|
|
|
|
2021-10-23 03:51:34 +00:00
|
|
|
__attribute_cold__
|
|
|
|
static handler_t fcgi_recv_0(const request_st * const r, const handler_ctx * const hctx) {
|
2018-03-18 23:01:32 +00:00
|
|
|
if (-1 == hctx->request_id) return HANDLER_FINISHED; /*(flag request ended)*/
|
2019-03-01 04:58:49 +00:00
|
|
|
if (!(fdevent_fdnode_interest(hctx->fdn) & FDEVENT_IN)
|
2020-01-13 02:51:12 +00:00
|
|
|
&& !(r->conf.stream_response_body & FDEVENT_STREAM_RESPONSE_POLLRDHUP))
|
2018-03-18 23:01:32 +00:00
|
|
|
return HANDLER_GO_ON;
|
2020-01-13 02:51:12 +00:00
|
|
|
log_error(r->conf.errh, __FILE__, __LINE__,
|
2019-11-25 06:54:08 +00:00
|
|
|
"unexpected end-of-file (perhaps the fastcgi process died):"
|
|
|
|
"pid: %d socket: %s",
|
|
|
|
hctx->proc->pid, hctx->proc->connection_name->ptr);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2017-05-06 03:57:55 +00:00
|
|
|
return HANDLER_ERROR;
|
2021-10-23 03:51:34 +00:00
|
|
|
}
|
2017-05-06 03:57:55 +00:00
|
|
|
|
2021-10-23 03:51:34 +00:00
|
|
|
static handler_t fcgi_recv_parse_loop(request_st * const r, handler_ctx * const hctx) {
|
2005-09-08 10:00:32 +00:00
|
|
|
/*
|
|
|
|
* parse the fastcgi packets and forward the content to the write-queue
|
|
|
|
*
|
2006-10-04 13:26:23 +00:00
|
|
|
*/
|
2021-10-23 03:51:34 +00:00
|
|
|
fastcgi_response_packet packet;
|
|
|
|
int fin = 0;
|
|
|
|
do {
|
2005-09-08 10:00:32 +00:00
|
|
|
/* check if we have at least one packet */
|
2019-11-25 06:54:08 +00:00
|
|
|
if (0 != fastcgi_get_packet(hctx, &packet)) {
|
2005-09-08 10:00:32 +00:00
|
|
|
/* no full packet */
|
2005-02-20 14:27:00 +00:00
|
|
|
break;
|
|
|
|
}
|
2005-09-08 10:00:32 +00:00
|
|
|
|
|
|
|
switch(packet.type) {
|
2005-02-20 14:27:00 +00:00
|
|
|
case FCGI_STDOUT:
|
2005-09-08 10:00:32 +00:00
|
|
|
if (packet.len == 0) break;
|
|
|
|
|
|
|
|
/* is the header already finished */
|
2020-01-13 02:51:12 +00:00
|
|
|
if (0 == r->resp_body_started) {
|
2017-03-18 04:10:48 +00:00
|
|
|
/* split header from body */
|
2018-11-05 04:12:55 +00:00
|
|
|
buffer *hdrs = hctx->response;
|
|
|
|
if (NULL == hdrs) {
|
2020-01-13 02:51:12 +00:00
|
|
|
hdrs = r->tmp_buf;
|
2019-11-25 06:54:08 +00:00
|
|
|
buffer_clear(hdrs);
|
2018-11-05 04:12:55 +00:00
|
|
|
}
|
|
|
|
fastcgi_get_packet_body(hdrs, hctx, &packet);
|
2020-01-13 02:51:12 +00:00
|
|
|
if (HANDLER_GO_ON != http_response_parse_headers(r, &hctx->opts, hdrs)) {
|
2016-06-19 23:32:46 +00:00
|
|
|
hctx->send_content_body = 0;
|
|
|
|
fin = 1;
|
2009-10-14 17:32:38 +00:00
|
|
|
break;
|
|
|
|
}
|
2020-01-13 02:51:12 +00:00
|
|
|
if (0 == r->resp_body_started) {
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
if (!hctx->response) {
|
2018-11-07 05:22:57 +00:00
|
|
|
hctx->response = chunk_buffer_acquire();
|
|
|
|
buffer_copy_buffer(hctx->response, hdrs);
|
2005-09-14 13:55:06 +00:00
|
|
|
}
|
2005-02-20 14:27:00 +00:00
|
|
|
}
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
else if (hctx->gw_mode == GW_AUTHORIZER &&
|
2020-01-13 02:51:12 +00:00
|
|
|
(r->http_status == 0 || r->http_status == 200)) {
|
2017-03-18 04:10:48 +00:00
|
|
|
/* authorizer approved request; ignore the content here */
|
|
|
|
hctx->send_content_body = 0;
|
2021-10-23 03:51:34 +00:00
|
|
|
hctx->opts.authorizer |= /*(save response streaming flags)*/
|
2021-09-25 19:10:35 +00:00
|
|
|
(r->conf.stream_response_body
|
|
|
|
& (FDEVENT_STREAM_RESPONSE
|
|
|
|
|FDEVENT_STREAM_RESPONSE_BUFMIN)) << 1;
|
|
|
|
r->conf.stream_response_body &=
|
|
|
|
~(FDEVENT_STREAM_RESPONSE|FDEVENT_STREAM_RESPONSE_BUFMIN);
|
2017-03-18 04:10:48 +00:00
|
|
|
}
|
2021-10-16 02:08:14 +00:00
|
|
|
#if 0
|
|
|
|
else if ((r->conf.stream_response_body &
|
|
|
|
(FDEVENT_STREAM_RESPONSE|FDEVENT_STREAM_RESPONSE_BUFMIN))
|
|
|
|
&& ( r->http_status == 204
|
|
|
|
|| r->http_status == 205
|
|
|
|
|| r->http_status == 304
|
|
|
|
|| r->http_method == HTTP_METHOD_HEAD)) {
|
|
|
|
/* disable streaming to wait for backend protocol to signal
|
|
|
|
* end of response (prevent http_response_write_prepare()
|
|
|
|
* from short-circuiting and finishing responses without
|
|
|
|
* response body) */
|
|
|
|
r->conf.stream_response_body &=
|
|
|
|
~(FDEVENT_STREAM_RESPONSE|FDEVENT_STREAM_RESPONSE_BUFMIN);
|
|
|
|
}
|
|
|
|
#endif
|
2018-11-05 04:12:55 +00:00
|
|
|
} else if (hctx->send_content_body) {
|
2021-10-21 13:45:06 +00:00
|
|
|
if (0 != http_response_transfer_cqlen(r, hctx->rb, (size_t)(packet.len - packet.padding))) {
|
2016-05-25 20:45:09 +00:00
|
|
|
/* error writing to tempfile;
|
|
|
|
* truncate response or send 500 if nothing sent yet */
|
2021-10-21 13:45:06 +00:00
|
|
|
hctx->send_content_body = 0;
|
2016-05-25 20:45:09 +00:00
|
|
|
fin = 1;
|
[core] option to stream response body to client (fixes #949, #760, #1283, #1387)
Set server.stream-response-body = 1 or server.stream-response-body = 2
to have lighttpd stream response body to client as it arrives from the
backend (CGI, FastCGI, SCGI, proxy).
default: buffer entire response body before sending response to client.
(This preserves existing behavior for now, but may in the future be
changed to stream response to client, which is the behavior more
commonly expected.)
x-ref:
"fastcgi, cgi, flush, php5 problem."
https://redmine.lighttpd.net/issues/949
"Random crashing on FreeBSD 6.1"
https://redmine.lighttpd.net/issues/760
"Memory usage increases when proxy+ssl+large file"
https://redmine.lighttpd.net/issues/1283
"lighttpd+fastcgi memory problem"
https://redmine.lighttpd.net/issues/1387
2016-06-11 15:04:01 +00:00
|
|
|
}
|
2018-11-20 01:52:34 +00:00
|
|
|
if (packet.padding) chunkqueue_mark_written(hctx->rb, packet.padding);
|
2018-11-05 04:12:55 +00:00
|
|
|
} else {
|
|
|
|
chunkqueue_mark_written(hctx->rb, packet.len);
|
2005-02-20 14:27:00 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case FCGI_STDERR:
|
2019-11-25 06:54:08 +00:00
|
|
|
if (packet.len) {
|
2020-01-13 02:51:12 +00:00
|
|
|
buffer * const tb = r->tmp_buf;
|
2019-11-25 06:54:08 +00:00
|
|
|
buffer_clear(tb);
|
|
|
|
fastcgi_get_packet_body(tb, hctx, &packet);
|
2021-08-25 22:41:52 +00:00
|
|
|
log_error_multiline(r->conf.errh, __FILE__, __LINE__,
|
|
|
|
BUF_PTR_LEN(tb), "FastCGI-stderr:");
|
2019-11-25 06:54:08 +00:00
|
|
|
}
|
2005-02-20 14:27:00 +00:00
|
|
|
break;
|
|
|
|
case FCGI_END_REQUEST:
|
2018-03-18 23:01:32 +00:00
|
|
|
hctx->request_id = -1; /*(flag request ended)*/
|
2005-02-20 14:27:00 +00:00
|
|
|
fin = 1;
|
|
|
|
break;
|
|
|
|
default:
|
2020-01-13 02:51:12 +00:00
|
|
|
log_error(r->conf.errh, __FILE__, __LINE__,
|
2019-11-25 06:54:08 +00:00
|
|
|
"FastCGI: header.type not handled: %d", packet.type);
|
2018-11-05 04:12:55 +00:00
|
|
|
chunkqueue_mark_written(hctx->rb, packet.len);
|
2005-02-20 14:27:00 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-10-23 03:51:34 +00:00
|
|
|
} while (0 == fin);
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2017-05-06 03:57:55 +00:00
|
|
|
return 0 == fin ? HANDLER_GO_ON : HANDLER_FINISHED;
|
2005-02-20 14:27:00 +00:00
|
|
|
}
|
|
|
|
|
2021-10-23 03:51:34 +00:00
|
|
|
static handler_t fcgi_recv_parse(request_st * const r, struct http_response_opts_t *opts, buffer *b, size_t n) {
|
|
|
|
handler_ctx * const hctx = (handler_ctx *)opts->pdata;
|
|
|
|
if (0 == n) return fcgi_recv_0(r, hctx);
|
|
|
|
chunkqueue_append_buffer(hctx->rb, b);
|
|
|
|
return fcgi_recv_parse_loop(r, hctx);
|
|
|
|
}
|
|
|
|
|
2020-01-13 02:51:12 +00:00
|
|
|
static handler_t fcgi_check_extension(request_st * const r, void *p_d, int uri_path_handler) {
|
2005-02-20 14:27:00 +00:00
|
|
|
plugin_data *p = p_d;
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
handler_t rc;
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2020-01-13 02:51:12 +00:00
|
|
|
if (NULL != r->handler_module) return HANDLER_GO_ON;
|
2008-08-01 16:13:34 +00:00
|
|
|
|
2020-01-13 02:51:12 +00:00
|
|
|
mod_fastcgi_patch_config(r, p);
|
2016-09-19 23:58:51 +00:00
|
|
|
if (NULL == p->conf.exts) return HANDLER_GO_ON;
|
|
|
|
|
2020-01-13 02:51:12 +00:00
|
|
|
rc = gw_check_extension(r, p, uri_path_handler, 0);
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
if (HANDLER_GO_ON != rc) return rc;
|
2006-10-04 13:26:23 +00:00
|
|
|
|
2020-01-13 02:51:12 +00:00
|
|
|
if (r->handler_module == p->self) {
|
|
|
|
handler_ctx *hctx = r->plugin_ctx[p->id];
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
hctx->opts.backend = BACKEND_FASTCGI;
|
|
|
|
hctx->opts.parse = fcgi_recv_parse;
|
2021-09-17 15:49:55 +00:00
|
|
|
hctx->opts.pdata = hctx; /*(skip +255 for potential padding)*/
|
|
|
|
hctx->opts.max_per_read = sizeof(FCGI_Header)+FCGI_MAX_LENGTH+1;
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
hctx->stdin_append = fcgi_stdin_append;
|
|
|
|
hctx->create_env = fcgi_create_env;
|
2018-07-01 01:43:19 +00:00
|
|
|
if (!hctx->rb) {
|
2020-09-29 20:50:39 +00:00
|
|
|
hctx->rb = chunkqueue_init(NULL);
|
2018-07-01 01:43:19 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
chunkqueue_reset(hctx->rb);
|
|
|
|
}
|
2005-02-20 14:27:00 +00:00
|
|
|
}
|
2006-01-02 23:17:04 +00:00
|
|
|
|
2005-02-20 14:27:00 +00:00
|
|
|
return HANDLER_GO_ON;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* uri-path handler */
|
2020-01-13 02:51:12 +00:00
|
|
|
static handler_t fcgi_check_extension_1(request_st * const r, void *p_d) {
|
|
|
|
return fcgi_check_extension(r, p_d, 1);
|
2005-02-20 14:27:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* start request handler */
|
2020-01-13 02:51:12 +00:00
|
|
|
static handler_t fcgi_check_extension_2(request_st * const r, void *p_d) {
|
|
|
|
return fcgi_check_extension(r, p_d, 0);
|
2005-02-20 14:27:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-03-07 21:05:37 +00:00
|
|
|
int mod_fastcgi_plugin_init(plugin *p);
|
2005-02-20 14:27:00 +00:00
|
|
|
int mod_fastcgi_plugin_init(plugin *p) {
|
2006-01-02 23:17:04 +00:00
|
|
|
p->version = LIGHTTPD_VERSION_ID;
|
2019-10-19 04:30:54 +00:00
|
|
|
p->name = "fastcgi";
|
2005-02-20 14:27:00 +00:00
|
|
|
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
p->init = gw_init;
|
|
|
|
p->cleanup = gw_free;
|
2005-02-20 14:27:00 +00:00
|
|
|
p->set_defaults = mod_fastcgi_set_defaults;
|
2020-07-25 12:23:58 +00:00
|
|
|
p->handle_request_reset = gw_handle_request_reset;
|
2005-02-20 14:27:00 +00:00
|
|
|
p->handle_uri_clean = fcgi_check_extension_1;
|
|
|
|
p->handle_subrequest_start = fcgi_check_extension_2;
|
[core] shared code for socket backends
common codebase for socket backends, based off mod_fastcgi with
some features added for mod_proxy
(mostly intended to reduce code duplication and enhance code isolation)
mod_fastcgi and mod_scgi can now use fastcgi.balance and scgi.balance
for similar behavior as proxy.balance, but the balancing is per-host
and not per-proc. proxy.balance is also per-host and not per-proc.
mod_proxy and mod_scgi can now use proxy.map-extensions and
scgi.map-extensions, similar to fastcgi.map-extensions.
mod_fastcgi behavior change (affects only mod_status):
- statistics tags have been renamed from "fastcgi.*" to "gw.*"
"fastcgi.backend.*" -> "gw.backend.*"
"fastcgi.active-requests" -> "gw.active-requests"
("fastcgi.requests" remains "fastcgi.requests")
("proxy.requests" is new)
("scgi.requests" is new)
mod_scgi behavior change (likely minor):
- removed scgi_proclist_sort_down() and scgi_proclist_sort_up().
procs now chosen based on load as measured by num socket connnections
Note:
modules using gw_backend.[ch] are currently still independent modules.
If it had been written as a single module with fastcgi, scgi, proxy
implementations, then there would have been a chance of breaking some
existing user configurations where module ordering made a difference
for which module handled a given request, though for most people, this
would have made no difference.
Details about mod_fastcgi code transformations:
unsigned int debug -> int debug
fastcgi_env member removed from plugin_config
renamed "fcgi" and "fastcgi" to "gw", and "FCGI" to "GW"
reorganize routines for high-level and lower-level interfaces
some lower-level internal interfaces changed to use host,proc,debug
args rather than knowing about higher-level (app) hctx and plugin_data
tabs->spaces and reformatting
2017-07-14 05:29:18 +00:00
|
|
|
p->handle_subrequest = gw_handle_subrequest;
|
|
|
|
p->handle_trigger = gw_handle_trigger;
|
|