Connecting Tech Pros Worldwide Forums | Help | Site Map

PHP File Transfers ending early - help!

Guest
 
Posts: n/a
#1: Jul 17 '05
I am having a major problem with file transfers - they are ending early when the bandwidth tops-out.

Smaller files transfer just fine, but large files (12Mb+) can 'abort' the transfer after maybe 35%-60% complete. I'm sending large MP3 files from my website www.TheDoctorDementoShow.com but the users are pretty upset because the files are incomplete.

I assume tis has something to do with headers or starting/stopping as the bandwidth tops-out, but I really don;t know for sure.

Is there a way I can find out why this is happening, or build in some logic to make sure the transfers don't end early?

I'm using the following code:

<?php
function send_file($path, $name) {
set_magic_quotes_runtime(0);
if (!is_file($path)) return(FALSE);
$len = filesize($path);
$ctype="audio/mpeg";
header("Cache-control: public");
header("Pragma: public");
header("Content-Type: $ctype");
header("Accept-Ranges: bytes");
$header="Content-Disposition: attachment; filename=\"" . $name . "\";";
header($header);
header("Accept-Ranges: bytes");
header("Content-Length: " . $len);

if ($file = fopen($path, 'rb')) {
while(!feof($file)) {
set_time_limit(0);
$buf = fread($file, 1024*256);
set_time_limit(0);
echo($buf);
set_time_limit(0);
flush();
}
fclose($file);
}
return(1);
}
?>

Wayne R.




Senator Jay Billington Bulworth
Guest
 
Posts: n/a
#2: Jul 17 '05

re: PHP File Transfers ending early - help!


<wayne@gpnservices.com> wrote in
news:b7CdnXNoJb2LqpffRVn-ug@giganews.com:
[color=blue]
> I am having a major problem with file transfers - they are ending
> early when the bandwidth tops-out.
>
> Smaller files transfer just fine, but large files (12Mb+) can 'abort'
> the transfer after maybe 35%-60% complete. I'm sending large MP3 files
> from my website www.TheDoctorDementoShow.com but the users are pretty
> upset because the files are incomplete.
>
> I assume tis has something to do with headers or starting/stopping as
> the bandwidth tops-out, but I really don;t know for sure.
>
> Is there a way I can find out why this is happening, or build in some
> logic to make sure the transfers don't end early?[/color]

The aborted downloads may be happening due to a script timeout. Try
adding this line at the very top of your script:

set_time_limit(0);

This may solve the problem, or it may not. Your web host may have PHP
configured so that you can't override the script timeout.

hth

--

Bulworth : PHP/MySQL/Unix | Email : str_rot13('f@fung.arg');
--------------------------|---------------------------------
<http://www.phplabs.com/> | PHP scripts, webmaster resources
Mookstah
Guest
 
Posts: n/a
#3: Jul 17 '05

re: PHP File Transfers ending early - help!



<wayne@gpnservices.com> wrote in message news:b7CdnXNoJb2LqpffRVn-ug@giganews.com...[color=blue]
> I am having a major problem with file transfers - they are ending early when the bandwidth tops-out.
>
> Smaller files transfer just fine, but large files (12Mb+) can 'abort' the transfer after maybe 35%-60% complete. I'm sending large[/color]
MP3 files from my website www.TheDoctorDementoShow.com but the users are pretty upset because the files are incomplete.[color=blue]
>
> I assume tis has something to do with headers or starting/stopping as the bandwidth tops-out, but I really don;t know for sure.
>
> Is there a way I can find out why this is happening, or build in some logic to make sure the transfers don't end early?
>
> I'm using the following code:
>
> <?php
> function send_file($path, $name) {
> set_magic_quotes_runtime(0);
> if (!is_file($path)) return(FALSE);
> $len = filesize($path);
> $ctype="audio/mpeg";
> header("Cache-control: public");
> header("Pragma: public");
> header("Content-Type: $ctype");
> header("Accept-Ranges: bytes");
> $header="Content-Disposition: attachment; filename=\"" . $name . "\";";
> header($header);
> header("Accept-Ranges: bytes");
> header("Content-Length: " . $len);[/color]

why won't you just use readfile($path) in here
and set_time_limit([seconds to set]) at the top

[color=blue]
>
> if ($file = fopen($path, 'rb')) {
> while(!feof($file)) {
> set_time_limit(0);
> $buf = fread($file, 1024*256);
> set_time_limit(0);
> echo($buf);
> set_time_limit(0);
> flush();
> }
> fclose($file);
> }
> return(1);
> }
> ?>
>
> Wayne R.
>
>
>[/color]


Chung Leong
Guest
 
Posts: n/a
#4: Jul 17 '05

re: PHP File Transfers ending early - help!


<wayne@gpnservices.com> wrote in message
news:b7CdnXNoJb2LqpffRVn-ug@giganews.com...[color=blue]
> I am having a major problem with file transfers - they are ending early[/color]
when the bandwidth tops-out.[color=blue]
>
> Smaller files transfer just fine, but large files (12Mb+) can 'abort' the[/color]
transfer after maybe 35%-60% complete. I'm sending large MP3 files from my
website www.TheDoctorDementoShow.com but the users are pretty upset because
the files are incomplete.[color=blue]
>
> I assume tis has something to do with headers or starting/stopping as the[/color]
bandwidth tops-out, but I really don;t know for sure.[color=blue]
>
> Is there a way I can find out why this is happening, or build in some[/color]
logic to make sure the transfers don't end early?

