; disable if you want php not to exit in case of redirects and cache hits
;http.force_exit = 0
+; disable if you don't want 404 Not found status messages
+; being sent, if a file attempted to be sent with
+; http_send_file() etc. cannot be found
+;http.send.not_found_404 = 0
+
; the hashing algorithm with wich ETags are generated (MD5, SHA1, CRC32B)
; if ext/hash is available, this can be set to any hash algorithm ext/hash supports
; MD5 is the default and fallback algorithm
; log file for redirects
;http.log.redirect =
+; log file for responses with http_send_file() etc. where the file's not been found
+;http.log.not_found =
+
; log file for requests with an unallowed request method
;http.log.allowed_methods =
G->request.time = time(NULL);
#endif
G->send.buffer_size = HTTP_SENDBUF_SIZE;
+ G->send.not_found_404 = 1;
G->read_post_data = 0;
}
HTTP_PHP_INI_ENTRY("http.etag.mode", "MD5", PHP_INI_ALL, OnUpdateString, etag.mode)
HTTP_PHP_INI_ENTRY("http.log.cache", "", PHP_INI_ALL, OnUpdateString, log.cache)
HTTP_PHP_INI_ENTRY("http.log.redirect", "", PHP_INI_ALL, OnUpdateString, log.redirect)
+ HTTP_PHP_INI_ENTRY("http.log.not_found", "", PHP_INI_ALL, OnUpdateString, log.not_found)
HTTP_PHP_INI_ENTRY("http.log.allowed_methods", "", PHP_INI_ALL, OnUpdateString, log.allowed_methods)
HTTP_PHP_INI_ENTRY("http.log.composite", "", PHP_INI_ALL, OnUpdateString, log.composite)
HTTP_PHP_INI_ENTRY("http.request.methods.allowed", "", PHP_INI_ALL, http_update_allowed_methods, request.methods.allowed)
HTTP_PHP_INI_ENTRY("http.send.deflate.start_auto", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateBool, send.deflate.start_auto)
HTTP_PHP_INI_ENTRY("http.send.deflate.start_flags", "0", PHP_INI_ALL, OnUpdateLong, send.deflate.start_flags)
#endif
+ HTTP_PHP_INI_ENTRY("http.send.not_found_404", "1", PHP_INI_ALL, OnUpdateBool, send.not_found_404)
#ifdef ZEND_ENGINE_2
HTTP_PHP_INI_ENTRY("http.only_exceptions", "0", PHP_INI_ALL, OnUpdateBool, only_exceptions)
#endif
STATUS _http_exit_ex(int status, char *header, char *body, zend_bool send_header TSRMLS_DC)
{
if ( (send_header && (SUCCESS != http_send_status_header(status, header))) ||
- (!send_header && status && (SUCCESS != http_send_status(status)))) {
+ (status && (SUCCESS != http_send_status(status)))) {
http_error_ex(HE_WARNING, HTTP_E_HEADER, "Failed to exit with status/header: %d - %s", status, header ? header : "");
STR_FREE(header);
STR_FREE(body);
case 305: http_log(HTTP_G->log.redirect, "305-REDIRECT", header); break;
case 307: http_log(HTTP_G->log.redirect, "307-REDIRECT", header); break;
case 304: http_log(HTTP_G->log.cache, "304-CACHE", header); break;
+ case 404: http_log(HTTP_G->log.not_found, "404-NOTFOUND", NULL); break;
case 405: http_log(HTTP_G->log.allowed_methods, "405-ALLOWED", header); break;
default: http_log(NULL, header, body); break;
}
cctl = convert_to_type_ex(IS_STRING, GET_STATIC_PROP(cacheControl), &cctl_p);
if (Z_LVAL_P(lmod) || Z_STRLEN_P(etag)) {
- http_send_cache_control(Z_STRVAL_P(cctl), Z_STRLEN_P(cctl));
+ if (Z_STRLEN_P(cctl)) {
+ http_send_cache_control(Z_STRVAL_P(cctl), Z_STRLEN_P(cctl));
+ } else {
+ http_send_cache_control(HTTP_DEFAULT_CACHECONTROL, lenof(HTTP_DEFAULT_CACHECONTROL));
+ }
if (Z_STRLEN_P(etag)) {
http_send_etag(Z_STRVAL_P(etag), Z_STRLEN_P(etag));
}
php_stream_statbuf ssb;
if ((!file) || php_stream_stat(file, &ssb)) {
+ char *defct = sapi_get_default_content_type(TSRMLS_C);
+
+ http_send_content_type(defct, strlen(defct));
+ http_send_header_string("Content-Disposition:");
+ http_error(HE_WARNING, HTTP_E_RESPONSE, "File not found; stat failed");
+ STR_FREE(defct);
+
+ if (HTTP_G->send.not_found_404) {
+ http_exit_ex(404, NULL, estrdup("File not found\n"), 0);
+ }
return FAILURE;
}
</stability>
<license>BSD, revised</license>
<notes><![CDATA[
++ Added INI entries: http.log.not_found, http.send.not_found_404
* Fixed build on Debian systems where access to Curl_* functions is prohibited
+* Fixed empty Cache-Control header if not customly set with HttpResponse
+* Reset Content-Disposition and Content-Type if file is not found by http_send_file() etc
]]></notes>
<contents>
<dir name="/">
<file role="test" name="HttpResponse_002.phpt"/>
<file role="test" name="HttpResponse_003.phpt"/>
<file role="test" name="HttpResponse_004.phpt"/>
+ <file role="test" name="HttpResponse_005.phpt"/>
<file role="test" name="match_request_header_001.phpt"/>
<file role="test" name="negotiation_001.phpt"/>
<file role="test" name="ob_deflatehandler_001.phpt"/>
struct _http_globals_log {
char *cache;
char *redirect;
+ char *not_found;
char *allowed_methods;
char *composite;
} log;
long start_flags;
void *stream;
} inflate;
+ zend_bool not_found_404;
} send;
struct _http_globals_request {
--- /dev/null
+--TEST--
+HttpResponse file not found
+--SKIPIF--
+<?php
+include 'skip.inc';
+checkcgi();
+checkmin(5.1);
+?>
+--FILE--
+<?php
+ini_set("error_reporting", 0);
+ini_set("default_mimetype", "text/plain");
+
+HttpResponse::setContentType("application/pdf");
+HttpResponse::setContentDisposition("doc.pdf");
+HttpResponse::setFile("__nonexistant__.pdf");
+HttpResponse::send();
+?>
+--EXPECTF--
+Status: 404
+X-Powered-By: PHP/%s
+Content-Type: text/plain
+Content-Disposition:
+
+File not found