Skip to content

Commit da0b05b

Browse files
committed
Added support for X-Sendfile and X-Accel-Redirect headers for file downloads via PHP.
1 parent 8d3a5b6 commit da0b05b

File tree

1 file changed

+46
-24
lines changed

1 file changed

+46
-24
lines changed

server/php/UploadHandler.php

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/*
3-
* jQuery File Upload Plugin PHP Class 6.4.6
3+
* jQuery File Upload Plugin PHP Class 6.5
44
* https://github.com/blueimp/jQuery-File-Upload
55
*
66
* Copyright 2010, Sebastian Tschan
@@ -62,6 +62,11 @@ function __construct($options = null, $initialize = true, $error_messages = null
6262
'Content-Disposition'
6363
),
6464
// Enable to provide file downloads via GET requests to the PHP script:
65+
// 1. Set to 1 to download files via readfile method through PHP
66+
// 2. Set to 2 to send a X-Sendfile header for lighttpd/Apache
67+
// 3. Set to 3 to send a X-Accel-Redirect header for nginx
68+
// If set to 2 or 3, adjust the upload_url option to the base path of
69+
// the redirect parameter, e.g. '/files/'.
6570
'download_via_php' => false,
6671
// Read files in chunks to avoid memory limits when download_via_php
6772
// is enabled, set to 0 to disable chunked reading of files:
@@ -179,8 +184,8 @@ protected function get_query_separator($url) {
179184
return strpos($url, '?') === false ? '?' : '&';
180185
}
181186

182-
protected function get_download_url($file_name, $version = null) {
183-
if ($this->options['download_via_php']) {
187+
protected function get_download_url($file_name, $version = null, $direct = false) {
188+
if (!$direct && $this->options['download_via_php']) {
184189
$url = $this->options['script_url']
185190
.$this->get_query_separator($this->options['script_url'])
186191
.'file='.rawurlencode($file_name);
@@ -705,30 +710,47 @@ protected function get_file_type($file_path) {
705710
}
706711

707712
protected function download() {
708-
if (!$this->options['download_via_php']) {
709-
$this->header('HTTP/1.1 403 Forbidden');
710-
return;
713+
switch ($this->options['download_via_php']) {
714+
case 1:
715+
$redirect_header = null;
716+
break;
717+
case 2:
718+
$redirect_header = 'X-Sendfile';
719+
break;
720+
case 3:
721+
$redirect_header = 'X-Accel-Redirect';
722+
break;
723+
default:
724+
return $this->header('HTTP/1.1 403 Forbidden');
711725
}
712726
$file_name = $this->get_file_name_param();
713-
if ($this->is_valid_file_object($file_name)) {
714-
$file_path = $this->get_upload_path($file_name, $this->get_version_param());
715-
if (is_file($file_path)) {
716-
if (!preg_match($this->options['inline_file_types'], $file_name)) {
717-
$this->header('Content-Description: File Transfer');
718-
$this->header('Content-Type: application/octet-stream');
719-
$this->header('Content-Disposition: attachment; filename="'.$file_name.'"');
720-
$this->header('Content-Transfer-Encoding: binary');
721-
} else {
722-
// Prevent Internet Explorer from MIME-sniffing the content-type:
723-
$this->header('X-Content-Type-Options: nosniff');
724-
$this->header('Content-Type: '.$this->get_file_type($file_path));
725-
$this->header('Content-Disposition: inline; filename="'.$file_name.'"');
726-
}
727-
$this->header('Content-Length: '.$this->get_file_size($file_path));
728-
$this->header('Last-Modified: '.gmdate('D, d M Y H:i:s T', filemtime($file_path)));
729-
$this->readfile($file_path);
730-
}
727+
if (!$this->is_valid_file_object($file_name)) {
728+
return $this->header('HTTP/1.1 404 Not Found');
729+
}
730+
if ($redirect_header) {
731+
return $this->header(
732+
$redirect_header.': '.$this->get_download_url(
733+
$file_name,
734+
$this->get_version_param(),
735+
true
736+
)
737+
);
731738
}
739+
$file_path = $this->get_upload_path($file_name, $this->get_version_param());
740+
if (!preg_match($this->options['inline_file_types'], $file_name)) {
741+
$this->header('Content-Description: File Transfer');
742+
$this->header('Content-Type: application/octet-stream');
743+
$this->header('Content-Disposition: attachment; filename="'.$file_name.'"');
744+
$this->header('Content-Transfer-Encoding: binary');
745+
} else {
746+
// Prevent Internet Explorer from MIME-sniffing the content-type:
747+
$this->header('X-Content-Type-Options: nosniff');
748+
$this->header('Content-Type: '.$this->get_file_type($file_path));
749+
$this->header('Content-Disposition: inline; filename="'.$file_name.'"');
750+
}
751+
$this->header('Content-Length: '.$this->get_file_size($file_path));
752+
$this->header('Last-Modified: '.gmdate('D, d M Y H:i:s T', filemtime($file_path)));
753+
$this->readfile($file_path);
732754
}
733755

734756
protected function send_content_type_header() {

0 commit comments

Comments
 (0)