Saturday, 15 September 2012

php - What encoding does xsendfile expect? -



php - What encoding does xsendfile expect? -

it seems googling xsendfile issues produces number of hits contradictory/outdated.

in involvement of total disclosure, i'm taking xsendfile 1.0 beta, documented @ https://tn123.org/mod_xsendfile/beta/ (this site doesn't show in search results, 1 without /beta does). i'm using apache 2.4 , php 5.4.34 on both linux , windows. besides beingness latest version, need utilize beta version because beta site has windows binaries built vc9 apache 2.4.

i made error of reading documentation, description of file name value in header says:

the value (file name) given header assmumed url-encoded, i.e. unescaping/url-decoding performed. see xsendfileunescape. if happen store files using url-encoded file names, must "double" encode names... %20 -> %2520

and description of xsendfileunescape says:

setting xsendfileunescape off restore pre-1.0 behavior of using raw header value, instead of trying unescape/url-decode first.

the documentation relative paths makes pretty clear file name on x-sendfile header should total pathname. ran pathnames through php's urlencode function.

the end result me invariably server internal error (500 status code) on both linux , windows. when had xsendfilepath directive in server config context, documentation says allowed, got nil more specific in error log. when (eventually) moved directive directory context, graduated getting in error log:

(404)unknown error: [client 127.0.0.1:20742] xsendfile: bad file name encoding

eventually, out of desperation, said "screw documentation", , removed urlencode on pathname. , started working (both windows , linux)!!!

i don't have pathnames non-ascii characters in them, i'm set. wonder sort of encoding supposed applied allow non-ascii characters work. if google xsendfile: bad file name encoding, you'll find next source code @ https://github.com/nmaier/mod_xsendfile/blob/master/mod_xsendfile.c message string produced taking true branch of:

rv = ap_unescape_url(file); if (rv != ok) {

but can't find description or source code ap_unescape_url(). unless source on github outdated, function objects simple %-encoding php's urlencode() function performs. wild guess tried calling ap_escape_url(), it's not defined in php. leaves question of encoding supposed applied pathname parameter in x-sendfile header??

one more observation/question description of xsendfile using "apache internals" send file might create think build content-type header filename extension using mod_mime. in fact doesn't, , examples show explicit header() phone call content-type. follow-on "right" way build header pathname beingness passed x-sendfile, such guaranteed match mod_mime if weren't using x-sendfile? best come next code using php's fileinfo extension - far know there's no particular reason expect match apache when given url filename.

$finfo = new finfo(fileinfo_mime); $mime_info = $finfo->file($pathname); if (! strlen($mime_info)) { $mime_info = 'application/octet-stream; charset=binary'; } $basename = basename($pathname); $encoded = "$pathname"; header("content-type: $mime_info"); header("content-disposition: attachment; filename=\"$basename\""); header("x-sendfile: $encoded");

i'm not going take reply question, because still haven't found "the" encoding function expected used. did find ancient apache api documentation: http://pedrowa.weba.sk/docs/apidoc/apidoc_ap_unescape_url.html. documents retuen value of ap_unescape_url() as:

returns 0 on success, bad_request if bad escape sequence found, or not_found if %2f (/) found.

but of course of study in php, both urlencode() , rawurlencode() encode '/' %2f.

so clearly, total pathname used in xsendfile header must not urlencoded using either of these functions!!

my guess "best" solution me use:

$encoded = str_replace('%2f', '/', rawurlencode($pathname));

i must admit i'm amazed xsendfile documentation not mention this. , i'm more amazed question has not gotten answers here. should have posted in different stack exchange site?

php apache encoding x-sendfile

No comments:

Post a Comment