I can not understand apache rewrite which use $1 in rewriteCond - regex

for example:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php)
RewriteRule ^(.*)$ /index.php/$1 [L]
I can not undertand the meaning of $1 in the RewriteCond.
If $1 appoint to (.*) of RewriteRule,so we can use like that in the RewriteCond?

Yes $1 corresponds to first matching group in your RewriteRule. This is usually done to prevent infinite looping (dreaded internal 500 error in Apache).
PS: This condition may not be necessary here since you already have RewriteCond %{REQUEST_FILENAME} !-f before it.

Related

htaccess regex to grab additional field

I have the following regex although it only picks one variable and puts that in user like user contains user/url, how would I modify this to grab the url variable seperately in $2.
RewriteCond %{HTTP_HOST} ^(^.*)\.example.com$ [NC]
RewriteRule ^(.+/?[^/]*)$ http://example.com/index.php?sub=%1&url=$1 [P,NC,QSA,L]
I need this to translate
http://sub.example.com/user/url
to
http://example.com/index.php?sub=%1&user=$1&url=$2
Your regex to capture 2 values from RewriteCond and RewriteRule doesn't seem correct.
You may use:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com$ [NC]
RewriteRule ^([^/]+)(?:/([^/]+))?/?$ http://example.com/index.php?sub=%1&user=$1&url=$2 [P,NC,QSA,L]
I assume you have mod_proxy setup since you're using P flag.

Use .htaccess to replace after the first slash but keep query

I have the following link:
http://example.net/invite/12345
I need to replace it to http://example.net/wedding/index.php?main_page=invite&invite_code=12345
I've got the following....but I'm just not hitting the nail here.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.*)$ /wedding/index.php?main_page=invite&invite_code=$1 [L,QSA]
It's taking me to:
http:///example.net/wedding/index.php?main_page=invite&invite_code=invite%2F12345
Thanks for the help!
$1 is a reference to the capturing group (.*), so:
RewriteRule ^invite/(.*)$ /wedding/index.php?main_page=invite&invite_code=$1 [L,QSA]

htaccess RewriteCond: Why doesn't a server variable match itself?

