https://issues.apache.org/bugzilla/show_bug.cgi?id=55415
Bug ID: 55415
Summary: Proxy loop caused by ProxyErrorOverride and
ErrorDocument 404
Product: Apache httpd-2
Version: 2.4.6
Hardware: PC
OS: Linux
Status: NEW
Severity: major
Priority: P2
Component: mod_proxy_fcgi
Assignee: [email protected]
Reporter: [email protected]
1. Overview Description
If ProxyErrorOverride is On, proxy's not found error page should be
overridden by ErrorDocument 404. But actually a proxy loop occurs
if ErrorDocument 404 points to a url of FastCGI server script.
The following is my test environment for this issue.
- apache 2.4.6
- mod_proxy_fcgi (reverse proxy)
- php-fpm (PHP 5.5.1, FastCGI server)
And these directives were added to httpd.conf to forward requests for php
scripts.
[ httpd.conf ]
ErrorDocument 404 /error.php
ProxyErrorOverride On
ProxyPassMatch ^/(.+\.php)$ fcgi://localhost:9010/home/httpd/htdocs/$1
This is the content of error.php.
[ error.php ]
<?php
echo "No such file.<br>";
In the environment, when I accessed a url that does not exist,
I got the next message after a while without overriding by ErrorDocument 404.
[ error page ]
Not Found
The requested URL /xxx.php was not found on this server.
Additionally, a 500 Internal Server Error error was encountered
while trying to use an ErrorDocument to handle the request.
And I got the following message in apache's error_log at the same time.
[ error_log ]
[Wed Aug 14 17:46:33.144561 2013] [proxy_fcgi:error] [pid 29478:tid
1111763264] [client 192.168.1.46:2322] AH01071: Got error 'Primary script
unknown\n'
[Wed Aug 14 17:46:37.258829 2013] [core:error] [pid 29478:tid 1111763264]
[client 192.168.1.46:2322] AH00124: Request exceeded the limit of 10 internal
redirects due to probable configuration error. Use 'LimitInternalRecursion' to
increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
Besides, in access_log of FastCGI server, I got ten success messages for
error.php.
[ access_log ]
192.168.1.46 [14/08/2013:17:46:33 +0900] "GET /error.php" 200 0.325 256
0.00% "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/28.0.1500.95 Safari/537.36"
...
(10 times)
In short, even though each ErrorDocument's request is success,
it is repeated until reaching ProxyMaxForwards's default value(10).
I checked modules/proxy/mod_proxy_fcgi.c to find the cause of this behavior
and found that sending ErrorDocument is controlled by script_error_status in
dispatch().
First script_error_status is initialized with HTTP_OK in dispatch().
[ dispatch() ]
551 int script_error_status = HTTP_OK;
When you access a url that does not exist on FastCGI server,
r->status has been NotFound(404).
Next, only in case that ProxyErrorOverride is On and r->status is error,
r->status's value(404) is assigned to script_error_status and r->status
is set to HTTP_OK.
[ dispatch() ]
759 if (conf->error_override &&
760 ap_is_HTTP_ERROR(r->status)) {
761 /*
762 * set script_error_status to discard
763 * everything after the headers
764 */
765 script_error_status = r->status;
766 /*
767 * prevent ap_die() from treating this as
a
768 * recursive error, initially:
769 */
770 r->status = HTTP_OK;
771 }
Because script_error_status(404) is not HTTP_OK, ap_die() is called
to send ErrorDocument.
[ dispatch() ]
865 if (script_error_status != HTTP_OK) {
866 ap_die(script_error_status, r); /* send ErrorDocument */
867 }
In ap_die() of modules/http/http_request.c, r->status is rewritten
with scrip_error_status's value(404).
[ ap_die() ]
76 AP_DECLARE(void) ap_die(int type, request_rec *r)
...
144
145 r->status = type;
146
Because ErrorDocument points to local url, ap_internal_redirect() is called.
[ ap_die() ]
181 else if (custom_response[0] == '/') {
...
200 r->method = "GET";
201 r->method_number = M_GET;
202 ap_internal_redirect(custom_response, r);
203 return;
204 }
r->status's value(404) is kept until this request reaches
to dispatch() of mod_proxy_fcgi.c.
Because dispatch() has no code that initializes r->status's value(404),
script_error_status's value will be 404 again and internal forwarding
is repeated until ProxyMaxForwards's value again.
It seems that this is why the proxy loop occurs.
2. Steps to Reproduce
1) Run FastCGI(php-fpm) server on localhost:9010.
Its document root is /home/httpd/htdocs.
2) Place error.php in the document root.
<?php
echo "No such file.<br>";
3) Add these directives to httpd.conf.
ErrorDocument 404 /error.php
ProxyErrorOverride On
ProxyPassMatch ^/(.+\.php)$ fcgi://localhost:9010/home/httpd/htdocs/$1
4) Start or restart Apache2.
5) Access a url that does not exist.
http://FQDN/not_exist.html
A proxy loop will be detected.
3. Actual Results
A proxy loop occurs.
4. Expected Results
FastCGI's not found error page is overrided by ErrorDocument 404.
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]