You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
3.0 KiB

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