Posts Tagged ‘Managed Fusion’

August 18th, 2009

How to create a Reverse Proxy using Url Rewriter

I just wanted to share a really well written article on how to setup a Reverse Proxy, by John Gully, using the Url Rewriter that I have been working on for the past 2 years. Here is an excerpt from his article.

I recently came to realize that our website situation was growing out of hand. We had a corporate website, an intranet site, and even a site for web access to email. All of these sites were scattered across multiple servers and each was on a unique port. While this worked, it was not simple. Each new site had to have a new rule configured in the firewall, and who wants the hassle of putting port number at the end of a url?

The solution to this mess turned out to be adding a reverse proxy to our network. By simply providing different urls (www.example.com, mail.example.com) the incomming traffic can be anlayzed by the proxy server and routed to the appropriate internal web server. All the incomming traffic is sent over the default port 80 so the end user never sees any difference. That’s exactly what I wanted, great!

Since our sites are all built upon ASP.NET and hosted on IIS6 the natural option for this was Microsoft ISA Server. Unfortunately, the $1500 cost was way beyond our small company’s internal IT budget. So it was off to Google for me, and after some searching, it appeared that the open source project Url Rewriter by ManagedFusion [sic] seemed to fit the bill.

Thanks for the great write up John.  I hope to be including John’s article in an up coming FAQ wiki on my CodePlex project site in the near future.

Tags: , ,

Posted in How To | kick it on DotNetKicks.com | Bookmark | View blog reactions | No Comments »

April 18th, 2009

Managed Fusion URL Rewriter Was Featured at PDC 2008

The Managed Fusion URL Rewriter, that I work on and that runs this blog, was featured in PDC 2008 by CJ Saretto (Senior Program Manager for Microsoft Home Server). He used it as a reverse proxy to demonstrate streaming video and music from Windows Home Server to the internet from a simulated internal home network.

I have cut down the actual video presentation to the segment that mentioned the Managed Fusion URL Rewriter. If you want to skip to the good parts in this segmented video, I recommend:

  • 2:20 – Managed Fusion URL Rewriter is first mentioned
  • 7:00 – An impressive video demonstration streaming through the rewriter


Clips comes from about 18:00 minutes in to http://channel9.msdn.com/pdc2008/ES12/

If you are actually wondering why I am bringing this up now, and not 6 months ago when PDC 2008 was going on… Well it is because I just found out about it at the end of last month, 5 months after the fact. And to be totally honest the video presentation blew me away, because that is some serious bandwidth to show a video of that high of a quality. Especially because the ProxyHandler.cs code was suppose to handle at most small images and HTML being served from a remote server.

Tags: , , ,

Posted in News, Personal, Portfolio | kick it on DotNetKicks.com | Bookmark | View blog reactions | No Comments »

December 9th, 2008

Creating an extension module for .NET URL Rewriter and Reverse Proxy

Wow that is a long title. Recently I have been looking for quick posts that I can put out each day to keep my blog relevant and also so I don’t feel like I am slacking off too much. Today I want to post about a little known feature in my .NET URL Rewriter and Reverse Proxy (aka. Managed Fusion URL Rewriter) that I have developed in my spare time, mostly out of necessity for this blog and other projects I have worked on.  Here is a quick run through of what it does.

Managed Fusion URL Rewriter is a powerful URL manipulation engine based on the Apache mod_rewrite extension. It is designed, from the ground up to bring all the features of Apache mod_rewrite to IIS 6.0 and IIS 7.0. Managed Fusion Url Rewriter works with ASP.NET on Microsoft’s Internet Information Server (IIS) 6.0 and Mono XPS Server and is fully supported, for all languages, in IIS 7.0, including ASP.NET and PHP. Managed Fusion Url Rewriter gives you the freedom to go beyond the standard URL schemes and develop your own scheme.

But one feature that I added that is not part of the official Apache mod_rewrite documentation is the ability to add custom modules to extend the use of the URL rewriter in non-traditional ways.  One great example of this was born out of wanting to clean up the SEO mess I created in the early days of this blog.  I had to support the following different types of URL patterns:

  1. http://www.coderjournal.com/?p=23
  2. http://www.coderjournal.com/2008/03/14/some-post.html
  3. http://www.coderjournal.com/2008/03/14/some-post

to transform them in to the URL pattern that I finally settled on today:

  • http://www.coderjournal.com/2008/03/some-post

