Browse Source

[core] config opt to intercept dynamic handler err (fixes #974)

new directive server.error-intercept = [ "enable" | "disable" ]
to intercept 4xx and 5xx responses from dynamic handlers
(e.g. CGI, FastCGI, SCGI, proxy)

Intercepted HTTP error status are then handled by one of
  server.error-handler
  server.error-handler-404
  server.errorfile-prefix
(if configured)

Do not use server.error-intercept with locations handled by mod_webdav!

x-ref:
  "would like something similar to nginx proxy_intercept_errors"
  https://redmine.lighttpd.net/issues/974
personal/stbuehler/mod-csrf
Glenn Strauss 5 years ago
parent
commit
8f651a2b30
  1. 1
      src/base.h
  2. 6
      src/configfile.c
  3. 6
      src/connections.c

1
src/base.h

@ -253,6 +253,7 @@ typedef struct {
unsigned short range_requests;
unsigned short stream_request_body;
unsigned short stream_response_body;
unsigned short error_intercept;
/* debug */

6
src/configfile.c

@ -163,6 +163,7 @@ static int config_insert(server *srv) {
{ "server.stream-request-body", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 76 */
{ "server.stream-response-body", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 77 */
{ "server.max-request-field-size", NULL, T_CONFIG_INT, T_CONFIG_SCOPE_SERVER }, /* 78 */
{ "server.error-intercept", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 79 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
@ -254,6 +255,7 @@ static int config_insert(server *srv) {
s->listen_backlog = (0 == i ? 1024 : srv->config_storage[0]->listen_backlog);
s->stream_request_body = 0;
s->stream_response_body = 0;
s->error_intercept = 0;
/* all T_CONFIG_SCOPE_CONNECTION options */
cv[2].destination = s->errorfile_prefix;
@ -319,6 +321,7 @@ static int config_insert(server *srv) {
#endif
cv[76].destination = &(s->stream_request_body);
cv[77].destination = &(s->stream_response_body);
cv[79].destination = &(s->error_intercept);
srv->config_storage[i] = s;
@ -514,6 +517,7 @@ int config_setup_connection(server *srv, connection *con) {
PATCH(use_xattr);
PATCH(error_handler);
PATCH(error_handler_404);
PATCH(error_intercept);
PATCH(errorfile_prefix);
#ifdef HAVE_LSTAT
PATCH(follow_symlink);
@ -569,6 +573,8 @@ int config_patch_connection(server *srv, connection *con) {
PATCH(error_handler);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.error-handler-404"))) {
PATCH(error_handler_404);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.error-intercept"))) {
PATCH(error_intercept);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.errorfile-prefix"))) {
PATCH(errorfile_prefix);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("mimetype.assign"))) {

6
src/connections.c

@ -306,11 +306,11 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
con->file_finished = 1;
break;
default: /* class: header + body */
if (con->mode != DIRECT) break;
/* only custom body for 4xx and 5xx */
if (con->http_status < 400 || con->http_status >= 600) break;
if (con->mode != DIRECT && (!con->conf.error_intercept || con->error_handler_saved_status)) break;
con->file_finished = 0;
connection_handle_errdoc_init(srv, con);
@ -1166,7 +1166,7 @@ int connection_state_machine(server *srv, connection *con) {
if (con->error_handler_saved_status > 0) {
con->request.http_method = con->error_handler_saved_method;
}
if (con->mode == DIRECT) {
if (con->mode == DIRECT || con->conf.error_intercept) {
if (con->error_handler_saved_status) {
if (con->error_handler_saved_status > 0) {
con->http_status = con->error_handler_saved_status;

Loading…
Cancel
Save