Apache URL Rewriting little bit complex - apache

I would like to rewrite an url according to a specific model.
From:
http://myhost/aa/bb/value1?var2=value2&var3=value3
To:
http://myhost/aa/bb/index/index?var1=value1&var2=value2&var3=value3
value1: [:0-9TZ-]
value2: [0-9]
value3: [0-9]
Here is the solution I thought was good :
RewriteRule ^/?([\:0-9TZ-]*)\?(.*)$ /aa/bb/index/index?var1=$1&$2 [R,L]
But, here are the errors I get (I tried each one alone) :
: : give me an 404 error (aa/bb/2015-09-15T10:00Z not found)
\?(.*)$ and &$2: gives me an 404 error (aa/bb/2015-09-15T1000Z not found, whereas I was looking for http://myhost/aa/bb/2015-09-15T1000Z?count=2)
But it works if I try with:
RewriteRule ^/?([0-9TZ-]*) /aa/bb/index/index?var1=$1 [R,L]
and
http://myhost/aa/bb/2015-09-15T1000Z
Any help would by really appreciated.
Quentin

You can't match against the query string in a rewrite rule, but since you aren't changing the query string at all, you can simply use your second attempt and include a QSA flag so that the existing query string gets appended:
RewriteRule ^/?([0-9TZ:-]*) /aa/bb/index/index?var1=$1 [R,L,QSA]
You can also include a : in the square brackets to trap the colon. Any URL encoding gets decoded before the URI is sent through rewrite rules.

Related

.htaccess rule match part of new url and use as query string for old url

I am trying to match part of a URL and then use the matched expression to append onto the end of a query string from the old URL.
I have the following line in .htaccess, once I've worked out what I'm doing wrong I'll be able to fix the rest so for now I will just focus on the following line:
RewriteRule ^league/([^/]*)$/matches/? index.php?page_id=1074&league=$1
I would like ([^/]*)$ to appear where $1 is
So essentially: /league/29/matches/ would point to index.php?page=1074&league=29
Can anyone please tell me what I am doing wrong? :)
RewriteRule ^league/([^/]*)$/matches/? index.php?page_id=1074&league=$1
The $ (end-of-string anchor) after the subpattern ([^/]*)$, in the middle of the regex, does not make sense here and will cause the regex to fail. You should also be using the + quantifier here (1 or more). You are also missing the end-of-string anchor ($) at the end of the regex (otherwise the trailing /? is superfluous). Although you shouldn't really make the trailing slash optional on the rewrite as it potentially opens you up for duplicate content. (You should redirect to append/remove the trailing slash to canonicalise the URL instead.) You are also missing the L flag on the RewriteRule.
Try the following instead:
RewriteRule ^league/([^/]+)/matches/?$ index.php?page_id=1074&league=$1 [L]
Although, if you are expecting digits only (as in your example) then you should be matching digits, not anything. So, the following is perhaps "more" correct:
RewriteRule ^league/(\d+)/matches/$ index.php?page_id=1074&league=$1 [L]

