JavaScript doesn't parse when mod-rewrited through a PHP file? - php

If I do the following (this is the actual/direct path to the JavaScript file):
<script href="http://localhost/tpl/blue/js/functions.js" type="text/javascript"></script>
It works fine, and the JavaScript parses - as its meant too.
However I'm wanting to shorten the path to the JavaScript file (aswell as do some caching) which is why I'm rewriting all JavaScript files via .htaccess to cache.php (which handles the caching).
The .htaccess contains the following:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^js/(.+?\.js)$ cache.php?file=$1 [NC]
</IfModule>
cache.php contains the following PHP code:
<?php
if (extension_loaded('zlib')) {
ob_start('ob_gzhandler');
}
$file = basename($_GET['file']);
if (file_exists("tpl/blue/js/".$file)) {
header("Content-Type: application/javascript");
header('Cache-Control: must-revalidate');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
echo file_get_contents("tpl/blue/js/".$file);
}
?>
and I'm calling the JavaScript file like so:
<script href="http://localhost/js/functions.js" type="text/javascript"></script>
But doing that the JavaScript doesn't parse? (if I call the functions which are within functions.js later on in the page they don't work) - so theirs a problem either with cache.php or the rewrite rule? (because the file by itself works fine).
If I access the rewrited file-> http://localhost/js/functions.js directly it prints the JavaScript code, as any JavaScript file would - so I'm confused as to what I'm doing wrong...
PS: I've tried changing the mime/content-type to text/javascript, aswell as clearing the browser cache - but no luck.
All help is appreciated! :)

I think your solution is ridiculus given your stated aims. Keep it simple.
I'm wanting to shorten the path to the
JavaScript file
Why? What's the problem with long paths?
(aswell as do some caching)
Good aim. But have you seen mod_expires? Enable it then stick this in your .htaccess
<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType text/javascript "access plus 1 days"
</IfModule>
Done.
And also, Apache serving a static file is so so much faster than apache starting up an entire PHP process which then serves a static file, not to mention (as you are finding out) less error prone.
Simplicity rules!

The content-type should be text/javascript, not application/javascript.

Be sure to send the correct content-type header from cache.php, e.g. with
header('Content-Type: text/javascript');
This is required because your webserver thinks he's serving a PHP script and by configuration it's told that the default output of such a script is text/html or text/plain. Therefore it adds one of these content-types unless you send one yourself from the script.

Related

Disguising .pdf extension using .htaccess avoiding cycling

I have a little bit stupid necessity to disguise links to PDF files as PHP files with the PDF filename as a parameter.
Something like:
Client requests xxxx.pdf file.
Server receives request but instead of returning xxxx.pdf goes to yyyy.php or whatever extension.
yyyy.php has an iframe in which the PDF file is loaded.
The thing is that I managed to do point 2. but when I try to do point 3. it either cycles or doesn't locate the file.
I was thinking of having a custom extension to "simulate" another file in order to not cycle but it's still cycling.
I have the following .htaccess:
AddType application/pdf .view
RewriteRule ^(.*)\.pdf$ yyyy.php?filename=$1 [L]
RewriteRule ^(.*)\.view$ $1.pdf [L]
The thing is that it cycles and I get nowhere.
I am not really good with .htaccess, so where am I doing this wrong?
You probably need to add something to prevent the referer for yyyy.php from getting rewritten back to the php file. Add this before your yyyy.php rule:
RewriteCond %{HTTP_REFERER} !yyyy\.php
Note that referers can be forged, so this is one way people will be able to bypass the yyyy.php file.
I found it easier to just redirect when I detect a .pdf extension.
So I basically did this:
.htaccess detects a PDF extension and redirects to a php file passing the filename without extension as a parameter.
The php file uses the filename and renders the PDF using header and readfile to avoid conflicts with .htaccess.
Something like that:
.htaccess
RewriteRule ^(.*)\.pdf$ /pdfreader/$1 [L,R=302,NC]
RewriteRule ^pdfreader/(.*)?$ pdfreader.php?file=$1 [L,NC]
pdfreader.php
$file = $_GET["file"].".pdf";
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $file . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
header('Accept-Ranges: bytes');
#readfile($file);

Browser Not Interpreting .css File when using AddType .css in .htaccess

I have a very interesting problem related to Deflate Compression, Apache (htaccess), and CSS files.
I have two CSS files on my server. One is called styles.php and has dynamic values added based on database values through mod_rewrite in the styles/ directory (it is rewritten from styles.php to site.css and there is a text/css header at the beginning of the file). I also have a regular old css file with static content that doesn't change in the same directory called styles.css.
I've wanted to add compression to my site so I added the following line to start compressing my css and js files. I added this to the root_directory for my website.
<ifModule mod_deflate.c>
<filesMatch "\.(js|css)$">
SetOutputFilter DEFLATE
</filesMatch>
</ifModule>
Well initially that didn't work. So I changed this line in the root htaccess file from this to the next thing. (this code below is located at the top of the file)
AddType application/x-httpd-php5 .html .php
AddType application/x-httpd-php5 .html .php .js .css
Then my js and one of the css files started to be compressed (verified with YSlow.....yay!). The odd thing was the css file that was being rewritten was being compressed (the styles.php file) but the styles.css file (the static one) was no longer being read by the browser. As soon as I deleted ".css" from that AddType line the browser started reading the file again and my css returned to normal, however it was no longer being compressed through apache.
Any thoughts on why a static css file is not being read by the browser if I add the type? I tried it with just text/css instead of .css and it was not compressing the file (but the browser interpreted it).
UPDATE:
I added this to the root htaccess file. We have compressed, interpretted sweetness now.
<filesMatch "\.css$">
FileETag None
<ifModule mod_headers.c>
Header set Content-type "text/css"
</ifModule>
</filesMatch>
When you run a CSS file through the PHP pre-processor, PHP will automatically output it as a text/html file, via default headers, since you're not manually specifying it. So really, your browser is receiving a file with a .css extension which has headers claiming it's an HTML file, so it's trying to interpret it as HTML rather than CSS.
If your CSS file actually needs to be run as PHP and there is PHP in it, you need to re-issue the appropriate file type so when it output, it's still CSS:
<?php
header('Content-type: text/css');
?>
You can't just send a CSS file through PHP and expect it to work exactly the same. If you're not actually pre-processing it with PHP, then you shouldn't be sending it through there.
As for the deflation issue, I could never actually get mod_deflate to work personally (no idea why). I had to use mod_gzip instead.

