How indirect file urls works? - php

A url is the direct link towards a resource as per my knowledge. I have experience with Apache and PHP, and I know that using .htaccess file, one may set a default file (like index.php) for a location where no need to provide end file name.
But for file links, one need to provide a direct link, having filename and extension like somedomain.com/file.txt. But recently I found some links, especially download links, that dont have a url with filename and extension.
For example, i tried to grab direct .mp4 file url for this youtube video www.youtube.com/watch?v=W1- L58y2uf4 , of resolution 1080p HD. Then I got a url (using clipconverter.cc) like;
http://r9---sn-25g7sne7.c.youtube.com /videoplayback?source=youtube& ip=2001:41d0:8:1f2b:3a0e:6049:6b4f:92 e9&expire=1378905654& sparams=cp,id,ip,ipbits,itag,ratebypass,sou rce,upn,expire&ipbits=48& upn=BgsjQ8lS424& cp=U0hWTVlLU19KTkNONl9RRVdHOkZIZ0 diYTFXLWRJ&key=yt1& id=5b5f8be7ccb6b9fe&mt=1378881529& ratebypass=yes&itag=37&sver=3& mv=m&fexp=903309,919391,910207,91 4071,916612,924606,929117,929121,92 9906,929907,929922,929127,929129,92 9131,929930,936403,925726,936310,92 5720,925722,925718,925714,929917,90 6945,929933,920302,906842,913428,92 0605,919811,913563,919373,930803,90 8536,938701,931924,936308,909549,90 0816,912711,904494,904497,939903,90 0375,900382,934507,907231,936312,90 6001&ms=au& signature=1DDD3BB4A46816E27075ADF1 3C84B810AD1DF72D.C9B4290CE7F0806A 3174E65DE3920F3AFDB06833& title=Kilimanjaro+-+ROBOT+%282010%29 +%2AHD%2A+1080p+%2ABluRay%2A+ Music+Video
The browser downloads the file perfectly. How this works? Where is the filename and extension in this link?

Please repeat:
URLs !== files
URLs !== files
URLs !== files
When requesting a URL, your browser/HTTP client/whatever is sending an HTTP request to a web server, requesting the URL. The web server is free to respond to this request in any way it pleases. URLs have nothing at all to do with files on a hard disk. It's just a convenient default configuration that web servers look for files of the same name as the requested URL and serve those. But it could do anything else it wanted as well. It can start up a shell script which gets the requested URL passed as an argument, which in turn can output anything it wanted. The web server may be a Java application which processes the requested URL internally and responds with some content. The server could be anything and everything at all and it can respond by doing anything it wants to. A web server is just an application that listens on port 80 (or elsewhere) and answers incoming HTTP requests. The file system doesn't have to be involved at all.

You're probably calling a script which depending on your parameters finds the file you want and before sending it, it modifies the headers to make your browser treat the file as a video file (and download it) and not as a regular html document
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: binary");

Related

How do I prevent a CDN Location redirect for download from Azure from altering the browser location?

