mod rewrite exclude all but php - .htaccess

Is it possible to edit htacces in such a way that only the following url is rewritten and the rest isn't?
http://www.example.com/index.php?x=foobar
to
http://www.example.com/foobar/
I want the pages not having x=... as a variable to behave normally
I got the following but that doesn't work
Options +FollowSymLinks
RewriteEngine on
RewriteRule (.*)/ index.php?x=$1
RewriteCond $1 !\.(js|ico|gif|jpg|png|css|html|swf|mp3|wav|txt)$
Who can help me?

First off, the RewriteCond must be put before the RewriteRule to which it belongs.
But I think that you need another approach for your case, something like this:
RewriteRule (.*)\.php - [PT,L]
RewriteRule ^(.*)/$ index.php?x=$1
The first rule Passes Through (PT) every PHP page, so the second rule is only applied to all non-PHP requests.
That second rule only applies to a "simple path", no matter if this path has a dot in it or not (e.g. hello.gif/ will match, too).
If this does not work for you, then you might consider one of these points to start further research:
the pattern ([^\.]*) matches everything that does not have a dot in it
see RewriteCond to skip rule if file or directory exists for RewriteConds where the following RewriteRule is only used if the request does not point to an existing file or directory
Hope this helps.

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]

url rewriting with htaccess not working

I am trying to rewrite my urls in my site so whatever is after the slash is passed as an argument (example.com/Page goes to example.com/index.php?page=Page)
here is the code that isn't working (it gives a Forbidden):
RewriteEngine On
RewriteRule ^/(.+)/$ /index.php?page=$1 [L]
Any Help will be appreciated
This is what I suggested in the comment to your question:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteRule ^(.+)$ /index.php?page=$1 [L,B]
The leading slash does not make sense in .htaccess style files, since you do not process an absolute oath in there, but a relative one. About the trailing slash: your example does not show such a slash, so why do you want to have it in the regular expression? It results in your pattern not matching anything but a request terminated by a slash. Which is not what you want.
The RewriteCond lines are there to still allow access to physical existing files and directories and to prevent an endless loop, though that should not occur with an internal-only rewriting. And you need the B flag to escape the part of the request url you want to specify as GET argument.
The last condition is actually obsolete, since obviously /index.php should be a file. I leave it in for demonstration purposes.
In general it is a very good idea to take a look at the documentation of apaches rewriting module: httpd.apache.org/docs/current/mod/mod_rewrite.html
It is well written, very precise and contains lots of really good examples. It should answer all your questions.

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 rule/condition gives file not found

This is what I am trying..
RewriteEngine On
RewriteCond $1 ^(.*)/__ver([0-9]+)__/(.*)$
RewriteRule ^(.*)$ /$1 [L]
What I am ultimately trying to do is version my file structure without actually changing the physical directory structure. I am also trying to set something up that will help prevent caching in some browsers. Either way I am basing this logic off of trying to remove the index.php from the URL with codeigniter but am failing.
I want to be able to in my html provide a uri in the src="" like
http://example.com/__ver333__/js/script.js
http://example.com/__ver333__/script.js
http://example.com/__ver333__/js/dir/script.js
or
__ver333__/js/script.js
__ver333__/script.js
__ver333__/js/dir/script.js
but as far as the server acts or is concerned I want it to remove the ver333 and pull the file accordingly. So its the equivilant of http://example.com/js/script.js or /js/script.js
RewriteCond $1 ^(.*)/__ver([0-9]+)__/(.*)$ does not mean anything. $1 is the first capture group in the regex in the first argument on that line. As this is the first argument, you are currently matching a file path against the characters $1. This will obviously never match.
What you want can easily be done with a regular rewriterule:
RewriteRule ^(.*)/__ver[0-9]+__/(.*)$ /$1/$2
Make sure that you enable the RewriteEngine and set RewriteBase /.

php to html .htaccess Help

I have the following code in the my .htaccess file and the top Rewrite works fine the bottem one does not I know why but I dont kno how to fix it.
Its seeing RewriteRule ^([^/]*).html index.php?p=order&course_id=$1 [L] as the top rewrite command becuase of the hightlighed part and i dont want to put it in a dir
RewriteEngine on
RewriteRule ^([^/.]+).html
index.php?p=$1 [L]
index.php?p=about_us
RewriteRule ^([^/]+).html
index.php?p=order&course_id=$1 [L]
index.php?p=order&course_id=5
Thank you,
Can you give example urls that should match the pattern block and what you would like them to be rewritten to? That would be very helpful.
One thing I notice is that your first regexp you test if you match the pattern block with a + which means 1 or more times and the second one you check it with a * which means 0 or more so I don't think the second one will ever be called, although I am very new to regexps but it is just something I noticed.
These are very helpful resources for me:
http://www.webforgers.net/mod-rewrite/mod-rewrite-syntax.php
http://forum.modrewrite.com/
From the example of the urls you would be using, this should work:
# http://website.com/about_us/ rewrites to /index.php?p=about_us
RewriteRule ^([0-9a-z_-]+)/?$ index.php?p=$1 [NC,L]
# http://website.com/order/12/ rewrites to /index.php?p=order&course_id=12
RewriteRule ^order/([0-9]+)/?$ index.php?p=order&course_id=$1 [NC,L]
The second Rewrite might be:
# http://website.com/order/12/ rewrites to /index.php?p=order&course_id=12
RewriteRule ^([0-9a-z_-]+)/([0-9]+)/?$ index.php?p=$1&course_id=$2 [NC,L]
Depending on your page structure.

Resources