Reputation: 40076
I am serving .pdf docs to users through anchor tags. However, serving the full document path through the anchor tag exposes the server directory structure. Here is a sample doc location: mydomain.com/_webstuff/docs/proj03/sub01/111.pdf
I am attempting to create an .htaccess that accepts the "proj03/sub01/111.pdf" portion, and redirects to the above full URI.
The HTML, then, would look like this:
View <a href="proj03/sub01/111.pdf">111.pdf</a>
This is the unworking htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /fetch.php?f=$1
FETCH.PHP looks like this:
<?php
$f = $_GET['f'];
echo '<meta HTTP-EQUIV="REFRESH" content="0; url=_webstuff/docs/' . $f . '">';
I'm sure there's a much better way to do this.
EDIT: MEA CULPA. My error was this: I had to add a slash before the url in FETCH.PHP, as follows:
NEW FETCH.PHP
<?php
$f = $_GET['f'];
echo '<meta HTTP-EQUIV="REFRESH" content="0; url=/_webstuff/docs/' . $f . '">';
HOWEVER... My design is still wrong, because the document shows the true document path in the address bar. That is, when the .pdf document is displayed in the browser window, the fully qualified URI is there for all to see. I'm too clever by half. Loop back to my earlier comment: "I'm sure there's a much better way to do this."
Suggestions?
Upvotes: 1
Views: 1687
Reputation: 56
If you want to just match some patterns, this would do.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z0-9]*)/([a-z0-9]*)/([a-z0-9]*).pdf$ /_webstuff/docs/$1/$2/$3.pdf [NC,L]
This would match /projNum/subNum/filename.pdf
and rewrite the URI. For this sort of rewrite, the viewer wouldn't see the rewritten URI.
Upvotes: 4
Reputation: 472
If you don't want to display your URL structure, then you should avoid doing redirects completely.
What I would do personally is use the FETCH.PHP page to force a download on the file - and just use the readfile()
function in PHP to grab the information.
Here's an example of what I would put on the FETCH.PHP page (obviously this would need some conditionals and checks and what-not, but it gives you an idea)
$pdf_filename = "name-of-pdf-user-will-see.pdf";
ob_end_clean();
ob_start();
header('Pragma: public');
header('Expires: 0');
header ("Cache-Control: max-age=0, must-revalidate, post-check=0, pre-check=0");
header('Content-Description: File Transfer');
header('Content-Transfer-Encoding: binary');
header("Content-Type: application/octet-stream");
header('Content-Length: ' . filesize(realpath(dirname(__FILE__))."_webstuff/docs/".$f));
header("Content-Disposition: attachment; filename=\"$pdf_filename\"");
readfile(realpath(dirname(__FILE__))."_webstuff/docs/".$f);
ob_flush();
exit;
The realpath(dirname(__FILE__))
portion just allows you to get the server folder structure to that file - you should add dirname()
around it until you get to the root of your web folder.
With this method you don't need to display the path to the file at all, and clicking the anchor link on the page won't do any redirects, it will just force download the file, user won't even know they're being re-routed.
Upvotes: 2
Reputation: 91742
I don't know why you need to hide your directory structure, but an easy solution without php would be to make a symlink on the root of your downloads section.
In linux - while in the web-root directory - that would be something like:
$ ln -s _webstuff/docs downloads
and then all your site-structure below _webstuff/docs
would be available below downloads
as well.
This way, you could even have the sensitive directories outside of the web-root, which is always the safest solution, and just make a symlink to the directories that need to be available via http.
Upvotes: 1