mod_rewrite vs files vs virtual subdirectories - regex

I have a site with virtual subdirectories (for languages) created by the means of mod_rewrite.
They work fine.
Now I need to upload some files that should be accessed via certain subdirectories only.
Currently I can access any files via any subdirectories.
site.com/file.txt
site.com/jp/file.txt
site.com/es/file.txt
site.com/another_file.txt
site.com/jp/another_file.txt
site.com/es/another_file.txt
site.com/third_file.txt
site.com/jp/third_file.txt
site.com/es/third_file.txt
I need to access these files via the related subdirectories only, if I try to access them via unrelated directory, it should throw the 404 error.
site.com/file.txt - for english (the only language that does not have a subdirectory)
site.com/jp/anoter_file.txt - for japaneese
site.com/es/third_file.txt - for Spanish.
Please note that there is no pattern in file names and there are many languages.
So, it is necessary to create separate rules for each file/subdirectory.
As there are many languages and files, it could be a nightmare to write rules for each language like this:
e.g. I want file another_file.txt to be displayed inside the jp directory only.
So, I have to exclude it like this:
RewriteRule ^de/another_file.txt - [R=404]
RewriteRule ^fr/another_file.txt - [R=404]
RewriteRule ^es/another_file.txt - [R=404]
But I think there is a more elegant solution.
As far as I understand, this could be achieved by the means of exception.
Like this:
RewriteRule ! ^jp/another_file.txt - [R=404] - but it does not work.
Could you please assist me and let me know how to fix this expression/create a new one.?

Related

htaccess URL masking without renaming files

I have an url www.example.com/english/magazine-one/offline/download.pdf, where I want to access the download.pdf but shows magazine-one.pdf (the magazine folder name) instead without actually renaming the PDF file.
So I have managed to come up with this in my htaccess
RewriteEngine On
RewriteRule ^(.*)offline/magazine-one.pdf$ $1offline/download.pdf [L]
This allows me to mask the URL and access the pdf directly from magazine-one.pdf. However, when I access download.pdf the url still does not change and point to magazine-one.pdf.
Would be great if someone can throw some ideas in.

Rewriting RewriteRule to include back one particular php file in the path

I inherited a large WordPress site: I was looking at the Wordfence live logs when I found users not loading a particular PHP page. I investigated and through an FTP client I found the file was where it was supposed to be. I used some network tool (in Chrome, Opera and Firefox) and, again, I found that file was returning a 404.
So, I found in the root of the website a short htaccess file containing this line:
RewriteRule ^wp-content/(.*)\.php$ [R=404,L]
I commented this out and reloaded the website: no error anymore. I must say, the error apparently doesn't cause anything strange to the website. But I would like to eliminate it.
I suppose this rule is meant to avoid someone can make a direct HTTP request to this and any other PHP file in that directory: in this case I suppose this file I'm talking about is called from an include, not directly, because in WordFence what I see is an error coming after a user accesses directly other pages, not this one in particular.
Anyway, I would like to rewrite this rule so that it stays the same as now, except for that php page. The PHP page is in the path of the theme:
wp-content/themes/themeName/core/css/customized.css.php
Is this possible? Any help is appreciated
If you want to exclude that specific php file from the RewriteRule, you can add a negative lookahead to the regex, like so:
RewriteRule ^wp-content/(?!themes/.*/core/css/customized\.css\.php$)(.*)\.php$ [R=404,L]

Moved Opencart site now product links not working

Basically duplicated http://www.smoothprint.co.uk at http://www.comitservices.co.uk/ben/ocart, I imported the old database into the new one and edited the php.ini files so they aren't both connected to the same database
However now the SEO friendly links aren't working and i'm not sure how to rectify this. Any ideas?
Make sure you have edited your .htaccess file's RewriteBase value. On your original store, it will have been
RewriteBase /
and for the new store it should be
RewriteBase /ben/ocart/
Although usually just removing the line completely will allow the file to work with both of those stores

.htaccess redirect files with certain paths to another directory

This might seem a bit basic and something that's been asked quite a lot around here, but I have a small .htaccess problem (mod_rewrite).
I'm working on a MVC framework for PHP (like everybody else...) and all traffic goes through index.php which then routes to the required controller and method. All that goes well. The structure is roughly something like this:
application
controllers
models
views
cache
framework
public
assets
img
css
js
index.php
.htaccess
For an URL like myapp.com/css/ I need o load the CSS controller, index function. But for URLs like myapp.com/css/style.css I need to fetch the file from the public/css/directory
I'd hate writing /public/ for each file I want to include, so basically I need to redirect all traffic to /public/ if it's an actual file and keep the normal rewriting rule for all other URLs. I'm planning to use this in production and it would be much easier to let frontend developers do their stuff the way they normally do it and then just copy paste stuff into place instread of going through CSS to modify paths and such.
I came up with this:
RewriteEngine on
RewriteRule ^(img|css|js|assets)/(.*).([a-z]{3})$ public/$1/$2 [L,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
But it has some obvious flaws. I don't mind having to set directories in the first regex, but checking that the path is a file the way I do seems rather unreliable. Using RewriteCond to check that it's a file didn't work for some reason and I think this method can fail for URLs like myapp.com/img/this-is-actually-an-article.aaa Of course, extensiuons can also be longer than 3 characters and I need to check that that's safe as well.
What's the best way to go about this? How do you guys ussually do it? Or is this a wrong approach from the very begining?
The -f isn't working because the requested file is /css/style.css whereas the file on disk is /public/css/style.css.
I see no problem with declaring some predefined namespaces that you can't use in your application (like img, css, js, assets).
Eventually I think you will move to a situation where plugins for your framework can no longer decide where their resources are, the framework should decide it for them and possibly even load it for them. This resolves all your current issues as no plugin code will ever need to know anything about URLs. Regardless of your rewriting strategy I think this is something to aspire to.

Codeigniter Routes for filename with extension

I am using codeigniter and its routes system successfully with some lovely regexp, however I have come unstuck on what should be an easy peasy thing in the system.
I want to include a bunch of search engine related files (for Google webmaster etc.) plus the robots.txt file, all in a controller.
So, I have create the controller and updated the routes file and don't seem to be able to get it working with these files.
Here's a snip from my routes file:
$route['robots\.txt|LiveSearchSiteAuth\.xml'] = 'search_controller/files';
Within the function I use the URI helper to figure out which content to show.
Now I can't get this to match, which points to my regexp being wrong. I'm sure this is a really obvious one but its late and my caffeine tank is empty :)
You should not need to escape the full stop, CodeIgniter does most of the escaping for you.
Here is a working example I use:
$route['news/rss/all.rss'] = "news/rss";
Issue was actually in .htaccess file where I had created a rewrite exception to allow the search engine files to be accessed directly rather than routing them through codeigniter.
RewriteCond $1 !^(index\.php|google421b29fc254592e0.html|LiveSearchSiteAuth.xml|content|robots\.txt|favicon.ico)
Became
RewriteCond $1 !^(index\.php|content|favicon.ico)