My suggestion is to leave it to Apache to serve the files. Apache can do it
much more efficiently and it also lets users resume interrupted downloads.

To control access to these files from PHP, use an Apache rewrite map.


Wayne R.
Guest
 
Posts: n/a
#5: Jul 17 '05

re: PHP File Transfers ending early - help!


I'm not sure I follow what you’re referring to.

Let me explain why I'm using PHP as opposed to a direct link on the
page:

1.) I want to record the number of files and bytes each user’s
transfers

2.) I don't want them to know the file locations so that can just URL
into the files (they might do this to avoid #1 above or to direct-link
to my files on their web pages). A session validates that they are
logged-in and not a 'snatcher'.

It appears that a rewrite map can take care of #2, but I don't see how
to initiate the transfer using PHP once I've validated the session and
recorded the # of bytes.

Basically, the user clicks on a link that runs a PHP script with the
database record number. The script looks up the number, gets the
filename and folder, records the bytes and sends the file.

I'd love to allow resume! Also, I'd like to know if Apache will
compensate for bad packets (back up to the last good packet in the
file and then resume forward again). After all, bad packets do happen.

Wayne



On Wed, 9 Feb 2005 20:55:26 -0500, "Chung Leong"
<chernyshevsky@hotmail.com> wrote:
[color=blue]
><wayne@gpnservices.com> wrote in message
>news:b7CdnXNoJb2LqpffRVn-ug@giganews.com...[color=green]
>> I am having a major problem with file transfers - they are ending early[/color]
>when the bandwidth tops-out.[color=green]
>>
>> Smaller files transfer just fine, but large files (12Mb+) can 'abort' the[/color]
>transfer after maybe 35%-60% complete. I'm sending large MP3 files from my
>website www.TheDoctorDementoShow.com but the users are pretty upset because
>the files are incomplete.[color=green]
>>
>> I assume tis has something to do with headers or starting/stopping as the[/color]
>bandwidth tops-out, but I really don;t know for sure.[color=green]
>>
>> Is there a way I can find out why this is happening, or build in some[/color]
>logic to make sure the transfers don't end early?
>
>My suggestion is to leave it to Apache to serve the files. Apache can do it
>much more efficiently and it also lets users resume interrupted downloads.
>
>To control access to these files from PHP, use an Apache rewrite map.
>[/color]

Chung Leong
Guest
 
Posts: n/a
#6: Jul 17 '05

re: PHP File Transfers ending early - help!


"Wayne R." <audio_fod@yahoo.com> wrote in message
news:q7kl01hajci08g60fe5a1ue56ci35c3hk1@4ax.com...[color=blue]
> I'm not sure I follow what you're referring to.
>
> Let me explain why I'm using PHP as opposed to a direct link on the
> page:
>
> 1.) I want to record the number of files and bytes each user's
> transfers
>
> 2.) I don't want them to know the file locations so that can just URL
> into the files (they might do this to avoid #1 above or to direct-link
> to my files on their web pages). A session validates that they are
> logged-in and not a 'snatcher'.
>
> It appears that a rewrite map can take care of #2, but I don't see how
> to initiate the transfer using PHP once I've validated the session and
> recorded the # of bytes.
>
> Basically, the user clicks on a link that runs a PHP script with the
> database record number. The script looks up the number, gets the
> filename and folder, records the bytes and sends the file.
>
> I'd love to allow resume! Also, I'd like to know if Apache will
> compensate for bad packets (back up to the last good packet in the
> file and then resume forward again). After all, bad packets do happen.[/color]

When the user logs in, you write his/her session id to the rewrite map.
Something like this:

#this is a rewrite map write
2b712a3be45a35247d89a1edab5c92e0 dingo
2b712a3be45a35247d8921edab5c9e01 dingo

Then you use one RewriteCond to capture the session id from the cookie, and
another to perform a hash lookup from the map file using the session id a
key:

RewriteMap access txt:C:/access.map

RewriteCond %{HTTP_COOKIE} PHPSESSID=(\w+)
RewriteCond ${access:%1} dingo
RewriteRule /bogus/(.*) C:/Restricted/$1

The rewrite rule is only performed if the session id was written to the map
file earlier. Now, "bogus" isn't actually a folder in the document root.
When someone not authorized to download the file access the link, he/she
gets a 404 file not found error. For authorized users, the URL gets
rewritten to an actual location and the download can be downloaded.

Another way to implement this is to invert the logic, rewrite the URL so it
goes to "You have no access, haha!" page when the session id isn't present
in the map file:

RewriteCond %{HTTP_COOKIE} !PHPSESSID=(\w+) [OR]
RewriteCond ${access:%1} !dingo
RewriteRule /mp3/.* /noaccess.html

The easy way to record the number of bytes is to link to a PHP file, which
records the size of the file being downloaded, and have it redirect to the
URL of the MP3 file. Here, we're assuming the download will run to
completion.

The harder, more accurate way is to capture the download info using a piped
log. Have Apache pipe the log entries for MP3 file access to a CLI PHP
script. Get the session id from the cookie to figure out who the downloader
is, then save the info in the database.

All this is complete voodoo, of course. It's worth pursuing though because
it will make your site much more scalable. Another benefit is HTTP partial
retrieval, used for resuming aborted download. Some media players also use
partial retrieval to allow users to seek ahead during playback.


--
Project Wapache - http://wapache.sourceforge.net


Closed Thread