Perhaps a better question would be, is there any way to use server variables in the matching string?
For example, I can't understand why this fails to match:
RewriteCond %{REQUEST_URI} %{REQUEST_URI}
First, two points.
I know this condition servers no purpose as is.
I know I have poor knowledge of both htaccess and regex.
What I want is to generically turn this URL www.example.com/dir/path/info into www.example.com/dir?foo=/path/info for bootstrapping.
I tried to accomplish this by removing the extra path info from the deepest actual directory in the URL. I was trying this code to test the premise:
RewriteEngine On
Options -Multiviews -Indexes +FollowSymLinks
RewriteBase /
DirectorySlash Off
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} (.+)%{PATH_INFO}
RewriteRule ^(.+?) index.php?dir=%1&path=%2 [L]
No luck. To troubleshoot I reduced it to this:
RewriteCond %{PATH_INFO} (.+)
RewriteRule ^(.+?) index.php?dir=%1 [L]
As expected the query returned foo='/path/info'
So I tried this which I thought would match no matter what:
RewriteCond %{PATH_INFO} %{PATH_INFO}
That failed so as a last attempt, I tried capturing the string:
RewriteCond %{PATH_INFO} (.+)
RewriteCond %{PATH_INFO} %1
That also failed to find a match which has me baffled. %1 should be the complete %{PATH_INFO} string. How could it not match itself???
I don't think it matters but I'm using XAMPP on Windows7 in FastCGI.
Rewrite pattern params only allow regex (tho Condpattern also has special flags for tests and comparisons):
RewriteCond TestString CondPattern
RewriteRule Pattern Substitution
Server variables like %{REQUEST_URI} can only be used in Teststring and Substitution. The following docs outline this usage:
http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewritecond
http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriterule
If this will go in your main .htaccess, perhaps try:
RewriteCond %{REQUEST_URI} !index\.php$
RewriteRule ^([^/]+)/(.+)$ index.php?dir=/$1&path=/$2 [L]
Two more Example:
Sample1
RewriteBase /
RewriteRule ^(.+/)?index.php(/.+) index.php?dir=/$1&path=$2 [R,L]
Sample2
RewriteBase /
RewriteRule ^((.+/)?index.php)(/.+) $1?path=$3 [R,L]
Sample3
RewriteBase /
RewriteRule ^(.+/)?(.+\.php)(/.+) $1$2?foo=$3 [R,L]
these all do external rewrite so you can see result in the browser address. To revert to internal rewrite, just remove [R] flag
Ok, I found a way to accomplish this goal.
Basically I was trying to compare two server variables. htaccess won't do that. I wanted to extract part of a "pretty" url which points to an actual file or folder. The variable ${SCRIPT_URL} should do that, but it is either depreciated or not reliable. The work around is to put both variables in the test string and use a regex back reference to find the point of duplication.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI}%{PATH_INFO} (.*?)(/.+)\2$
RewriteRule ^(.*)$ %1.php?strappath=%2 [QSA,END]
In the above example %1 will be the uri of the file and %2 will be the remaining path after the URI, duplicating %{PATH_INFO}.
Follow with this rule for when there is no extra path info
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)$ $1.php [QSA,END]
If no .php file is found, I want the index of that directory and add the un-found file name to the pathinfo. This is a bit trickier.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php !-f
RewriteCond %{REQUEST_FILENAME} ^(.*)(/.+)$
RewriteCond %1 -d
RewriteCond %1/index.php -f
RewriteCond %{REQUEST_URI}%{PATH_INFO} ^(.*?)(/.+)\2$ [OR]
RewriteCond %{REQUEST_URI} ^(/.+)(/.+)?$
RewriteCond %1 ^(.*)(/.+)$
RewriteRule ^(.*)$ %1/index.php?strappath=%2%{PATH_INFO} [QSA,END]
The above section fails to catch urls that point directly to an existing folder with an index.php, so to catch those:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_FILENAME}/index.php -f
RewriteCond ^(.+)$ $1/index.php [QSA,END]
I doubt anyone ever finds this useful but I've seen variations of this question asked over and over with no working solution given.

rewrite move up directory

I have a rewrite rule where if you type:
www.whatever.com/profile-one.php
that is the url you see, but the actual template page is:
www.whatever.com/profile.php
Here are the lines in htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)([^/])$ http://www.whatever.com/$1$2/ [R=301,L]
RewriteRule profile-(.*)\.php$ profile.php?name=$1
My problem is, if you visit a url like:
www.whatever.com/second/profile-one.php
It still tries to bring back the profile page, even though the profile.php template does not exist in the "second" directory. What would be the best way to prevent this please?
This is happening due to wrong regex here. You need to use start anchor in your 2nd rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)([^/])$ http://www.whatever.com/$1$2/ [R=301,L]
RewriteRule ^profile-(.*)\.php$ profile.php?name=$1 [L,QSA]

Rewrite condition catchall if the URI doesn't start with this

So I have this rewrite condition at the bottom of my .htaccess file as a catchall. works great, but I want it to ignore any requests and begin with "/index.cfm"
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.+) /index.cfm?event=baduri&uri=$1
so /index.cfm?fddssds would not be touched
but /gdfgdfgdfdgf would be redirected..
Can you try this and let me know:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/index.cfm
RewriteRule (.+) /index.cfm?event=baduri&uri=$1 [L,NC]
Use a RewriteCond directive to check whether the URL path does not start with /index.cfm
RewriteCond %{REQUEST_URI} !^/index\.cfm
RewriteRule (.+) /index.cfm?event=baduri&uri=$1
See this question:
Rewriteengine in .htaccess to catch files not ending in html