htaccess file seems to pick up 'if contains' for a RewriteRule - .htaccess

We currently have a .htaccess RewriteRule that's incorrectly (or correctly as the rule is incorrect) redirecting a URL.
The Rule
RewriteRule ^holiday-ecards/?.*$ /appindex.php [L]
The desired redirects for this are:
http://domain.com/holiday-ecards/
http://domain.com/holiday-ecards/1/
http://domain.com/holiday-ecards/1/2
http://domain.com/holiday-ecards/1/2/3
However, it seems to also be redirecting the following, which is undesired:
http://domain.com/holiday-ecards-business/
EDIT
/appindex.php
This is taking care of the app routing and works as intended.

A number of ways you could do it, one would be setting a rewrite condition to not touch URI's that have holiday-ecards plus hyphen, like so:
RewriteCond %{REQUEST_URI} !^/holiday-ecards-.*$
RewriteRule ^holiday-ecards/?.*$ /appindex.php [L]
Not sure how many variations you have of URI's with holiday-ecards in them.

RewriteRule ^holiday-ecards/?.*$ /appindex.php [L]
(Note that this is an internal rewrite, not a redirect.)
The above RewriteRule pattern makes the slash after holiday-ecards optional (so it will also match holiday-ecards-business). However, in the example URLs that should be rewritten, the slash is mandatory. So, it would appear that you just need to make it mandatory (?), for example:
RewriteRule ^holiday-ecards/ /appindex.php [L]
The trailing pattern .*$ is superfluous.

Related

HTACCESS How to "cut" URL at one point

I am new to .htaccess and I don't understand it well. Recently I have built the following code:
RewriteEngine On
RewriteCond %{HTTP_HOST} (.*)
RewriteCond %{REQUEST_URI} /api/v2/
RewriteRule ^api/v2(.*) /api/v2/api.php?input=$1
This was in the root public folder (example.com/.htaccess). But now I have to create second Rewrite and I want to make .htaccess file in example.com/api/v2/ folder. I tried to remove /api/v2/ part in each Rewrite Rule, but only thing I got was error 500.
What I want to achieve:
If someone uses this link: https://example.com/api/v2/test/test/123, I'd like to make it into https://example.com/api/v2/api?input=test/test/123 with .htaccess located in example.com/api/v2 folder.
Addressing your existing rule first:
RewriteCond %{HTTP_HOST} (.*)
RewriteCond %{REQUEST_URI} /api/v2/
RewriteRule ^api/v2(.*) /api/v2/api.php?input=$1
The first RewriteCond (condition) is entirely superfluous and can simply be removed. The second condition simply asserts that there is a slash after the v2 and this can be merged with the RewritRule pattern. So, the above is equivalent to a single RewriteRule directive as follows:
RewriteRule ^api/v2(/.*) /api/v2/api.php?input=$1 [L]
This would internally rewrite the request from /api/v2/test/test/123 to /api/v2/api.php?input=/test/test/123 - note the slash prefix on the input URL parameter value.
However, unless you have another .htaccess file in a subdirectory that also contains mod_rewrite directives then this will create a rewrite loop (500 error).
Also note that you should probably include the L flag here to prevent the request being further rewritten (if you have other directives).
If someone uses this link: https://example.com/api/v2/test/test/123, I'd like to make it into https://example.com/api/v2/api?input=test/test/123 with .htaccess located in example.com/api/v2 folder.
I assume /api? is a typo and this should be /api.php?. Note also that the slash is omitted from the start of the URL parameter value (different to the rule above).
I tried to remove /api/v2/ part in each Rewrite Rule, but only thing I got was error 500.
This is the right idea, however, you need to be careful of rewrite loops (ie. 500 error response) since the rewritten URL is likely matching the regex you are trying to rewrite.
Try the following instead in the /api/v2/.htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_URI} !api\.php$
RewriteRule (.*) api.php?input=$1 [L]
The preceding RewriteCond directive checks that the request is not already for api.php, thus avoiding a rewrite loop, since the pattern .* will naturally match anything, including api.php itself.
You could avoid the additional condition by making the regex more specific. For example, if the requested URL-path cannot contain a dot then the above RewriteCond and RewriteRule directives can be written as a single directive:
RewriteRule ^([^.]*)$ api.php?input=$1 [L]
The regex [^.]* matches anything except a dot, so avoids matching api.php.
Alternatively, only match the characters that are permitted. For example, lowercase a-z, digits and slashes (which naturally excludes the dot), which covers your test string test/test/123:
RewriteRule ^([a-z0-9/]*)$ api.php?input=$1 [L]
Or, if there should always be 3 path segments, /<letters>/<letters>/<digits>, then be specific:
RewriteRule ^([a-z]+/[a-z]+/\d+)$ api.php?input=$1 [L]

htaccess rewrite rewrite url with folders after php file

