Index: src/mod_fastcgi.c =================================================================== --- src/mod_fastcgi.c (revision 2907) +++ src/mod_fastcgi.c (working copy) @@ -241,6 +241,14 @@ */ unsigned short allow_xsendfile; + /* + * If X-Sendfile or X-Sendfile2 is used and the file doesn't exist, + * this module will send a "404 Not Found" error, just as lighttpd + * would. The default is to send a "502 Bad Gateway" error, + * indicating an error on the (possibly remote) FastCGI side. + */ + unsigned short allow_xsendfile_404; + ssize_t load; /* replace by host->load */ size_t max_id; /* corresponds most of the time to @@ -1261,6 +1269,7 @@ { "strip-request-uri", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 13 */ { "kill-signal", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 14 */ { "fix-root-scriptname", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 15 */ + { "allow-x-send-file-404", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 16 */ { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } }; @@ -1285,6 +1294,7 @@ host->disable_time = 1; host->break_scriptfilename_for_php = 0; host->allow_xsendfile = 0; /* handle X-LIGHTTPD-send-file */ + host->allow_xsendfile_404 = 0; host->kill_signal = SIGTERM; host->fix_root_path_name = 0; @@ -1306,6 +1316,7 @@ fcv[13].destination = host->strip_request_uri; fcv[14].destination = &(host->kill_signal); fcv[15].destination = &(host->fix_root_path_name); + fcv[16].destination = &(host->allow_xsendfile_404); if (0 != config_insert_values_internal(srv, da_host->value, fcv)) { return HANDLER_ERROR; @@ -2268,7 +2279,7 @@ if (p->conf.debug) { log_error_write(srv, __FILE__, __LINE__, "ss", "Couldn't find range after filename:", filename); } - return 1; + return 502; } buffer_copy_string_len(srv->tmp_buf, filename, range - filename); @@ -2282,14 +2293,14 @@ "send-file error: couldn't get stat_cache entry for X-Sendfile2:", srv->tmp_buf); } - return 1; + return host->allow_xsendfile_404 ? 404 : 502; } else if (!S_ISREG(sce->st.st_mode)) { if (p->conf.debug) { log_error_write(srv, __FILE__, __LINE__, "sb", "send-file error: wrong filetype for X-Sendfile2:", srv->tmp_buf); } - return 1; + return 502; } /* found the file */ @@ -2314,7 +2325,7 @@ if (p->conf.debug) { log_error_write(srv, __FILE__, __LINE__, "ss", "Couldn't decode range after filename:", filename); } - return 1; + return 502; range_success: ; } @@ -2322,10 +2333,10 @@ /* no parameters accepted */ while (*pos == ' ') pos++; - if (*pos != '\0' && *pos != ',') return 1; + if (*pos != '\0' && *pos != ',') return 502; range_len = end_range - begin_range + 1; - if (range_len < 0) return 1; + if (range_len < 0) return 502; if (range_len != 0) { http_chunk_append_file(srv, con, srv->tmp_buf, begin_range, range_len); } @@ -2484,7 +2495,7 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) { int fin = 0; - int toread; + int toread, ret; ssize_t r; plugin_data *p = hctx->plugin_data; @@ -2596,8 +2607,8 @@ } /* parse the response header */ - if (fcgi_response_parse(srv, con, p, hctx->response_header)) { - con->http_status = 502; + if ((ret = fcgi_response_parse(srv, con, p, hctx->response_header))) { + con->http_status = ret; hctx->send_content_body = 0; con->file_started = 1; break; @@ -2635,13 +2646,20 @@ con->parsed_response |= HTTP_CONTENT_LENGTH; con->response.content_length = sce->st.st_size; } else { - log_error_write(srv, __FILE__, __LINE__, "sb", - "send-file error: couldn't get stat_cache entry for:", - ds->value); - con->http_status = 502; - hctx->send_content_body = 0; - con->file_started = 1; - break; + if (host->allow_xsendfile_404) { + con->http_status = 404; + hctx->send_content_body = 0; + con->file_started = 1; + break; + } else { + log_error_write(srv, __FILE__, __LINE__, "sb", + "send-file error: couldn't get stat_cache entry for:", + ds->value); + con->http_status = 502; + hctx->send_content_body = 0; + con->file_started = 1; + break; + } } }