Asynchronous Streaming Reverse Proxy for IIS 6.0

I recently started to use Subsonic on my Windows Home Server to make my music collection available over the internet. Subsonic must be configured to run on a port other than port 80, because this port is already used by the IIS web server. This is a major inconvenience, because it may prevent you from accessing the media from firewall restricted networks, and it will make the URLs to your media server somewhat more ugly. In order to get around these two problems, IIS has to serve as a proxy for the media server.

Unfortunately, IIS does not have built-in proxy functionality, and after looking at many possible solutions, including proxy servers (such as Squid), ISAPI filters (such as IIS Mod-Rewrite, IIS Proxy, ISAPI_Rewrite, IIRF and ManagedFusion Url Rewriter) and various ASP.NET scripts, I found that they either cost money, did not work for my purpose or had other disadvantages. One blog post even suggested the parallel installation of Apache with mod_proxy to provide the required functionality, but you may agree that installing a second web server for such a simple problem cannot be an elegant solution.

I came to the conclusion that the best workaround would be to write a custom HTTP handler DLL, which can easily be added to an existing IIS installation. Based on existing implementations on the internet, I wrote an asynchronous reverse proxy with support for content streaming and URL reversal. The HTTP handler has been written and tested with Subsonic, but it should be generic enough to work with many other types of HTTP based servers, including HTTPS and ASP.NET. I have also included the full source code and a sample configuration file for use with Subsonic.

Download

Name: Reverse Proxy
Version: CL 63
Released: 5/20/2010
Download: ReverseProxyHandler.zip (8.82 kB)

Name: Source Code
Version: CL 63
Released: 5/20/2010
Download: ReverseProxyHandler_Source.zip (9.75 kB)

Note: By downloading the files above you agree to the disclaimer at the bottom of this page.

Prerequisites

The project has been compiled against .NET Framework version 4.0.30319. Make sure to install the latest version of the framework on your server. Alternatively, you can compile the included source code against an earlier version of the framework. Minor code modifications may be necessary. If there is sufficient interest in other frameworks and platforms, I may include additional pre-built binaries in future versions of the download.

Installation

The reverse proxy is delivered in the form of a dynamic link library (DLL), which will be executed through the ASP.NET ISAPI extension. The configuration options for the reverse proxy are in a web.config file. Both the DLL and the configuration file need to be installed in the following way:

  1. In IIS Manager, create a new website or a virtual directory in an existing website for the location you want to be proxied.
  2. In Windows Explorer, unpack the downloaded archive ReverseProxyHandler.zip into this location.
  3. In IIS Manager, open the Properties dialog for the location.
  4. Navigate to the Home Directory tab and click on the Configuration… button in the Application Settings section.
  5. In the Mappings tab, click the Insert… button in the Wildcard application maps section.
  6. Enter c:\windows\microsoft.net\framework\v4.0.30319\aspnet_isapi.dll
  7. Uncheck Verify that file exists
  8. Click OK on all dialog windows to return to the IIS Manager.
  9. Modify the file web.config to configure your specific setup.

At this point, all requests to the website or virtual directory should be forward to the remote server that you configured. The remote server’s replies will be sent back to IIS, which replaces all hard-coded remote URLs that may exist in them and then forwards it to the client.

In order to separate the execution of requests to the proxied website or virtual directory, you may want to create a special application pool and assign it in the Properties dialog of the website or virtual directory. On my own server, I created a ProxyAppPool for this purpose.

Configuration

All configuration options for the reverse proxy are included in the web.config file, which is placed in the root of each website or virtual directory to be proxied. The following configuration options are available:

