Welcome to WebmasterWorld Guest from 107.22.14.254

Forum Moderators: coopster & jatar k

Message Too Old, No Replies

How can I prevent the songs from being downloaded?

Is there any PHP way?

     
11:10 am on Mar 3, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I want to provide online music which I want the visitors to listen to and not download them. The website is all PHP and want to somehow control this. I don't know if there is a simpler way of preventing my mp3 files from being downloaded.

Habtom

11:34 am on Mar 3, 2006 (gmt 0)

5+ Year Member



use a header to redirect them to file with out revealing its location:::

something like
<?php

//Path to where the requested files should be(needs trailing slash);
$path="downloads/";
$filetype="mp3";

//Get the requested file
$file = $_GET['file'];

//Stop the script if file selected is invalid
if( ( !$file ) or (!file_exists( $path . $file ) ) ) {
die( "File wasnt set or it didnt exist" );
}

//Set the filename
header("Content-Disposition: attachment; filename=\"$file\"");

//Set the content type
header('Content-type: '.$filetype);

//Read the file into the browser.
readfile( $path . $file );

?>
then use link
<a href="download.php?file=mp3.mp3">Click me</a>

This is a very bare bones version of the script...

12:08 pm on Mar 3, 2006 (gmt 0)

10+ Year Member



But with that script, you could just save the file that is output to the browser, so from what habtom is saying that would be useless surely?

I think that you would need to play the music through somesort of flash music player, and detect the referrer of the requests. If the user tried to access the file directly then they could be denied access.

You could use philestine's script, but just with a few extra lines of code to check the referrer.

Chris

12:25 pm on Mar 3, 2006 (gmt 0)

10+ Year Member



Here's philestine's script with the extra lines.

<?
$path = "home/musicdir/"; //MAKE SURE IT IS OUTSIDE OF THE PUBLIC DOMAIN!

$file = $_GET['file'];

if( (!$file ) or (!file_exists( $path . $file ) ) ) {
die( "File wasnt set or it didnt exist" );
}

$ref = $_SERVER['HTTP_REFERER'];
$domain = 'http://example.com/'; // your domain

if(substr($ref,0,strlen($domain))!= $domain !isset($ref) $ref == ''){
die('No stealing music!');
}

header("Content-Disposition: attachment; filename=\"$file\"");
header("Content-type: audio/mpeg"); //mp3 contenttype
header("Cache-Control: no-cache, must-revalidate"); //The page must not be stored in the cache
header("Expires: Mon, 01 Jan 2000 00:00:00 GMT");
readfile( $path . $file );

?>

12:29 pm on Mar 3, 2006 (gmt 0)

10+ Year Member



How abt using hot linking feature in cpanel to protect downloads or songs from leeching?
2:03 pm on Mar 3, 2006 (gmt 0)

5+ Year Member



sorry i misread the topic i assumed as i often do that you were selling the mp3's, If it was me i would use a flash based system.
7:24 pm on Mar 3, 2006 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member



<?
$path = "home/musicdir/"; //MAKE SURE IT IS OUTSIDE OF THE PUBLIC DOMAIN!
$file = $_GET['file'];

if( (!$file ) or (!file_exists( $path . $file ) ) ) {
die( "File wasnt set or it didnt exist" );
}

$ref = $_SERVER['HTTP_REFERER'];
$domain = 'http://example.com/'; // your domain

if(substr($ref,0,strlen($domain))!= $domain !isset($ref) $ref == ''){
die('No stealing music!');
}

header("Content-Disposition: attachment; filename=\"$file\"");
header("Content-type: audio/mpeg"); //mp3 contenttype
header("Cache-Control: no-cache, must-revalidate"); //The page must not be stored in the cache
header("Expires: Mon, 01 Jan 2000 00:00:00 GMT");
readfile( $path . $file );

?>

I think your logic is also wrong to implement the exact solution. what if i use www.validdomain.com/music/song.mp3 URL directly? it will give me popup asking to save it. your script will allow bacause I am coming from his domain name but i am downloading it not listening, I hope i am on the right track.

11:58 am on Mar 4, 2006 (gmt 0)

10+ Year Member



$path = "home/musicdir/"; //MAKE SURE IT IS OUTSIDE OF THE PUBLIC DOMAIN!

