Mod_rewrite based on IP and use linked folder name - apache

I want to use .htaccess to rewrite to a folder based on the visitors IP-address. I have a list of IP-addresses with associated usernames (in a text file). The usernames are also the folder names.
192.168.0.2 - John
192.168.0.3 - Ben
Example: when John (IP ..0.2) goes to www.domain.com, he must see the the content of folder /John
Because the username-IP binding will be made in PHP, I prefer to use RewriteMap so I can generate a .txt file.
Unfortunately, I have to idea where to start. Rewriting based on the users IP is not the problem, the problem is finding the linked username.
Any help appreciated!

There are several ways of doing this, but I wonder why as there are a number of existing modules that provide user directory and authentication already, anyway you could:
# Call an external program each time
RewriteMap userDir "prg:/srv/www/cgi-bin/ipToUserDirectoryMapper.php"
RewriteCond %{REQUEST_URI} !somePatternCommonToAllAlreadyRewrittenRequests
RewriteRule .* /${userDir:%{REMOTE_ADDR}}%{REQUEST_URI} [L,R]
where: ipToUserDirectoryMapper.php takes an IP address as an argument and returns a directory, with a default for unknown IP's.
alternitively, is the mapping is in a txt file:
# Use a static remap file
RewriteMap userDirMap "txt:/srv/www/ipToDirectoryMap.txt"
RewriteCond %{REQUEST_URI} !somePatternCommonToAllAlreadyRewrittenRequests
RewriteRule ^(.*) /${userDirMap:%{REMOTE_ADDR}|someDefaultUser}%{REQUEST_URI} [L,R]
Note: your directory names will need a common element, or you'll need to set a CGI parameter or environment variable for the user directories ( SetEnvIf Request_URI "^/John" alreadyRewritten), to prevent a redirection loop eg. call your directories UserJohn, UserBen and instead of somePatternCommonToAllAlreadyRewrittenRequests have:
**!^/User[a-zA-Z0-9-_]+**

Related

Redirect to a specific page from any dir or subdir in htaccess