AllowRemoteCompression
A value of true will enable support for gzip and deflate compression of the remote server’s response stream. All compressed data from the remote server will then automatically be decompressed in IIS prior to parsing it for URL reversal. A value of false will notify the remote server that compressed response streams are not supported, in which case the remote server should send all data uncompressed. This may be useful if the remote server is on the same LAN or if proxy performance becomes an issue due to decompression overhead in IIS.
EventLogEnabled
A value of true will enable debug logs in the Windows Event Log (see next paragraph for additional instructions).
EventLogName
Specifies the name of the event log the entries will be written to. The default is Application
EventLogSource
Specifies the name of the event log source that generates the event log entries. The default is ReverseProxy
RemoteWebsite
Specifies the full URL of the remote website that is the target of the proxy request. For example, if you configured the proxy for a website with the URL http://www.yourdomain.com and the remote website is configured as http://localhost:123, then a request of the form http://www.yourdomain.com/foldername/filename.txt will be resolved internally as http://localhost:123/foldername/filename.txt.
ReverseContentTypes
Specifies the HTTP content types that need to be parsed for URLs. Some websites or web applications may contain hard-coded URLs in their response that point to the remote server. Since the remote server is proxied, these links will be dysfunctional from the client’s point of view. For example, if the remote server returns an HTML page with an image http://localhost:123/images/pic.jpg and the text/html content type is included in this setting, the reverse proxy will replace the URL with http://www.yourdomain.com/images/pic.jpg before the HTML page is sent back to the client.
ReverseBasePrefixes
Specifies a comma-separated list of text prefixes that will be parsed for reversal of base URLs. Base URLs start with a forward slash and are used by some web applications when they assume that they are running in the root of the application directory. For example, a website may return an image with the source attribute src=”/images/foo.jpg”. If the proxy is running inside a virtual directory then this URL needs to be reversed to src=”/virtualdirectory/images/foo.jpg”. A prefix will be used to filter the response text in two ways: with a trailing double-quote (PREFIX”/) and a trailing single-quote (PREFIX’/). For example, the prefix src= will match src=”/ and src=’/. Please note that base URLs are sometimes generated at run-time in JavaScript. In such cases you will have to locate the offending script line and find an appropriate prefix. For example, in the Subsonic music server there is a JavaScript function call setupZoom(‘/’) that specifies the base directory for images, so that the prefix setupZoom( has been added to the example web.config file.

Debugging

The reverse proxy is able to log HTTP requests and their results to the Windows Event Log. This will help you to determine if URLs are resolved correctly and which content types need to be checked for URL reversal. By default the event log is not accessible by ASP.NET, so that you may get a security permission error when logging is enabled. You can allow access to the event log by performing the following steps:

  1. Open the Registry Editor (regedit.exe)
  2. Navigate to the following key:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application
  3. Create a new sub-key ReverseProxy
  4. Right-click this new key and select Permissions…
  5. Grant full control to the user account running the application pool for your web site
    (by default this is NETWORK SERVICE)

If you are not sure which user account is used by the application pool:

  1. Start IIS Manager
  2. Open Properties for your web site
  3. Select Home Directory tab
  4. Note the Application pool name at the bottom
  5. Back in IIS Manager, open the Properties for the application pool
  6. Select the Identity tab to view or change the selected user account.

Implementation Details

The reverse proxy is implemented as an asynchronous HTTP handler that inherits from IHttpAsyncHandler. The handler instance itself keeps no internal state and is therefore reused for subsequent requests to conserve memory and reduce memory fragmentation.

The DLL included in the download has been compiled with Any CPU as the target platform, so that it will run on both 32-bit and 64-bit servers. Feel free to compile a platform-specific version from the included source code.

Every request from the client browser will be forwarded to an instance of HttpWebRequest. All headers and other important fields are fully preserved. The remote request itself is executed asynchronously, and the state information is kept in an AsyncState object.

Please note that the handler is asynchronous in the sense that it does not lock execution between submitting the HTTP request to the remote server and processing the remote servers results. The copying of the remote server’s result to the client’s response stream is still synchronous in the sense that reading and writing operations block each other. This is something you may want to change if you have a very high number of requests on your server. For most practical purposes on personal home servers this should never be an issue.

The proxy has support for gzip and deflate compression between the remote server and IIS. However, the response returned to the client is currently uncompressed, regardless of the client’s accepted content encodings.

The Log class implements the logging functionality for the Windows Event Log. Since only static methods of the EventLog class are used, the logging functions are thread safe.

Known Bugs and Issues

There are no known bugs.

Resources

For the implementation of the reverse proxy I borrowed ideas from the following projects:

Disclaimer

Copyright (c) 2010 headcrash industries. All rights reserved.

This software is provided “as is”, without warranty of any kind, expressed or implied. In no event shall the author or its contributors be held liable for any direct, indirect, incidental, special or consequential damages arising out of the use of or inability to use this software.

Redistribution of the software’s code or compiled binaries in any form, including but not limited to websites, CDROM and printed media, is strictly prohibited and requires the explicit permission of the author.

Uninstalling Twonky and HP Software from MediaSmart Home Server

What do you do to convert a barely useful system into a completely broken system? You release a patch! And so HP set to work to develop and release the long awaited update 2 for the MediaSmart 3.0 software, providing large parts of their customer base with a whole new level of psychological terror. If you’re lucky enough to see TwonkyMedia re-index your entire media collection without crashing in the process, you will be rewarded with ASP.net related error pop-ups and a dysfunctional HP tab in the Home Server Console, a sloppy and bug infested media browser, high CPU utilization and literally hundreds of errors and warnings in the Windows event log.

Like many other users, I have previously spent a lot of time with getting the home server to work somewhat reliably for more than a few days in a row, and I have decided that it’s time to stop playing this game and pull the trigger on uninstalling TwonkyMedia and the HP software alltogether. Despite temporarily losing support for the system health LED, which I haven’t looked into yet, my quality of life improved instantly, and I have not yet regretted my decision.

This article describes the steps for getting rid of the factory malware that ships with the HP home servers. I hope I can encourage others to liberate themselves as well.

Uninstalling

Warning: If you uninstall the HP software as described below, currently the only way to reinstall it later is to re-image the server using the factory CD.

Use Remote Desktop to connect to your home server and perform the following steps:

  1. Click StartControl PanelAdd or Remove Programs
  2. Locate and uninstall TwonkyMedia Server
  3. Locate and uninstall HP MediaSmart/Data Vault Update (if you have it installed)
  4. Locate and uninstall HP MediaSmart Server
  5. Restart your home server to finalize the uninstall.

Fixing up WHS Start Page

When you first connect to your home server with a web browser it shows the WHS start page. Since HP customized this page, you will be redirected to /HPHome and get a 404 – Not Found error, because you uninstalled the HP software. Remote desktop into your home server and follow the steps below to fix it up:

  1. Open Windows Explorer and navigate to c:\Inetpub\home\
  2. Open the file WebSites.xml in a text editor

    By default the file contents look like this:

    1. <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    2. <WebSites default="HP MediaSmart Server Home Page">
    3.   <WebSite name="HP MediaSmart Server Home Page" uri="/HPHome" imageUrl="/HPHome/images/server.gif" absolute="false" />
    4. </WebSites>

    You can either remove the <WebSite> entry or add one or more of your own relative or absolute web site URLs. For example, I added Subsonic as one of the pages as follows:

    1. <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    2. <WebSites default="HP MediaSmart Server Home Page">
    3.   <WebSite name="Subsonic Media Server" uri="http://your.domain.com:1234" imageUrl="images/subsoniclogo.png" absolute="true" />
    4. </WebSites>

    Note the subsoniclogo.png image, which I created and placed into c:\Inetpub\home\images\. It will be shown next to the link. Replace your.domain.com:1234 with your server’s domain name or public IP address and port number.

Fixing up WHS Remote Page

After logging on to the WHS page, the server will redirect you to the WHS remote page that displays additional options for authenticated users. This page needs to be fixed up in the same way as the start page. Please note that this time the corresponding XML file is located in the remote directory:

  1. Open Windows Explorer and navigate to c:\Inetpub\remote\
  2. Open the file WebSites.xml in a text editor

    By default the file contents look like this:

    1. <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    2. <WebSites>
    3.   <!– This is a Sample Template
    4.   <WebSite name="An internal Website" uri="/OEM" imageUrl="/OEM/icon.png" absolute="false">
    5.   </WebSite>
    6.   <WebSite name="An external Website" uri="http://www.microsoft.com" imageUrl="http://www.microsoft.com/icon.png" absolute="true">
    7.   </WebSite>
    8. –>
    9.   <WebSite name="HP MediaSmart Server Home Page" uri="/HPHome" imageUrl="/HPHome/images/websites_xml/server.gif" absolute="false" />
    10.   <WebSite name="HP Photo Viewer" uri="/PhotoViewer" imageUrl="/HPHome/images/websites_xml/photo_view.gif" absolute="false" />
    11.   <WebSite name="HP Photo Publisher" uri="/PhotoPublisher" imageUrl="/HPHome/images/websites_xml/photo_publish.gif" absolute="false" />
    12.   <WebSite name="Media Streamer" uri="/MediaStreamer" imageUrl="/HPHome/images/websites_xml/media_streaming.gif" absolute="false" />
    13. </WebSites>

    Make sure to remove and/or replace the existing web sites since they no longer exist.

Notes

Since Backup, Media Center, Media Sharing and Remote Access are provided by Windows Home Server, these features will not be impacted by uninstalling the HP bundled software and continue to function properly.

As a replacement for TwonkyMedia audio streaming I highly recommend the free Subsonic Music Streamer. I was concerned about it being written in Java, but once you have it installed, you’ll ask yourself why you tortured yourself with Twonky. The server is super fast, supports bit-rate transcoding, indexes thousands of MP3s in seconds, includes user account management, has a lot of cool features and simply looks and works great. I wrote a reverse proxy for clean integration into IIS and your WHS home page.

For iTunes support you can continue to use Firefly, which should still be installed. You will have to reinstall Apple’s Bonjour service for Firefly to work properly.

Wordpress 2.5 Broken Media Library Fix

This article is part of a backup. It was originally posted on Sunday, April 13. 2008.

The Media Library in WordPress 2.5 is a great new feature. Unfortunately, it doesn’t work for many users right out of the box. This article provides solutions to the two most common problems.

Server Configuration (IIS)

If you are running your blog on IIS, and you are unable to upload files, make sure that your PHP configuration file is set up correctly and that your web server has access to PHP upload directory. The php.ini should contain the following entries:

  1. file_uploads = On
  2. upload_tmp_dir = "C:\Example\Upload\Folder"

Obviously, you can set an upload directory of your choice. Make sure that the IIS_IUSRS user account has full access to this directory.

Server configuration (Apache)

If you are running WordPress on an Apache web server, you might not be able to upload files to the media library with following symptoms:

HTTP Error
An error occurred in the upload. Please try again later.

To fix this issue, add the following lines to the end of your .htaccess file in the root of your WordPress installation:

  1. <IfModule mod_security.c>
  2.     <Files async-upload.php>
  3.         SecFilterEngine Off
  4.         SecFilterScanPOST Off
  5.     </Files>
  6. </IfModule>

JavaScript Fix

The release version of WordPress 2.5 has two typos in the source code that cause the Media Library to break with the following symptoms:

  • Files can be uploaded but not actually added to postings.
  • The Show links in the media library don’t work
  • The browser shows an Object Expected JavaScript error at line 136

To fix this issue, you have to manually edit two files of your WordPress installation in a text editor:

  1. Open the file wp-admin/includes/media.php
  2. At line 817
    debug: false,
            

    remove the comma after false

    debug: false
            

    and save the file.

  3. 3.Open the file wp-includes/js/swfupload/handlers.js
  4. At line 99
    1. .animate({minHeight:0,height:36,}, 400, null …)

    remove the comma after 36

    1. .animate({minHeight:0,height:36}, 400, null, …)

    and save the file.

Other Resources

The server configuration fix has been posted on many forums and blogs. The JavaScript bug fix was first posted on the WordPress Trac bug tracker.

SQL Server 2005 Express on Windows Vista 64-bit

This article is part of a backup. It was originally posted on Sunday, April 13. 2008.

At the very bottom of the SQL Server 2005 Express download page, Microsoft offers 64-bit versions of their installers. Unfortunately, this is not everything you need to run SQL Server Express on 64-bit versions of Windows Vista. As it turns out, the installer currently provided on the download page is bundled with the 32-bit version of the SQL Server Native Client, which causes the subsequent SQL Server installation to fail with the following symptoms:

  • The installer prompts for sqlncli_x64.msi

Restarting the whole installation or uninstalling the Native Client doesn’t help.

Solution

Prior to running the installer for SQL Server 2005 Express 64-bit, you have to manually install the 64-bit version of the Native Client. The following steps proved successful:

  1. Install the 32-bit version of the SQL Native Client if it is not already installed.
  2. Download and install the 64-bit Native Client.
  3. Download and install SQL Server 2005 Express Edition 64-bit
  4. Download and install SQL Server Management Studio Express Edition 64-bit

You should now have a working installation of SQL Server 2005 Express Edition on Windows Vista 64-bit.

References

The problem was first discussed and solved on the MSDN Forums.

MySQL Configuration Wizzard on Windows Vista

This article is part of a backup. It was originally posted on Sunday, April 13. 2008.

The MySQL Server Instance Configuration Wizzard MySQLInstanceConfig.exe (current version 1.0.10.0) that comes with the MySQL Server Community Edition (current version 5.0.51a) has a typo in the embedded manifest file that prevents it from running on Windows Vista machines.

The error can be corrected manually by opening the executable in a resource editor (for example XN Resource Editor) and making the following changes:

  1. Open the resource entry for XP Theme Manifest/1/English (United States)
  2. Change the following line from
    1. <requestedExecutionLevel level="asAdministrator" uiAccess="false"></requestedExecutionLevel>

    to

    1. <requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel>

You should now be able to run the tool without problems.

References

A bug report for this issue has been filed in the MySQL bug tracking system.