i am trying to get something like this:
http://localhost/Engine/admin.php/users/manage
to rewrite to something like this:
http://localhost/Engine/admin.php?p=users&a=manage
i am a beginner with rewrite rules, but i have a basic one here, they cant conflict...
RewriteEngine on
RewriteBase /
RewriteRule ^([^.]*)$ /Engine/index.php?page=$1 [QSA,L]
also, if anyone has any improvements for my other rewrite, it would be most helpfull, it rewrites
http://localhost/Engine/somepage
to:
http://localhost/Engine/index.php?page=somepage
Your generic rule that matches everything should be listed as last rule. You can improve it by only allowing to match if .php is not in the url. For admin.php you know how many arguments there should be, so you can simply match the static part of the url with ^Engine/admin\.php/, then all arguments with ([^/]+) (match everything but /). The last /? matches a trailing slash that might or might not be appended.
For more information read the documentation.
RewriteRule ^Engine/admin\.php/([^/]+)/([^/]+)/?$ /Engine/admin.php?p=$1&a=$2 [L]
RewriteCond %{REQUEST_URI} !^/Engine/.*\.php.*$
RewriteRule ^Engine/(.*)$ /Engine/index.php?page=$1 [QSA,L]

Two rules in one .htaccess file not working

Below is my code for .htaccess
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)/([0-9]+)$ /products/product-full-view.php?src=$1&id=$2
RewriteRule ^([a-zA-Z0-9_-]+)/([0-9]+)/?$ /products/product-full-view.php?src=$1&id=$2
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)/([0-9]+)$ /buy/buy-full-view.php?src=$1&id=$2
RewriteRule ^([a-zA-Z0-9_-]+)/([0-9]+)/?$ /buy/buy-full-view.php?src=$1&id=$2
First rule is working fine but its not taking the second rule...Unable to understand what is happening here...
Original URL's are like this
www.example.com/products/product-full-view.php?src=somevalue&id=somevalue
and for second one
www.example.com/buy/buy-full-view.php?src=somevalue&id=somevalue
Please help me to run second rule also.
Thanks in advance
You're trying to match the same pattern, give or take an optional trailing slash, four times. By the time you reach the last two rules, your URL is already rewritten to something else.
You probably want something that looks more like:
RewriteEngine On
RewriteRule ^products/([0-9]+)/?$ /products/product-full-view.php?id=$1 [L]
RewriteRule ^buy/([0-9]+)/?$ /buy/buy-full-view.php?id=$1 [L]
Or:
RewriteEngine On
RewriteRule ^products/([a-zA-Z0-9_-]+)/([0-9]+)/?$ /products/product-full-view.php?src=$1&id=$2 [L]
RewriteRule ^buy/([a-zA-Z0-9_-]+)/([0-9]+)/?$ /buy/buy-full-view.php?src=$1&id=$2 [L]
Or something to that order anyway.
Note the stub and the [L] each time: the products/ and buy/ avoid that the same URL refers to two different locations, and the [L] (for "Last") tells the rewrite engine to stop processing rules when it gets matched.
If a URL matches the second rule, it also matches the first rule. After applying the first rule, the resulting URL no longer matches the second rule. That's why the second rule is never applied.

Htaccess rewrite index with trailing slash or without

I am currently having a problem with my index url rewrite in my .htaccess file, I know if I use
RewriteRule ^profile/([^/]*)/?$ /profile.php?x=$1 [L]
I would be able to use www.example.com/profile/get or www.example.com/profile/get/ (with or without trailing slash)
But I would like www.example.com/get what I have so far is
RewriteRule ^([^/]*)\/$ /index.php?x=$1 [L]
But if I put a ? before the $ it errors any answers welcome
Making the trailing slash optional will lead to an infinite loop, since [^/]* will match anything that doesn't include a /, ie it would also match index.php?x=get
You can avoid this by making the rule apply conditionally, for example by testing the reqeust URI:
RewriteCond %{REQUEST_URI} !^/index\.php.*
RewriteRule ^([^/]*)\/?$ /index.php?x=$1 [L]
That way the rule can only apply in case the request URI doesn't start with /index.php

Fixing Rewrite Rules and Conditions In HTACCESS file

Well lets say I have this follow code in my htaccess file,
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,NC,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^([^/]+)$ $1.php
RewriteRule ^forums/([0-9]+) forums.php?category=$1 [NC]
I was wondering how would I, with the above code, redirect certain extensions in a url to my websites 404 page.
For instance, if this link mywebsite.com/forums has any extension at the end of it such as .asp, .php, .html, and so forth it then would get redirected to my 404 page.
And on a quick side note how can I limit the last RewriteRule to only a certain forward slash where mywebsite.com/forums/2 would show the page fine and anything after that certain limit such as mywebsite.com/forums/2/so on... would be redirected to my 404 page.
Anyone have any ideas?
If I understand the question properly, then you need to firm up the regular expressions to only match the patterns you really want - at the moment, they're a bit too lenient for your needs.
For example:
RewriteRule ^([^/]+)$ $1.php
This will match anything without a trailing slash, whereas if you wanted to restrict it to only match, say, things without a trailing slash and consisting of alphanumeric characters, then you might do this:
RewriteRule ^([a-zA-Z0-9]+)$ $1.php
(You could achieve the same effect for certain extensions only by using a lookahead assertion, but that complicates your regular expression. I feel it's probably saner (and easier on the mind) to think about the patterns you really want matched, and then express those up-front.)
Likewise, your latter example:
RewriteRule ^forums/([0-9]+) forums.php?category=$1 [NC]
will match anything which starts with the string forums/, followed by one or more digits, whether or not there's anything after that. Adding an end anchor ($) as you have above
RewriteRule ^forums/([0-9]+)$ ...
will assert that the string ends after the digits.
This relies on the fact that if mod_rewrite can't find a match, it won't attempt any rewrites, and will (in the absence of any explicit resource at that path) fall through to Apache's 404 handling, which is then up to you to override.

Resources