Trouble with mod rewrite and slashes and $_GET - regex

I'm trying to implement nicer urls using mod rewrite to a php script I wrote to view documents pulled from a mysql database by their entry name. i use the following code and it works fine.
RewriteRule ^view.doc.(.+) index.php?doc=$1
so basically
view.doc.xyz whould be index.php?doc=xyz
But im having trouble with entry names with '/' and '\' in them being viewed through the rewritten link.
view.doc.abc/123 into index.php?doc=abc/123
or like
view.doc.sg1\123 into index.php?doc=sg1\123
Ether i'd get an endless loop or get a 404 error. I'm pretty new to mod rewrite and Id very much appreciate any help on the matter.

Try this rule:
RewriteRule ^view\.doc\.(.+)$ index.php?doc=$1 [L,QSA,NE,NC]

I propose a slightly different solution from the #anubhava's one, by prepending a slash before index.php, tested on Debian/Apache2:
RewriteEngine On
RewriteRule ^view\.doc\.(.+)$ /index.php?doc=$1 [L,QSA,NE,NC]
It gives:
view.doc.abc/123 => /index.php?doc=abc/123
I cannot test anti-slash \, as no browser permits me to test this in URL without transforming it to slash /.

Related

How to redirect from specific subdirectory to a subdomain via .htaccess?

I've been trying to redirect this URL (and all its substructures):
http://example.com/archive/
to (and its corresponding substructures):
http://archive.example.com/
For example: http://example.com/archive/signature/logo.png ==> http://archive.example.com/signature/logo.png
I tried to generate an .htaccess rule using a generator and evaluating it by looking at the regex, which I can understand (I think).
The result was the following rule:
RewriteEngine On
RewriteRule http://example.com/archive/(.*) http://archive.example.com/$1 [R=301,L]
The way I see it, the server will proccess any URL that starts with http://example.com/archive/ , will capture the string that comes next and will change the whole initial portion with the subdomain structure and append the captured string.
Unfortunately, this doesn't seem to work neither on my server, nor on online testing tools such as: http://htaccess.madewithlove.be/
Is there anything I'm missing there?
Thank you!
You should be able to try it this way.
RewriteEngine On
RewriteRule ^archive/(.*)$ http://archive.example.com/$1 [R=301,L]
Note that I did not make it dynamic as you didn't specific if you will have more URL's that need to work this way as well or not.

Htaccess mod_rewrite issue - Regex not working correct

just experiencing a huge (for me, the regex newb) problem:
We have a multiste with nested folders, and one line in the htaccess fails in converting to the correct urls:
RewriteRule ^(.+)?/(wp-.*) /$2 [L]
The line should break out everything before the first wp-, and append the rest of the string to the root url. f.e:
/kitchen/wp-includes/js/mediaelement/wp-mediaelement.css
should become
/wp-includes/js/mediaelement/wp-mediaelement.css
but with the above Regex converts to
wp-mediaelement.css
On Urls where there is only one wp-, the thing works. So the error is that apache takes the last occurence of wp- instead of the first.
Long talking:
How can i adjust the above regex to work as expected?
Greets to all!
Edit: Beforte the first wp- can be anything. not only one path. It could also be
/lalelu/loleli/wp-includes
RewriteRule ^(.*?)/(wp-.*) /$2 [L]
should do the trick
edit: http://htaccess.madewithlove.be is a nice tool to quickly debug your rewrite rules

.htaccess rewrite rule remove everything after RK=0/RS=

I have a website that is getting a lot of requests for pages that don't exist.
All the requests are based on an existing page, but have RK=0/RS= plus a random string of characters at the end.
For example, the request is:
www.domain.com/folder/article/RK=0/RS=M9j32OWsFAC_u8I6a0xOMjYKU_Q-
but the page www.domain.com/folder/article does exist.
I would like to use htaccess to say:
if RK=0/RS= exists, remove it and everything after
but haven't been able to get it working.
All the htaccess rules talking about removing query strings, but I'm guessing because this doesn't have a ? it's not a query.
Could someone help me understand how to do this?
Someone found where this mess is coming from.
http://xenforo.com/community/threads/server-logs-with-rk-0-rs-2-i-now-know-what-these-are.73853/
It looks like actually NOT malicious, it's something broken with Yahoo rewrites that create URLs that point to pages that don't exist.
The demo described on xenforo does replicate it, and the pattern of the URLS that Yahoo is producing:
http://r.search.yahoo.com/_ylt=A0SO810GVXBTMyYAHoxLBQx./RV=2/RE=1399899526/RO=10/RU=http%3a%2f%2fkidshealth.org%2fkid%2fhtbw%2f/RK=0/RS=y2aW.Onf1Hs6RISRJ9Hye6gXvow-
Sure does look like the RV=, RE=, RU=, RK=, RS= values are of the same family. It's just that somewhere the arg concatenation is screwing up on their side.
You can use this rule in root .htaccess file:
RewriteEngine On
RewriteRule ^(folder/article/)RK=0/RS= /$1 [L,NC,R=301]

