MVC3 .net 4.0 extensionless urls and isapi_rewrite - asp.net-mvc-3

Unfortunatly I am forced to use IIS6 for my MVC website. .net 4.0 adds functionality to mimic the stupid hack for getting extensionless urls to work in IIS6. My website is designed to take advantage url rewriting for SEO purposes. The keyword urls that the client wishes to use dictate an elaborate url rewriting scheme.
The problems with Microsofts impelmentation of the feature really comes down to url rewriting and the attempt to match a pattern. I have seen various rules that attempt to strip the dreaded eurl.axd from the url so that the patterns will match. I attempted to use these rules
RewriteRule ^(.)/eurl.axd/[a-f0-9]{32}(.)$ $1$2
or
RewriteRule (.)eurl.axd/. $1
which does work but it also introduces other problems when there are nested redirects. i.e. handling old urls to new ones, etc
what happens is the eurl.axd gets stripped and on the redirect the isapi_filter doesnt get the request which results in an IIS 404 errror.
Tinkering around with the urls, i came up with this possible solution.
RewriteRule ^generators/generator-parallel-capability/([^/])/([^/])$ /generators/htmlcontent/generator-parallel-capability/$1/$2 [NC,L]
it just grabs the eurl.axd portion and rewrites it to the executing url with it appended.
Is there a better way? I have several hundred urls that meet this pattern and it would be nice to have a single rule handle them all.

We used one generic rule on top of the config to cut the /eurl.axd234234
RewriteRule ^(.)/eurl.axd.$ $1 [NC]
this must work for everything but the root.

