Wrapcode

Configure reverse proxy with URL Rewrite and ARR for IIS

| 5 min read

Dictionary<string, object> dict = new Dictionary<string, object>();
dict.Add("ticket_id", "this is string");
dict.Add("order", this.order);
context.Call(this.dialogFactory.Create<OrderSummaryDialog, Dictionary<string, object>>(dict), this.AfterOrderSummaryDialog);
view raw RootDialog.cs hosted with ❤ by GitHub

Finally, feel good to be back with one more article. I'm writing about just another "developer life challenge" I faced few weeks back. We got stuck in a situation where we wanted to test our web application in IE8 and IE9. Basically I wanted to make it compatible with both the browsers. Yeah I know, being a modern web technology fan, you'll hate me for this but it was a need since most of the legacy non technical users are still stuck on those browsers. Good thing is Microsoft is shutting down support for old browsers in upcoming years. Good move Microsoft... like a boss :D

> Good bye old browsers, we will (not) miss you!

Well, our web application was still in development stage. The application was hosted on localhost (http://localhost/) where and the dogfooding was done through API running on another remote server (let's assume http://wrapcode.com:1234/api/{API}). The application was not working on old browsers as CORS (Cross domain resource sharing) was playing it's role in between which is not supported by browsers like IE8 and IE9. Web application was single page application (SPA) with lots of ajax roundups involved including PUT, DELETE. These verbs are not even remotely supported by old version of browsers (see, http://caniuse.com/#feat=cors).

In production stage both the API and web app were supposed to be on single domain and bound to single port so we didn't have to worry about production. And since this situation was only occurring in development stage, we didn't want to make drastic change in service layer / JavaScript code and we also wanted to avoid migration of database / API service to local machine because of the complexity in process. We had to find some way to avoid CORS and make the application in working in old browsers. Here's how we avoided CORS and let the local IIS make appear that the request from remote domain is coming from local machine.

Reverse Proxy

(Drawn with draw.io)

Prepare the base

This article is written with the consideration that you are configuring reverse proxy for IIS. So you basically need Windows Server (preferred) or Windows Operating system with IIS 7.0 or later.

  1. Download and Install Url Rewrite module - Head over to this link : Download
  2. Download and install ARR (Application request routing) module : Download We can use our old good friend Web Platform Installer to install these modules. I prefer installing such modules using WPI because WPI takes care of all the dependencies if any. Life is so easy with these tools, isn't it?

Let it route

  1. Open IIS manager. Double click on  Application Request Routing Cache menu in center pane. If you don't see it, you've not installed it properly. Repeat the above steps or reboot the system, sometimes it helps. ARR Icon

  2. You'll find Server Proxy Settings on right pane. Open it and check Enable Proxy option.

  3. Now, you have to chose either you want to apply reverse proxy globally or to the specific website. If you want to apply reverse proxy globally skip to 5.

  4. If you want to apply reverse proxy to specific website -

    1. Click on your computer name located on left pane, expand it.
    2. Right click on sites, click Add Website
    3. Fill in the required information, provide valid physical path (path to website content), assign different port or connection type if required.
    4. Check Start Website Immediately option.
    5. Click OK.
  5. You'll find URL Rewrite option in root level (computer name) as well as in added website. If you want to configure reverse proxy for all the requests coming to IIS, follow next procedure on root level URL rewrite otherwise do it on per website level. Open URL Rewrite by double clicking on it.

  6. Let's add inbound rule by clicking Add rule -> Blank rule (Inbound) as per given in the picture below. Click to expand the picture. temp

  7. Now add outbound rule (to rewrite remote domain response to localhost) and configure it as given in the picture below. outbound

  8. If everything goes well, you'll see following code in web.config of your website.

    Dictionary<string, object> dict = new Dictionary<string, object>();
    dict.Add("ticket_id", "this is string");
    dict.Add("order", this.order);
    context.Call(this.dialogFactory.Create<OrderSummaryDialog, Dictionary<string, object>>(dict), this.AfterOrderSummaryDialog);
    view raw RootDialog.cs hosted with ❤ by GitHub

  9. Add server variables. If the service is serving gzipped content, this implementation may block the data. To avoid it, you need to add several server variables. If you look at right pane in URL Rewrite settings, you'll find server variables option. Open it and add following variables to avoid gzip and https related issues. CMS2 Well, that's it. Reset your IIS and you are good to go. Now only change you've to do is replace** www.wrapcode.com:1234/api** to** /api** (relative to localhost) in your service layer from where you are supposed to make ajax calls and the configured reverse proxy rules will take care of the rest.

Hope the article was informative. I struggled a bit with the right sort of setting for my needs but I found this work best and requires very minimal configuration and code change. However, if you have any better way of doing it, we can discuss below. I would love to explore all the possible ways of doing this.

Peace, RP