Is it possible to use an universal rule to redirect to a specific page from whatever directory or subdirectory using .htaccess?
To be more precise, if I want to have an URL like example.com/login that redirects to example.com/login.php?action=login, I use the following line in my .htaccess file:
RewriteRule ^login$ /login.php?action=login [L]
But is it possible to to have a rule that lets me redirect from example.com/any_directory/login to example.com/login.php?action=login? So from anywhere down the example.com subdirectories to ``example.com/login.php?action=login`. And if yes, how can I do this
Certainly that is possible. Easiest is to use a rewrite condition since that operates on the absolute request path even inside a dynamic configuration file. Rewrite rules operate on a relative path i such location which makes matching complicated...
Take a look at this simple example:
RewriteEngine on
RewriteCond %{REQUEST_URI} /login$
RewriteRule ^ /login.php?action=login [L]
If you do the rewriting in the http servers host configuration instead you can simplify that. Reason is that it is always absolute paths the rules work on in that location:
RewriteEngine on
RewriteRule /login$ /login.php?action=login [L]
The main approach in both variants is to rely on the slash preceding the login key word. It always is present in an absolute request path and clearly left-delimits the key word. And not to insist on matching at the line start.
And a general hint: you should always prefer to place such rules inside the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).
You need to adjust your regex pattern .Simply remove the ^ ,so that it can match anychars before login/ in uri ie : /foobar/login .
RewriteRule /login/?$ /login.php?action=login [L]

Apache 301 redirect with get parameters

I am trying to do a 301 redirect with lightspeed webserver htaccess with no luck.
I need to do a url to url redirect without any related parameters.
for example:
from: http://www.example.com/?cat=123
to: http://www.example.com/some_url
I have tried:
RewriteRule http://www.example.com/?cat=123 http://www.example.com/some_url/ [R=301,L,NC]
Any help will be appreciated.
Thanks for adding your code to your question. Once more we see how important that is:
your issue is that a RewriteRule does not operate on URLs, but on paths. So you need something like that instead:
RewriteEngine on
RewriteRule ^/?$ /some_url/ [R=301,L,NC,QSD]
From your question it is not clear if you want to ignore any GET parameters or if you only want to redirect if certain parameters are set. So here is a variant that will only get applied if some parameter is actually set in the request:
RewriteEngine on
RewriteCond %{QUERY_STRING} (?:^|&)cat=123(?:&|$)
RewriteRule ^/?$ /some_url/ [R=301,L,NC,QSD]
Another thing that does not really get clear is if you want all URLs below http://www.example.com/ (so below the path /) to be rewritten, or only that exact URL. If you want to keep any potential further path component of a request and still rewrite (for example http://www.example.com/foo => http://www.example.com/some_url/foo), then you need to add a capture in your regular expression and reuse the captured path components:
RewriteEngine on
RewriteRule ^/?(.*)$ /some_url/$1 [R=301,L,NC,QSD]
For either of this to work you need to have the interpretation of .htaccess style files enabled by means of the AllowOverride command. See the official documentation of the rewriting module for details. And you have to take care that that -htaccess style file is actually readable by the http server process and that it is located right inside the http hosts DOCUMENT_ROOT folder in the local file system.
And a general hint: you should always prefer to place such rules inside the http servers host configuration instead of using .htaccess style files. Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

apache redirect / Rewrite-Engine

Is the following possible?
A user requests the url http://example1.com/example.php and the apache opens http:// example1.com/example.php?id=1
A user requests the url http://example2.com/example.php and the apache opens http:// example2.com/example.php?id=2
But the user should not see the id in his browser adress bar (the user should only see http://example1.com/example.php or http://example2.com/example.php).
You can say the id is invisible for the user but transfered to the example.php.
How can I implement this?
Is that the correct solution?
RewriteEngine On
RewriteRule ^/example.php http://example1.com/example.php$1 [P]
ProxyPassReverse /example.php?id=1 http:// example1.com/example.php
RewriteEngine On
RewriteRule ^/example.php http://example2.com/example.php$1 [P]
ProxyPassReverse /example.php?id=2 http:// example2.com/example.php
You have to understand several concept.
Once the server received the user requested url he can do several things
Take the requested path from the url and use it without modifications. That's the default solution
Map the requested path to any other physical path, things that can be done via Alias, AliasMatch or RewriteRules.
Map the requested path to another website while hiding the fact thtat another website is requested. That's the proxy solution, thta mod_proxy or mod_rewrite could handle (but you do not need that)
Redirect the user to another path, sending him a new url to use, making another client/server roundtrip, with Redirect instructions or mod_rewrite (the swiss knife). But you do no need that.
So you want a server-side only remapping of the requested path.
Let,s say we will use mod rewrite to make this mapping. If you check all tags available in RewriteRule (summary here) the interesting ones are:
passthrough|PT : Forces the resulting URI to be passed back to the URL mapping engine for processing of other URI-to-filename translators, such as Alias or Redirect.
qsappend|QSA: Appends any query string from the original request URL to any query string created in the rewrite target
last|L: Stop the rewriting process immediately and don't apply any more rules. Especially note caveats for per-directory and .htaccess context (see also the END flag)
nocase|NC: Makes the pattern comparison case-insensitive.
details on the PT flag shows that:
The target (or substitution string) in a RewriteRule is assumed to be a file path, by default.
Well, that,s maybe enough for you. But using PT is a good thing, if you have other apache configusation elements you should try to let them apply after mod_rewrite job.
So... assuming you may need to handle some query strings arguments and that this id argument is based on the domain name in the request, and that only the example.php script needs this behavior; you should start your research with such rules (untested):
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example1.com$ [nocase]
RewriteRule ^example\.php$ example.php?id=1 [passthrough,qsappend,last]
RewriteCond %{HTTP_HOST} ^example2.com$ [nocase]
RewriteRule ^example\.php$ example.php?id=2 [passthrough,qsappend,last]

Using .htaccess to restrict access to files

I have 2 domains hosted on the same account but I want to restrict the second one to not access files.
I have abc123.com and zyx987.com.
In my php I do everything I need to display the domain name and template based on the domain but I want only the /download files to be accessed from abc123.com.
The download folder has files like: file1.pdf or file2.zip.
I tried the 'deny from all' but this didnt work since the other domain is blocked too.
Is there another way?
Here's what you have to do. Put this in your .htaccess
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^(www.)?zyx987.com$
RewriteRule ^download - [F]
This will block any request like:
/download/
/download/file1.jpg
/download/another/file.zip
and give a permission denied.

rewritemap for SEO and pretty URLs

I am attempting to redirect & rewrite some dynamic PHP URL's to pretty and SEO friendly URLs. I have manged to do this successfully through .htaccess with the following code:
RewriteCond %{QUERY_STRING} ^somevar=green&nodescription=([a-zA-Z0-9_-]*)$
RewriteRule (.*) /green\/%1\/? [L,R=301]
RewriteRule ^green/([^/]*)/$ /script.php?somevar=green&nodescription=$1&rewrite=on [L]
This creates a somewhat pretty URL as follows:
http://www.mysite.com/green/aA43-/
As I say, this works absolutley fine. Apart from one thing. The parameter nodescription contains a non-descriptive random set of letters, numbers and other characters.
I would like to rewrite the nodescription parameter to a more descriptive one. I understand that I can do this with a rewritemap through Apache. However, I have no experience at doing soemthing like this, and I'm not entirely sure where to start.
Normally I would simply alter script.php so that it contains more descriptive parameters, but this time I have no control over the script; I am pulling it from another site using cURL.
Can anybody give me an example of how to pull this off?
Thanks!
Matt
Well, to answer my own question, to pull this off you need access httpd.conf file on your apache server. My shared hosting company didn't allow access to this file (I doubt any would allow you access).
So I bit the bullet and purchased a VPS. I will post the steps I took here in order to set the rewritemap up in the hope that it will help a lost soul :) Ok, here goes...
My VPS has WHM installed, so in WHM I went to:
Server Configuration >> Apache Configuration >> Include Editor
Pre Virtual Host Include >> All Versions
This feature takes any text you put in and includes it in your httpd.conf file without worrying that it will be overwritten at a later stage. If you don't have WHM on your server then you can add the text directly to your httpd.conf file; make sure it is outside and before any virtual hosts.
OK, so I included the following map declaration and rewrite rule:
#Map to redirect (swaps key and value)
RewriteMap rwmap txt:/home/*/public_html/rdmap.txt
<Directory /home/*/public_html/test>
Options All -Indexes
RewriteEngine on
RewriteRule ^url/([^/]*)/$ /script.php?foo=${rwmap:$1|$1}&rewrite=on [L]
</Directory>
The actual map is a simple text file containing key/value pairs - you need to place this file in the directory declared in RewriteMap rwmap txt:/home/*/public_html/rdmap.txt.
And there you go. Apache now rewrites my URLs for me and I now have some nice and pretty SEO optimized links thanks to my rewrite map! Hoorah!
RewriteEngine on
RewriteRule ^green/([^/]*)/(.*)$ /script.php?somevar=green&nodescription=$1&rewrite=on [L]
This rewrite will allow you to pass "arbitrary text" that has nothing to do with the rewrite. For example:
http://www.mysite.com/green/aA43-/some-seo-boosting-title
Will still reroute correctly to script.php; the latter part will simply be ignored by the rewrite.