Having problems with a Rewrite rule - mod-rewrite

I have an application most of it is still in development that's why i need to block access on all pages but just not two of them.
Suppose i have a.php all requests will be redirected to here except b.php.
So i think there should be 3 rules:
1st: when a.php and b.php are requested they should be visible to user,
2nd: if anything other than those two is requested,
it should be redirected to a.php.
3rd: for external css,javascript and image files
there should be an access rule
Since i dont have much experience with server administration, i believe i'm totally lost:)
This is what i tried:
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !^/b.php
RewriteRule !\.(js|ico|txt|gif|jpg|png|css)$ a.php

In practice you would swap the second and third rule as your second rule would be the default route:
# 1st
RewriteRule ^(a\.php|b\.php)$ - [L]
# 3rd
RewriteRule \.(js|ico|txt|gif|jpg|png|css)$ - [L]
# 2nd
RewriteRule !^a\.php$ a.php [L]
The subsitution - means that the URI is not changed.

I am not sure what you means about #3 but see from what you are trying, I guess you means, all js,ico,... are to be redirect to a.php. Is that right?
If so, that means, a => a.php (with parameter), b => b.php (with parameter) and other => a.php. So try this:
RewriteBase /
RewriteRule ^a\.php(.*) /a.php$1
RewriteRule ^b\.php(.*) /b.php$1
RewriteRule ^.* /a.php
But if you means that all those script and media files are to be accessible normally, try this:
RewriteBase /
RewriteRule ^a\.php(.*) /a.php$1
RewriteRule ^b\.php(.*) /b.php$1
RewriteRule ^(.*)\.(js|ico|txt|gif|jpg|png|css)$ /$1.$2
Basically, the rewrite rule is the regular expression and $1,$2,... are match-string group (those wrapped with "(" and ")").
Hope this help.

Related

Regex not matching the whole word in htaccess rule

I'm trying to work out why this doesn't work:
RewriteRule ^search/(.*)-more([0-9]+).html /cgi-bin/search.cgi?bool=and&substring=0&query=$1;nh=$2 [P,L]
RewriteRule ^search/(.*).html /cgi-bin/search.cgi?bool=and&substring=0&query=$1 [P,L]
Example usage:
http://foo.com/search/test.html
http://foo.com/search/test-more-2.html
http://foo.com/search/test%20extra.html
http://foo.com/search/test%20extra-more-2.html
The first 2 work fine - test gets passed along to the query param.
However, on the 2nd one - it gets cutoff at %20 ... so instead of passing test%20extra, all it passes is test
I've compared a similar rule I'm using on another server, and it works fine with (.*) as the selector... so I'm not sure whats different here!
Any suggestions?
Argh... I got it! It wanted NC,L and not P,L as the flags. So:
RewriteRule ^search/(.*)-more([0-9]+).html /cgi-bin/search.cgi?bool=and&substring=0&query=$1;nh=$2 [P,L]
RewriteRule ^search/(.*).html /cgi-bin/search.cgi?bool=and&substring=0&query=$1 [P,L]
Needed to be:
RewriteRule ^search/(.*)-more([0-9]+).html /cgi-bin/search.cgi?bool=and&substring=0&query=$1;nh=$2 [NE,L]
RewriteRule ^search/(.*).html /cgi-bin/search.cgi?bool=and&substring=0&query=$1 [NE,L]

mod_rewrite: transform = and & in slashes

