Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

add optional support for the X-Sendfile header #105

Closed
wants to merge 1 commit into from

3 participants

Mike Frysinger Andrew Dolgov ymage
Mike Frysinger

testing on my own webserver, this improves transfer rates noticably while using less memory/cpu

i've defaulted it to off though because apache requires a 3rd party module

Andrew Dolgov
Owner

This looks way too obscure to add to config.php.

Edit: also what exactly is the configuration you're running if file_get_contents() on a binary file is slow? Raspberry pi?

Mike Frysinger vapier add X-Sendfile support to speed up file transfers
file_get_contents() can be really slow, even for smaller files (a few
hundred kb).  Add support for using the X-Sendfile header instead.
722d556
Mike Frysinger

file_get_contents() reads the entire file into memory first before transferring it. you don't have to be on an embedded system for this to affect performance. a moderately loaded server will see a difference. a better algo (while staying simple) would be to put it into a while(read()) write() loop.

for large images, php memory constraints can kill it too as it isn't uncommon for people to lower the default.

the X-Sendfile isn't obscure as soon as you do any research on the topic of "php" and "file transfer". this is the standard.

i don't know if there's other places in the code base that have php code do file transfers, but they'd all benefit from centralizing this logic.

ymage
ymage commented

The way as Sendfile mechanism is processed depends on webserver.

  • Apache needs a filesystem location.
  • Lighttpd seems on its way
  • Nginx needs an URL location set in X-Accel-Redirect header (http://wiki.nginx.org/XSendfile)
Andrew Dolgov
Owner

Completely valid point with loading in memory, images being potentially large never crossed my mind. :-)

I suppose a while/read loop is a better fix here then, unless it's possible to detect x-sendfile in a bulletproof manner. We're definitely not asking the user to perform research regarding file transfers in php.

Mike Frysinger

the latest code using readfile() is much better than get_file_contents()

i can dynamically detect under apache. if other people care, they can submit code.

Mike Frysinger vapier closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Mar 30, 2013
Mike Frysinger vapier add X-Sendfile support to speed up file transfers
file_get_contents() can be really slow, even for smaller files (a few
hundred kb).  Add support for using the X-Sendfile header instead.
722d556
This page is out of date. Refresh to see the latest.

Showing 2 changed files with 14 additions and 4 deletions. Show diff stats Hide diff stats

  1. +4 0 config.php-dist
  2. +10 4 image.php
4 config.php-dist
@@ -57,6 +57,10 @@
57 57 // Unless you really know what you're doing, please keep those relative
58 58 // to tt-rss main directory.
59 59
  60 + define('X_SENDFILE', false);
  61 + // Use the X-Sendfile header when possible to transmit files rather than
  62 + // php itself. Note: this requires the server to support it first.
  63 +
60 64 // **********************
61 65 // *** Authentication ***
62 66 // **********************
14 image.php
@@ -27,10 +27,16 @@
27 27 $filename = CACHE_DIR . '/images/' . $hash . '.png';
28 28
29 29 if (file_exists($filename)) {
30   - header("Content-type: image/png");
31   - $stamp = gmdate("D, d M Y H:i:s", filemtime($filename)). " GMT";
32   - header("Last-Modified: $stamp", true);
33   - echo file_get_contents($filename);
  30 + if (X_SENDFILE) {
  31 + header("X-Sendfile: $filename");
  32 + header("Content-type: application/octet-stream");
  33 + header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
  34 + } else {
  35 + header("Content-type: image/png");
  36 + $stamp = gmdate("D, d M Y H:i:s", filemtime($filename)). " GMT";
  37 + header("Last-Modified: $stamp", true);
  38 + echo file_get_contents($filename);
  39 + }
34 40 } else {
35 41 header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
36 42 echo "File not found.";

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.