Project

General

Profile

Actions

Feature #2702

closed

REDIRECT_URI not set in mod_cgi

Added by stbuehler about 8 years ago. Updated almost 8 years ago.

Status:
Fixed
Priority:
Normal
Category:
mod_cgi
Target version:
ASK QUESTIONS IN Forums:
Actions #1

Updated by stbuehler about 8 years ago

  • Target version changed from 1.4.39 to 1.4.40
Actions #2

Updated by gstrauss about 8 years ago

REDIRECT_URI is not part of the CGI specification. Please change this ticket to Feature request, and not Bug.

Please also provide more information about REDIRECT_URI and why and when you expect it, e.g. it is provided in mod_fastcgi and mod_scgi.

Actions #3

Updated by gstrauss about 8 years ago

Is this ticket potentially related to https://redmine.lighttpd.net/issues/1828 ("REDIRECT_STATUS == 200 on 404 redirect")?

Should whatever change is made to mod_cgi also be made in mod_ssi, which is also missing REDIRECT_URI?

Actions #4

Updated by gstrauss about 8 years ago

diff --git a/src/mod_cgi.c b/src/mod_cgi.c
index bfbfa13..b8b2dec 100644
--- a/src/mod_cgi.c
+++ b/src/mod_cgi.c
@@ -968,6 +968,9 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
                if (!buffer_string_is_empty(con->request.orig_uri)) {
                        cgi_env_add(&env, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri));
                }
+               if (!buffer_is_equal(con->request.uri, con->request.orig_uri)) {
+                       cgi_env_add(&env, CONST_STR_LEN("REDIRECT_URI"), CONST_BUF_LEN(con->request.uri));
+               }

                switch (con->dst_addr.plain.sa_family) {
Actions #5

Updated by gstrauss about 8 years ago

Please bear with me as I contemplate differences between REQUEST_URI and REDIRECT_URI, and REDIRECT_URL, none of which are standard CGI variables, and then propose a breaking change (with limited impact) to REQUEST_URI and REDIRECT_URI in mod_fastcgi and mod_scgi.

https://httpd.apache.org/docs/current/custom-error.html
Apache provides REDIRECT_* variables. In Apache, these all refer back to the original request. This includes REDIRECT_URL and REDIRECT_QUERY_STRING. REDIRECT_URL and REDIRECT_QUERY_STRING could be used to reconstruct the original request.

lighttpd provides the original URI in REQUEST_URI, which could be parsed by the receiving script into REDIRECT_URL, REDIRECT_QUERY_STRING, etc for compatibility with scripts written for Apache.

lighttpd REQUEST_URI would be better named REDIRECT_URI to match the convention of REDIRECT_* being info about the original request. However, lighttpd sets REDIRECT_URI to the URI of the error handler, and this in turn would be better named REQUEST_URI for the current request. This lighttpd definition of REDIRECT_URI is somewhat redundant since it can typically be constructed from standard CGI variables SCRIPT_NAME + QUERY_STRING. (I still prefer REDIRECT_URI rather than reconstructing, but think REDIRECT_URI should be named REQUEST_URI.)

For most CGI, fastcgi, scgi, SSI requests in lighttpd, con->request.orig_uri matches con->request.uri, and so REDIRECT_URI does not get set, as it would duplicate REQUEST_URI. The difference comes up when server.error-handler-404 is set, which intercepts only 403 and 404 HTTP status responses which do not originate from dynamic handlers (mod_cgi, mod_fastcgi, mod_proxy, mod_scgi)

The FAQ (https://redmine.lighttpd.net/projects/lighttpd/wiki/FrequentlyAskedQuestions) and other tickets discussing server.error-handler-404 indicate that server.error-handler-404 is intended for intercepting what would be 403 and 404 responses to the client and providing the results of an alternate request with its own HTTP status response, potentially different from 404. This is in contrast to server.errorfile-prefix, which provides a 404 error page with a 404 response and can handle other error HTTP status codes, too. There are limitations in both server.error-handler-404 and server.errorfile-prefix. server.errorfile-prefix provides only for static pages for error HTTP status codes, not dynamic error pages. server.error-handler-404 allows dynamic handlers, but intercepts only 403 and 404 HTTP status codes. Some people requiring dynamic content for 404 error pages have thus used server.error-handler-404. Other people are surprised that server.error-handler-404 returns 200 OK when the error handler is a static page to handle the 404, e.g. see https://redmine.lighttpd.net/issues/2456 and the FAQ (https://redmine.lighttpd.net/projects/lighttpd/wiki/FrequentlyAskedQuestions).

Now, given the intended use of server.error-handler-404, and the definition of PHP $_SERVER['REQUEST_URI'] at http://php.net/manual/en/reserved.variables.server.php

'REQUEST_URI'
    The URI which was given in order to access this page; for instance, '/index.html'.

it would make sense for the URI to the error handler target to be in REQUEST_URI instead of the original URI whose response was intercepted by server.error-handler-404. This is currently not the case for mod_fastcgi and mod_scgi. Also, REDIRECT_URI is not currently set for mod_cgi or mod_ssi, so we have some inconsistency between the modules. Before extending REDIRECT_URI to mod_cgi and mod_ssi, perhaps we can consider making a potentially breaking change to REQUEST_URI and REDIRECT_URI? The impact is specifically limited to those using server.error-handler-404 to intercept 403 and 404 HTTP status codes and handle them with fastcgi or scgi. Further, those scripts would have to also rely on REQUEST_URI or REDIRECT_URI. (I am not sure, but this might also affect mod_cml_lua if it uses REQUEST_URI in error handler, though unlikely since it always gets con->request.orig_uri)

Once REDIRECT_STATUS is properly updated (patch in https://github.com/lighttpd/lighttpd1.4/pull/35) any of cgi, fastcgi, scgi, and ssi can detect they are being called from an error handler by checking REDIRECT_STATUS >= 400. For those interested in the original URI, we could provide that in REDIRECT_URI instead of REQUEST_URI.

I propose that REQUEST_URI be set to con->request.uri and, when con->response.in_error_handler is set, that REDIRECT_URI be set to con->request.orig_uri.

(If you look at https://github.com/lighttpd/lighttpd1.4/pull/35, it is obvious that REDIRECT_URI could be set in con->environment in the same place that REDIRECT_STATUS is set in that patch.)

Actions #6

Updated by gstrauss about 8 years ago

Submitted pull request https://github.com/lighttpd/lighttpd1.4/pull/36 with new directive server.error-handler and I implemented the new behavior above for the new directive. I preserved the prior behavior (which I think is backwards) for server.error-handler-404. (It bears repeating that the behavior in question occurs in 403 or 404 responses where error page content is not already provided by dynamic handlers, and so the 403 or 404 response is intercepted by server.error-handler-404, where con->request.uri is made different from con-request.orig_uri.)

The patch sets REDIRECT_STATUS and REDIRECT_URI in con->environment, making it available to all of lua magnet, CGI, SSI, FastCGI, SCGI.

[Edit] ...mod_magnet and mod_rewrite might also modify con->request.uri, so I'll add a patch that has them set REDIRECT_URI, too.

Actions #7

Updated by gstrauss almost 8 years ago

  • Tracker changed from Bug to Feature
Actions #8

Updated by gstrauss almost 8 years ago

  • Status changed from New to Patch Pending
Actions #9

Updated by gstrauss almost 8 years ago

  • Status changed from Patch Pending to Fixed
  • % Done changed from 0 to 100
Actions

Also available in: Atom