diff --git a/app/call_recordings/resources/classes/call_recordings.php b/app/call_recordings/resources/classes/call_recordings.php
index 838f66aca9..b5fe8bdad7 100644
--- a/app/call_recordings/resources/classes/call_recordings.php
+++ b/app/call_recordings/resources/classes/call_recordings.php
@@ -134,14 +134,14 @@ if (!class_exists('call_recordings')) {
$default_path = $_SESSION['switch']['call_recordings']['dir']."/".$_SESSION['domain_name'];
//build full path
- $full_recording_path = $call_recording_path . '/' . $call_recording_name;
+ $full_recording_path = $call_recording_path.'/'.$call_recording_name;
//download the file
if (file_exists($full_recording_path)) {
//content-range
- //if (isset($_SERVER['HTTP_RANGE'])) {
- // range_download($full_recording_path);
- //}
+ if (isset($_SERVER['HTTP_RANGE']) && !$this->binary) {
+ $this->range_download($full_recording_path);
+ }
ob_clean();
$fd = fopen($full_recording_path, "rb");
if ($this->binary) {
@@ -151,18 +151,19 @@ if (!class_exists('call_recordings')) {
header("Content-Description: File Transfer");
}
else {
- $file_ext = substr($call_recording_name, -3);
- if ($file_ext == "wav") {
- header("Content-Type: audio/x-wav");
- }
- if ($file_ext == "mp3") {
- header("Content-Type: audio/mpeg");
+ $file_ext = pathinfo($call_recording_name, PATHINFO_EXTENSION);
+ switch ($file_ext) {
+ case "wav" : header("Content-Type: audio/x-wav"); break;
+ case "mp3" : header("Content-Type: audio/mpeg"); break;
+ case "ogg" : header("Content-Type: audio/ogg"); break;
}
}
header('Content-Disposition: attachment; filename="'.$call_recording_name.'"');
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
- // header("Content-Length: ".filesize($full_recording_path));
+ if ($this->binary) {
+ header("Content-Length: ".filesize($full_recording_path));
+ }
ob_clean();
fpassthru($fd);
}
@@ -174,6 +175,100 @@ if (!class_exists('call_recordings')) {
}
} //method
+
+ /*
+ * range download method (helps safari play audio sources)
+ */
+ private function range_download($file) {
+ $fp = @fopen($file, 'rb');
+
+ $size = filesize($file); // File size
+ $length = $size; // Content length
+ $start = 0; // Start byte
+ $end = $size - 1; // End byte
+ // Now that we've gotten so far without errors we send the accept range header
+ /* At the moment we only support single ranges.
+ * Multiple ranges requires some more work to ensure it works correctly
+ * and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
+ *
+ * Multirange support annouces itself with:
+ * header('Accept-Ranges: bytes');
+ *
+ * Multirange content must be sent with multipart/byteranges mediatype,
+ * (mediatype = mimetype)
+ * as well as a boundry header to indicate the various chunks of data.
+ */
+ header("Accept-Ranges: 0-$length");
+ // header('Accept-Ranges: bytes');
+ // multipart/byteranges
+ // http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
+ if (isset($_SERVER['HTTP_RANGE'])) {
+
+ $c_start = $start;
+ $c_end = $end;
+ // Extract the range string
+ list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
+ // Make sure the client hasn't sent us a multibyte range
+ if (strpos($range, ',') !== false) {
+ // (?) Shoud this be issued here, or should the first
+ // range be used? Or should the header be ignored and
+ // we output the whole content?
+ header('HTTP/1.1 416 Requested Range Not Satisfiable');
+ header("Content-Range: bytes $start-$end/$size");
+ // (?) Echo some info to the client?
+ exit;
+ }
+ // If the range starts with an '-' we start from the beginning
+ // If not, we forward the file pointer
+ // And make sure to get the end byte if spesified
+ if ($range0 == '-') {
+ // The n-number of the last bytes is requested
+ $c_start = $size - substr($range, 1);
+ }
+ else {
+ $range = explode('-', $range);
+ $c_start = $range[0];
+ $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
+ }
+ /* Check the range and make sure it's treated according to the specs.
+ * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+ */
+ // End bytes can not be larger than $end.
+ $c_end = ($c_end > $end) ? $end : $c_end;
+ // Validate the requested range and return an error if it's not correct.
+ if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
+
+ header('HTTP/1.1 416 Requested Range Not Satisfiable');
+ header("Content-Range: bytes $start-$end/$size");
+ // (?) Echo some info to the client?
+ exit;
+ }
+ $start = $c_start;
+ $end = $c_end;
+ $length = $end - $start + 1; // Calculate new content length
+ fseek($fp, $start);
+ header('HTTP/1.1 206 Partial Content');
+ }
+ // Notify the client the byte range we'll be outputting
+ header("Content-Range: bytes $start-$end/$size");
+ header("Content-Length: $length");
+
+ // Start buffered download
+ $buffer = 1024 * 8;
+ while(!feof($fp) && ($p = ftell($fp)) <= $end) {
+ if ($p + $buffer > $end) {
+ // In case we're only outputtin a chunk, make sure we don't
+ // read past the length
+ $buffer = $end - $p + 1;
+ }
+ set_time_limit(0); // Reset time limit for big files
+ echo fread($fp, $buffer);
+ flush(); // Free up memory. Otherwise large files will trigger PHP's memory limit.
+ }
+
+ fclose($fp);
+ }
+
} //class
}
diff --git a/app/music_on_hold/music_on_hold.php b/app/music_on_hold/music_on_hold.php
index b8d997d04a..ea4f62fb76 100644
--- a/app/music_on_hold/music_on_hold.php
+++ b/app/music_on_hold/music_on_hold.php
@@ -102,7 +102,7 @@
$stream_path = str_replace('..', '', $stream_path);
//get the file and sanitize it
- $stream_file = basename($_GET['file']);
+ $stream_file = basename('danza-espanola-op-37-h-142-xii-arabesca.wav');
$search = array('..', '/', ':');
$stream_file = str_replace($search, '', $stream_file);
@@ -111,6 +111,11 @@
//download the file
if (file_exists($stream_full_path)) {
+ //content-range
+ if (isset($_SERVER['HTTP_RANGE']) && $_GET['t'] != "bin") {
+ range_download($stream_full_path);
+ }
+
$fd = fopen($stream_full_path, "rb");
if ($_GET['t'] == "bin") {
header("Content-Type: application/force-download");
@@ -129,7 +134,10 @@
header('Content-Disposition: attachment; filename="'.$stream_file.'"');
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
- header("Content-Length: ".filesize($stream_full_path));
+ if ($_GET['t'] == "bin") {
+ header("Content-Length: ".filesize($stream_full_path));
+ }
+ ob_clean();
fpassthru($fd);
}
exit;
@@ -538,7 +546,7 @@
}
echo "
".escape($stream_file)."
\n";
echo "
";
- echo "";
+ echo "";
echo button::create(['type'=>'button','title'=>$text['label-play'].' / '.$text['label-pause'],'icon'=>$_SESSION['theme']['button_icon_play'],'id'=>'recording_button_'.$row_uuid,'onclick'=>"recording_play('".$row_uuid."');"]);
//echo button::create(['type'=>'button','title'=>$text['label-stop'],'icon'=>$_SESSION['theme']['button_icon_stop'],'onclick'=>"recording_stop('".$row_uuid."'); this.blur(); return false;"]);
echo button::create(['type'=>'button','title'=>$text['label-download'],'icon'=>$_SESSION['theme']['button_icon_download'],'link'=>"?action=download&id=".urlencode($row['music_on_hold_uuid'])."&file=".urlencode($stream_file)]);
@@ -567,4 +575,95 @@
//include the footer
require_once "resources/footer.php";
+//define the download function (helps safari play audio sources)
+ function range_download($file) {
+ $fp = @fopen($file, 'rb');
+
+ $size = filesize($file); // File size
+ $length = $size; // Content length
+ $start = 0; // Start byte
+ $end = $size - 1; // End byte
+ // Now that we've gotten so far without errors we send the accept range header
+ /* At the moment we only support single ranges.
+ * Multiple ranges requires some more work to ensure it works correctly
+ * and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
+ *
+ * Multirange support annouces itself with:
+ * header('Accept-Ranges: bytes');
+ *
+ * Multirange content must be sent with multipart/byteranges mediatype,
+ * (mediatype = mimetype)
+ * as well as a boundry header to indicate the various chunks of data.
+ */
+ header("Accept-Ranges: 0-$length");
+ // header('Accept-Ranges: bytes');
+ // multipart/byteranges
+ // http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
+ if (isset($_SERVER['HTTP_RANGE'])) {
+
+ $c_start = $start;
+ $c_end = $end;
+ // Extract the range string
+ list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
+ // Make sure the client hasn't sent us a multibyte range
+ if (strpos($range, ',') !== false) {
+ // (?) Shoud this be issued here, or should the first
+ // range be used? Or should the header be ignored and
+ // we output the whole content?
+ header('HTTP/1.1 416 Requested Range Not Satisfiable');
+ header("Content-Range: bytes $start-$end/$size");
+ // (?) Echo some info to the client?
+ exit;
+ }
+ // If the range starts with an '-' we start from the beginning
+ // If not, we forward the file pointer
+ // And make sure to get the end byte if spesified
+ if ($range0 == '-') {
+ // The n-number of the last bytes is requested
+ $c_start = $size - substr($range, 1);
+ }
+ else {
+ $range = explode('-', $range);
+ $c_start = $range[0];
+ $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
+ }
+ /* Check the range and make sure it's treated according to the specs.
+ * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+ */
+ // End bytes can not be larger than $end.
+ $c_end = ($c_end > $end) ? $end : $c_end;
+ // Validate the requested range and return an error if it's not correct.
+ if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
+
+ header('HTTP/1.1 416 Requested Range Not Satisfiable');
+ header("Content-Range: bytes $start-$end/$size");
+ // (?) Echo some info to the client?
+ exit;
+ }
+ $start = $c_start;
+ $end = $c_end;
+ $length = $end - $start + 1; // Calculate new content length
+ fseek($fp, $start);
+ header('HTTP/1.1 206 Partial Content');
+ }
+ // Notify the client the byte range we'll be outputting
+ header("Content-Range: bytes $start-$end/$size");
+ header("Content-Length: $length");
+
+ // Start buffered download
+ $buffer = 1024 * 8;
+ while(!feof($fp) && ($p = ftell($fp)) <= $end) {
+ if ($p + $buffer > $end) {
+ // In case we're only outputtin a chunk, make sure we don't
+ // read past the length
+ $buffer = $end - $p + 1;
+ }
+ set_time_limit(0); // Reset time limit for big files
+ echo fread($fp, $buffer);
+ flush(); // Free up memory. Otherwise large files will trigger PHP's memory limit.
+ }
+
+ fclose($fp);
+ }
+
?>
\ No newline at end of file
diff --git a/app/recordings/recordings.php b/app/recordings/recordings.php
index a8736d36c1..f0b9b1d1f1 100644
--- a/app/recordings/recordings.php
+++ b/app/recordings/recordings.php
@@ -40,7 +40,6 @@
//download the recording
if ($_GET['a'] == "download" && (permission_exists('recording_play') || permission_exists('recording_download'))) {
- //session_cache_limiter('public');
if ($_GET['type'] = "rec") {
//set the path for the directory
$path = $_SESSION['switch']['recordings']['dir']."/".$_SESSION['domain_name'];
@@ -77,7 +76,7 @@
//send the headers and then the data stream
if (file_exists($full_recording_path)) {
//content-range
- if (isset($_SERVER['HTTP_RANGE'])) {
+ if (isset($_SERVER['HTTP_RANGE']) && $_GET['t'] != "bin") {
range_download($full_recording_path);
}
@@ -89,18 +88,19 @@
header("Content-Description: File Transfer");
}
else {
- $file_ext = substr($recording_filename, -3);
- if ($file_ext == "wav") {
- header("Content-Type: audio/x-wav");
- }
- if ($file_ext == "mp3") {
- header("Content-Type: audio/mpeg");
+ $file_ext = pathinfo($recording_filename, PATHINFO_EXTENSION);
+ switch ($file_ext) {
+ case "wav" : header("Content-Type: audio/x-wav"); break;
+ case "mp3" : header("Content-Type: audio/mpeg"); break;
+ case "ogg" : header("Content-Type: audio/ogg"); break;
}
}
header('Content-Disposition: attachment; filename="'.$recording_filename.'"');
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
- // header("Content-Length: ".filesize($full_recording_path));
+ if ($_GET['t'] == "bin") {
+ header("Content-Length: ".filesize($full_recording_path));
+ }
ob_clean();
fpassthru($fd);
}
@@ -223,38 +223,44 @@
}
else {
//file found in db, check if base64 present
- if ($_SESSION['recordings']['storage_type']['text'] == 'base64') {
- $found_recording_uuid = array_search($recording_filename, $array_recordings);
- if (!$array_base64_exists[$found_recording_uuid]) {
- $recording_base64 = base64_encode(file_get_contents($_SESSION['switch']['recordings']['dir'].'/'.$_SESSION['domain_name'].'/'.$recording_filename));
- //build array
- $array['recordings'][0]['domain_uuid'] = $domain_uuid;
- $array['recordings'][0]['recording_uuid'] = $found_recording_uuid;
- $array['recordings'][0]['recording_base64'] = $recording_base64;
- //set temporary permissions
- $p = new permissions;
- $p->add('recording_edit', 'temp');
- //execute update
- $database = new database;
- $database->app_name = 'recordings';
- $database->app_uuid = '83913217-c7a2-9e90-925d-a866eb40b60e';
- $database->save($array);
- unset($array);
- //remove temporary permissions
- $p->delete('recording_edit', 'temp');
+ if ($_SESSION['recordings']['storage_type']['text'] == 'base64') {
+ $found_recording_uuid = array_search($recording_filename, $array_recordings);
+ if (!$array_base64_exists[$found_recording_uuid]) {
+ $recording_base64 = base64_encode(file_get_contents($_SESSION['switch']['recordings']['dir'].'/'.$_SESSION['domain_name'].'/'.$recording_filename));
+ //build array
+ $array['recordings'][0]['domain_uuid'] = $domain_uuid;
+ $array['recordings'][0]['recording_uuid'] = $found_recording_uuid;
+ $array['recordings'][0]['recording_base64'] = $recording_base64;
+ //set temporary permissions
+ $p = new permissions;
+ $p->add('recording_edit', 'temp');
+ //execute update
+ $database = new database;
+ $database->app_name = 'recordings';
+ $database->app_uuid = '83913217-c7a2-9e90-925d-a866eb40b60e';
+ $database->save($array);
+ unset($array);
+ //remove temporary permissions
+ $p->delete('recording_edit', 'temp');
+ }
}
- }
}
//if base64, remove local file
- if ($_SESSION['recordings']['storage_type']['text'] == 'base64' && file_exists($_SESSION['switch']['recordings']['dir'].'/'.$_SESSION['domain_name'].'/'.$recording_filename)) {
- @unlink($_SESSION['switch']['recordings']['dir'].'/'.$_SESSION['domain_name'].'/'.$recording_filename);
- }
+ if ($_SESSION['recordings']['storage_type']['text'] == 'base64' && file_exists($_SESSION['switch']['recordings']['dir'].'/'.$_SESSION['domain_name'].'/'.$recording_filename)) {
+ @unlink($_SESSION['switch']['recordings']['dir'].'/'.$_SESSION['domain_name'].'/'.$recording_filename);
+ }
}
}
closedir($dh);
}
+
+ //redirect
+ if ($_GET['rd'] != '') {
+ header("Location: recordings.php");
+ exit;
+ }
}
//get posted data
@@ -506,7 +512,7 @@
//include the footer
require_once "resources/footer.php";
-//define the download function
+//define the download function (helps safari play audio sources)
function range_download($file) {
$fp = @fopen($file, 'rb');
@@ -516,16 +522,16 @@
$end = $size - 1; // End byte
// Now that we've gotten so far without errors we send the accept range header
/* At the moment we only support single ranges.
- * Multiple ranges requires some more work to ensure it works correctly
- * and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
- *
- * Multirange support annouces itself with:
- * header('Accept-Ranges: bytes');
- *
- * Multirange content must be sent with multipart/byteranges mediatype,
- * (mediatype = mimetype)
- * as well as a boundry header to indicate the various chunks of data.
- */
+ * Multiple ranges requires some more work to ensure it works correctly
+ * and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
+ *
+ * Multirange support annouces itself with:
+ * header('Accept-Ranges: bytes');
+ *
+ * Multirange content must be sent with multipart/byteranges mediatype,
+ * (mediatype = mimetype)
+ * as well as a boundry header to indicate the various chunks of data.
+ */
header("Accept-Ranges: 0-$length");
// header('Accept-Ranges: bytes');
// multipart/byteranges
@@ -559,8 +565,8 @@
$c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
}
/* Check the range and make sure it's treated according to the specs.
- * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
- */
+ * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+ */
// End bytes can not be larger than $end.
$c_end = ($c_end > $end) ? $end : $c_end;
// Validate the requested range and return an error if it's not correct.
diff --git a/app/voicemail_greetings/voicemail_greetings.php b/app/voicemail_greetings/voicemail_greetings.php
index 946dd03b78..12e9bad461 100644
--- a/app/voicemail_greetings/voicemail_greetings.php
+++ b/app/voicemail_greetings/voicemail_greetings.php
@@ -99,6 +99,11 @@
}
unset($sql, $row, $greeting_decoded);
if (file_exists($v_greeting_dir.'/'.$greeting_filename)) {
+ //content-range
+ if (isset($_SERVER['HTTP_RANGE']) && $_GET['t'] != "bin") {
+ range_download($v_greeting_dir.'/'.$greeting_filename);
+ }
+
$fd = fopen($v_greeting_dir.'/'.$greeting_filename, "rb");
if ($_GET['t'] == "bin") {
header("Content-Type: application/force-download");
@@ -107,18 +112,19 @@
header("Content-Description: File Transfer");
}
else {
- $file_ext = substr($greeting_filename, -3);
- if ($file_ext == "wav") {
- header("Content-Type: audio/x-wav");
- }
- if ($file_ext == "mp3") {
- header("Content-Type: audio/mpeg");
+ $file_ext = pathinfo($greeting_filename, PATHINFO_EXTENSION);
+ switch ($file_ext) {
+ case "wav" : header("Content-Type: audio/x-wav"); break;
+ case "mp3" : header("Content-Type: audio/mpeg"); break;
+ case "ogg" : header("Content-Type: audio/ogg"); break;
}
}
header('Content-Disposition: attachment; filename="'.$greeting_filename.'"');
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
- header("Content-Length: ".filesize($v_greeting_dir.'/'.$greeting_filename));
+ if ($_GET['t'] == "bin") {
+ header("Content-Length: ".filesize($v_greeting_dir.'/'.$greeting_filename));
+ }
ob_clean();
fpassthru($fd);
}
@@ -570,4 +576,95 @@
//include the footer
require_once "resources/footer.php";
+//define the download function (helps safari play audio sources)
+ function range_download($file) {
+ $fp = @fopen($file, 'rb');
+
+ $size = filesize($file); // File size
+ $length = $size; // Content length
+ $start = 0; // Start byte
+ $end = $size - 1; // End byte
+ // Now that we've gotten so far without errors we send the accept range header
+ /* At the moment we only support single ranges.
+ * Multiple ranges requires some more work to ensure it works correctly
+ * and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
+ *
+ * Multirange support annouces itself with:
+ * header('Accept-Ranges: bytes');
+ *
+ * Multirange content must be sent with multipart/byteranges mediatype,
+ * (mediatype = mimetype)
+ * as well as a boundry header to indicate the various chunks of data.
+ */
+ header("Accept-Ranges: 0-$length");
+ // header('Accept-Ranges: bytes');
+ // multipart/byteranges
+ // http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
+ if (isset($_SERVER['HTTP_RANGE'])) {
+
+ $c_start = $start;
+ $c_end = $end;
+ // Extract the range string
+ list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
+ // Make sure the client hasn't sent us a multibyte range
+ if (strpos($range, ',') !== false) {
+ // (?) Shoud this be issued here, or should the first
+ // range be used? Or should the header be ignored and
+ // we output the whole content?
+ header('HTTP/1.1 416 Requested Range Not Satisfiable');
+ header("Content-Range: bytes $start-$end/$size");
+ // (?) Echo some info to the client?
+ exit;
+ }
+ // If the range starts with an '-' we start from the beginning
+ // If not, we forward the file pointer
+ // And make sure to get the end byte if spesified
+ if ($range0 == '-') {
+ // The n-number of the last bytes is requested
+ $c_start = $size - substr($range, 1);
+ }
+ else {
+ $range = explode('-', $range);
+ $c_start = $range[0];
+ $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
+ }
+ /* Check the range and make sure it's treated according to the specs.
+ * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+ */
+ // End bytes can not be larger than $end.
+ $c_end = ($c_end > $end) ? $end : $c_end;
+ // Validate the requested range and return an error if it's not correct.
+ if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
+
+ header('HTTP/1.1 416 Requested Range Not Satisfiable');
+ header("Content-Range: bytes $start-$end/$size");
+ // (?) Echo some info to the client?
+ exit;
+ }
+ $start = $c_start;
+ $end = $c_end;
+ $length = $end - $start + 1; // Calculate new content length
+ fseek($fp, $start);
+ header('HTTP/1.1 206 Partial Content');
+ }
+ // Notify the client the byte range we'll be outputting
+ header("Content-Range: bytes $start-$end/$size");
+ header("Content-Length: $length");
+
+ // Start buffered download
+ $buffer = 1024 * 8;
+ while(!feof($fp) && ($p = ftell($fp)) <= $end) {
+ if ($p + $buffer > $end) {
+ // In case we're only outputtin a chunk, make sure we don't
+ // read past the length
+ $buffer = $end - $p + 1;
+ }
+ set_time_limit(0); // Reset time limit for big files
+ echo fread($fp, $buffer);
+ flush(); // Free up memory. Otherwise large files will trigger PHP's memory limit.
+ }
+
+ fclose($fp);
+ }
+
?>
\ No newline at end of file
diff --git a/app/voicemails/resources/classes/voicemail.php b/app/voicemails/resources/classes/voicemail.php
index 32847e1366..63773b2699 100644
--- a/app/voicemails/resources/classes/voicemail.php
+++ b/app/voicemails/resources/classes/voicemail.php
@@ -725,9 +725,6 @@
//change the message status
$this->message_saved();
- //clear the cache
- session_cache_limiter('public');
-
//set source folder path
$path = $_SESSION['switch']['voicemail']['dir'].'/default/'.$_SESSION['domain_name'].'/'.$this->voicemail_id;
@@ -778,32 +775,37 @@
$file_path = $path.'/msg_'.$this->voicemail_message_uuid.'.mp3';
}
if ($file_path != '') {
+ //content-range
+ if (isset($_SERVER['HTTP_RANGE']) && $this->type != 'bin') {
+ $this->range_download($file_path);
+ }
+
$fd = fopen($file_path, "rb");
if ($this->type == 'bin') {
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
- $file_ext = substr($file_path, -3);
- if ($file_ext == "wav") {
- header('Content-Disposition: attachment; filename="msg_'.$this->voicemail_message_uuid.'.wav"');
- }
- if ($file_ext == "mp3") {
- header('Content-Disposition: attachment; filename="msg_'.$this->voicemail_message_uuid.'.mp3"');
+ $file_ext = pathinfo($file_path, PATHINFO_EXTENSION);
+ switch ($file_ext) {
+ case "wav" : header('Content-Disposition: attachment; filename="msg_'.$this->voicemail_message_uuid.'.wav"'); break;
+ case "mp3" : header('Content-Disposition: attachment; filename="msg_'.$this->voicemail_message_uuid.'.mp3"'); break;
+ case "ogg" : header('Content-Disposition: attachment; filename="msg_'.$this->voicemail_message_uuid.'.ogg"'); break;
}
}
else {
- $file_ext = substr($file_path, -3);
- if ($file_ext == "wav") {
- header("Content-Type: audio/wav");
- }
- if ($file_ext == "mp3") {
- header("Content-Type: audio/mpeg");
+ $file_ext = pathinfo($file_path, PATHINFO_EXTENSION);
+ switch ($file_ext) {
+ case "wav" : header("Content-Type: audio/x-wav"); break;
+ case "mp3" : header("Content-Type: audio/mpeg"); break;
+ case "ogg" : header("Content-Type: audio/ogg"); break;
}
}
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // date in the past
- header("Content-Length: " . filesize($file_path));
+ if ($this->type == 'bin') {
+ header("Content-Length: ".filesize($file_path));
+ }
ob_end_clean();
fpassthru($fd);
}
@@ -815,6 +817,100 @@
}
+ /*
+ * range download method (helps safari play audio sources)
+ */
+ private function range_download($file) {
+ $fp = @fopen($file, 'rb');
+
+ $size = filesize($file); // File size
+ $length = $size; // Content length
+ $start = 0; // Start byte
+ $end = $size - 1; // End byte
+ // Now that we've gotten so far without errors we send the accept range header
+ /* At the moment we only support single ranges.
+ * Multiple ranges requires some more work to ensure it works correctly
+ * and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
+ *
+ * Multirange support annouces itself with:
+ * header('Accept-Ranges: bytes');
+ *
+ * Multirange content must be sent with multipart/byteranges mediatype,
+ * (mediatype = mimetype)
+ * as well as a boundry header to indicate the various chunks of data.
+ */
+ header("Accept-Ranges: 0-$length");
+ // header('Accept-Ranges: bytes');
+ // multipart/byteranges
+ // http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
+ if (isset($_SERVER['HTTP_RANGE'])) {
+
+ $c_start = $start;
+ $c_end = $end;
+ // Extract the range string
+ list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
+ // Make sure the client hasn't sent us a multibyte range
+ if (strpos($range, ',') !== false) {
+ // (?) Shoud this be issued here, or should the first
+ // range be used? Or should the header be ignored and
+ // we output the whole content?
+ header('HTTP/1.1 416 Requested Range Not Satisfiable');
+ header("Content-Range: bytes $start-$end/$size");
+ // (?) Echo some info to the client?
+ exit;
+ }
+ // If the range starts with an '-' we start from the beginning
+ // If not, we forward the file pointer
+ // And make sure to get the end byte if spesified
+ if ($range0 == '-') {
+ // The n-number of the last bytes is requested
+ $c_start = $size - substr($range, 1);
+ }
+ else {
+ $range = explode('-', $range);
+ $c_start = $range[0];
+ $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
+ }
+ /* Check the range and make sure it's treated according to the specs.
+ * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+ */
+ // End bytes can not be larger than $end.
+ $c_end = ($c_end > $end) ? $end : $c_end;
+ // Validate the requested range and return an error if it's not correct.
+ if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
+
+ header('HTTP/1.1 416 Requested Range Not Satisfiable');
+ header("Content-Range: bytes $start-$end/$size");
+ // (?) Echo some info to the client?
+ exit;
+ }
+ $start = $c_start;
+ $end = $c_end;
+ $length = $end - $start + 1; // Calculate new content length
+ fseek($fp, $start);
+ header('HTTP/1.1 206 Partial Content');
+ }
+ // Notify the client the byte range we'll be outputting
+ header("Content-Range: bytes $start-$end/$size");
+ header("Content-Length: $length");
+
+ // Start buffered download
+ $buffer = 1024 * 8;
+ while(!feof($fp) && ($p = ftell($fp)) <= $end) {
+ if ($p + $buffer > $end) {
+ // In case we're only outputtin a chunk, make sure we don't
+ // read past the length
+ $buffer = $end - $p + 1;
+ }
+ set_time_limit(0); // Reset time limit for big files
+ echo fread($fp, $buffer);
+ flush(); // Free up memory. Otherwise large files will trigger PHP's memory limit.
+ }
+
+ fclose($fp);
+ }
+
+
}
//example voicemail messages
diff --git a/app/xml_cdr/resources/classes/xml_cdr.php b/app/xml_cdr/resources/classes/xml_cdr.php
index 4c7d7a8ec4..4f85fcfaef 100644
--- a/app/xml_cdr/resources/classes/xml_cdr.php
+++ b/app/xml_cdr/resources/classes/xml_cdr.php
@@ -1086,9 +1086,6 @@ if (!class_exists('xml_cdr')) {
public function download($uuid) {
if (permission_exists('xml_cdr_view')) {
- //cache limiter
- session_cache_limiter('public');
-
//get call recording from database
if (is_uuid($uuid)) {
$sql = "select record_name, record_path from v_xml_cdr ";
@@ -1106,14 +1103,14 @@ if (!class_exists('xml_cdr')) {
}
//build full path
- $record_file = $record_path . '/' . $record_name;
+ $record_file = $record_path.'/'.$record_name;
//download the file
if (file_exists($record_file)) {
//content-range
- //if (isset($_SERVER['HTTP_RANGE'])) {
- // range_download($record_file);
- //}
+ if (isset($_SERVER['HTTP_RANGE']) && $_GET['t'] != "bin") {
+ $this->range_download($record_file);
+ }
ob_clean();
$fd = fopen($record_file, "rb");
if ($_GET['t'] == "bin") {
@@ -1123,28 +1120,119 @@ if (!class_exists('xml_cdr')) {
header("Content-Description: File Transfer");
}
else {
- $file_ext = substr($record_name, -3);
- if ($file_ext == "wav") {
- header("Content-Type: audio/x-wav");
- }
- if ($file_ext == "mp3") {
- header("Content-Type: audio/mpeg");
- }
- if ($file_ext == "ogg") {
- header("Content-Type: audio/ogg");
+ $file_ext = pathinfo($record_name, PATHINFO_EXTENSION);
+ switch ($file_ext) {
+ case "wav" : header("Content-Type: audio/x-wav"); break;
+ case "mp3" : header("Content-Type: audio/mpeg"); break;
+ case "ogg" : header("Content-Type: audio/ogg"); break;
}
}
$record_name = preg_replace('#[^a-zA-Z0-9_\-\.]#', '', $record_name);
header('Content-Disposition: attachment; filename="'.$record_name.'"');
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
- header("Content-Length: " . filesize($record_file));
+ if ($_GET['t'] == "bin") {
+ header("Content-Length: ".filesize($record_file));
+ }
ob_clean();
fpassthru($fd);
}
}
} //end download method
+ /*
+ * range download method (helps safari play audio sources)
+ */
+ private function range_download($file) {
+ $fp = @fopen($file, 'rb');
+
+ $size = filesize($file); // File size
+ $length = $size; // Content length
+ $start = 0; // Start byte
+ $end = $size - 1; // End byte
+ // Now that we've gotten so far without errors we send the accept range header
+ /* At the moment we only support single ranges.
+ * Multiple ranges requires some more work to ensure it works correctly
+ * and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
+ *
+ * Multirange support annouces itself with:
+ * header('Accept-Ranges: bytes');
+ *
+ * Multirange content must be sent with multipart/byteranges mediatype,
+ * (mediatype = mimetype)
+ * as well as a boundry header to indicate the various chunks of data.
+ */
+ header("Accept-Ranges: 0-$length");
+ // header('Accept-Ranges: bytes');
+ // multipart/byteranges
+ // http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
+ if (isset($_SERVER['HTTP_RANGE'])) {
+
+ $c_start = $start;
+ $c_end = $end;
+ // Extract the range string
+ list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
+ // Make sure the client hasn't sent us a multibyte range
+ if (strpos($range, ',') !== false) {
+ // (?) Shoud this be issued here, or should the first
+ // range be used? Or should the header be ignored and
+ // we output the whole content?
+ header('HTTP/1.1 416 Requested Range Not Satisfiable');
+ header("Content-Range: bytes $start-$end/$size");
+ // (?) Echo some info to the client?
+ exit;
+ }
+ // If the range starts with an '-' we start from the beginning
+ // If not, we forward the file pointer
+ // And make sure to get the end byte if spesified
+ if ($range0 == '-') {
+ // The n-number of the last bytes is requested
+ $c_start = $size - substr($range, 1);
+ }
+ else {
+ $range = explode('-', $range);
+ $c_start = $range[0];
+ $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
+ }
+ /* Check the range and make sure it's treated according to the specs.
+ * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+ */
+ // End bytes can not be larger than $end.
+ $c_end = ($c_end > $end) ? $end : $c_end;
+ // Validate the requested range and return an error if it's not correct.
+ if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
+
+ header('HTTP/1.1 416 Requested Range Not Satisfiable');
+ header("Content-Range: bytes $start-$end/$size");
+ // (?) Echo some info to the client?
+ exit;
+ }
+ $start = $c_start;
+ $end = $c_end;
+ $length = $end - $start + 1; // Calculate new content length
+ fseek($fp, $start);
+ header('HTTP/1.1 206 Partial Content');
+ }
+ // Notify the client the byte range we'll be outputting
+ header("Content-Range: bytes $start-$end/$size");
+ header("Content-Length: $length");
+
+ // Start buffered download
+ $buffer = 1024 * 8;
+ while(!feof($fp) && ($p = ftell($fp)) <= $end) {
+ if ($p + $buffer > $end) {
+ // In case we're only outputtin a chunk, make sure we don't
+ // read past the length
+ $buffer = $end - $p + 1;
+ }
+ set_time_limit(0); // Reset time limit for big files
+ echo fread($fp, $buffer);
+ flush(); // Free up memory. Otherwise large files will trigger PHP's memory limit.
+ }
+
+ fclose($fp);
+ }
+
/**
* delete records
*/
@@ -1223,4 +1311,4 @@ if (!class_exists('xml_cdr')) {
} //class
}
-?>
+?>
\ No newline at end of file