RewriteCond exception only single path - apache

I'm setting up htaccess. How to configure it to work like this:
example.com/dir/* → example.com/dir/index.php
example.com/dir/subdir/* → example.com/dir/index.php
example.com/dir/index.html → example.com/dir/ (I want to replace index.php to index.html only in this directory)
example.com/dir/ → example.com/dir/ (I want to see the index.html as content)
There are two different files in dir:
index.php
index.html
I am trying to ensure that these conditions work as before, with the exception of the one directory (example.com/dir/) only:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^index\.php$ - [L]
That's how I tried:
DirectoryIndex index.html index.php ## trying to make index.html first
RewriteCond %{REQUEST_URI} ^/dir/
RewriteRule ^index\.html$ - [L]
#
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_URI} !^/dir/?$ ## trying to make an exception
RewriteRule ^ - [L]
RewriteRule ^index\.php$ - [L]

I think your approach is much too complicated, unless there are additional restriction you failed to name in the question.
RewriteEngine on
RewriteRule ^/?dir/index\.html$ /dir/ [END]
RewriteRule ^/?dir/ /dir/index.php [END]
One could also understand the remark about the index.html file different:
RewriteEngine on
RewriteRule ^/?dir/(index\.php)?$ /dir/index.html [END]
RewriteRule ^/?dir/ /dir/index.php [END]
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, but things get more complicated then:
RewriteEngine on
RewriteRule ^/?dir/(index\.php)?$ /dir/index.html [END]
RequestCond %{REQUEST_URI} ^!/dir/index\.html$
RewriteRule ^/?dir/ /dir/index.php [END]
These rules will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

Related

.htaccess two domains redirects to one ssl domain

I've been struggling to get this code to work. I have two domains in my site, and I need to redirects all traffic to the secure url.
This is my code:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?old-domain\.cl$ [OR]
RewriteCond %{HTTPS} ^(www\.)?old-domain\.cl$ [OR]
RewriteCond %{HTTP_HOST} ^www\.new-domain\.cl$ [NC]
RewriteRule ^(.*)$ https:\/\/new-domain\.cl/$1 [L,R=301]
RewriteCond %{HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
Works with the root url: http://new-domain.cl --> https://new-domain.cl and http://old-domain.cl --> https://new-domain.cl, but not in others locations within the site (ex: http://old-domain.cl/foo not changing at all).
I understand from your question that "new-domain.cl" is the host name you want to redirect to? So that %{SERVER_NAME} points to that host name? If so this probably is what you are looking for:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?old-domain\.cl$ [OR]
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,END]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,END]
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This implementation will work likewise in the http servers host configuration or inside a distributed configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a distributed configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using distributed configuration files (".htaccess"). Those distributed configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

Unable to rewrite multiple URL rewrite with same paramters

Need your expert help. I am trying to rewrite 2 url's in htaccess where both url's have same parameters. After rewriting url only 1st url rewrite is working. Can anybody help me on how to make both url rewrite work?
Here is my htaccess code code.
1st URL : http://www.example.com/quotaid.php?id=id/address
which i want to rewrite to
http://www.example.com/id/address
//1st URL rewrite
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/([a-zA-Z0-9]+|[0-9a-zA-Z]+)/?$
RewriteRule ^([a-zA-Z0-9]+|[0-9a-zA-Z]+)/(.*)$ quotaid.php?id=$1 [NC,L]
2nd URL : http://www.example.com/zipquota.php?zip=zip/address
which i want to rewrite to
http://www.example.com/zip/address
//2nd URL rewite in htaccess
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/([a-zA-Z0-9]+)?$
RewriteRule ^(.*)$ zipquota.php?zip=$1 [NC,L]
Only one url rewrite is working which comes first. If i move the 2nd url rewrite to top, then the 2nd url rewrite is working but the 1st url stops working. PLease help on how to manage both url rewrite working.
I assume this is what you are looking for:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([0-9]+)/(.+)$ /zipquota.php?zip=$1&address=$2 [NC,END]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([0-9a-z]+)/(.+)$ /quotaid.php?id=$1&address=$2 [NC,END]
These are the internal rewritings applied by that, as specified by you in the comments to the question, though I dare say that the address argument makes zero sense and probably will get removed in future...:
https://example.org/91007/HOMES-FOR-Arcadia-CA => /zipquota.php?zip=91007&address=HOMES-FOR-Arcadia-CA
https://example.org/CV17057071/3677-Louise-Street-Lynwood-CA-90262 => /quotaid.php?id=CV17057071&address=3677-Louise-Street-Lynwood-CA-90262
Those rules should work in the http servers host configuration and likewise in dynamic configuration files (.htaccess). To be able to use them in a dynamic configuration file some preconditions have to be matched: the interpretation of such files has to be enabled in the http servers configuration (AllowOverride ...), the file has to be readable by the http server and it has to be placed inside the DOCUMENT_ROOT folder configured for that http host.
The zip based URLs are rewritten first, since they use a more specific pattern, purely number based. Then comes the more general rule for ids with alphanumeric patterns. The condition you originally had does not really make sense, I removed it.
Note: I also took the liberty to make those target paths absolute (leading slash) to make the setup more robust. That obviously requires those scripts to be located directly inside the DOCUMENT_ROOT folder. otherwise the paths have to be adjusted.
Warning: In case you get a http status 500 (internal server error), chances are that you operate a very old version of the apache http server. In that case you have to replace the END flag with the L flag. You can see a hint on that in your http servers error log file in that case. The L flag should work too, unless you have more rewriting rules that might create a conflict.
And a general hint: you should always prefer to place such rules inside the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

How to redirect url to the url with htaccess

I didn't know how to question this but my problem is like this
I have written a rule for a url
RewriteRule ^mysite.com.pk/([a-zA-Z0-9]+) index.php?store=$1
RewriteRule ^mysite.com.pk/([a-zA-Z0-9]+)/products index.php?store=$1&view=products
RewriteRule ^mysite.com.pk/([a-zA-Z0-9]+)/products/([0-9]+) index.php?store=$1&view=products&category=$2
RewriteRule ^mysite.com.pk/([a-zA-Z0-9]+)/single/([0-9]+) index.php?store=$1&view=single&product=$2
I am new to htaccess so I don't know much about it. Is there a way that even if a old url comes like index.php?store=abc&view=single&product=123
this will be redirected to a new one like mysite.com.pk/abc/single/123
You have to make some small modifications to your proposed rules to get them to work. And you have to add additional rewriting rules to achieve what you actually ask: redirecting "old" URLs to your new syntax.
This is probably what you are looking for:
RewriteEngine on
RewriteRule ^/?([a-zA-Z0-9]+)$ index.php?store=$1 [END]
RewriteRule ^/?([a-zA-Z0-9]+)/products$ index.php?store=$1&view=products [END]
RewriteRule ^/?([a-zA-Z0-9]+)/products/([0-9]+)$ index.php?store=$1&view=products&category=$2 [END]
RewriteRule ^/?([a-zA-Z0-9]+)/single/([0-9]+)$ index.php?store=$1&view=single&product=$2 [END]
# index.php?store=xyz&view=single&product=123
RewriteCond %{QUERY_STRING} store=([^&]+)&?
RewriteCond %{QUERY_STRING} view=single&?
RewriteCond %{QUERY_STRING} product=([^&]+)&?
RewriteRule /?index.php$ /%1/single/%3 [END,R=301]
# index.php?store=xyz&view=products&product=123
RewriteCond %{QUERY_STRING} store=([^&]+)&?
RewriteCond %{QUERY_STRING} view=products&?
RewriteCond %{QUERY_STRING} category=([^&]+)&?
RewriteRule /?index.php$ /%1/products/%3 [END,R=301]
# index.php?store=xyz&view=products
RewriteCond %{QUERY_STRING} store=([^&]+)&?
RewriteCond %{QUERY_STRING} view=products&?
RewriteRule /?index.php$ /%1/products [END,R=301]
# index.php?store=xyz
RewriteCond %{QUERY_STRING} store=([^&]+)&?
RewriteRule /?index.php$ /%1 [END,R=301]
Those rules should work the same in a .htaccess style file and in the real http host configuration. Please see the note below about that.
If you are using an old version of the apache http server then you may have to replace the END flag by the L flag. Try that if you receive an "internal server error" (http status 500) and the server complains about the END flag in the error log file. You may have to add some additional conditions to prevent an endless rewriting loop in that case.
Please note that I did not test that rule set. I hope it does not contain any silly mistakes and you certainly will have to test it.
All of the above assumes that mysite.com.pk is meant to match your host name ("domain"). But that will not work, since the RewriteRules work on the request path, not the full URL. If you want to limit the application of the rules to a specific host, then you can add a leading condition to stop the rewriting process:
RewriteCond %{HTTP_HOST} !^mysite\.com\.pk`
RewriteRule .* - [END]
And a general hint: you should always prefer to place such rules inside the http servers host configuration instead of using .htaccess style files. Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

RewriteCond %{QUERY_STRING}

Here's what I'm trying to accomplish:
http://example.com/real-estate/?group=rentals
needs to go to
http://example.com/real-estate/rentals
Here's what I have in my .htaccess that isn't working:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/real-estate/ [NC]
RewriteCond %{QUERY_STRING} ^group=rentals
RewriteRule (.*) http://example.com/real-estate/rentals/? [NC,R=301,L]
</IfModule>
This is very unusual... Typically people want the redirection the other way around....
Your code looks nearly fine, only some minor corrections. But those might be what you are missing:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/real-estate/?$ [NC]
RewriteCond %{QUERY_STRING} ^group=rentals$
RewriteRule ^ http://example.com/real-estate/rentals [R=301,L]
</IfModule>
For this to work the rules have to either be placed directly inside the http hosts configuration, or inside a .htaccess style file in the hosts document root with enabled interpretation of such files.
And a general hint: you should always prefer to place such rules inside the http servers host configuration instead of using .htaccess style files. Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).
Just use this in your .htaccess file:
RewriteEngine On
RewriteRule ^real-estate/([^/]*)$ /real-estate/?group=$1 [L]
It will leave you with the URL: http://example.com/real-estate/rentals. Make sure you clear your cache before you test this.

How do I make a custom URL parser with Apache?

I heard this can be done with the web.config file. I want to make it so, for instance, my URL http://help.BHStudios.org/site might go to http://BHStudios.org/help.php?section=site, or http://i.BHStudios.org/u3Hiu might redirect to some other URL stored in a database with the hash u3Hiu as the key, or if something goes wrong and the internal file structure is exposed like http://Kyli.BHStudios.org/http/bhstudios/v2/self/index.php (something that happens with GoDaddy's servers for whatever reason) it'll change it to its intended URL http://Kyli.BHStudios.org before that's exposed tot he user.
Since I've never done this before, could you please also explain why you gave the answer you did?
A few Apache mod_rewrite rules in either your servers httpd.conf or in a .htaccess file, in your htdocs directory will do the majority of what you want e.g.
RewriteEngine On
RewriteBase /
# Default Rule - for non physical objects (not a file or directory):
# Internally rewrite (user won't see the URL) to /index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ /index.php [L]
#If the Browser request contains a .php, instruct the browser to remove it.
RewriteCond %{THE_REQUEST} \.php [NC]
RewriteRule ^/?(.*)\.php$ http://%{HTTP_HOST}/$1 [R=301,NC,L]
# Specific rule
RewriteRule ^/?site /help.php?section=site
The masking of real file system objects will not be perfect, and slightly pointless, as a user just needs to right click and view source on any served page, to obtain the actual URL's.