ampersand in friendly url failing with rewrite module - iis-7.5

I can do say: ?a=1&b=r%26d to the aspx page just fine. The & in the second parameter is encoded as %26 since & is reserved as a delimiter.
I downloaded and installed the URL Rewrite Module 2.0 for IIS7.5 on 2008 R2.
I wrote a simple rule: ^([^/]+)/([^/]+)/?$ to match and rewrite the url: Default.aspx?a={R:1}&b={R:2}.
So, things like 1/a b work out fine to ?a=1&b=a b, but something like 1/a%26b or 1/a&b only work out to ?a=1&b=a it seems everything is cutoff after that %26 or & at run-time. However, in the Server Manager I can test the rewrite and nothing is cut-off in the test tool in their GUI.
Not sure what to do about this, everything I've done seemed pretty straight-forward. So to be clear, how can I have a friendly URL that has an ampersand in it (or %26 if I have to) and have the URL Rewrite 2.0 module pass along the full parameter?

It took a while, but I found the answer. The URL gets decoded before it's passed, so an extra variable is created.
Anyways, the solution was actually quite simple. Turns out all I needed to do was adjust the Rewrite URL rule to this:
Default.aspx?a={UrlEncode{R:1}}&b={R:2}
The UrlEncode function will encode {R:1} correctly.

Related

IIS URL Rewrite - need help rewriting friendly urls for a forum

I'm new to using the URL Rewrite module and I'm having trouble with what I thought would be a simple URL rewrite for forum threads (using IIS 7.5)
I need to rewrite:
/forum/100/2534/friendly-title
or:
/forum/100/2534/334/comment/friendly-thread-title
to:
/forum/?forum=100&thread=2534&post=334&postType=comment
The rule that I have written (not working) is:
^forum/([1-9][0-9][0-9]*)/([1-9]*)/(([1-9]*)/(post|comment)/)?([a-zA-Z0-9-]{5,50})$
Which maps to:
/forum/?forum={R:1}&thread={R:2}&post={R:4}&postType={R:5}
I'm getting a 404 error.
It's correct that {R:4} and {R:5} are empty when you use the first URL. That's because there are no values for these fields. The RegEx still matches though so the URL will still be rewritten. Your code should properly handle empty values for the post and postType querystring parameters to display the entire thread and not just a specific comment (at least that what I assume is suppose to happen).
By the way, a more logical URL structure would be:
/forum/100/2534/friendly-thread-title/comment/334
This won't help you this this particular problem though but just on a side note.

Multiple and Variable parameters URL rewriting

I don't know how to rewrite URLs of this type:
mywebsite/param1-val1-param2-val2-param3-val3-param4-val4.html
that's really simple to do BUT my problem is that my parameters are variables like:
mywebsite/param1-val1-param3-val3-param4-val4.html
or
mywebsite/param3-val3-param4-val4.html
so, the number of parameters is not always the same. It can sometimes be just one, sometimes it can be 10 or more. It redirects to a search script which will grab the parameters through GET querystring.
What I want to do is to not write (on htaccess) a line for every link. The links are pretty simple in that form separated by a -(hyphen) sign.
Rather than rely on complex rewrite rules, I would suggest a simple rewrite rule and then modifying the code of your web application to do the hard part. Supporting this kind of variable parameters is not something that a rewrite rule is going to be very good at on its own.
I would use the following rewrite rule that intercepts any url that contains a hyphen separator and ends in .html
RewriteRule ^(.+[\-].+)\.html$ /query.html?params=$1
Then in your web application can get the parameters from the CGI parameter called params . They look like this now param1-val1-param3-val3-param4-val4. Your code should then split on the hyphens, and then put the parameters into a map. Most web frameworks support some way of adding to or overriding the request parameters. If so, you can do this without doing invasive modifications to the rest of your code.

& Ampersand in URL

I am trying to figure out how to use the ampersand symbol in an url.
Having seen it here: http://www.indeed.co.uk/B&Q-jobs I wish to do something similar.
Not exactly sure what the server is going to call when the url is accessed.
Is there a way to grab a request like this with .htaccess and rewrite to a specific file?
Thanks for you help!
Ampersands are commonly used in a query string. Query strings are one or more variables at the end of the URL that the page uses to render content, track information, etc. Query strings typically look something like this:
http://www.website.com/index.php?variable=1&variable=2
Notice how the first special character in the URL after the file extension is a ?. This designates the start of the query string.
In your example, there is no ?, so no query string is started. According to RFC 1738, ampersands are not valid URL characters except for their designated purposes (to link variables in a query string together), so the link you provided is technically invalid.
The way around that invalidity, and what is likely happening, is a rewrite. A rewrite informs the server to show a specific file based on a pattern or match. For example, an .htaccess rewrite rule that may work with your example could be:
RewriteEngine on
RewriteRule ^/?B&Q-(.*)$ /scripts/b-q.php?variable=$1 [NC,L]
This rule would find any URL's starting with http://www.indeed.co.uk/B&Q- and show the content of http://www.indeed.co.uk/scripts/b-q.php?variable=jobs instead.
For more information about Apache rewrite rules, check out their official documentation.
Lastly, I would recommend against using ampersands in URLs, even when doing rewrites, unless they are part of the query string. The purpose of an ampersand in a URL is to string variables together in a query string. Using it out of that purpose is not correct and may cause confusion in the future.
A URI like /B&Q-jobs gets sent to the server encoded like this: /B%26Q-jobs. However, when it gets sent through the rewrite engine, the URI has already been decoded so you want to actually match against the & character:
Rewrite ^/?B&Q-jobs$ /a/specific/file.html [L]
This makes it so when someone requests /B&Q-jobs, they actually get served the content at /a/specific/file.html.

