.htaccess - translation to layman terms needed - regex

My .htaccess is running with the Zend framework and one of our developers previously added this code:
RewriteCond %{THE_REQUEST} ^.*/index.php
RewriteRule ^(.*)/index.php$ http://www.mydomain.com/$1 [R=301,L]
Can someone please translate this to English for me? I believe it is saying, if someone tries to access index.php, then do a 301 redirect to the main domain (i.e. don't show the world "index.php" exists). I don't know why the RewriteCond is there when the RewriteRule has the same rule it seems, perhaps this was a mistake. Anyway I don't know if it even works as there are other rules and my site can actually access the index.php file (no redirection) so perhaps the above can be removed entirely. Looking for a proper translation of this to understand.
Many thanks!

Actually both RewriteCond and RewriteRule are required here. But first thing first this rule isn't going to work way it is.
Correct working code will be this:
RewriteCond %{THE_REQUEST} /index\.php [NC]
RewriteRule ^(.*?)index\.php$ /$1 [L,R=301,NC,NE]
Main difference is presence of / in your RewriteRule which will fail it for http://domain.com/index.php
Explanation:
THE_REQUEST variable represents original request received by Apache from your browser
You need to match URI with THE_REQUEST to make sure /index.php is there in the original URI and not a result of some internal rewrite to /index.php
If you remove RewriteCond it might still work but you have to make sure that none of rules are rewriting your URI to /index.php anywhere.

The RewriteCond test string contains the server-variable %{THE_REQUEST} which takes the form:
GET /index.php HTTP/1.1
or
POST /login.php HTTP/1.1
The condition pattern ^.*/index.php contains a regular expression that matches anything with /index.php in it...
The ^ marks the start of the string, the .* matches zero-or-more instances of any character and the /index.php is self-explanatory.
So, any URL which contains /index.php will be matched. If the condition pattern ended with a $ symbol (the end-of-string symbol), then it wouldn't match any instance of %{THE_REQUEST} as all instances of %{THE_REQUEST} contain the HTTP request type after the URL.
The RewriteRule is then used to do the 301 redirect as you describe, but importantly, the RewriteRule directive matches it's pattern against the current URL (and not against the whole request string like the RewriteCond does in this example).
The RewriteRule pattern ^(.*)/index.php captures (denoted by the brackets) everything in front of /index.php and then creates a 301 redirect that removes the /index.php.
#anubhava has pointed out that if you visit website.com/index.php then the RewriteRule won't work, because the URL it matches against does not include the leading /.
Those two lines can be rewritten as:
RewriteRule ^(.*)index.php$ http://www.mydomain.com/$1 [R=301,L,NC]
Then, if you visit http://website.com/index.php then the (.*) part of the pattern will match an empty string.
Or if you visit http://website.com/sub/folder/index.php then the (.*) part of the pattern will match sub/folder/, which is then referenced in the substitution string by $1.
Remember that every redirect works by telling the browser to request a new URL, and each request gets re-processed by the htaccess, so if there are other rules that allow viewing index.php then that could explain why you can see some URLs containing index.php.

Related

.htaccess redirect from old root domain to new specific sub-dir domain

RewriteEngine on
RewriteRule ^(.*)$ http://www.NEWfoobar.com/$1 [R=301,L]
I have this line of code from https://stackoverflow.com/a/7578810, inside .htaccess and it currently works by migrating www.OLDfoobar.com to www.NEWfoobar.com and all its sub-directory structure just fine (intended behavior, all good)
now, how do I add additional rule that captures www.OLDfoobar.com to redirect to one specific page in www.NEWfoobar.com? say for example `www.NEWfoobar.com/welcomeToNewDomain
The [L] flag is what gets me. and btw, I'm not so sure about what the $1 is for. That can't be a regex flag for the RewriteRule pattern, yes?
ACCEPTED ANSWER
RewriteEngine on
RewriteRule ^/?$ http://www.NEWfoobar.com/some/sub/directory [R=301,L]
RewriteRule ^(.*)$ http://www.NEWfoobar.com/$1 [R=301,L]
You need
RewriteEngine on
RewriteRule ^(.*)$ http://www.NEWfoobar.com/welcomeToNewDomain [R=301,L]
The $1 meant use the first capture group which is the value between the brackets on the left.
The L in the options means stop processing the rewrite rules (ie this is the Last Rule) if the match applies.
The ^(.*)$ means:
`^` match beginning of string
`(.*)` match zero or more characters and store in capture group 1
`$` match end of string
If I've miss understood an you only want to redirect the root requests while keeping the old capture you need to add a new rule before the existing one that reads
RewriteRule ^/?$ https://www.NEWfoobar.com/welcomeToNewDomain [R=301,L]
This will match either an empty path or just /

Htaccess Regex won't match

I'm in desperate need of a quick tip.
Trying to use htaccess to change this not so lovely url
http://localhost/test/index.php?page=Article&articleID=61
to
http://localhost/test/article/2015-09-21-this-is-the-headline
From what I've gathered I need to send the last part to a php script which can then get the matching id from the database. Knowing that I should be able to send the user to the original url up top.
RewriteRule ^(.*)\/article\/(.*)$ redirect/article.php [L]
# RewriteRule ^(.*)$ index.php
As of right now I'm not passing the information to the script yet. redirect/article.php only contains a print statement to let me know once I get that far.
However, despite my brain and every regex debugger saying otherwise, it won't match the url provided in the second code box. All I'm getting is the good old 404. If I activate the second rule it is applied to my url, telling me that the first one is simply being skipped.
What am I missing?
.htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
# rename individual pages
RewriteRule ^(.*)\/article\/(.*)$ redirect/article.php [L]
# RewriteRule ^(.*)$ index.php
# resize images
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.)*\/([0-9]+)\-(([0-9]|[a-z])+)\.(prev)$ filePreview.php?id=$2&size=$3 [L]
php_value upload_max_filesize 20M
php_value post_max_size 21M
</IfModule>
The location of a .htaccess file informs how you must list paths for mod_rewrite. Inside .htaccess, paths for RewriteRule are not received with a leading /. Since yours was residing in /test, the (.*) at the start of your rule wasn't matching anything and harmless. Since that was followed by /, the article/ path was expecting a / it would never receive. The simplest fix is to change this rule to match article at the start via:
RewriteRule ^article/(.*) redirect/article.php [L]
Assuming you'll use that as a lookup in the PHP script, add a parameter to use the $1 captured pattern like:
RewriteRule ^article/(.*) redirect/article.php?article=$1 [L]

mod_rewrite: Redirect all urls ending with "/video/[anyfilename].mp4"

Sorry for this probably very noob-style question, but I just can't get it to work.
Here's my current .htacces file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteRule ^_res/.*$ - [L] # all URLs beginning with "_res" are not changed.
# put new fancy rule doing what I want here...
RewriteRule . index.php [L] # all other URLs are redirected to index.php
</IfModule>
This works fine. It's redirecting all urls except the ones starting with "_res/" to index.php.
What I need now is that all URLs matching "[anypath]/video/[anyfilename].mp4" will be rewritten to "content/[anypath]/video/[anyfilename].mp4" (which is the actual path of this file on the server - I can't use x-sendfile on this shared web space, thus I need to rewrite large file urls to their actual server locations to avoid php's fileread-function).
From my understanding of these RewriteRules, I think I have to place this rule just before the last one.
Unfortunately my regexp-expertise is practically non-existent.
What I thought should work is this:
RewriteRule ^(.*)/video/(^/*)\.mp4$ content/$1/video/$2.mp4 [L]
The regexp should mean "starts with any amount of any characters, followed by "/video/", followed by any amount of any characters which are not '/' and ends with ".mp4".
When I insert this into my .htaccess right before the last rule, urls ending with "/video/myvid.mp4" are still rewritten to index.php.
You see me clueless. Any suggestions?
Thanks alot in advance!
I think you want:
RewriteCond %{REQUEST_URI} !^/content/
RewriteRule ^(.*)/video/([^/]+)\.mp4$ content/$1/video/$2.mp4 [L]
And you want to add this rule above the one that routes to index.php

rewrite rule: regular expression to remove variable from link

I've got urls like this one:
my-party/viewparty/243-party-in-berlin-2013.html
where the variable part of the url is:
243-party-in-berlin-2013.html
I neet to get a url like:
events/party-in-berlin-2013.html
how can I do it with the apache rewrite rule? I've managed to remove the "my-party/viewparty" but I can't remove the portion of variable link.
Thank you very much
Alessandro
The following will map any URI in the format:
my-party/viewparty/<digits>-<rest-of-file-name>.html
to
/events/<rest-of-file-name>.html
RewriteEngine On
RewriteCond %{REQUEST_URI} my-party/viewparty/\d+-([^\.]*\.html)$
RewriteRule .* /events/%1 [L]
The way it works, is that it captures (what's inside the parentheses) the last part (denoted by the dollar-sign) of the request uri, that ends with .html and is preceded by my-party/viewparty/\d+-, where \d+ denotes a string of digits, with a minimum length of one digit. It then appends this captured pattern (denoted by %1) to /events/ in the RewriteRule.
If you want to redirect (301 Moved Permanently) to the new URI, use:
RewriteEngine On
RewriteCond %{REQUEST_URI} my-party/viewparty/\d+-([^\.]*\.html)$
RewriteRule .* /events/%1 [R=301,L]
And, if the party-in-berlin-2013 part is not variable, then you could can simply replace the RewriteCond with this:
RewriteCond %{REQUEST_URI} my-party/viewparty/\d+-(party-in-berlin-2013\.html)$

.htaccess determine if refferer is not current domain

I'm trying to create an .htaccess mod_rewrite that will behave differently if the current referer isn't my own domain. For instance, say I own example.com (i.e. www.example.com, http://example.com, etc). When somebody goes to example.com (or an subdomain such as beta.example.com), I want to ignore this .htaccess rule. So I guess the regex would basically just look for example.com somewhere in it and ignore those.
However, is a domain such as otherdomain.com (which is assumed to point to example.com via cname or A-record) access my site, I want to redirect them somewhere. Here's what I have so far that I believe is close but isn't working.
My main confusion with these rules is the part that comes after the RewriteRule (^$ in this case). I've seen a few different things put there in my Googling and I'm not sure on the differences. For instance, I've also seen just a ^, a (.*)$, etc.
RewriteCond %{HTTP_REFERER} !^http://([^.]+\.)*(example)\.com
RewriteRule ^$ redirectfile.php [L]
I've also been messing with
RewriteCond %{HTTP_REFERER} ^http://(.+\.)*\.com
RewriteCond %1 !^(example)\.$
RewriteRule ^$ redirectfile.php [R=302,L]
Try
RewriteCond %{HTTP_REFERER} !^http://([^.]+\.)*example\.com
RewriteRule ^ redirectfile.php [L]
You had ^$, which would only match the home page.
I changed it to just ^ which will match every request, assuming that you want to match every request.
A (.*)$ would also match every request, but also capture the match so that you reuse in in the target as $1