Using the rewrite rule RewriteRule ^(.)/eurl.axd.$ $1 [NC] results in some unplesant behavior when the url is rewritten more than one time. i.e. from an old url to the new vanity url then to the actual execution url.
Using maps, I was able to produce a pattern that works quite nicely and keeps the .htaccess file from being cluttered.
RewriteCond ${contentmap:$2} >"" [NC]
RewriteRule ([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /$1/${contentmap:$2}/$2/$3/$4 [NC,L]
RewriteCond ${contentmap:$2} >"" [NC]
RewriteRule ([^/]*)/([^/]*)$ /$1/${contentmap:$2}/$2 [NC,L]
The first detects the pattern /controller/some-content/eurl.axd/1234 and rewrites it to /controller/some-controller-action/eurl.axd/1234
the second does the same thing just without the eurl junk at the end. this is for my dev machine running iis 7
Im sure there are better ways and I am certainly open to better suggestions.

Related

Using mod_rewrite or htaccess to apply 301's to entire site structure, with URL's built using query strings

I am taking over an old website, and need to change the domain name.
The current domain is http://www.example.com/folder/ and the new domain is http://example.school.nz
An example of an existing and desired URL is:
Before: http://www.example.com/folder/index.php?page=sport
Desired: http://example.school.nz/about-us/sport
The site is built using CMSMS (http://www.cmsmadesimple.org), so pages and URL's are generated through the CMS, although it's easy enough to export a list of URL's.
Ideally I could set up 301 redirects for the entire site so the user doesn't get 404'd. Any clues to the easiest way to accomplish this?
It depends on how general you want things to be, but this set of rules will do what you asked in your question:
RewriteCond %{HTTP_HOST} .*
RewriteCond %{QUERY_STRING} page=sport
RewriteRule ^folder/index.php http://example.school.nz/about-us/sport? [L,R=301]

Apache2 redirect all but some pages back to http using vhosts

I am using rewrite rules with Apache 2 to redirect certain types of pages to HTTPS using vhosts. These are anything that starts with mydomain.com/users. In other words, all pages having to do with users and their information should be on HTTPS. I want to redirect all other pages to HTTP.
What happens now is that when a user goes to a /users page, he is redirected fine to HTTPS. But when he navigates away from the /users area, I can't get the redirect back to HTTP.
I need the rules and conditions to rewrite anything that is NOT /users/* to HTTP. In other words, please help me fill in the blanks:
RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{REQUEST_URI} __blank__
RewriteRule __blank__ http://mydomain.com%{REQUEST_URI} [R=301,L]
In researching this, there are a few things I am trying to avoid. I need a wildcard under /users because I am developing the app and often add pages under users (it's a Rails app).
I understand that it is not easy to do a NOT match with regular expressions. All I am trying to do here is have the bulk of the site run on HTTP except the /users/* pages on HTTPS.
Also, yes I have a valid cert and yes I have verified that the Apache2 rewrite mod works. I can get all URLs rewritten to HTTP no problem. How do I NOT rewrite ones that start with /users in the REQUEST_URI? I think I have actually tried about every answer on this site so far...
There quite a few answers for this sort of questions, -- you just need to search this site a bit. Yes, they do not answer your question 100% straight away (as everyone has slightly different requirements -- like different page name etc) but the whole approach is the same.
In any case -- here how it can be done:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
# don't do anything for images/css/js (leave protocol as is)
RewriteRule \.(gif|jpe?g|png|css|js)$ - [NC,L]
# force https for /users/*
RewriteCond %{HTTPS} =off
RewriteRule ^/users/ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# force http for all other URLs
RewriteCond %{HTTPS} =on
RewriteCond %{REQUEST_URI} !^/users/
RewriteRule .* http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# your other rewrite rules below
These rules need to be placed inside VirtualHost directive BEFORE any other rewrite rules (if such present). If placed elsewhere some small tweaking may be required.
They will
force HTTPS for all resources in /users/,
do nothing for images, css styles and JavaScript files (to be precise, for files with those extensions)
and will force HTTP for all other URLs
IMPORTANT NOTE: It is very likely that these rule will not work for you straight away. That is because modern browser do CACHE 301 redirects from your previous attempts. Therefore I recommend testing it on another browser and change 301 to 302 during testing (302 is not cached) .. or clear all browser caches (maybe even history) and restart browser.

Redirecting all dynamic URLs from an old site to a single static url

We had an old coldfusion website a couple of years ago and I recently realized there are some old links still floating around causing 404 errors. I don't know what was on any of the pages and I just want to redirect them to a new static page. Our new site is a Joomla 1.5 site with SEF URLs turned on.
An old URL would look like this: http://www.example.com/content.cfm?id=2010 where the only difference between the URLs would be the number after id=.
I want to redirect any URL that begins with content.cfm to a the static page http://www.example.com/oops-thats-an-old-page which lists some helpful links to find what they are looking for.
I am successfully accomplishing this with the following code in the .htaccess file:
RewriteCond %{QUERY_STRING} id=
RewriteRule (.*) http://www.example.com/$1? [R=301]
RewriteRule ^content\.cfm$ /oops-thats-an-old-page [R=301,L]
I'm new to rewriting URLs and I'm not sure this is the best way to do it. I am also concerned that it may brake non-sef joomla URLs that I am not aware of because they also have the id= in them.
Can I make the rewrite conditional on whether or not it begins with content.cfm?
The first rule will already be applied when the query contains id=. If you don’t want that but rather redirect only if /content.cfm with query containing id= was requested, try this rule:
RewriteCond %{QUERY_STRING} id=
RewriteRule ^content\.cfm$ /oops-thats-an-old-page? [R=301,L]

mod_rewrite rule not working

I have the following rules in my htaccess:
RewriteRule ^([^/.]+)/?$ list.php?categoryShortForm=$1&locationShortForm=world [QSA]
RewriteRule ^([^/.]+)/([^/.]+)/?$ list.php?categoryShortForm=$1&locationShortForm=$2 [QSA]
RewriteRule ^([^/.]+)/([^/.]+)/[^/.]*-p([0-9]+)/?$ view.php?categoryShortForm=$1&locationShortForm=$2&postingId=$3 [QSA]
In my localhost (windows, xampp), it all works fine.
In my real server (linux, apache) the first 2 rules work fine, but not there 3rd one.
For example:
/plastic-surgery/california-usa/ works fine, but
/plastic-surgery/los-angeles-california-usa/test-1-p1 gives me a 404
Any idea??
Check to make sure that you can browse directly to the target URLs. If mod_rewrite is rewriting onto something that doesn't exist, you'll get that 404. It might help to ratchet up mod_rewrite's log level to a high value, so you can see what it's rewriting to.
I am a little unclear on how your working URL is supposed to actually work. All three of your patterns start with "one or more non-slash, non-period characters" ([^/.]+), but URLs going into the pattern matching start with slashes: "/plastic-surgery/california-usa/".
Have you turned on mod_rewrite logging and checked out what mod_rewrite is actually doing?
RewriteLog "/tmp/rewrite.log"
RewriteLogLevel 9

How to deal with "#" in a query string in mod_rewrite?

I asked this question about rewriting old "ugly" links into seo friendly ones.
I need to "extract" some information after the "sharp" symbol in some urls. I've created a regular expression to it but it can't seen to work.
After my question, I created this logic for this url for example, script.php?mode=full&id=23:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /script\.php\?mode=full&id=([0-9]+)\ HTTP/
RewriteRule ^script\.php$ fix_old_urls.php?phpfile=script2&id=%1 [NC,L]
But I'm working in a legacy application, and I need to extract the value after the sharp symbol in some pages, in the example url script.php?mode=full#23:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /script\.php\?mode=list\#([0-9]+)\ HTTP/
RewriteRule ^script\.php$ fix_old_urls.php?phpfile=script&id=%1 [NC,L]
(in fix_old_urls I properly redirect with a 301 code).
The first one works, but not the second. To me it looks like it`s the same logic in both. What am I'm doing wrong?
Anchor information (the part starting with the #) is never actually sent to the server. It's handled completely by the browser, and thus you can't touch it with mod_rewrite (nor can you access it via server-side scripting languages). The only things that can see it are the browser and client-side scripts (like Javascript).

Resources