homepage Welcome to WebmasterWorld Guest from 54.167.182.201
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
Forum Library, Charter, Moderators: coopster & jatar k

PHP Server Side Scripting Forum

    
How can I prevent the songs from being downloaded?
Is there any PHP way?
Habtom

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 11957 posted 11:10 am on Mar 3, 2006 (gmt 0)

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

 

philestine

5+ Year Member



 
Msg#: 11957 posted 11:34 am on Mar 3, 2006 (gmt 0)

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...

chriswragg

10+ Year Member



 
Msg#: 11957 posted 12:08 pm on Mar 3, 2006 (gmt 0)

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

chriswragg

10+ Year Member



 
Msg#: 11957 posted 12:25 pm on Mar 3, 2006 (gmt 0)

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 );

?>


phprockz

5+ Year Member



 
Msg#: 11957 posted 12:29 pm on Mar 3, 2006 (gmt 0)

How abt using hot linking feature in cpanel to protect downloads or songs from leeching?

philestine

5+ Year Member



 
Msg#: 11957 posted 2:03 pm on Mar 3, 2006 (gmt 0)

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.

phparion

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 11957 posted 7:24 pm on Mar 3, 2006 (gmt 0)

<?
$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.

chriswragg

10+ Year Member



 
Msg#: 11957 posted 11:58 am on Mar 4, 2006 (gmt 0)

$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.

dmmh

10+ Year Member



 
Msg#: 11957 posted 6:52 pm on Mar 4, 2006 (gmt 0)

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

dmmh

10+ Year Member



 
Msg#: 11957 posted 12:01 pm on Mar 7, 2006 (gmt 0)

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?>

phprockz

5+ Year Member



 
Msg#: 11957 posted 4:28 am on Mar 9, 2006 (gmt 0)

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,

phprockz

5+ Year Member



 
Msg#: 11957 posted 5:29 am on Mar 9, 2006 (gmt 0)

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"; }

?>

dmmh

10+ Year Member



 
Msg#: 11957 posted 8:34 am on Mar 9, 2006 (gmt 0)

:p

phprockz

5+ Year Member



 
Msg#: 11957 posted 2:23 pm on Mar 9, 2006 (gmt 0)

This script is not working...please fix it .

dmmh

10+ Year Member



 
Msg#: 11957 posted 11:14 pm on Mar 9, 2006 (gmt 0)

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

phprockz

5+ Year Member



 
Msg#: 11957 posted 3:40 am on Mar 10, 2006 (gmt 0)

iam exteremely Sorry man...I wont repeat like this anymore.

chriswragg

10+ Year Member



 
Msg#: 11957 posted 12:07 pm on Mar 11, 2006 (gmt 0)

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

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved