How to add/ignore a subfolder in htaccess file? - apache

I have build an app at http://url/sdf19/
I have a .htaccess placed in /sdf19/ containing RewriteRule for clean urls.
But I have built a PDF generating tool, which is in a subfolder /inc/tools.
I need to link to it direct to run before headers.
Despite a few hours of searching, trying snippets, generators, etc. I cannot get any request to http://url/sdf19/inc/tools to be allowed, without the existing RewriteRule set taking over
Here is my starting file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z]+)\/?$ index.php?page=$1 [NC]
RewriteRule ^([a-z]+)\/([0-9]+)\/?$ index.php?page=$1&id=$2 [NC]
RewriteRule ^([a-z]+)\/([a-z]+)\/?$ index.php?page=$1&action=$2 [NC]
RewriteRule ^([a-z]+)\/([a-z]+)\/([0-9]+)\/?$ index.php?page=$1&action=$2&id=$3 [NC]
I've tried to add this on line 4;
RewriteCond %{REQUEST_URI} !^ inc/tools/ [NC]
This gave RewriteCond: bad argument line error
I've tried to add this to line 2;
RewriteCond %{REQUEST_URI} ^/inc/tools/(.*)$
RewriteRule ^.*$ - [L]
Desired result is that I can allow direct access to http://url/sdf19/inc/tools > everything I have tried so far i get redirected to base http://url/sdf19/

Maybe, we could step by step solve this problem. First step, we might just want to make something work with as less as boundaries that'd be possible.
Let's design a low boundary expression, maybe something similar to:
(.+)(\/inc\/tools)
From here, we can just add \/inc\/tools to the RewriteCond, just for testing. Later, we can modify that.
RegEx
If this wasn't a desired expression, you can modify/change your expressions in regex101.com.
RegEx Circuit
You can also visualize your expressions in jex.im:
RewriteRule Test
You can test your RewriteRules in htaccess.madewithlove.be.
I'm not so sure about the rest of RewriteRules, but I'm assuming they are working fine and not conflicting with the new one. Maybe, this or something similar would work:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} \/inc\/tools [NC]
RewriteRule ^(.*)$ $1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z]+)\/?$ index.php?page=$1 [NC]
RewriteRule ^([a-z]+)\/([0-9]+)\/?$ index.php?page=$1&id=$2 [NC]
RewriteRule ^([a-z]+)\/([a-z]+)\/?$ index.php?page=$1&action=$2 [NC]
RewriteRule ^([a-z]+)\/([a-z]+)\/([0-9]+)\/?$ index.php?page=$1&action=$2&id=$3 [NC]
</IfModule>

Related

friendly url only opens the post.php not cat.php

Friends, what is the right way to get both the php files to open friendly URL contents?
My current code works OK if I only use:
Options +FollowSymLinks
RewriteEngine On
# SEO URL Settings
RewriteBase /site/
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteRule ^(.*)$ post.php?id=$1 [QSA,L]
but then I also need friendly URL for my categories so I tried to add:
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteRule ^(.*)$ cat.php?cat=$1 [QSA,L]
but doing so only the post URL opens but category links redirect back to index.php but if you remove the rewrite for post than the cat.php contents shows.
If someone could help me out here would really appreciate your kindness.
This is because of your use of the [L] flag.
The [L] flag causes mod_rewrite to stop processing the rule set. In
most contexts, this means that if the rule matches, no further rules
will be processed. This corresponds to the last command in Perl, or
the break command in C. Use this flag to indicate that the current
rule should be applied immediately without considering further rules.
Documentation
Instead, try and have your rules laid out like this:
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteRule ^(.*)$ post.php?id=$1 [QSA]
RewriteRule ^(.*)$ cat.php?cat=$1 [QSA,L]

Multiple RewriteRule to one RewriteCond

On the side I have about 400,000 subdomains. in view of the above, some calls also operate subdomain level, e.g..
subdomain1.example.com/some_action/
Such actions that should be performed only from the domain have 27.
Htaccess file I created a rule:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www.)?example.com
RewriteRule ^some_action1/?$ index.php?some_action1 [L]
If i add this line
RewriteRule ^some_action2/?$ index.php?some_action2 [L]
not work in the same way as for some_action3, etc.
I have added for each action separately
RewriteCond %{HTTP_HOST} ^(www.)?example.com
Can you somehow skip to harmonize?
Each RewriteCond condition only applies to the immediately following RewriteRule. That means if you have a bunch of rules, you have to duplicate the conditions. If you really don't want to do that for some reason, you could use a negate at the very beginning of all your rules. This may or may not be a good solution since it could affect how you make future changes to the rules:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^(www.)?example.com
RewriteRule ^ - [L]
RewriteRule ^some_action1/?$ index.php?some_action1 [L]
RewriteRule ^some_action2/?$ index.php?some_action2 [L]
RewriteRule ^some_action3/?$ index.php?some_action3 [L]
etc...
So the first rule checks for the negative of the host being example.com, and skips everything. Then you can add all your rules without having to worry about that condition.
However, if your "some_action" is always going to be part of the GET parameters, you can maybe just use a single rule:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www.)?example.com
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/?$ index.php?$1 [L]

Check URL and stop processing using htaccess

I want to check URL using htaccess. Developer might want run special file - specialfile.php. I use htaccess:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /specialfile\.php$
RewriteRule .* [L] #don't change adress
RewriteRule ^$ public/index.html [NC,L]
RewriteRule (.*) public/$1 [NC,L]
My idea was: if rewriteCond %{REQUEST_URI} !/specialfile.php$ true than htaccess should use RewriteRule .* [L] - that should mean that specialfile.php will be run and this all. But it doesn't work because it runs next rule: RewriteRule (.*) public/$1 [NC,L].
I think you are using the RewriteCond not correctly. The conditions only affect the next RewriteRule that follows.
Check out the example on the Apache Homepage. Since your 2nd RewriteRule is evalutated, I think your conditions are not correct. To get a litte bit more information about the rewriting, you should increase the log level. This is also documented here.
Your 2nd rule ^$ matches only an empty request btw. That's why it probably does not work as you expect it to.

Apache mod_rewrite query string before page and remove extention

I've scavenged the web for answers to my mod_rewrite woes and I feel I'm at the end of my wits. I will have a URL like such: http://www.website.com/dashboard.php?username=stackoverflow. This url isn't the prettiest of such. So my goal is to do a few things here...
Eliminate the extension of the php file (I've been able to do this so far with the code I'll show below, but I don't know that it will stay according to the other things I need to do)
Eliminate the "www" prefix
Move the username query string (only if it's "username", I don't want to match "id" or such) directly after ".com/"
Move the php filename (without the extension) after query string.
The final URL should look like such: http://website.com/stackoverflow/dashboard or perhaps http://website.com/stackoverflow/profile.
The code I have right now which eliminates the file extension is such:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# remove .php ONLY if requested directly
RewriteCond %{THE_REQUEST} (\.php\sHTTP/1)
RewriteRule ^(.+)\.php$ /$1 [R=301,L,QSA]
# remove trailing slash ONLY if it is not an existing folder
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# rewrite to FILENAME.php if such file does exist and is not a folder
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ /$1.php [L,QSA]
Sadly this only fixes one of my issues and after looking at it, I'm getting the feeling there would be a better way to do this...
(1, 3, 4) As I understand you want to use pretty URLs, but backed by PHP pages. So it should be like this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(\w+)/profile$ /dashboard.php?username=$1 [L]
It will make http://website.com/stackoverflow/profile working as http://www.website.com/dashboard.php?username=stackoverflow
(2)
# Redirect www.site.com to site.com with 301
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

Simulating a 2-level If-Else using RewriteCond

I'm trying to get my head around RewriteCond, and want to rewrite any requests either to a static html page (if it exists), or to a specific index.php (so long as the requested file doesn't exist).
To illustrate the logic:
if HTTP_HOST is '(www\.)?mydomain.com'
if file exists: "/default/static/{REQUEST_URI}.html", then
rewrite .* to /default/static/{REQUEST_URI}.html
else if file exists: {REQUEST_FILENAME}, then
do not rewrite
else
rewrite .* to /default/index.php
I don't seem to have much trouble doing it when I don't need to test for the HTTP_HOST. Ultimately, this one .htaccess file will be handling requests for several domains.
I know I could get around this with vhosts, but I'd like to figure out how to do it this way.
I'm not too familiar with some of the other flags, will any of them be of use here (like chain|C, next|N or skip|S)?
Thanks in advance!
UPDATE: I've managed to do it, but would appreciate alternatives:
RewriteCond %{HTTP_HOST} ^(domainA|domainB)\..* [NC]
RewriteCond %{DOCUMENT_ROOT}/%1/static/%{REQUEST_URI}.html -f
RewriteRule (.*)? /%1/static/$1.html [NC,L]
RewriteCond %{HTTP_HOST} ^(domainA|domainB)\..* [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* /%1/index.php [L,QSA]
UPDATE #2: With help from Gumbo's answer, came up with another. I like that this would would require less maintenance in the case of added domains. (Thanks Gumbo!)
Are there any reasons why I shouldn't set ENV variables?
RewriteCond %{HTTP_HOST} ^(domainA|domainB)\..*$ [NC]
RewriteRule ^ - [E=APP:%1]
RewriteCond %{DOCUMENT_ROOT}/%{ENV:APP}/static/%{REQUEST_URI}.html -f
RewriteRule (.*)? /%{ENV:APP}/static/$1.html [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* /%{ENV:APP}/index.php [L,QSA]
I would probably do it like this:
RewriteCond %{HTTP_HOST} !^(www\.)?example\.com$
RewriteRule ^ - [S=2]
RewriteCond %{DOCUMENT_ROOT}/default/static%{REQUEST_URI}.html -f
RewriteRule !^default/static/ default/static%{REQUEST_URI}.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^default/static/ default/index.php [L]
This is similar to your updated example. Except that the first rule will skip the following two rules if the host is not appropriate. And the RewriteRule patterns exclude any path that starts with /default/static/. But your rules are already pretty good.