.htaccess mod_rewrite variables through redirect

Short Version:
I wrote the question, and realized most people wouldn't want to read that much text. Consider the below reference, here's the TL;DR:
I need to 301 redirect this url http://app.com/search/foo-bar/
to this url http://app.com/#!/search/foo-bar/
and send this: /foo-bar/, or anything else past /search/ to a server side script. In this case, it's written in php.
Edit for clarity:
Current answers seem to focus on the rewrite to hashbang. That part is not the problem. The problem is that I lose any associated data when rewriting to a hashbang url, as the server side will see app.php as the location, not app.php/#!/foo-bar/ - So I need to capture foo-bar, and send it to the server somewhere other than in the URL. The rewrite works, and is not the issue. Thanks for your answers though!
Long Version:
Ok, so I have an interesting issue that has been tough for me to figure out.
The Scenario:
I have a backbone.js app that uses the hashbang for state:
app.com/#!/search/search-term/key-value/foo-bar/
In addition, I have google traffic coming to the site from the previous version that will be hitting "pretty url" style urls:
app.com/search/search-term/key-value/foo-bar/
I use an .htaccess mod_rewrite to swap the old url out for a hashbanged one if a user hits the legacy url.
I recently introduced a javascript-less bootstrapped version of the site that the site will be built on top of to gracefully downgrade and support crawlers. This is written using php.
For the php site to work, I need to pass in the values past the hashbang to the server side script, so I can figure out what to display.
The Problem:
When I transform a url and add an anchor, everything past the anchor (hashbang) is no longer sent to the request, so I don't have access to it in php.
RewriteRule search/?(.*) #!/search/$1 [R=301,NC,L]
My options for sending things to the server side then are reduced to:
1. Query String
2. Environment Variables
3. Headers
So, I tried sending things via the query string
RewriteRule search/?(.*) #!/search/$1?filter=$1 [R=301,NC,L]
Obviously that didn't work (the query is behind the anchor), so I tried it in front of the hashbang
RewriteRule search/?(.*) ?filter=$1/#!/search/$1 [R=301,NC,L]
That works, but is hideous and redundant to the end user. So, I thought I might try using environment variables.
RewriteRule search/?(.*) /!#/search/$1 [R=301,NC,L,E=FILTER:$1]
That failed, because environment variables aren't preserved through a redirect (duh). I turned to using headers:
RewriteRule search/?(.*) /#!/search/$1 [R=301,NC,L,E=FILTER:$1]
Header set filterParams "%{FILTER}e"
But for some reason, the headers aren't received by the page through the redirect. That seemed to make sense (although I've now stepped well outside of my comfort level with apache directives), so I tried echoing the header, in hopes that it would be passed, received by the second rewrite (that didn't find search), and echoed out.
RewriteRule search/?(.*) /#!/search/$1 [R=301,NC,L,E=FILTER:$1]
Header set filterParams "%{FILTER}e"
Header echo filterParams
Nada - the filter doesn't exist, so although it makes it to the server, it is null. My next thought was to attempt to employ some sort of conditional. Here was my attempt:
RewriteRule search/?(.*) legacy.php/#!/search/$1 [R=301,NC,L,E=FILTER$1]`
<FilesMatch "legacy.php">
Header set filterParams "%{FILTER}e"
</FilesMatch>
Header echo filterParams
That didn't seem to work either, so I'm stumped. I realize that I've spent so long on this that I probably have the solution within my grasp and I'm just tired of looking at it, or it's not even remotely possible, even with gross header hacking.
Anyone have a clue how to to this?
rfc1738.txt says # is not a valid url character
additionally the apache docs says # signals a comment in apache config files.
short answer is your solution is broken not your implementation
AFAIK, there's no good way to preserve variables through redirect without sticking them in the query string...

Is it possible to handle such URL

http://www.example.com/http://www.test.com
I have tried many different methods using .htaccess with no luck. I need to get that second url coming as parameter. Is it possible to redirect it to index.php and get it as $_SERVER["REQUEST_URI"] or other method? Thanks
UPD: Looks like it is impossible to get whole URL, question marks are not recognized. Ideal example:
127.0.0.1/http://www.test.com/script.php?a=hello&b=world#blabla;par2?%par3
and i need to get in my index.php exact string
www.test.com/script.php?a=hello&b=world#blabla;par2?%par3
It's definitely possible: http://downforeveryoneorjustme.com/http://www.google.com/
As to how, it's been covered on ServerFault already
The Problem:
This is a problem with Apache running on Windows. Apache on Windows does not let you have a colon (:) in your REQUEST URI. This is basically for avoiding URLs like http://www.mysite.com/C:/SomeFile.exe but is actually annoying.
If you use mod_rewrite at the same time it will be skipped.
You and some applications (like wikipedia) uses colon : in URL. so what to do in Apache on Windows?
The Solution:
At the time of writing this answer this bug still persists and there is no absolute solution, BUT there is a trick:
You may change your URL to something like this:
http://www.mysite.com/url/http://www.test.com
in this example http://www.mysite.com/ is your SCRIPT PATH and /url/http://www.test.com is your REQUEST URI.
The problem will be gone if there is a Slash (/) before Colon (:).
You can get the URI but only without the fragment since that is not transmitted to the server. Try this rule:
RewriteRule ^http:/ index.php [L]
Then the requested URI path plus query (so the part from the third / up to the first # or the end of the URI) is available at $_SERVER['REQUEST_URI'].

Resources