Bug #2793
closed1.4.40 regression: broken redirect (using Location) between url.rewrite-once URLs
Description
Hi, I use Lighttpd with following mod_rewrite rules:
url.rewrite-once = ( "^/(foo)" => "/foo.php", "^/(bar)" => "/bar.txt" )
My
foo.php
is a trivial file:<?php header('Location: /bar'); die('Redirected to the bar');
My
bar.txt
is just a dummy:Bar!
My use case is sending
GET /foo
request. It used to work with all old Lighttps versions including 1.4.39. It stopped working with 1.4.40.
1.4.39
> curl -v http://192.168.1.1/foo
* Trying 192.168.1.1...
* Connected to 192.168.1.1 (192.168.1.1) port 80 (#0)
> GET /foo HTTP/1.1
> Host: 192.168.1.1
> User-Agent: curl/7.42.1
> Accept: */*
>
< HTTP/1.1 302 Found
< Status: 302 Found
< X-Powered-By: PHP/7.1.1
< Location: /bar
< Content-type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Date: Wed, 15 Feb 2017 10:49:45 GMT
< Server: lighttpd/1.4.39
<
Redirected to the bar
* Connection #0 to host 192.168.1.1 left intact
> curl -v http://192.168.1.1/bar
* Trying 192.168.1.1...
* Connected to 192.168.1.1 (192.168.1.1) port 80 (#0)
> GET /bar HTTP/1.1
> Host: 192.168.1.1
> User-Agent: curl/7.42.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8
< Accept-Ranges: bytes
< ETag: "1794762551"
< Last-Modified: Wed, 15 Feb 2017 10:48:10 GMT
< Content-Length: 6
< Date: Wed, 15 Feb 2017 10:49:49 GMT
< Server: lighttpd/1.4.39
<
Bar!
* Connection #0 to host 192.168.1.1 left intact
1.4.40
> curl -v http://192.168.1.1/foo
* Trying 192.168.1.1...
* Connected to 192.168.1.1 (192.168.1.1) port 80 (#0)
> GET /foo HTTP/1.1
> Host: 192.168.1.1
> User-Agent: curl/7.42.1
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Content-Type: text/html
< Content-Length: 345
< Date: Wed, 15 Feb 2017 10:48:30 GMT
< Server: lighttpd/1.4.40
<
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>404 - Not Found</title>
</head>
<body>
<h1>404 - Not Found</h1>
</body>
</html>
* Connection #0 to host 192.168.1.1 left intact
Files
Updated by stbuehler almost 8 years ago
- Related to Bug #2108: CGI local redirect not implemented correctly added
Updated by gstrauss almost 8 years ago
- Category set to mod_cgi
- Target version changed from 1.4.x to 1.4.46
@stbuehler: thx for cross-reference.
Seems like a bad interaction between CGI local-redir feature (added in lighttpd 1.4.40) and the url.rewrite-once state, which does not rewrite the resulting /bar to /bar.txt after CGI local-redir.
Updated by gstrauss almost 8 years ago
- Status changed from New to Patch Pending
This might work (still needs to be tested):
--- a/src/mod_cgi.c +++ b/src/mod_cgi.c @@ -590,6 +590,7 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) { } connection_response_reset(srv, con); /*(includes con->http_status = 0)*/ + plugins_call_connection_reset(srv, con); con->mode = DIRECT; return FDEVENT_HANDLED_COMEBACK;
Updated by rmilecki almost 8 years ago
gstrauss wrote:
This might work (still needs to be tested):
[...]
It doesn't (tried on top of 1.4.45). Server crashes when processing the first request
# /usr/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf -D 2017-02-15 11:10:19: (log.c.217) server started Segmentation fault
Updated by rmilecki almost 8 years ago
rmilecki wrote:
gstrauss wrote:
This might work (still needs to be tested):
[...]
It doesn't (tried on top of 1.4.45). Server crashes when processing the first request
[...]
I used gdb
to check why lighttpd crashes with your diff applied:
(gdb) run -f lighttpd.conf -D Starting program: /usr/local/sbin/lighttpd -f lighttpd.conf -D Missing separate debuginfo for /lib64/ld-linux-x86-64.so.2 Try: zypper install -C "debuginfo(build-id)=afa98667969782208459e394f8c8f87ac7510710" Missing separate debuginfo for /usr/lib64/libpcre.so.1 Try: zypper install -C "debuginfo(build-id)=fef485da4e84bae0a0245b782cb2c575bd244a88" Missing separate debuginfo for /lib64/libdl.so.2 Try: zypper install -C "debuginfo(build-id)=666913ec064c25fde1720db77b1f57bdeb5d9b3a" Missing separate debuginfo for /lib64/libc.so.6 Try: zypper install -C "debuginfo(build-id)=d21e5369d55e688fb863ceade4984189ab3f7ae7" Missing separate debuginfo for /lib64/libpthread.so.0 Try: zypper install -C "debuginfo(build-id)=24a941b6c85e244bd2e4906928dc17ab63b0a38a" [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Detaching after fork from child process 25789. *** Error in `/usr/local/sbin/lighttpd': double free or corruption (out): 0x00000000006dcda0 *** Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7636fc2 in malloc_consolidate () from /lib64/libc.so.6 (gdb) (gdb) bt #0 0x00007ffff7636fc2 in malloc_consolidate () from /lib64/libc.so.6 #1 0x00007ffff7638218 in _int_malloc () from /lib64/libc.so.6 #2 0x00007ffff763aed3 in calloc () from /lib64/libc.so.6 #3 0x00007ffff7de776f in _dl_new_object () from /lib64/ld-linux-x86-64.so.2 #4 0x00007ffff7de31b4 in _dl_map_object_from_fd () from /lib64/ld-linux-x86-64.so.2 #5 0x00007ffff7de4ff5 in _dl_map_object () from /lib64/ld-linux-x86-64.so.2 #6 0x00007ffff7def887 in dl_open_worker () from /lib64/ld-linux-x86-64.so.2 #7 0x00007ffff7deb6e4 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2 #8 0x00007ffff7def29b in _dl_open () from /lib64/ld-linux-x86-64.so.2 #9 0x00007ffff76db722 in do_dlopen () from /lib64/libc.so.6 #10 0x00007ffff7deb6e4 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2 #11 0x00007ffff76db7bf in dlerror_run () from /lib64/libc.so.6 #12 0x00007ffff76db831 in __libc_dlopen_mode () from /lib64/libc.so.6 #13 0x00007ffff76b2135 in init () from /lib64/libc.so.6 #14 0x00007ffff73ad470 in pthread_once () from /lib64/libpthread.so.0 #15 0x00007ffff76b224c in backtrace () from /lib64/libc.so.6 #16 0x00007ffff75dde36 in backtrace_and_maps () from /lib64/libc.so.6 #17 0x00007ffff763164f in __libc_message () from /lib64/libc.so.6 #18 0x00007ffff7636eae in malloc_printerr () from /lib64/libc.so.6 #19 0x00007ffff7637b87 in _int_free () from /lib64/libc.so.6 #20 0x0000000000415da1 in buffer_free (b=0x6dcdd0) at buffer.c:47 #21 0x00007ffff6f98965 in cgi_handler_ctx_free (hctx=0x6dcd70) at mod_cgi.c:102 #22 cgi_connection_close (srv=srv@entry=0x633010, hctx=hctx@entry=0x6dcd70) at mod_cgi.c:656 #23 0x00007ffff6f99553 in cgi_recv_response (srv=0x633010, hctx=<optimized out>) at mod_cgi.c:782 #24 0x00007ffff6f9967b in cgi_handle_fdevent (srv=srv@entry=0x633010, ctx=0x6dcd70, revents=revents@entry=1) at mod_cgi.c:802 #25 0x00000000004085e2 in main (argc=<optimized out>, argv=<optimized out>) at server.c:1798
Calling plugins_call_connection_reset
results in calling cgi_connection_close_callback
and this probably frees handler_ctx *hctx
that we try to access later.
Updated by gstrauss almost 8 years ago
Thanks for testing. Yes, you are correct that the hctx has already been cleaned up. Here is an additional patch to make it work.
@@ -810,7 +809,7 @@ static int cgi_recv_response(server *srv, handler_ctx *hctx) { /* if we get a IN|HUP and have read everything don't exec the close twice */ return HANDLER_FINISHED; case FDEVENT_HANDLED_COMEBACK: - cgi_connection_close(srv, hctx); + /*cgi_connection_close(srv, hctx);*//*(already cleaned up)*/ return HANDLER_COMEBACK; case FDEVENT_HANDLED_ERROR: log_error_write(srv, __FILE__, __LINE__, "s", "demuxer failed: ");
Updated by rmilecki almost 8 years ago
gstrauss wrote:
Thanks for testing. Yes, you are correct that the hctx has already been cleaned up. Here is an additional patch to make it work.
[...]
Hooray, applying both your diffs resolves the problem, thank you!
Updated by gstrauss almost 8 years ago
- Status changed from Patch Pending to Fixed
- % Done changed from 0 to 100
Applied in changeset ab85841b142c62c47f69fc45c0b54f080d54ddc9.
Also available in: Atom