Problem with htaccess GET form variables in a rewritten url

Essentially my problem is thus; I have a MVC system that redirects all requests to index.php on my site. I have a rewrite rule in my htaccess file to handle those requests like so:
RewriteRule ^([a-zAZ\_\-]+)\/([a-zA-Z\_\-]+)\/([^\/?]*) /?module=$1&class=$2&event=$3
Which translates urls into these type of urls
http://example.com/users/login/
http://example.com/users/info/me
My problem is that I also want GET variables to be applied and used in the URL like so
http://example.com/users/login/?var1=val1&var2=val2
http://example.com/users/info/me?var1=val2...
I've written two different regexes that work perfectly well in a my workbench (expresso) and I've tested them out in PHP however they refuse to work in htaccess. They're not particular complex, I have tried:
^([a-zAZ_\-]+)\/([a-zA-Z_\-]+)\/([^\/\?]*)[\?]*(.*) /?module=$1&class=$2&event=$3&$4
and
^([a-zAZ_\-]+)\/([a-zA-Z_\-]+)\/([^\/\?]*)(?(?=\?)\?(.+)) /?module=$1&class=$2&event=$3&$4
Neither of these work and I'm racking my brains as to why. Essentially it just doesn't recognise the fourth group and returns nothing I thought it might have been due to it being next to an ampersand but I did &var=$4 as a test and it still fell over.
Any help with this would be greatly appreciated as this is driving me insane.
Thanks in advance,
Rupert S.
After all, this is what you need:
RewriteRule ^([a-z_-]+)/([a-z_-]+)/([^/?]*) /?module=$1&class=$2&event=$3 [QSA,NC,L]
[QSA] will append the additional GET parameters to the rewritten query string.
[NC] since it is case insensitive, no need for A-Z matches

Mod-rewrites on apache: change all URLs

Right now I'm doing something like this:
RewriteRule ^/?logout(/)?$ logout.php
RewriteRule ^/?config(/)?$ config.php
I would much rather have one rules that would do the same thing for each url, so I don't have to keep adding them every time I add a new file.
Also, I like to match things like '/config/new' to 'config_new.php' if that is possible. I am guessing some regexp would let me accomplish this?
Try:
RewriteRule ^/?(\w+)/?$ $1.php
the $1 is the content of the first captured string in brackets. The brackets around the 2nd slash are not needed.
edit: For the other match, try this:
RewriteRule ^/?(\w+)/(\w+)/?$ $1_$2.php
I would do something like this:
RewriteRule ^/?(logout|config|foo)/?$ $1.php
RewriteRule ^/?(logout|config|foo)/(new|edit|delete)$ $1_$2.php
I prefer to explicitly list the url's I want to match, so that I don't have to worry about static content or adding new things later that don't need to be rewritten to php files.
The above is ok if all sub url's are valid for all root url's (book/new, movie/new, user/new), but not so good if you want to have different sub url's depending on root action (logout/new doesn't make much sense). You can handle that either with a more complex regex, or by routing everything to a single php file which will determine what files to include and display based on the url.
Mod rewrite can't do (potentially) boundless replaces like you want to do in the second part of your question. But check out the External Rewriting Engine at the bottom of the Apache URL Rewriting Guide:
External Rewriting Engine
Description:
A FAQ: How can we solve the FOO/BAR/QUUX/etc. problem? There seems no solution by the use of mod_rewrite...
Solution:
Use an external RewriteMap, i.e. a program which acts like a RewriteMap. It is run once on startup of Apache receives the requested URLs on STDIN and has to put the resulting (usually rewritten) URL on STDOUT (same order!).
RewriteEngine on
RewriteMap quux-map prg:/path/to/map.quux.pl
RewriteRule ^/~quux/(.*)$ /~quux/${quux-map:$1}
#!/path/to/perl
# disable buffered I/O which would lead
# to deadloops for the Apache server
$| = 1;
# read URLs one per line from stdin and
# generate substitution URL on stdout
while (<>) {
s|^foo/|bar/|;
print $_;
}
This is a demonstration-only example and just rewrites all URLs /~quux/foo/... to /~quux/bar/.... Actually you can program whatever you like. But notice that while such maps can be used also by an average user, only the system administrator can define it.