Hi to all,
I have Joomla 1.5.22 with phocadownload 1.3.8.
On an internal page I have many PDF about a seminar with embedded audio and/or video. The authors required us to SECURED it with Acrobat function.
I can download many of these files without problems but a few of it result corrupted when downloaded, so Acrobat X try to rebuild but without success.
I have tried to download it and save and I see that the tail, with PDF %END command is missing. I have check the size of files was no too large but the error was on large or small file; there are other file more large of it that I download correctly.
For example 41.19M file size is corrupted, 90M file size is corrupted, 94M file is ok!!
In setting I have:
{pdf=application/pdf}
....
Can you help me?
This problem let me in trouble and hope I am not obligate to change document management software. I like Phocadownload!
Thanks in advance
Alessandro Agostini
PDF SECURED file corrupted on download
-
a.agostini
- Phoca Newbie

- Posts: 5
- Joined: 10 Jun 2011, 15:34
- Jan
- Phoca Hero

- Posts: 49144
- Joined: 10 Nov 2007, 18:23
- Location: Czech Republic
- Contact:
Re: PDF SECURED file corrupted on download
Hi, hmm, no experiences there, Phoca Download only gives information between server and browser, it says, this file with this information should be given for download. So maybe try to check (really no idea), if there is no some security settings on the server, etc. For now I didn't see such problem so cannot give right advice there 
Jan
Jan
If you find Phoca extensions useful, please support the project
-
a.agostini
- Phoca Newbie

- Posts: 5
- Joined: 10 Jun 2011, 15:34
Re: PDF SECURED file corrupted on download
uhmmm.
i'm investigating....
If I transfer file by winSCP the PDF file is ok.
So, I compared two files good and corrupted and I see that is missing many finals bytes approx 50Kbyte!!
I have compared other files and the diff is not the same. Also HEX CODE of first bytes missing is not the same so there aren't problem on particular hash breakin communication.
I see there are some forum talk about problem with Apache/php ; I have tried to disable "EnableMME Off" and "EnableSendFile Off" but no change.
However I have tried to move a file on DocumentRoot and I can download it correctly.
So I think that the only component that operate on file is Phocadownload.
Now I'll check the scripts.
AA
i'm investigating....
If I transfer file by winSCP the PDF file is ok.
So, I compared two files good and corrupted and I see that is missing many finals bytes approx 50Kbyte!!
I have compared other files and the diff is not the same. Also HEX CODE of first bytes missing is not the same so there aren't problem on particular hash breakin communication.
I see there are some forum talk about problem with Apache/php ; I have tried to disable "EnableMME Off" and "EnableSendFile Off" but no change.
However I have tried to move a file on DocumentRoot and I can download it correctly.
So I think that the only component that operate on file is Phocadownload.
Now I'll check the scripts.
AA
-
a.agostini
- Phoca Newbie

- Posts: 5
- Joined: 10 Jun 2011, 15:34
Re: PDF SECURED file corrupted on download
Hi,
Now all is ok.
The problem was the HTTP_RANGE feature of Apache, or however the instruction in script about it.
I have commented out the following rows in:
components/com_phocadownload/helpers/phocadownload.php in download function. See the commented code:
/*
// HTTP Range
$httpRange = 0;
if(isset($_SERVER['HTTP_RANGE'])) {
list($a, $httpRange) = explode('=', $_SERVER['HTTP_RANGE']);
str_replace($httpRange, '-', $httpRange);
$newFileSize = $fileSize - 1;
$newFileSizeHR = $fileSize - $httpRange;
header("HTTP/1.1 206 Partial Content");
header("Content-Length: ".(string)$newFileSizeHR);
header("Content-Range: bytes ".$httpRange . $newFileSize .'/'. $fileSize);
} else {
$newFileSize = $fileSize - 1;
header("Content-Length: ".(string)$fileSize);
header("Content-Range: bytes 0-".$newFileSize . '/'.$fileSize);
}
*/
Without these rows all is ok. I have checked the $_SERVER['HTTP_RANGE'] variable is 'false' so the problem is in last three rows, I think.
I hope this is useful for you for other posts.
Thanks
Alessandro
Now all is ok.
The problem was the HTTP_RANGE feature of Apache, or however the instruction in script about it.
I have commented out the following rows in:
components/com_phocadownload/helpers/phocadownload.php in download function. See the commented code:
/*
// HTTP Range
$httpRange = 0;
if(isset($_SERVER['HTTP_RANGE'])) {
list($a, $httpRange) = explode('=', $_SERVER['HTTP_RANGE']);
str_replace($httpRange, '-', $httpRange);
$newFileSize = $fileSize - 1;
$newFileSizeHR = $fileSize - $httpRange;
header("HTTP/1.1 206 Partial Content");
header("Content-Length: ".(string)$newFileSizeHR);
header("Content-Range: bytes ".$httpRange . $newFileSize .'/'. $fileSize);
} else {
$newFileSize = $fileSize - 1;
header("Content-Length: ".(string)$fileSize);
header("Content-Range: bytes 0-".$newFileSize . '/'.$fileSize);
}
*/
Without these rows all is ok. I have checked the $_SERVER['HTTP_RANGE'] variable is 'false' so the problem is in last three rows, I think.
I hope this is useful for you for other posts.
Thanks
Alessandro
-
SonRiab
- Phoca Professional

