Search code examples
apacheapache-modules

XSendFile won't serve the files in Apache 2.2


I'm using mod_xsendfile (v0.12) to serve static files where Django is controlling access to the files based on users and permissions.

In my conf file, I have:

XSendFile On
XSendFilePath e:/documents/

<Directory e:/Documents>
  Order allow,deny
  Allow from all
</Directory>

In my django code, I set the headers like so:

assert(isinstance(filename, FieldFile))

xsendfile = filename.name
if(platform.system() == 'Windows'):
    xsendfile = xsendfile.replace('\\', '/')

response = HttpResponse()
response['X-Sendfile'] = xsendfile
mimetype = mimetypes.guess_type(xsendfile)[0]
response['Content-Type'] = mimetype
response['Content-Length'] = filename.size

And in my log file I get:

[Fri Oct 22 08:54:22 2010] [error] [client 192.168.20.34] (20023)The given path
was above the root path: xsendfile: unable to find file:
e:/Documents/3/2010-10-20/TestDocument.pdf

In this version of mod_xsendfile,

XSendFileAllowAbove On

generates the error:

Invalid command 'XSendFileAllowAbove', perhaps misspelled or defined by a module
not included in the server configuration

I assumed that was because they have added the XSendFilePath white list. Anyone else got this to work?


Solution

  • Do not set a Content-Length yourself. This will only confuse handlers such as mod_wsgi in this case. mod_xsendfile will itself set the correct Content-Length.

    On Windows you must not only provide the drive letter, the drive letter must be actually in upper-case (IIRC)!

    I have a working test configuration like so:

    <Directory "E:/">
      XSendFile on
      XSendFilePath E:/localhosts
    </Directory>
    

    One of my working test scripts in E:/Apache2.2/htdocs/ looks like this:

    <?php
      header('X-SendFile: E:/localhosts/archive.tar.bz2');
      header('Content-type: application/octet-stream');
      header('Content-disposition: attachment; filename="blob"');
    ?>
    

    XSendFileAllowAbove was removed a while back in favor of XSendFilePath