mod_rewrite to fix bad subdomain naming - php

I have a lot of uncleverly named folders on my server. They're called things like cdn-1 cdn3 img1 and so on. I have collected all of the files in these folders and put them in one folder, called cdn. Now, I don't want users to get a 404 when they try to access a file that is at cdn-3.website.com/file/img/1.jpg. Instead, is there a way to mod_rewrite this folder so that even if a user tries to access a file at, say, cdn-7382910731293.website.com/file/1.jpeg, it'll still work? This might be far fetched, but I have seen this be done before. The only working code I've found for a solution like this is for a single file, not a folder.
EDIT: This is what I've tried so far. It just won't work. What's the problem with it?
RewriteRule ^cdn([^/]*).1$ http://cdn.website.com/$1 [L]

Simplest thing would be to use .htaccess to redirect all 404 pages to a single PHP page, which would in turn check if such a file/image exists in your new cdn folder and either server it or display a valid 404 page.
Don't forget about headers when serving images etc., too ;-)

Maybe try make the sub-domains all point to the same place (wherever cdn.website.com points to) and then stick the following in the htaccess on that domain:
RewriteCond %{HTTP_HOST} ^(cdn-1|cdn1|img1|etc)\.website\.com
RewriteRule (.*) http://cdn.website.com/$1 [R=301,L]
That should work seamlessly, as long as the files otherwise would be in the same place. That is, only the host name is different and not also the file path after the host name. The RewriteCond is a regular expression I think, so you should be able to write it to match whatever you need.
I have used this method successfully to redirect an old domain to a new one, and to redirect example.com to www.example.com.

Related

Subdomains and related links on a website

I'm working on the complete structure of a web page, and I'm using directories to the url of the site the user can understand the site map, with categories and subcategories. for example. My homepage is www.mantarrayamx.com.
The page I am trying to load is www.mantarrayamx.com/services/seo, but for seo I am using the subdomain seo.mantarrayamx.com to access this directory directly.
I'm using third-party code, for example "font awesome". Unfortunately, the web page loading failed because the links are relative. I try entering in the CSS and JS including of third-party code and yet it still loads with errors. You can see the difference between loading by subdomain and loading by sub-directory here:
mantarrayamx.com/servicios/posicionamientoweb/
posicionamientoweb.mantarrayamx.com/
The question is:
What is the best way to use and manage subdomains and links (../img/)?
For example: How do you do google in your applications:
drive.google.com
mail.google.com
If I have to modify the .htaccess file, please give me an example.
As far as I get your question, you are accessing a subdirectory of your server by using a subdomain. On this subdomain, your data is in the root-directory. I guess you are using absolute links in your app, like:
/service/type/(index.php) or
/about/me/(index.php)
First of all: If you just want to have this for seo-friendlieness and beautiful links, you should definitely use mod_rewrite or the appropriate nginx-config. This saves you from having real subdirectories - you just "fake" them. The following code rewrites all requested URLS to index.php?r=theenteredurl. In PHP (or, if you want, any other processing language of your choice) you can sanitize the URL, analyse it and then server the correct content.
mod_rewrite:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteBase /
RewriteRule ^(.*)$ index.php?r=$1 [L]
Nginx:
location / {
try_files $uri $uri/ /index.php?r=$request_uri;
}
The good thing about this solution is, that the only file that really gets processed is your index.php and you therefor have your app/website tidy and on one place. But be aware: HTML, CSS and JS relative links do NOT work as you might expect with this solution, since they do not see what PHP processes, but only what is in the address-bar of your browser. All relative links are relative to the fake subdirectory. To solve this, you can define a base-url in your HTML-file. All other files loaded in this HTML file will be relative to this url.
If I got you wrong and you really want to have real sub-directories on the one domain and no subdirectories on the other, then you could use the HTML base-tag to define a different base-URL depending on whether you are on the main domain or the subdomain. To find out the latter, try the PHP super-global $_SERVER. Please note, that HTML cannot access something that is out of the public scope - if your ressources are in a higher subdirectory that is not publicly accessable on this subdomain, you have no chance of loading it in HTML files.

Mapping URL into custom files

