Home » Php » php – Test if X-Sendfile header is working

php – Test if X-Sendfile header is working

Posted by: admin July 12, 2020 Leave a comment


I am looking for a way to confirm if X-Sendfile is properly handling requests handed back to the webserver by a script (PHP). Images are being served correctly but I thought I would see the header in curl requests.

$ curl -I http://blog2.stageserver.net/wp-includes/ms-files.php?file=/2011/05/amos-lee-feature.jpg
HTTP/1.1 200 OK
Date: Wed, 04 Jan 2012 17:19:45 GMT
Server: Cherokee/1.2.100 (Arch Linux)
ETag: "4dd2e306=9da0"
Last-Modified: Tue, 17 May 2011 21:05:10 GMT
Content-Type: image/jpeg
Content-Length: 40352
X-Powered-By: PHP/5.3.8
Content-Disposition: inline; filename="amos-lee-feature.jpg"


Cherokee 1.2.100 with PHP-FPM 5.3.8 in FastCGI:
cherokee.conf: vserver!20!rule!500!handler!xsendfile = 1
(Set by vServer > Behavior > Extensions php > Handler: Allow X-Sendfile [check Enabled])

WordPress Network / WPMU 3.3.1:
define('WPMU_SENDFILE',true); is set in the wp-config.php the following just before wp-settings.php is included. This will trigger the following code to be executed in WP’s wp-includes/ms-files.php:50 serves up files for a particular blog:

header( 'X-Sendfile: ' . $file );

I have confirmed that the above snippet is executing by adding an additional header for disposition right before the exit(); call. That Content-Disposition is present with curl results above and not originally in the ms-files.php code. The code that was added is:
header('Content-Disposition: inline; filename="'.basename($file).'"');


I have:

  • Rebooted php-fpm / cherokee daemons after making configuration changes.
  • Tried several tricks in the comments over at php.net/readfile and replaced the simple header in ms-files.php with more complete code from examples.
    • php.net/manual/en/function.readfile.php
    • www.jasny.net/articles/how-i-php-x-sendfile/
    • *codeutopia.net/blog/2009/03/06/sending-files-better-apache-mod_xsendfile-and-php/*
  • Confirmed [cherokee support][5] and tested [with and without][6] compression even though I don’t think it would apply since my images are serving correctly. I also found a suspiciously similar problem from a lighttpd post.
    • *cherokee-project.com/doc/other_goodies.html*
    • code.google.com/p/cherokee/issues/detail?id=1228
    • webdevrefinery.com/forums/topic/4761-x-sendfile/
  • Found a blurb here on SO that may indicate the header gets stripped
    • stackoverflow.com/questions/7296642/django-understanding-x-sendfile
  • Tested that the headers above are consistent from curl, wget, Firefox, Chrome, and web-sniffer.net.
  • Found out that I can’t post more than 2 links yet due to lack of reputation.


  • Will X-Sendfile be present in the headers when it is working correctly or is it stripped out?
  • Can the access logs be used to determine if X-Sendfile is working?

I am looking for general troubleshooting tips or information here, not necessarily specific to PHP / Cherokee.


I have found a suitable way to confirm X-Sendfile or X-Accel-Redirect in a test or sandbox environment: Disable X-Sendfile and check the headers.

With Allow X-Sendfile disabled in Cherokee:

$ curl -I http://blog2.stageserver.net/wp-includes/ms-files.php?file=/2011/05/amos-lee-feature.jpg
HTTP/1.1 200 OK
Date: Fri, 06 Jan 2012 15:34:49 GMT
Server: Cherokee/1.2.101 (Ubuntu)
X-Powered-By: PHP/5.3.6-13ubuntu3.3
Content-Type: image/jpeg
X-Sendfile: /srv/http/wordpress/wp-content/blogs.dir/2/files/2011/05/amos-lee-feature.jpg
Content-Length: 40352

The image will not load in browsers but you can see that the header is present. After re-enabling Allow X-Sendfile the image loads and you can be confident that X-Sendfile is working.

How to&Answers:

According to the source on github X-Sendfile headers will be stripped.

If I’m skimming the file correctly, it’s only logging success if it’s been compiled in debug mode.


You could check memory usage of sending large files with and without xsendfile.


They are being stripped, simply because having them present will prevent one of the reasons to use it, namely having the file served without the recepient knowing the location of the file being served.