In the above list #2 and #3 were pretty easy to transform using the following rules:

RewriteRule ^(/[0-9]{4}/.*).html$    $1/ [NC,R=301]
RewriteRule ^(/[0-9]{4}/[0-9]{1,2}/)[0-9]{1,2}/(.*)$    $1$2 [R=301]

Because they contained all of the elements that make up my current URL.  As you can imagine problems arose when I had to support links that used #1’s syntax.  It contains zero elements that I can use to create my current URL.  Being a programmer who beleives that each part of a system should handle gracefully the domain it was designed to support, in this case a URL rewriter should be able to handle any senario that has to do with URL rewriting.  I added in support that allowed developers to naturally extend the URL rewriter to accomplish any type of URL rewriting task they could think of.

Setting Up the URL Rewriter Rules

In my case I needed to handle the following SQL query everytime I saw a URL that matched #1.

select concat('http://www.coderjournal.com/',year(post_date),'/',month(post_date),'/',post_name,'/') from wp_posts where ID = $1;

What this query does is query the WordPress database table that contains all the posts by the post ID and have it return the actual absolute path to the post, that should be displayed in the URL.  To do this I created a new directive for the mod_rewrite syntax called RewriteModule.  I also had to extend the RewriteRule and RewriteCond directives to support these new module extensions.  The RewriteModule, RewriteRule, and RewriteCond are defined by the following syntax:

RewriteModule <Reference Name> <Namespace>,<Assembly>
RewriteRule[([<Left Module>],[<Right Module>])] <Pattern> <Substitution>
RewriteCond[([<Left Module>],[<Right Module>])] <Test String> <Condition Pattern>

The parts in light blue parts above are optional to creating the rule.  In my case for this blog the rewriter directives looked like the following:

RewriteModule PostQueryString CoderJournal.Rewriter.Rules.PostQueryStringRuleAction, CoderJournal.Rewriter.Rules
RewriteRule(,PostQueryString)   ^/\?p=([0-9]+)$    "select guid from wp_posts where ID = $1;" [R=301]

I have highlighted in red the important parts of the syntax that indicate the custom module processor that should be used on the RewriteRule directive and how it relates back to the class defined in the RewriteModule

Creating the Module

I have to warn you that I am not going to demonstrate and show all the properties and methods on the interface that are important for creating a custom module, but I am going to show you the actual meat of the module that is involved in the lookup of the URL from the database.

public Uri Execute(int logLevel, string logCategory, HttpContext context,
                   Pattern pattern, Uri url, string[] conditionValues,
                   IDictionary<string, string> flags)
{
	string inputUrl = url.GetComponents(UriComponents.PathAndQuery, UriFormat.UriEscaped);
	string sqlCommand = pattern.Replace(inputUrl, Text, conditionValues);
	string substituedUrl = String.Empty;

	using (MySqlConnection connection = new MySqlConnection(Properties.Settings.Default.DatabaseConnection)) {
		using (MySqlCommand command = connection.CreateCommand()) {
			command.CommandText = sqlCommand;
			command.CommandType = CommandType.Text;

			try {
				connection.Open();
				substituedUrl = command.ExecuteScalar() as string;
			} finally {
				connection.Close();
			}
		}
	}

	return new Uri(url, substituedUrl);
}

It may not be clear right away what is going on, but on line 6, I am replacing the defined value in the regular expression (^/\?p=([0-9]+)$) with the SQL query (from above) to produce a query that will be run against the database. So if the following URL came in to my server:

It would produce a SQL query that looked like this:

select concat('http://www.coderjournal.com/',year(post_date),'/',month(post_date),'/',post_name,'/') from wp_posts where ID = 372;

Notice that the ID, 372, shows up in both the URL and the query, that is because this is the part I am most interested in, in the URL, because it is the only part of the URL that I need to query the database to find the actual path of the post.

Now that we have the query we can execute it on the database, using lines 9 through 21, and create the resulting URL on line 23. The resulting URL is then passed back through the URL rewriter, and processed using the flags defined. In my case [R=301], actually indicates that I want to do a 301 Permanent Redirect on the URL, which tells the browser and search engines, a like, that they need to update their URL for this page.