I was just looking for a solution to transform any =,?,& found in a query string into a simple slash /.
To be more specific, my link is something like:
http://www.mydomain.com/product.php?c=1&sc=12&products_id=15
and I would it like this:
http://www.mydomain.com/product.php/c/1/sc/12/products_id/15
whatever the master page could be (in this case is product.php, but it could be foo.php, bar.php...or else).
I have googled a lot but didn't find any good solution to achieve what i'm looking for.
I have found complex rewrite rules, but they all include the "page name" into them:
i.e.
RewriteRule ^/?index/([^/]+)/([^/]+)$ /index.php?foo=$1&bar=$2 [L,QSA]
That rule is only applicable to index.php and to known variables like foo, bar.
I need a more general one, whatever the master page is, whatever the variables are.
Can this be done?
Any suggestion?
Thanks
I assume you're using apache >= 2.2. Add this to your apache conf:
<IfModule mod_rewrite.c>
RewriteEngine On
# you absolutely need to use RewriteBase if this snippet is in .htaccess
# if the .htaccess file is located in a subdirectory, use
# RewriteBase /path/to/subdir
RewriteBase /
RewriteCond %{QUERY_STRING} ^(=|&)*([^=&]+)(=|&)?(.*?)=*$
RewriteRule ^(.*)$ $1/%2?%4= [N,NE]
RewriteCond %{QUERY_STRING} ^=$
RewriteRule ^(.*)$ $1? [R,L]
</IfModule>
The first RewriteCond/RewriteRule pair repeatedly matches a token delimited by & or = and adds it to the path. The important flag is the [N] that causes the whole ruleset to start over again, as often as the rule matches. Additionally, a = is appended to the end of the query string. This is to create a mark in the URL that at least one rewrite has happened.
The second ruleset checks for the = mark that remains after the URL has been rewritten completely and issues a redirect.
Have a look at http://wiki.apache.org/httpd/RewriteQueryString for some useful hints.

mod rewrite - multiple variables

Apologies if this is a basic solution but mod rewrite still give me gip.
I have a current mod rewrite rule to convert a slug into a usable variable like so:
RewriteRule ^/c/([a-z0-9_\-]+)/?.*$ /content.asp?slug=$1 [L]
I need to add a second, optional variable. Only the slug matters, the second variable may or may not be there.
www.domain.com/this-is-the-slug/
and
www.domain.com/this-is-the-slug/optional-variable/
should both work. I tried:
RewriteRule ^/c/([a-z0-9_\-]+)/([a-z0-9_\-]+)/?.*$ /content.asp?slug=$1&scotland=$2 [L]
But now every page (without the optional variable) just redirects to the root.
any ideas?
I worked it out.
I need both rules:
RewriteRule ^/c/([a-z0-9_\-]+)/([a-z0-9_\-]+)/?.*$ /content.asp?slug=$1&scotland=$2 [L]
RewriteRule ^/c/([a-z0-9_\-]+)/?.*$ /content.asp?slug=$1 [L]

Rewrite Query String with .htaccess