mod_rewrite in .htaccess, go/*, go?, go?/* work, but go/?* doesn't

I tried going through some of the mod_rewrite questions on the site, but didn't find an answer to my problem (the fact that most questions were titled "mod_rewrite doesn't work" didn't help make that task any easier, hopefully my title is a little more helpful).
this is the content of my /somepath/.htaccess:
RewriteEngine On
RewriteRule ^go/(.*) /cgi-bin/goto.cgi?$1
# ^^^ WORKS: /somepath/go/200001..
RewriteRule ^go?(.*) /cgi-bin/goto.cgi$1
# ^^^ WORKS: /somepath/go?200001..
ErrorDocument 404 /cgi-bin/goto.cgi?error404
In testing, I made goto.cgi simply return $ENV{QUERY_STRING}, $ENV{QUERY_STRING_UNESCAPED} and $ENV{PATH_INFO}. Currently, the above rules mean that I am getting the QUERY_STRING passed on correctly when the urls:
/somepath/go/200001
/somepath/go?200001
/somepath/go?/200001
are accessed, but not when
/somepath/go/?200001
is accessed, in which case $ENV{QUERY_STRING}, $ENV{QUERY_STRING_UNESCAPED} and $ENV{PATH_INFO} are empty.
So the question is, what rule can I use so that
/somepath/go/?200001
gives my script the ?200001 or even /?200001 part back?
The first rule is destroying the query string of the example that fails, since $1 will be empty and an empty query string in the substitution removes any existing query string.
And the second rule is gibberish.
RewriteRule ^go/(.+)$ /cgi-bin/goto.cgi?$1
RewriteRule ^go/?$ /cgi-bin/goto.cgi

Rewrite to append to query string

I don't understand why I always have such a massive problem with rewrite rules, but I simply want to append to the query string if it exists and add a ? if it does not. I actually don't care if the URL is changed in the browser or not -- it just has to load the correct target page.
RewriteRule /cia16(.*)\?(.*) /cia$1?$2&CIA=16
RewriteRule /cia16(.*) /cia/$1?CIA=16
If I go to /cia16/steps.php?page=1 it actually gets rewritten to /cia/steps.php?CIA=16 -- that is it seems accept the query string part is not even considered part of the URL for the purposes of the rewrite.
What do I have to do to get the rewrite to work properly with an existing query string?
You can't match against the query string within a RewriteRule, you need to match against the %{QUERY_STRING} variable in a RewriteCond. However, if you want to just append the query string, you can just use the QSA flag:
RewriteRule /cia16(.*) /cia/$1?CIA=16 [QSA]
The URI: /cia16/steps.php?page=1 would get rewritten to /cia/steps.php?CIA=16&page=1. If for some reason, you need the page=1 before the CIA=16, then you can do something like this:
RewriteRule /cia16(.*) /cia/$1?%{QUERY_STRING}&CIA=16

Apache rewrite backreference variable not accessible after first use

I have come across a situation that seems odd to me. It seems that backreference variables when building apache rewrite rules get lost after the first use.
My requirement is changing an old URL pattern to conform to a new path pattern, e.g:
www.example.com/documents/newsletter/newsletter-issue-50.htm
to become
www.example.com/sites/default/newsletter/50/English/newsletter-issue-50.htm
As you can see, the new URL pattern needs to have the issue number specified in 2 places.
My rewrite rule is as follows:
RewriteRule ^documents/newsletter/newsletter-issue-(.*).htm$ http://www.example.com/sites/default/newsletter/$1/English/newsletter-issue-$1.htm [R=301,L]
When I use this rule, I still get a 404 because the resultant URL misses to replace the second "$1" with the issue number , in this case "50". What I get is
http://www.example.com/sites/default/newsletter/50/English/newsletter-issue-.htm
I have used this test site and it confirms that the second backreference variable is not being evaluated at all. Am sure am missing something here, since it should be a simple rule to put in place.
Any help on this would be greatly appreciated.
Thanks.
Strangely enough, I works in the rewrite tester if you surround with 2 sets of parenthesis:
RewriteRule ^documents/newsletter/newsletter-issue-((.*))[.]htm$ http://www.example.com/sites/default/newsletter/$1/English/newsletter-issue-$1.htm [R=301,L]
I have also escaped the file extension prefix

mod_rewrite rule gives 404 errors

I am having problems with mod_rewrite which is throwing me the same error 404 is as follows:
RewriteRule ^music.mp3?id=(.*)$ music.php?id= [L]
i need url /music.mp3?id=1 and real url /music.php?id=1
any idea??
I think something is misunderstood in the path RewriteRule
You can't match against the query string (everything after the ? in the URL) in a RewriteRule. But you're not really matching against it anyways, it looks like you just need to appended to your target URI, so:
RewriteRule ^music\.mp3$ music.php [L]
Should be good enough. Any query string parameters (like ?id=1) will automatically get appended at the end.
In your expression (the engine rule), what you want to say is:
"When the url starts with music.mp3?id=, take whatever is after the = and change the URL to music.php?id= and put the part after id="
In regular expressions the . character has special meaning. If you want to say "the dot character", and not give it special meaning, you need to escape it, but putting a \ behind it, like this:
^music\.mp3?id=(.*)$
#Jon Lin already gave you the other part, which is about query strings.