ERR_CONTENT_LENGTH_MISMATCH when loading video in chrome - php

So I get this error when some of the video plays. When Chrome completely downloads the video, it stops playing with this error. Also the status of the request changes from 206 to (failed) and then Chrome sends some other requests with Range:bytes=2990775- and the server response is:
Accept-Ranges:bytes
Cache-Control:private
Connection:keep-alive
Content-Disposition:attachment; filename="About The Author.mp4"
Content-Length:0
Content-Range:bytes 2990775-2990775/2990776
Content-Transfer-Encoding:binary
Content-Type:video/mp4
Date:Tue, 14 Feb 2017 13:46:24 GMT
Last-Modified:Wed, 08 Feb 2017 05:43:27 GMT
Pragma:public
Server:Apache/2
Vary:User-Agent
X-Powered-By:PHP/5.4.45
I have another website on the same server and it works fine there.
Here is my PHP code:
$filesize = filesize($resource->path);
$matches = explode("-", substr($_SERVER['HTTP_RANGE'],6));
if (empty($matches[1]))
{
$matches[1] = $filesize - 1;
}
$offset = intval($matches[0]);
$length = intval($matches[1]) - $offset;
$file = fopen($resource->path, 'r');
fseek($file, $offset);
$data = fread($file, $length);
fclose($file);
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes ' . $offset . '-' . ($offset + $length) . '/' . $filesize);
header('Pragma: public');
header('Last-Modified: '.gmdate ('D, d M Y H:i:s', filemtime ($resource->path)).' GMT');
header('Cache-Control: private',false);
header('Content-Type: ' . $mime);
header('Content-Length: ' . ($length + 1));
header('Content-Disposition: attachment; filename="' . $resource->filename . '"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
print($data);
Sorry for my bad english.

I've found the problem.
I changed $data = fread($file, $length); to $data = fread($file, $length + 1);.
I don't know why the requested length should be plus one but it solve'd the problem.

Related

PHP Mailer: XLSX file coruplted when sending from html file

I am currently having a problem with my PHP code as it corrupts the data/xlsx file when exporting it from HTML.
i am viewing PHP Mailer scripts which has multiple pages connected to it.
This is my PHP XLS Function.
this->_request->download ? true : false;
$htmlPath = realpath(dirname(__FILE__) . "/../../public/reports/html/") . "/" . $fileName;
$fileSource = file_get_contents($htmlPath);
preg_match('!<title>([^<]+)!', $fileSource, $title);
$title = trim($title[1]);
if (stristr($fileSource, '<graph>')) {
$fileSource = preg_replace('!<graph>[^<]+</graph>!is', '', $fileSource);
file_put_contents($htmlPath, $fileSource);
}
file_put_contents($htmlPath,preg_replace('!<title>[^<]+</title>!is','',$fileSource));
$reader = new PHPExcel_Reader_HTML;
$content = $reader->load($htmlPath);
// Pass to writer and output as needed
$objWriter = PHPExcel_IOFactory::createWriter($content, 'Excel2007');
$download = 1;
// Redirect output to a client’s web browser (Excel5)
//header('Content-Type: application/vnd.ms-excel');
$fileName = str_replace(' ', '-', ($title . "-" . date('Y-m-d')));
if ($download) {
// Redirect output to a client’s web browser (Excel2007)
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
// header('Cache-Control: max-age=1');
// If you're serving to IE over SSL, then the following may be needed
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header('Pragma: public'); // HTTP/1.0
header('Content-Disposition: attachment;
filename=' . $fileName . ".xlsx")
this is my caller function
if ($reportRow->reportString) {
$reportRow->reportString = stripslashes($reportRow->reportString);
if (!stristr($reportRow->reportString, '</body>'))
$reportRow->reportString = $reportRow->reportString . "</table></body></html>";
$fileName = time() . rand(111, 222);
$htmlPath = realpath(dirname(__FILE__) . "/../../public/reports/html/") . "/" . $fileName;
if ($headerPath) {
$reportRow->html_string = preg_replace('!(\s*</htmlpageheader>)!', '$1<img width="100%" style="clear:both" id="headerPath" src="' . $headerPath . '" />', $reportRow->html_string);
}
$corp_name = preg_replace('!\s+!',' ',$userSessionData->corp_name);
$reportRow->reportString = preg_replace_callback(
'!<title>([^<]+)!is',
function($matches) use ($corp_name){
return '<title>' . $corp_name . '_' . preg_replace('!\s+!',' ',$matches[1]);
},
$reportRow->reportString
);
file_put_contents($htmlPath, $reportRow->reportString);
$kilobites = filesize($htmlPath);
$kilobites = $kilobites / 1024;
$kilobites = 0;
if ($ifXLS) {
echo json_encode(array(
'reportPath' => '/helper/file-To-xls/fileName/' . $fileName,
'error' => false
));
would anyone have any ideas on how to fix this issue?
you can use CSV functions or PHPExcel to do it straight forward
or you can try like below
<?php
$file="1.xls";
$html="<table><tr><td>Col1</td><td>Col2</td></tr></table>";
header("Content-type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=$file");
echo $html;
?>
The header for .xlsx files is Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet if you prefer to export it as .xlsx

android webview file download/php provides

Provides file downloads with PHP.
It works fine on the web, but it does not work properly in the app.
What is the reason why the header of the file is normally displayed but the file is not downloaded?
android webview download
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setMimeType(mimetype);
request.addRequestHeader("User-Agent", userAgent);
request.setDescription("Downloading file");
request.setTitle(URLUtil.guessFileName(url,contentDisposition,mimetype));
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(url,contentDisposition,mimetype));
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
headers
header('Content-Type: ' . $this->mimetype);
header('Content-Disposition: attachment; filename="' . $this->dl_filename . '"');
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');
/* The three lines below basically make the
download non-cacheable */
header("Cache-control: private");
header('Pragma: private');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
// multipart-download and download resuming support
if(isset($_SERVER['HTTP_RANGE']) && !$this->force_single){
list($a, $range) = explode("=", $_SERVER['HTTP_RANGE'], 2);
list($range) = explode(",", $range, 2);
list($range, $range_end) = explode("-", $range);
$range = intval($range);
if(!$range_end){
$range_end = $size - 1;
}else{
$range_end = intval($range_end);
}
$new_length = $range_end - $range + 1;
header('HTTP/1.1 206 Partial Content');
header('Content-Length: ' . $new_length);
header('Content-Range: bytes ' . $range . '-' . $range_end . '/' . $size);
//set the offset range
$this->mt_range = $range;
}else{
$new_length = $size;
header("Content-Length: " . $size);
}
download file
if($file = fopen($filename, 'r')){
if(isset($_SERVER['HTTP_RANGE']) && !$this->force_single){
fseek($file, $this->mt_range);
}
//write the data out to the browser
while(!feof($file) && !connection_aborted() && $bytes_send < $block_size){
$buffer = fread($file, $chunksize);
echo $buffer;
flush();
$bytes_send += strlen($buffer);
}
fclose($file);
}

PHP Website not responding while streaming a video

My website is developed using pure PHP with MySQL
while streaming a video "Please try this link"
Here
If you click on any button called "مشاهدة", the website will not respond to any other request like navigating to any other page.
Here is the code of my Stream.php file
<?php
session_start();
require("includes/connect.php");
set_time_limit(0);
if(isset($_GET["file"])){
if(!isset($_GET["start"])) $_GET["start"] = 0;
$seekPos = $_GET["start"];
$file = htmlspecialchars($_GET["file"]);
$fileName = basename($file);
$file = $config["videoFilesPath"]."/".$fileName;
if(!file_exists($file)) die("file does not exist: $file");
$fh = fopen($file, "rb") or die("failed to open file");
fseek($fh, 0, SEEK_END); $seek_end = ftell($fh);
fseek($fh, $seekPos); $seek_start = ftell($fh);
$fileSize = $seek_end - $seek_start;
session_cache_limiter('nocache');
header("Expires: Thu, 19 Nov 1981 08:52:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
header("Pragma: no-cache");
header("Content-Type: video/x-flv");
//header("Content-Disposition: attachment; filename=\"" . $fileName . "\"");
header('Content-Length: ' . $fileSize);
if($seekPos != 0){
print("FLV");
print(pack('C', 1 ));
print(pack('C', 1 ));
print(pack('N', 9 ));
print(pack('N', 9 ));
}
fseek($fh, $seekPos);
$i=1;
while (true){
$var = fread($fh, 1024);
if($var==false) break;
echo $var;
if(++$i%(1<<20)) ob_flush();
}
fclose($fh);
}
session_start() opens and locks the session file, therefore you must call session_write_close() before any long running process:
session_start();
require("includes/connect.php");
session_write_close();

passing header data in .NET and IIS

I have existing code that passes information for a video file in php to the video player through .htaccess. I'm trying to understand how something like this can be replicated in IIS and .NET
php script:
$hash = $_GET['h'];
$streamname = $_GET['v'];
$timestamp = $_GET['t'];
$current = time();
$token = 'sn983pjcnhupclavsnda';
$checkhash = md5($token . '/' . $streamname . $timestamp);
if (($current - $timestamp) <= 2 && ($checkhash == $hash)) {
$fsize = filesize($streamname);
header('Content-Disposition: attachment; filename="' . $streamname . '"');
if (strrchr($streamname, '.') == '.mp4') {
header('Content-Type: video/mp4');
} else {
header('Content-Type: video/x-flv');
}
header('Content-Length: ' . $fsize);
session_cache_limiter('nocache');
header('Expires: Thu, 19 Nov 1981 08:52:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Pragma: no-cache');
$file = fopen($streamname, 'rb');
print(fread($file, $fsize));
fclose($file);
exit;
} else {
header("location:.$player_id");
}
.htaccess
RewriteEngine on
RewriteRule ^(.*)/(.*)/(.*)$ videoSecure.php?h=$1&t=$2&v=$3
RewriteRule ^$ - [F]
RewriteRule ^[^/]+\.(flv|mp4)$ - [F]
What this does is obfuscate and secure a video file from being downloaded directly off the sever, but still allowing it to be streamed.
I'm trying to understand if I can achieve something like this in IIS6/7 + .NET MVC4
Alternatively, would I be able to keep the php and have it execute through IIS despite a .NET environment for the majority of the site and would that produce any problems?
You can use some thing like this.
Response.AppendHeader("Content-Type", "video/mp4");

pseudo streaming

I currently test script an pseudo-streaming for read mp4 files, when I reading everything works fine, but I can not move the timeline? probleme ?
my coding (mp4 metadata) is correct because when reading without this code in the player, I can move in the timeline. I use fplayer for read the mp4.
// ----- NO CACHE -----
session_cache_limiter('nocache');
// General header for no caching
$now = gmdate('D, d M Y H:i:s') . ' GMT';
header('Expires: ' . $now); // rfc2616 - Section 14.21
header('Last-Modified: ' . $now);
header('Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0'); // HTTP/1.1
header('Pragma: no-cache'); // HTTP/1.0
// ----- Seek position -----
$seekat = 0;
if (isset($_GET["pos"])) {
$position = $_GET["pos"];
if (is_numeric ($position)) {
$seekat = $position;
}
if ($seekat < 0) $seekat = 0;
}
$filename = 'test.mp4';
$ext = strrchr($filename, ".");
$prefix = "";
$file = $prefix . $filename;
if (($filename != "") && (file_exists($file)) && ($ext==".mp4")) {
header("Content-Type: video/x-mp4");
if ($seekat > 0) header('Content-Length: ' . (filesize($file)-$seekat));
else header('Content-Length: ' . filesize($file));
if ($seekat != 0) {
print("FLV");
print(pack('C', 1 ));
print(pack('C', 1 ));
print(pack('N', 9 ));
print(pack('N', 9 ));
}
$fh = fopen($file, "rb");
fseek($fh, $seekat);
while (!feof($fh)) {
print (fread($fh, 16384));
// print (fread($fh, filesize($file)));
}
fclose($fh);
}
Can you help me thank you.
header("Content-Type: video/x-mp4");
i currently use the same code but even when i stream an mp4 i let the header content as for a flv
Content-Type: video/x-flv
hope it's will help

Categories