I'm trying to do a very simple rewrite of a query string
http://www.example.com/library.php?q=abscessed-tooth
to
http://www.example.com/library/abscessed-tooth
This is the code that I've written in my .htaccess file and it is doing nothing
RewriteEngine On
RewriteRule ^/library/?([^/]*)/?\/http://www.example.com/library.php?q=$1 [L]
Maybe likely .htaccess files are not considered in your environment. If in doubt turn on RewriteLogging as it is explained in the excellent documentation of the rewriting module.
Oh, and check the error log, you have a syntax error in the RewriteRule anyway: RewriteRule takes 2 arguments plus flags, your rule has only a single argument:
RewriteEngine On
RewriteRule ^library/([^/]*) http://www.example.com/library.php?q=$1 [L]
You need dollar sign in the end of "left" part not question mark:
^/library/([^/]*)/$ http://www.example.com/library.php?q=$1 [L]
Also do you need the question mark between / and ( ? It doesn't look like lookahead or lookbehind?
Try without wrapping slashes as well
^library/([^/]*)$ http://www.example.com/library.php?q=$1 [L]

Problem redirect CodeIgniter URLs to WWW

I have a CI application that uses .htaccess for URL routing. My basic setup is as follow:
RewriteRule ^$ /var/www/html/ferdy/jungledragon/index.php [L]
RewriteCond $1 !^(index\.php|images|img|css|js|swf|type|themes|robots\.txt|favicon\.ico|sitemap\.xml)
RewriteRule ^(.*)$ /var/www/html/ferdy/jungledragon/index.php/$1 [L]
These rules are pretty standard for CI apps. They rewrite all URLs (except for those in the exception list) to the index.php front controller. The lines above also hide index.php, as it would normally appear as part of every URL.
So far, so good. Everything works just fine. Now, for the sake of SEO I would like to force all traffic to www. So I extended the rules as follow:
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^$ /var/www/html/ferdy/jungledragon/index.php [L]
RewriteCond $1 !^(index\.php|images|img|css|js|swf|type|themes|robots\.txt|favicon\.ico|sitemap\.xml)
RewriteRule ^(.*)$ /var/www/html/ferdy/jungledragon/index.php/$1 [L]
rewritecond %{http_host} ^jungledragon.com [nc]
rewriterule ^(.*)$ http://www.jungledragon.com/$1 [r=301,nc]
These last two lines rewrite http://jungledragon.com/anything URLs to http://www.jungledragon.com/anything URLs. This kind of works, but it brings back the index.php part back: http://jungledragon.com/anything becomes http://www.jungledragon.com/index.php/anything.
How exactly do I combine these rules so that they do not interfere with each other? I tried doing the WWW rewrite before the CI rules. That shows an Apache 301 page with an error, rather than doing the actual redirect.
Additionally, I would like to also include rules to get rid of trailing slashes, but for now let's keep the question simple. Note that I did find useful post here and elsewhere yet for some reason I still can't find the correct exact syntax for my situation.
Edit: Thanks for the help. This works:
Options +FollowSymlinks
RewriteEngine on
rewritecond %{http_host} ^jungledragon.com [nc]
rewriterule ^(.*)$ http://www.jungledragon.com/$1 [r=301,nc,L]
RewriteRule ^$ /var/www/html/ferdy/jungledragon/index.php [L]
RewriteCond $1 !^(index\.php|images|img|css|js|swf|type|themes|robots\.txt|favicon\.ico|sitemap\.xml)
RewriteRule ^(.*)$ /var/www/html/ferdy/jungledragon/index.php/$1 [L]
mod_rewrite processes rules in a linear fashion. Rules at the top of the file are processed first.
The [nc] and [L] at the end of the rules are the options for how to process rules.
nc - nocase: case insensative
L - last: last rule in the execution (if you hit this, stop processing)
You need to put your www redirect rules above your CI rules so it will first add the www, THEN apply the CI rules to the newly re-written url. **And also use either the C or N flag with your www redirect rule so it will parse the next rule.
http://mysite.com/blah ==becomes==> http://www.mysite.com/blah ==becomes==> http://www.mysite.com/index.php/blah (Executed, not redirected)
What's happening currently is:
http://mysite.com/blah ==becomes==> http://mysite.com/index.php/blah (STOP)
Browser goes to http://mysite.com/index.php/blah and a second re-write pass is done since your exceptions stop /index.php urls from being processed
http://mysite.com/index.php/blah ==becomes==> http://www.mysite.com/index.php/blah (Redirected)
As Suggested, here is a link to mod_rewrite's documentation if you want to look further.
#LazyOne: Brainfart, sorry.
Here's an excerpt from the docs outlining the flags you'll probably need:
'chain|C' (chained with next rule)
This flag chains the current rule with the next rule (which itself can be chained with the following rule, and so on). This has the following effect: if a rule matches, then processing continues as usual - the flag has no effect. If the rule does not match, then all following chained rules are skipped. For instance, it can be used to remove the .www'' part, inside a per-directory rule set, when you let an external redirect happen (where the.www'' part should not occur!).
'next|N' (next round)
Re-run the rewriting process (starting again with the first rewriting rule). This time, the URL to match is no longer the original URL, but rather the URL returned by the last rewriting rule. This corresponds to the Perl next command or the continue command in C. Use this flag to restart the rewriting process - to immediately go to the top of the loop.
Be careful not to create an infinite loop!
'nocase|NC' (no case)
This makes the Pattern case-insensitive, ignoring difference between 'A-Z' and 'a-z' when Pattern is matched against the current URL.
'noescape|NE' (no URI escaping of output)
This flag prevents mod_rewrite from applying the usual URI escaping rules to the result of a rewrite. Ordinarily, special characters (such as '%', '$', ';', and so on) will be escaped into their hexcode equivalents ('%25', '%24', and '%3B', respectively); this flag prevents this from happening. This allows percent symbols to appear in the output, as in

Resources