July 1007

IIS URL Rewrite module doesn’t run

The URL Rewrite IIS extension gives IIS similar URL rewriting capabilities to Apache mod_rewrite, but being Microsoft you get a nice GUI to help. However I couldn’t get it to work, somehow I stumbled across a solution that fixed it for me…

The extension is available as part of the Web Platform Installer so, because I like installing things, I’ve had it installed for quite some time. Back in February I needed to use a redirect for a website, we were setting up a new website but needed to redirect traffic to the current site – for a little while. Quite keen to give my new toys a go I initially tried to get the HTTP Redirect module to redirect my traffic. It looked pretty easy, fill in the boxes and any traffic coming to the site would be redirected with the status code I set. 

http-redirect

Unfortunately I couldn’t get the HTTP Redirect to redirect but one of the responses to that post suggested that another option was to use the URL Rewrite module and helpfully provided me with an example. I tried the module but again couldn’t get the rewrite / redirect to work, in the end I resorted to adding a default.aspx with

<%Response.Redirect(“http://www.newurl.com”)%>

Which wasn’t a great solution as it only worked if going to the root of the directory, but for a quick fix was fine. However yesterday I needed to do the same thing again but wasn’t prepared to use such a hacky fix. Somehow I discovered that the redirect worked if I had other files in my website. I had been trying to get the redirect / rewrite to work with only a web.config file in the root, no other files, no other folders just the web.config with this redirect:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Redirect" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions logicalGrouping="MatchAny">
                        <add input="{HTTP_HOST}" pattern="olddomain.com" />
                    </conditions>
                    <action type="Redirect" url="http://www.newdomain.com" redirectType="Permanent" />
                </rule>
            </rules>
        </rewrite>
        <httpRedirect enabled="false" destination="http://www.newdomain.com" exactDestination="true" />
    </system.webServer>
</configuration>

Frustratingly this wasn’t working, when I ran the Test pattern tool with the regex (.*) and gave it anything it matched, which is just what I wanted – any traffic that made it to this site should be redirected to newdomain.com – so why wasn’t it working when I used it on the site?

I wish I could explain why this only works when I have more than just the web.config in the folder, but it just does – maybe the website isn’t considered a website without there being at least 1 web page, maybe just a web.config alone isn’t enough – I don’t know. If anyone else knows, or can explain what’s going on here and why I’d be very interested to hear about it in the comments. In the meantime I’m posting this in case it helps anyone else with this gotcha!

Spread/Promote this post

If you enjoyed this article, consider bookmarking or helping me promote it! Thanks.

  • Del.icio.us
  • Digg It!
  • Technorati
  • BlinkList
  • DZone It!
  • Furl
  • NewsVine
  • Reddit
  • StumbleUpon

Don't miss another post

Subscribe to SJM Dev's RSS Feed to stay updated with our latest articles!

Permalink | Comments (0)

March 1018

URL Rewriting and problems with web-services

Towards the end of the yesterday an interesting bug started to show up whenever anyone went into the Modules section of the CMS  "Stack Trace: /r/nError: The server method 'GetContentItems' failed./r/nStatus Code: 500/r/nException Type: /r/nTimed Out: false". This was not good news. So I opened up Firebug and sure enough the call to that webservice was coming back with a 500 error status, looking in the Response tab all I could see was that the server was returning a 500 error status.

First things first, I tried to reproduce the problem locally but without success, everything was working fine for me. I checked the builds for Live, Staging and Development and they were all the same, but I couldn’t reproduce the error on Dev or Staging. OK, I’ve set the servers machine.config into production mode with deployment = retail, so went in and changed that. Not the best thing to do on a production server because potentially any errors would now be visible. However as I was unable to reproduce the error locally or on either the development or staging servers I didn’t have much choice. Annoyingly Firebug was still giving me the generic error page, nothing I could use to debug or see what was happening. I even gave Fiddler the chance to shine, but again all I could see was the generic error. Even though I’d disabled deployment=”retail” for the servers and set customErrors off in the application web.config I wasn’t seeing the real error. I tried to run the application locally on the production web server, but that box is locked down quite tightly and I couldn’t get it to run (even as an virtual directory from within the Default Website).

Enter ELMAH

This wasn’t going well, I needed to see the real error but couldn’t seem to get to it, the logs weren’t being very helpful either. I’ve been meaning to install ELMAH on the web server globally for a while, I even started but couldn’t get it to run, so figured I’d just quickly install ELMAH for this site only. For anyone who doesn’t know ELMAH rocks! This is what the site says about it:

Once ELMAH has been dropped into a running web application and configured appropriately, you get the following facilities without changing a single line of your code:

  • Logging of nearly all unhandled exceptions.
  • A web page to remotely view the entire log of recoded exceptions.
  • A web page to remotely view the full details of any one logged exception.
  • In many cases, you can review the original yellow screen of death that ASP.NET generated for a given exception, even with customErrors mode turned off.
  • An e-mail notification of each error at the time it occurs.
  • An RSS feed of the last 15 errors from the log.
  • A number of backing storage implementations for the log, including in-memory, Microsoft SQL Server and several contributed by the community.

Setting it up for the site was really easy, I dropped the dll into the bin and added the relevant lines to web.config - setting it to send me emails for the errors. So back to my website and cause the problem, within seconds the first email arrived in my inbox and there was an interesting bit of information in there. The web service was being called as “getcontentitems” and not “GetContentItems”, the error was even kind enough to explain that method names are case sensitive.

The penny drops

At this point I remembered that we’d installed the URL Rewrite module for IIS at work earlier this week in order to fix up some issues the SEOToolkit was reporting. As well as the canonical url issue of missing ‘www’ from our urls we’d wanted to enforce lowercase urls. Personally I prefer seeing SentenceCase on urls but if this causes SEO issues then as it is only a matter of taste I saw no reason not to lowercase everything by the URL Rewrite module and then it doesn’t matter what file name authors give to their pages. We had added a rule at server level to lowercase everything, set up rules at application level to enforce the www in urls and got on with other things. All was good when we did this and no one was complaining about broken functionality. Clearly this was the cause of our problems and explained why we weren’t seeing this elsewhere.

So we deleted the rule and refreshed the CMS, no more errors, problem solved! I’m getting emails quite often still and am tempted to divert these to the Helpdesk system so it can log them and we’ll work on them as and when there’s time. I also need to look into ELMAH a bit more to enable filtering so it only sends an email if a certain type of error occurs more than say 10 times in 10 minutes so we’re not bombarded with emails.

Warning

For anyone rewriting their urls be careful it may break things that are case sensitive!

Spread/Promote this post

If you enjoyed this article, consider bookmarking or helping me promote it! Thanks.

  • Del.icio.us
  • Digg It!
  • Technorati
  • BlinkList
  • DZone It!
  • Furl
  • NewsVine
  • Reddit
  • StumbleUpon

Don't miss another post

Subscribe to SJM Dev's RSS Feed to stay updated with our latest articles!

Permalink | Comments (7)

February 1008

Machine.config changes for Production

On Thursday my company’s new website went live but that’s not the point of this post; this post is more to do with optimising the server / site now it is in production.

All .NET websites inherit their settings from other .config files that exist ‘lower’ down the chain; so a web.config in the root of the wwwroot folder can contain settings that apply to all websites on that server. However going lower still is the machine.config and settings made here apply to the machine generally. Here I am going to make some changes to the machine.config to harden the production server and give a slight boost to performance. I don’t have any statistics to back up the settings, they are based on a bit of trial & error and an article on tuning IIS 6.0 your mileage with these may vary.

The machine.config can be found at C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG or C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG depending on your OS. Be careful when editing this file as you can stop things from working with something as simple as an invalid xml node or not closing something properly, so I usually create a backup copy before I start making changes.

<Deployment="retail" /> is quite well known, but I keep forgetting where it belongs so here are the changes I made – for future reference as much as anything else.

<system.web>
   <deployment retail="true" />
   <processModel
     autoConfig="true"
     memoryLimit="75″
     maxIoThreads="100″
     minIoThreads="30″
     minWorkerThreads="40″
     maxWorkerThreads="100″
     clientConnectedCheck="00:00:05″ />
...
</system.web>
 

With deployment = retail set all web applications compile without debug enabled, essentially if you forget to set debug=”false” this will take care of that, and a few other settings you would want.

The settings in the processModel node are all set to their default (autoConfig=true), except for those that I’m overriding. The memoryLimit is the % memory a web process can use before creating a new process. I’m only using this server for a few sites so will happily set this quite high. The clientConnectedCheck instructs the server to check every 5 seconds to see if the client is connected and if not then to dump any outstanding requests they’ve made – garbage collecting.

Spread/Promote this post

If you enjoyed this article, consider bookmarking or helping me promote it! Thanks.

  • Del.icio.us
  • Digg It!
  • Technorati
  • BlinkList
  • DZone It!
  • Furl
  • NewsVine
  • Reddit
  • StumbleUpon

Don't miss another post

Subscribe to SJM Dev's RSS Feed to stay updated with our latest articles!

Permalink | Comments (1)