By placing the original mp3 files OUTSIDE of the web directory, it would not be possible to access them from the web. For example, on a linux server if the default web directory is /home/user/public_html/ then placing the mp3 files in /home/user/mp3/ would protect them from web access.

The only way to get to the files would be using php script, and furthermore they would have to be requested from another page on the site (Flash mp3 player etc.). If you did visit the script DIRECTLY file.php?file=track.mp3 then your request would have NO REFERERING URL, and therefore be denied.

6:52 pm on Mar 4, 2006 (gmt 0)

10+ Year Member



ill get back on this to u 2mrw, made a excellent solution myself :)
bascilly it works like this:
<embed bla bla src="http://www.domain.com/play.php?song=some file name.mp3>">
even reads ID tags etc etc

and no, the mp3s are in another dir :p

12:01 pm on Mar 7, 2006 (gmt 0)

10+ Year Member



ok, ive done it like this:

in the file that has to play the song, Ive embedded a mediaplayer. Ofcourse you may choose to do otherwise, but Ill just give you the code anyway, so you can seen the way it works

<OBJECT ID="mediaPlayer" CLASSID="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95" CODEBASE="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701" STANDBY="Loading Microsoft Windows Media Player components..." TYPE="application/x-oleobject">
<PARAM NAME="fileName" VALUE="http://www.site.com/dir1/play.php?song=<? echo $song;?>">
<PARAM NAME="animationatStart" VALUE="true">
<PARAM NAME="transparentatStart" VALUE="true">
<PARAM NAME="autoStart" VALUE="true">
<PARAM NAME="showControls" VALUE="false">
<EMBED type="application/x-mplayer2" pluginspage = "http://www.microsoft.com/Windows/MediaPlayer/" SRC="http://www.site.com/dir1/play.php?song=<? echo $song;?>" name="MediaPlayer1" width="0" height="0" AutoStart="true" ShowControls="0" ShowStatusBar="0" ShowDisplay="0">
</OBJECT>

in the play.php file, you hardcode the directory where the actual files are (not in dir1 if you want to make this have any sense at all)
then set directory indexing of for that dir or it wont work after all; the file names can still be selected by a spider or whatever

this is what my play.php file looks like, heavily modified from an example found on php.net:

<?
$file = $_GET['song'];
if (!empty($file)){
$banned_strings = array('../','./','..\\','.\\');

foreach($banned_strings as $str){ //delete all dangerous input
$file = str_replace($str, '', $file);
}

//get random song
$orig_dir = getcwd();//retrieve original working dir
chdir($_SERVER['DOCUMENT_ROOT']);
$path = 'dir2/dir3/';//set path to folder with mp3 songs
$play_file = $path.$file;
$content_len = @intval(filesize($play_file));

if (@fopen($play_file, 'r')){
header("Pragma: public");
header("Expires: 0");
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: pre-check=0, post-check=0, max-age=0', false);
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
$browser = $_SERVER['HTTP_USER_AGENT'];

if (preg_match('/MSIE 5.5/', $browser) preg_match('/MSIE 6.0/', $browser)) {
header('Pragma: private');
header('Cache-control: private, must-revalidate'); // the c in control is lowercase, didnt work for me with uppercase
header("Content-Length: ".$content_len); // MUST be a number for IE
header('Content-Type: audio/mpeg');
header('Content-Disposition: inline; filename="'.$play_file.'"');
}else{
header("Content-Length: ".$content_len);
header('Content-Type: audio/mpeg');
header("Content-Disposition: inline; filename=".$play_file."");
}
header('Content-Transfer-Encoding: binary');

if ($play_file = @fopen($play_file, 'r')) {
while(!feof($play_file) && (connection_status()==0)) {
print(fread($play_file, 8*1500));//note, this should be set to $content_len but does not work for me somehow :S
flush();
//usleep(100000); // can be used to limit download speed
}
fclose($play_file);
}
}else{
echo "</br>error opening file $file";
}
chdir($orig_dir);//change back to dir script runs in
}//end of script?>

4:28 am on Mar 9, 2006 (gmt 0)

10+ Year Member