I'm using the PHP Azure library to create a SAS token for delivering files (File Storage, not blob, and not public) to an authenticated user of a site after they click a link. The link leads to a PHP page where I create the SAS and then issue a Location: header to invoke the downloads. There are no known issues with anything leading up to the final completion of the download.
In the attached image the steps 1-4 are repeated.. one for each file selected.
The issue is that as the URLs are external to the site (CDN) the Location: $url + sas is used. This alters the browser location but is not reflected in the browser... the headers push the file as an attachment.
As mentioned, he user can continue to click other download links on the originating page and they work fine (this is desirable) however the first time they select any link on that same page to go elsewhere on the originating page/site (shown as clicking "home" in the example, the browser true location is revealed (accountname.file.core.windows.net/etc ) and the user gets a Resource not found error originating from the Azure File Storage server. (shown under the chart)
7.10.2017 added this image to illustrate the process used:
Link to SAS process chart
I'm slightly at a loss on how to push a URL download from a CDN without the browser location getting "reset" in this manner. I've done this from local servers/files many times but the Location: $url/SAS aspect is a different dynamic. In my mind, this should behave no differently than pointing the browser to a publicly accessible URL with an EXE that pushes the download, and still allows the user to say on the originating site. I'm starting to think this should be a redirect instead of Location but I haven't found very many Azure/SAS/File Storage examples to back this up. I have to be missing something simple here but it's escaping me.
I am not sure if I get it correctly, you seem to wanna download the file from Azure storage without changing address in the browser by using PHP script.
Basically, you can use file_get_contents() function as below to achieve this.
header('Content-Type: application/octet-stream');
header("Content-Disposition: attachment; filename=$filename");
$response = file_get_contents($SASUri);
echo $response;

Concerns on file permissions

I have a video file and I have commanded the server through htaccess to redirect when requesting the file url. However, I wonder if someone remote can use php functions such as file_get_contents to access the video file since I have only one server and I am not sure whether remote servers can access to it. In my own server I can access to it. Yet I don't want others to access the video file unless authenticated by php.
If you really do not want people to get that video why have it in public web folder? Just put it somewhere else and problem solved. What is the use case of this?
That said, if your redirect is working correctly, the file will not be served. file_get_contents() is still requesting the file from your webserver so it can't just magically ignore the redirect.
If you want to be able to download that file but prevent everyone else from doing it, put the file out of your www root and have a php script to retreive it. You can set up basic http authentication to prevent anyone accessing the php script.
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: Binary")
header("Content-disposition: attachment; filename=\"myvideo.avi\"");
echo file_get_contents("/directory/out/of/www/that/is/readable/by/www-data");

PHP output internal server file?

On my server I have a directory with music files, generally in .mp3 format. I'm writing a web application to search for and play these tracks.
All the files are stored, with their absolute server path, artist, album and title info in a MySQL database.
What I want to do is have a PHP file that "outputs" an mp3 file on the server that would normally be inaccessible from the web. So, this is what I want to achieve:
client requests play.php?id=10
PHP gets absolute server path from MySQL database where ID = 10
PHP outputs the file (which would really be at e.g. '/home/user/files/no_web/mp3/Thing.mp3')
To the client, it looks like there is an mp3 file called http://myserver.com/play.php?id=10 and it starts to play.
I'm sure this sort of thing is possible, just not sure how. Thanks in advance :)
You need to send correct content-type header and then just output the file:
header('Content-type: audio/mpeg3');
readfile('filename.mp3');
For reading the file and sending it, you can use the readfile function.
For setting the mime-type, so the browser actually knows what type of file is sent by the webserver, use the header function like:
header('Content-Type: audio/mpeg');
Additionally, you may also want to set the Content-Length HTTP header.
header('Content-Length: ' . filesize($filepath) );
If all you're trying to do is let the user download the mp3, just use the readfile command which will read the mp3 file and pass it along to the client. However you need to make sure to set the mime-type correctly.

PHP - Protecting digital Downloads

I'm trying figure out how I can protect digital downloads in PHP. Just need some general directions so I can start my research. I don't seem to be able to find anything useful.
I want to make files available for my users to download but don't want them to be able to directly access a download folder. Also, I want the download link to be available only for set period of time or a single download.
Could some one point me in the right direction?
The best way is to delegate the download managment after your check to the mod for apache
x_sendfile
https://tn123.org/mod_xsendfile/
Usage:
<?php
...
if ($user->isLoggedIn())
{
header("X-Sendfile: $path_to_somefile");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$somefile\"");
exit;
}
?>
<h1>Permission denied</h1>
<p>Login first!</p>
Basically when you send the header X-Sendfile the mod intercepts the file and manages the download for you (the file can be located whenever you want outside the virtualhost).
Otherwise you can just implement a simple file download.php that gets the id of the file and prints the contents with readfile after the login check
Just some examples: You can place your files outside of the webserver's document root or in a directory that is protected by a .htaccess file with a "deny from all" rule; then you deliver the files by a custom PHP function that sets the correct headers (mime-type, filesize etc.) and returns the file.
You could create links with unique id's based on MD5 or SHA1 hashes - a mod_rewrite rule points the id to your PHP file, you lookup the id in the database and do your time checks, like
example.com/downloads/73637/a8d157edafc60776d80b6141c877bc6b
is rewritten to
example.com/dl.php?id=a8d157edafc60776d80b6141c877bc6b&file=73637
Here's an example of doing something you want with nginx and PHP:
http://wiki.nginx.org/HttpSecureLinkModule
"Secure Download Links", a PHP Script can be used to hide download url or rename download file, it has option for storing below web root and for files stored above webroot that is with absolute http urls also.

Renaming File on another server as user downloads it [2] - using PHP

I have asked this question today already but this time I want to know if I can achieve this via PHP since Javascript wasn't up to it.
I have a link to a file on another server. If i provide this link to my users the headers are pushed out to download that file from that server.
Is there a way for me to capture those headers and file and redirect the download to the user? I would like to do this so that I can change the filename of the download since it is
always 'file.zip'.
Is this possible with PHP?
Thank you for any help.
You can download the file to your server using curl and serve it correctly(with a Content-Disposition header). As long as you are using HTTP, there's no way to send just the header and let another server stream the content directly to the client.
You could do this, and you can do it in several ways.
1) (simple) copy the file to your server, and rename it. Point your download links to this copy.
2) (harder) Create a stub php file, called , read the file from the remote server within php, and stream the content to the script output. This will need you to set appropriate headers, etc. as well as setting up your webserver to parse through PHP.
Seriously, I'd go with option 1. (assumes you have a legal right to serve the content, etc.)
Maybe you can use a script similar to the following one:
<?php
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://www.example.com/the_path/file.zip");
header('Content-Disposition: attachment; filename="alternate_filename.zip"');
exit();
?>

Categories