- Posts: 258
- Joined: 02 Jun 2011, 09:29
- Contact:
Re: PDF SECURED file corrupted on download
If the $_Server variable is really false, then the if block is used!
How do you check the value of $_SERVER['HTTP_RANGE'] ?
-Edit-
If your are willing to test some code try this one:
// HTTP Range - see RFC2616 for more informations (http://www.ietf.org/rfc/rfc2616.txt)
$httpRange = 0;
$newFileSize = $fileSize - 1;
// Default values! Will be overridden if a valid range header field was detected!
$resultLenght = (string)$fileSize;
$resultRange = "0-".$newFileSize;
// We support requests for a single range only.
// So we check if we have a range field. If yes ensure that it is a valid one.
// If it is not valid we ignore it and sending the whole file.
if(isset($_SERVER['HTTP_RANGE']) && preg_match('%^bytes=\d*\-\d*$%', $_SERVER['HTTP_RANGE'])) {
// Let's take the right side
list($a, $httpRange) = explode('=', $_SERVER['HTTP_RANGE']);
// and get the two values (as strings!)
$httpRange = explode('-', $httpRange);
// Check if we have values! If not we have nothing to do!
if(!empty($httpRange[0]) || !empty($httpRange[1])) {
// We need the new content length ...
$resultLenght = $fileSize - $httpRange[0] - $httpRange[1];
// ... and we can add the 206 Status.
header("HTTP/1.1 206 Partial Content");
// Now we need the content-range, so we have to build it depending on the given range!
// ex.: -500 -> the last 500 bytes
if(empty($httpRange[0]))
$resultRange = $resultLenght.'-'.$newFileSize;
// ex.: 500- -> from 500 bytes to filesize
elseif(empty($httpRange[1]))
$resultRange = $httpRange[0].'-'.$newFileSize;
// ex.: 500-1000 -> from 500 to 1000 bytes
else
$resultRange = $httpRange[0] . '-' . $httpRange[1];
}
}
header("Content-Length: ". $resultLenght);
header("Content-Range: bytes " . $resultRange . '/' . $fileSize);
You can place it directly under your commented version or replace it!
With this version you can keep the feature that users can resume paused downloads.
This could save some traffic because if the user can not resume the download he/she has to download the whole file again.
How do you check the value of $_SERVER['HTTP_RANGE'] ?
-Edit-
If your are willing to test some code try this one:
// HTTP Range - see RFC2616 for more informations (http://www.ietf.org/rfc/rfc2616.txt)
$httpRange = 0;
$newFileSize = $fileSize - 1;
// Default values! Will be overridden if a valid range header field was detected!
$resultLenght = (string)$fileSize;
$resultRange = "0-".$newFileSize;
// We support requests for a single range only.
// So we check if we have a range field. If yes ensure that it is a valid one.
// If it is not valid we ignore it and sending the whole file.
if(isset($_SERVER['HTTP_RANGE']) && preg_match('%^bytes=\d*\-\d*$%', $_SERVER['HTTP_RANGE'])) {
// Let's take the right side
list($a, $httpRange) = explode('=', $_SERVER['HTTP_RANGE']);
// and get the two values (as strings!)
$httpRange = explode('-', $httpRange);
// Check if we have values! If not we have nothing to do!
if(!empty($httpRange[0]) || !empty($httpRange[1])) {
// We need the new content length ...
$resultLenght = $fileSize - $httpRange[0] - $httpRange[1];
// ... and we can add the 206 Status.
header("HTTP/1.1 206 Partial Content");
// Now we need the content-range, so we have to build it depending on the given range!
// ex.: -500 -> the last 500 bytes
if(empty($httpRange[0]))
$resultRange = $resultLenght.'-'.$newFileSize;
// ex.: 500- -> from 500 bytes to filesize
elseif(empty($httpRange[1]))
$resultRange = $httpRange[0].'-'.$newFileSize;
// ex.: 500-1000 -> from 500 to 1000 bytes
else
$resultRange = $httpRange[0] . '-' . $httpRange[1];
}
}
header("Content-Length: ". $resultLenght);
header("Content-Range: bytes " . $resultRange . '/' . $fileSize);
You can place it directly under your commented version or replace it!
With this version you can keep the feature that users can resume paused downloads.
This could save some traffic because if the user can not resume the download he/she has to download the whole file again.
-
a.agostini
- Phoca Newbie

- Posts: 5
- Joined: 10 Jun 2011, 15:34
Re: PDF SECURED file corrupted on download
Hello,
You are right. I'm wrong!
I have check the isset($_SERVER['HTTP_RANGE'] and it is 'false', so my script use else code. I used anothor similar function.
So, in my case there are three code line under suspect:
} else {
$newFileSize = $fileSize - 1;
header("Content-Length: ".(string)$fileSize);
header("Content-Range: bytes 0-".$newFileSize . '/'.$fileSize);
}
Why decrement $filesize by 1 in this case?
I think I resolved only commented out these 'else' lines.
AA
You are right. I'm wrong!
I have check the isset($_SERVER['HTTP_RANGE'] and it is 'false', so my script use else code. I used anothor similar function.
So, in my case there are three code line under suspect:
} else {
$newFileSize = $fileSize - 1;
header("Content-Length: ".(string)$fileSize);
header("Content-Range: bytes 0-".$newFileSize . '/'.$fileSize);
}
Why decrement $filesize by 1 in this case?
I think I resolved only commented out these 'else' lines.
AA
-
SonRiab
- Phoca Professional

- Posts: 258
- Joined: 02 Jun 2011, 09:29
- Contact:
Re: PDF SECURED file corrupted on download
You decrease the filesize, because the range is beginning with 0 which is actual the first 1 byte of data.
So you have filesize - 1 byte data left.
This is defined by RFC2616 http://www.w3.org/Protocols/rfc2616/rfc ... l#sec14.16.
So this is actual ok but I have no idea why your pdfs are corrupted by these 5 lines of code.
Maybe the result of the filesize function some lines above is incorrect.
Can you check this?
-Edit-
Are the files accessible by the server so you can download them without using Joomla and PD?
If yes: Can you download them correctly?
So you have filesize - 1 byte data left.
This is defined by RFC2616 http://www.w3.org/Protocols/rfc2616/rfc ... l#sec14.16.
So this is actual ok but I have no idea why your pdfs are corrupted by these 5 lines of code.
Maybe the result of the filesize function some lines above is incorrect.
Can you check this?
-Edit-
Are the files accessible by the server so you can download them without using Joomla and PD?
If yes: Can you download them correctly?
-
a.agostini
- Phoca Newbie

- Posts: 5
- Joined: 10 Jun 2011, 15:34
Re: PDF SECURED file corrupted on download
Hi,
I have tries to comment out only the line:
header("Content-Length: ".(string)$fileSize);
in else block and all working correctly.
The filesize variable is the problem as you said.
I don't know how test it because it is in header.
I user Firebug for Mozilla but I cant' see anything.
Yes, the file is downloadable correctly by other way.
Thanks.
Alessandro
I have tries to comment out only the line:
header("Content-Length: ".(string)$fileSize);
in else block and all working correctly.
The filesize variable is the problem as you said.
I don't know how test it because it is in header.
I user Firebug for Mozilla but I cant' see anything.
Yes, the file is downloadable correctly by other way.
Thanks.
Alessandro
-
SonRiab
- Phoca Professional

- Posts: 258
- Joined: 02 Jun 2011, 09:29
- Contact:
Re: PDF SECURED file corrupted on download
So it is possible that the filesize function returns the wrong value.
It could also be possible that the path is wrong.
So we first try to get the filesize by calling a system command.
Could you please try this code to getting the filesize:
$fileSize = system("stat {$absOrRelFile} | awk '/Size/ {print $2}'");
Please comment the other line!
If this is not working maybe the path is wrong although I can not image why this could happen.
-Edit-
If you have access via ssh then you can create a php file with the following code
and run it in the command line with php test.php for example.
Or create it on your pc, upload it to your server and run it in the browser.
Now you can see the header of the download.
It could also be possible that the path is wrong.
So we first try to get the filesize by calling a system command.
Could you please try this code to getting the filesize:
$fileSize = system("stat {$absOrRelFile} | awk '/Size/ {print $2}'");
Please comment the other line!
If this is not working maybe the path is wrong although I can not image why this could happen.
-Edit-
If you have access via ssh then you can create a php file with the following code
Code: Select all
<?php
$cH = curl_init();
curl_setopt($cH, CURLOPT_URL, 'the download link');
curl_setopt($cH, CURLOPT_HEADER, 1);
curl_setopt($cH, CURLOPT_NOBODY, 1);
echo curl_exec($cH);
?>Or create it on your pc, upload it to your server and run it in the browser.
Now you can see the header of the download.