Hello Guys,
Iam having same problem.but i need like files should only able to download when reffered from my site.I think by somehow philestine and chris given solution...But there is still problem in it .they gave URL like
" $domain = 'http://example.com/'; // your domain "

what if some one open sitelike http://www.example.com will it work?

Please fix these problem.

Thanks for all,

5:29 am on Mar 9, 2006 (gmt 0)

10+ Year Member



I modified code ...can u guys plz check it whether it is correct..

<?
$path = "home/musicdir/"; //MAKE SURE IT IS OUTSIDE OF THE PUBLIC DOMAIN!
?>
<?
$domain = 'http://example.com/'; // your domain
$domain1 = 'http://www.example.com/'; // your domain

if($domain) {

$file = $_GET['file'];

if( (!$file ) or (!file_exists( $path . $file ) ) ) {
die( "File wasnt set or it didnt exist" );
}

$ref = $_SERVER['HTTP_REFERER'];

if(substr($ref,0,strlen($domain))!= $domain ¦¦!isset($ref) ¦¦ $ref == ''){
die('No stealing music!');
}

header("Content-Disposition: attachment; filename=\"$file\"");
header("Content-type: audio/mpeg"); //mp3 contenttype
header("Cache-Control: no-cache, must-revalidate"); //The page must not be stored in the cache
header("Expires: Mon, 01 Jan 2000 00:00:00 GMT");
readfile( $path . $file );
}
elseif($domain1) {

$file = $_GET['file'];

if( (!$file ) or (!file_exists( $path . $file ) ) ) {
die( "File wasnt set or it didnt exist" );
}

$ref = $_SERVER['HTTP_REFERER'];

if(substr($ref,0,strlen($domain1))!= $domain ¦¦!isset($ref) ¦¦ $ref == ''){
die('No stealing music!');
}

header("Content-Disposition: attachment; filename=\"$file\"");
header("Content-type: audio/mpeg"); //mp3 contenttype
header("Cache-Control: no-cache, must-revalidate"); //The page must not be stored in the cache
header("Expires: Mon, 01 Jan 2000 00:00:00 GMT");
readfile( $path . $file );
}
else { echo "invalid domain"; }

?>

8:34 am on Mar 9, 2006 (gmt 0)

10+ Year Member



:p
2:23 pm on Mar 9, 2006 (gmt 0)

10+ Year Member



This script is not working...please fix it .
11:14 pm on Mar 9, 2006 (gmt 0)

10+ Year Member



look dude, this is no place where people normally hand you entire scripts that work

I posted a perfectly fine example, which works for what you need
the meaning of this place is for all people to learn from eachother
you simply want us to do your work for you, given the attitude of your last post

thats just not gonna cut it
put some effort into it, I dont think many people will be very willing to help you after your last post, I certainly am not

3:40 am on Mar 10, 2006 (gmt 0)

10+ Year Member



iam exteremely Sorry man...I wont repeat like this anymore.
12:07 pm on Mar 11, 2006 (gmt 0)

10+ Year Member



Got to agree with dmmh. "Please help me fix it" would be a bit more like it.

Anyway, if you put all your domains and subdomains into an array, and then check each one against the referrer it should work.

This code works, but it might not be the easiest way of doing it:

<?
$path = "home/musicdir/";

$file = $_GET['file'];

if( (!$file ) or (!file_exists( $path . $file ) ) ) {
die( "File wasnt set or it doesn't exist" );
}

$ref = $_SERVER['HTTP_REFERER'];
$domains = array(
'http://example.com/',
'http://www.example.com/',
'http://music.example.com/',
'http://etc.example.com/');

$length = array();

foreach($domains as $i => $url){
$length[$i] = strlen($url);
}
$error = false;

foreach($domains as $i => $url){
if(substr($ref,0,$length[$i])!= $url){
$error = true;
}
}
if($error or!isset($ref) or $ref == ''){
die('No Stealing Music!');
}

header("Content-Disposition: attachment; filename=\"$file\"");
header("Content-type: audio/mpeg"); //mp3 contenttype
header("Cache-Control: no-cache, must-revalidate"); //The page must not be stored in the cache
header("Expires: Mon, 01 Jan 2000 00:00:00 GMT");
readfile( $path . $file );

?>

Chris

 

Featured Threads

Hot Threads This Week

Hot Threads This Month