I want to map URL in my localhost XAMPP into custom files.
For example:
localhost/index.php --> d:\xampp\htdocs\index.php (default)
localhost/normal/data.php --> d:\xampp\htdocs\normal\data.php (default)
localhost/view/userinfo.php --> d:\xampp\htdocs\view.php?p=userinfo (custom)
localhost/view/welcome.php --> d:\xampp\htdocs\view.php?p=welcome (custom)
So, basically, all URL that goes into inside view path will be mapped to view.php files with the filename.php (minus the .php) as its query parameter. There's actually no physical folder view, and no physical files userinfo.php and welcome.php inside the folder.
The reason that I need to do this is that so I can pass all the pages that viewing data into an "application frame" that will wrap the page with header, menu, and footer, and I don't need to give header, menu, and footer call in each page. I might have the actual files userinfo.php that I can $include_once, or I might not (I can just generate it from within the view.php), but hey, that's one of the power of this kind of framework, right? And, if someday I need to change this structure, I can change it from just within one file (view.php), not all.
Can I do this in PHP and XAMPP? How? I've noticed that some website seems to used this practice (URL which have no actual files or even path at all), but when I try to read tutorial for it, I got confused.
URL mapping in PHP?
The accepted answer listed 3 links to learn about URL rewriting. Mostly they're written for Apache in Linux, and mostly they pull all the possible scenario and configuration that I got confused which one I really need with all those long documents and technical jargon. I need just the practical step of my specific problem, and then, I will be able to start from there to explore myself if I have more advanced needs. Please help.
if you do want to go down the mod rewrite route adding the following to an .htaccess file in the site root should do it. You will need to make sure mod rewrite is on for XAMPP and I can't help you there I'm afraid. As you can see it rewrites the url, not the windows filename - so it would work on any OS.
The ([a-z]*) means it will take any filename.php with lowercase letters and redirect to /view.php?p=$1 where the $1 will be replaced by filename.
the [L,R] (L means last rule so stop processing if any more are reached, and the R means redirect (it will change the url in the browser). Use P instead to reverse Proxy (the user will still see the url they requested but the server will serve the correct file) - This will require mod_proxy as well.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^view/
RewriteRule ^view/([a-z]*).php$ /view.php?p=$1 [L,R]
</IfModule>
XAMPP uses apache so the rewrites would work the same in Windows as they do in Linux. You could place a .htaccess in the site root directory with some rewrite rules.
However, using PHP
in d:\xampp\htdocs\view\userinfo.php you could include the line
<?php
header('Location: http://localhost/view.php?p=userinfo');
?>
But this must be before any thing is echoed to the screen (even whitespace).
You can use the Apache module mod_rewrite to edit requests before they hit PHP. You want to put something like the following in a .htaccess file in your htdocs directory.
RewriteEngine on
RewriteCond %{REQUEST_URI} ^view/
RewriteRule ^view/(.*)\.php.*$ view.php?p=$1 [L,QSA]
QSA means Query String Append. This means that if there are any GET parameters set on the original request they will be appended to the end of the new request too.
Note that this assumes that Apache is configured with AllowOverride enabled and the mod_rewrite module loaded.

htaccess rewrite subdomain without filename map and extension

Is there a way of doing a rewrite JUST for a subdomain? So it needs to affect only the subdomain. I'm looking for a way to 'hide' the maps/filename+extension.
Example:
www.sub.domain.com/mapname/filename.php#settings
simply to
www.sub.domain.com
This has to be done for every single file in the subdomain directory. I have no clue how to do this. I'm not familiar with .htaccess and I cant really find anything useful.
Thanks in advance! :)
You can add a condition so that a rule is only affected by a subdomain:
RewriteCond %{HTTP_HOST} ^(www\.)?sub\.domain\.com$ [NC]
right above your rule.
However, not sure if there's any way to "hide" the /mapname/filename.php#settings part of the URL. If that part of the URL is never sent to the webserver, the webserver isn't going to know what to serve. What you may want to look into is running your entire site in an iframe, so that only www.sub.domain.com shows in the browser's URL address bar.

How to setup .htaccess to show 404 for unallowed urls?

