|
|
- From dde50f1939e22926d17342b5d812e9a3034e7e98 Mon Sep 17 00:00:00 2001
- From: Glenn Strauss <gstrauss@gluelogic.com>
- Date: Wed, 25 Jan 2017 11:22:39 -0500
- Subject: [PATCH] [mod_cgi] RFC3875 CGI local-redir strict adherence (#2108)
-
- RFC3875 CGI local-redir stricter adherence
-
- do not apply local-redir if any response headers besides "Location"
- do not apply local-redir if any response body has been received
- (though it might not have been received yet, and we do not wait to find
- out, if lighttpd is configured to stream response body back to client)
-
- x-ref:
- RFC3875 CGI 1.1 specification section 6.2.2 Local Redirect Response
- http://www.ietf.org/rfc/rfc3875
- "CGI local redirect not implemented correctly"
- https://redmine.lighttpd.net/issues/2108
- ---
- src/mod_cgi.c | 25 ++++++++++++++++++++++++-
- 1 file changed, 24 insertions(+), 1 deletion(-)
-
- --- a/src/mod_cgi.c
- +++ b/src/mod_cgi.c
- @@ -527,6 +527,27 @@ static int cgi_demux_response(server *sr
- /* parse the response header */
- cgi_response_parse(srv, con, p, hctx->response_header);
-
- + /* [RFC3875] 6.2.2 Local Redirect Response
- + *
- + * The CGI script can return a URI path and query-string
- + * ('local-pathquery') for a local resource in a Location header field.
- + * This indicates to the server that it should reprocess the request
- + * using the path specified.
- + *
- + * local-redir-response = local-Location NL
- + *
- + * The script MUST NOT return any other header fields or a message-body,
- + * and the server MUST generate the response that it would have produced
- + * in response to a request containing the URL
- + *
- + * scheme "://" server-name ":" server-port local-pathquery
- + *
- + * (Might not have begun to receive body yet, but do skip local-redir
- + * if we already have started receiving a response body (blen > 0))
- + * (Also, while not required by the RFC, do not send local-redir back
- + * to same URL, since CGI should have handled it internally if it
- + * really wanted to do that internally)
- + */
- if (con->http_status >= 300 && con->http_status < 400) {
- /*(con->parsed_response & HTTP_LOCATION)*/
- size_t ulen = buffer_string_length(con->uri.path);
- @@ -535,7 +556,9 @@ static int cgi_demux_response(server *sr
- && ds->value->ptr[0] == '/'
- && (0 != strncmp(ds->value->ptr, con->uri.path->ptr, ulen)
- || (ds->value->ptr[ulen] != '\0' && ds->value->ptr[ulen] != '/' && ds->value->ptr[ulen] != '?'))
- - && NULL == array_get_element(con->response.headers, "Set-Cookie")) {
- + && 0 == blen
- + && !(con->parsed_response & HTTP_STATUS) /* no "Status" or NPH response line */
- + && 1 == con->response.headers->used) {
- if (++con->loops_per_request > 5) {
- log_error_write(srv, __FILE__, __LINE__, "sb", "too many internal loops while processing request:", con->request.orig_uri);
- con->http_status = 500; /* Internal Server Error */
|