Dancer
Dancer copied to clipboard
Fix send_file environment variables
Some request environment variables, such as psgi.*
, are missing when a file is served using send_file
. I'm not sure how to write a proper test for this, but the problem can be demonstrated with a simple app:
package testenv;
use Dancer ':syntax';
our $VERSION = '0.1';
get '/' => sub {
template 'index';
};
get '/file' => sub {
send_file('/etc/hostname', system_path => 1, content_type => 'text/plain');
};
hook 'after_file_render' => sub {
debug "url_scheme: " . request->env->{'psgi.url_scheme'};
};
true;
A request for, say, /images/perldancer.jpg
, produces url_scheme: http
, while a request for /file
results in url_scheme:
(undefined).
This change fixes the problem by passing the SharedData->request
environment to the new request object created in _send_file
.
In the existing code a minimal replacement request
object is created (it's simply a GET $path
with nothing else). Unfortunately, this drops certain headers that were already computed in the original request
object.
Why doesn't it just take the original request
object, and just use method()
and path()
to override the values instead?
This bug also shows up in the logs if you are using certain logging placeholders (like %h
) which are populated from the (non-existent) environment. For example, the client's IP/host will show up as -
in the logs for any responses that use send_file
.
I didn't realize it at the time, but this bug is at least one reason #1029 was happening in some situations.