I noticed in Drupal if you add .php to the url bar of any page it gives you a 404 message; clean urls enabled. The page is obviously a .php, but the .htaccess is preventing the user from being able to tamper with url extensions in the url bar. How could you do this using .htaccess. I have file extensions omitted at the moment, but would also like to add that feature. Thank you.
Also, this question does not pertain to Drupal. I only mentioned Drupal for and example.
Just because a file contains PHP code it doesn't mean it has to have the .php extension; even more so when you're accessing a file over the internet.
When you request http://mysite.com/page and you're using an .htaccess like Drupal's, the request is forwarded onto index.php?q=page whereupon Drupal will check it's database for a path matching page. If it finds one it will display the content for that page, if not it will (rightly) give a 404.
If you want all of your pages to be accessible with a PHP extension you could add an extra rule in your .htaccess file to remove .php from any request where the PHP file doesn't physically exist:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\.php $1 [NC]
Bear in mind though that this adds zero extra value for your site's visitors (in fact they have to remember a file extension as well as the path to the page), and it exposes exactly what server-side technology you're using so a potential attacker would have some of his work done for him.
Hope that helps.
Could you please explain that in more depth. How can it redirect content into an existing page? Is that common practice / typical way of doing things?
Yes it is a very common practice, used by most frameworks and CMS.
The principle is simple: you setup your .htaccess so that every request which doesn't match a real file or directory will be redirected to a front controller, usually the index.php in the root directory of the application. That front controller handles the request by analyzing the URL and calling the necessary actions.
In this way you can minimize the rewrite rules to just one, and you can offer customized 404 pages.
I dunno Drupal but in the usual php app every request being routed to the front controller which performs some validations and throws 404 on errors.
easy-peasy

Is PHP allowed to modify .htaccess file in current folder?

I have a PHP web app located on shared hosting.
My goal is to modify .htaccess file from PHP code when the PHP page is running.
I need that .htaccess to insert a couple of mod_rewrite lines into it.
The problem is that on Windows+Apache I can dynamically modify .htaccess file
but the same code on Linux reports a problem when I try to access this file in any
way (copy or fopen):
"failed to open stream: Permission denied"
I have given .htaccess file 777 permissions - still no result.
WHat prevents me from doing this? How can I develop a workaround?
P.S.
My initial goal was to be able to add a new RewriteRule into .htaccess that maps a
newly added category_id with new category_name.
If it wasn't shared hosting, I would use something like RewriteMap (in main Apache config) and would be able to access the map file.
This is the first real limitation I've been unable to tackle with PHP+Apache, but I hope it's circuventable too.
This seems like an overly-complex solution to just having a general "load category" page that takes the category name from the URL and loads the corresponding ID.
For example, if the URL is:
http://yoursite.com/category/programming
I would remap that to something like:
http://yoursite.com/category.php?name=programming
I want to suggest something else that also works. Instead of writing a rule for every 'special' url, why not use one for all?
I found it a whole lot easier to use what wordpress uses: every url is redirected to the index.
All you have to do is, set up the index file, read in the directory that was loaded (perhaps using $_SERVER['URI_REQUEST']), and deal with it.
add to .htaccess this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Thanks to that chunck you have a system somewhat unlimited at your disposal. If you ever feel like renaming you categrory url, or add another special case, it's already ready!
You only need a small set of rewrite rules. To do what Chad suggests:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/category/.*$ category.php [QSA]
Thus, anytime someone navigates to /category/category_id, the request will be directed to category.php, which will be handed the /category/ URI in $_SERVER['REQUEST_URI'], from which you can easily get the category ID, and you don't need to bother with editing the .htaccess file every time you add a category.
While I agree with the above comments, it can definitely be done. PHP apps like WordPress do exactly this based on changes made on the settings page. It should be as simple as writing the file out however the parent directory NEEDS to have permission for the web server user to write to it.
If it isn't working for you the trick will be making the parent directory either 777 or 775 and having the group set to whatever group Apache runs under (usually "apache" or "www" or something similar)
Adam (commented on your question) is quite correct though, some other security layer on your server might be preventing you from doing this, and this is probably a good indication that you might be approaching the problem the wrong way.
I agree with Chad Birch. In case you can't be dissuaded, though, in your situation I would first be looking for parent directories with locked-down permissions.
FYI, one of the reasons that rewriting the .htaccess is a bad idea is that any requests that come in while the .htaccess is being rewritten will not have any of your redirects applied.

Categories