Change http-header of linked files without explicit download script (in an own file)

I want to force the browser to download all files linked inside a RSS-Feed, that is created by a php-script.
Therefore I need to change the HTTP-headers of these files and set
header("Content-Disposition: attachment; filename=$file");
(and maybe also some other changes).
At the moment I try to do this using a download script, that sets these parameters.
However, the disadvantage of this method is, that I have to link to "download.php" instead of "target.file", which is somehow misleading for the user. Besides, I have to reveal the internal file path to the user or use quite a lot of GET-variables instead.
It would be much better if it was possible to change the HTTP-headers inside the script that generates the RSS-Feed. Is there a way to achieve this?
You can't change the headers from inside the RSS feed. You could, however, hide the download.php part with some rewrite magic:
RewriteEngine on
RewriteRule ^download/.*$ /download.php?file=$1 [L]
This would cause any URL starting with /download/ to be run through your download script:
/img/foo.jpg - normal file
/download/img/foo.jpg - force a download
You could do a similar thing without the PHP too:
RewriteEngine on
RewriteRule ^download/.*$ /$1 [L]
<Location /download>
Header add Content-Disposition "attachment"
</Location>

How to prevent PHP files from being downloaded? And what are some ways someone can download them?

How do i prevent php files from being downloaded "illegally" like through the browser. And what are some ways someone can use to download the php files?
You can't really avoid files from being downloaded if your application is not secure. The following example allows a malicious user to view any file on your server:
<?php
readfile($_GET['file']);
?>
If you want to prevent Apache from exposing the source code if something is wrong with PHP, add this in your httpd.conf / .htaccess:
# In case there is no PHP, deny access to php files (for safety)
<IfModule !php5_module>
<FilesMatch "\.(php|phtml)$">
Order allow,deny
Deny from all
</FilesMatch>
</IfModule>
# the following should be added if you want to parse .php and .phtml file as PHP
# .phps will add syntax highlighting to the file when requesting it with a browser
<IfModule php5_module>
AddType text/html .php .phtml .phps
AddHandler application/x-httpd-php .php .phtml
AddHandler application/x-httpd-php-source .phps
</IfModule>
Under normal circumstances, nobody is able to download PHP source code, since it is executed on the server. The webserver recognizes PHP scripts and passes them to PHP. The result is then passed back to the browser of the requesting user. The situation you described can only be achieved, if the webserver configuration is really messed up.
<?php
header('Content-disposition: attachment; filename=http://www.victim.com/phpfile.php');
header('Content-type: application/pdf');
readfile('http://www.victim.com/phpfile.php');
?>
Under normal circumstances, nobody is able to download PHP source code (same as the other answer), But if you have a file with a different extension example : page1.bak and you have a page1.php, the page.bak gets downloaded if you just put in the url ht..//.../page1
I have confirmed this with PHP version 5.3.10-1ubuntu3.2 and Apache/2.2.22
In summary avoid putting your config or test files in the production directory unless you want them to be downloaded in raw state.
The Option Multiview should also be disabled in apache2.conf or httpd.conf to avoid defaulting to returning "near-like" filename.
You never download the php file from a web server running php. You can donwload the HTML delivered from the php like in this answer. You don't get php script you get HTML + JavaScript (if some)
<?php
header('Content-disposition: attachment;
filename=http://www.victim.com/phpfile.php');
header('Content-type: application/pdf');
readfile('http://www.victim.com/phpfile.php');
?>

How can I turn all rewrite x.php into x.css in a specific directory?

I need to rewrite all the files in a directory and essentially make their extentions css instead of php. I want to do with with a .htaccess file within that specific directory.
What is the correct method of doing so and are there any special PHP headers I need to set the ensure the file is read as a .css file correctly?
I think that you rather want requests of *.css to be rewritten internaly to *.php. So try this:
RewriteEngine on
RewriteRule ^(foo/.*)\.css$ $1.php [L]
While foo is here the specific directory.
You now should explicitly declare the output as text/css using the following at the begin of the PHP script:
<?php
header('Content-Type: text/css;charset=<your charset>');
Replace <your charset> by whatever charset/encoding you are using (probably ISO-8859-1 or UTF-8).
well they don't need a css extension if your just using them from with in your site. They just need to output the header Content-Type: text/css before rendering (I assume) the generated css. Similar sort of thing applies to other file types, if you have a php script that generates an image, you'd do it the same way, except you change the content type to image/png or jpeg or whatever.
However, if you want the outside would to see these generated css files as files with a css extension then mix what I've said with what Gumbo said.

Categories