You can test out the above conditions by using the following URL’s that all redirect back to this page:

  1. http://www.coderjournal.com/?p=372
  2. http://www.coderjournal.com/2008/12/9/creating-extension-module-net-url-rewriter-reverse-proxy.html
  3. http://www.coderjournal.com/2008/12/9/creating-extension-module-net-url-rewriter-reverse-proxy/

The code as always is available on my SVN server at Google Code.

I hope this comes in handy to some of you developers that have to support legacy URL’s in your own product or a project that you are working on. As always if you have any questions or need anything clarified please feel free to contact me or leave a comment below.

Tags: , , , , ,

Posted in C#, How To, SEO, SQL | kick it on DotNetKicks.com | Bookmark | View blog reactions | 3 Comments »

February 27th, 2008

ASP.NET MVC Route Validation and SEO

Recently I have been using the ASP.NET MVC framework for a project at work. And one of the requirements was that certain data inputed in to the URL be tightly verified. I originally thought that data was verified by the type specified in the ControllerAction, however I came to find out that it wasn’t. So if you have say a page number and the user enters a letter in the URL the application just proceeds on it’s marry way. For example on the Kigg site:

  1. http://kigg.dotnetslackers.com/Story.mvc/Category/Lifestyle/1
  2. http://kigg.dotnetslackers.com/Story.mvc/Category/Lifestyle/a
  3. http://kigg.dotnetslackers.com/Story.mvc/Category/Lifestyle/
  4. http://kigg.dotnetslackers.com/Default.aspx

I am not sure yet if this is because Kigg is implemented with a int? and any failure of the parsing results in a null. But that wouldn’t explain the 3rd result in which Kigg returns the category as if it was the 4th result. I would expect that the 3rd result should return the same results as the 1st result. This setup can results in many SEO issues where I can inject keywords in to the URL with malicious intent and still have it resolve correctly. For example:

  1. http://kigg.dotnetslackers.com/Story.mvc/Category/Lifestyle/coderjournal

So my recommendation to my readers is to also implement a URL Rewriter to force normalization on to the MVC URLs. I am personally using my own URL Rewriter on this project that I am creating to better control my inputs, by providing type validation, into my application. At the very least use the built in verification and don’t put null in the defaults.

RouteTable.Routes.Add(new Route {
	Url = "[controller]/[action]/[page]",
	Defaults = new { controller = "Home", action = "Index", page = 1 },
	RouteHandler = typeof(MvcRouteHandler),
	Validation = new { method = "GET", page = "[0-9]+" }
});

The Validation property that you see on the last line above allows the type of HTTP Method allowed POST or GET usually. And the other properties are similar to what you do with the Default only they are RegEx statements that validate the specific part of the URL.

Really what I would like to see from ScottGu and the rest from the MVC framework is a more extensible Route object or RouteTable. I was really surprised that I wasn’t able to overload the handling of the URL in the MVC framework. Don’t get me wrong the team has done a great job hitting 95% of the potential needs of the development community. However if you fall in that 5% you are either out of luck, or forced to create a new Module, Controller, RouteTable, Route, and a whole host of supporting objects. For instance if I wanted to give the users of my URL Rewriter and Reverse Proxy a common interface that they can both do their advanced URL Rewriting and Reverse Proxying and their MVC Action/Controller setup. I wouldn’t be able to do it unless I basically reimplemented the URL handling of the MVC framework. I might end up doing that in the future, but I will probably wait until the Gold Version of MVC is released. If this was a perfect world I would probably implement some syntax in my URL Rewriter Rules file that looked like:

# if not feed burner requesting
RewriteCond %{HTTP_USER_AGENT} !^FeedBurner.*$
# rearrange old structure
RewriteRule ^/<?'controller'([a-z]+)>/index.html$  /$1/List/page$2.html [C]
# in to new MVC model
RewriteRule ^/<?'controller'([a-z]+)>/<?'action'([a-z]+)>/page<?'page'([0-9]+)>.html$  {controller="Home",action="List",page=1} [MVC,NC,L]

But that is just me making a wish for the future of MVC extensibility. All that I would need to accomplish this task is a little more flexibility in the URL handling. If anybody from the MVC wants to talk to me more about my requirements please feel free to contact me.

Really the last thing, I imagine, that the MVC team would want to cause is more SEO problems than are already created by uneducated developers.

Tags: , , , ,

Posted in ASP.NET, C#, Personal | kick it on DotNetKicks.com | Bookmark | View blog reactions | 1 Comment »