Saturday, June 21, 2008

Using the HttpListener class

Since Windows XP Service Pack 2, there's been a buddy living in the system called Http.sys. IIS and SQL Server both interact with this kernel-mode HTTP listener to receive and response to HTTP requests.

Within the .NET framework, you can build your own application to interact with HTTP requests using the HttpListener class, which is simply managed code built over the Http.sys API.

The code to work with the HttpListener class is quite simple, as illustrated with this example:

System.Net.HttpListener newHttpListener = new System.Net.HttpListener();

System.Net.HttpListenerContext context = newHttpListener.GetContext();
byte[] byteArr = System.Text.ASCIIEncoding.ASCII.GetBytes("Hello World!");
context.Response.OutputStream.Write(byteArr, 0, byteArr.Length);


After instantiation of the HttpListener, we specify the prefix with which we want to receive requests. To process requests originating locally, you can specify a URL with localhost. To receive all requests, you can instead use an asterisk (*). The port number can be specified if you want to listen to requests on a non-standard port (the standard port is 80). The application starts listening for requests on calling GetContent, which is a synchronous blocking method (you can use the asynchronous method instead, if that's what you need). We then examing the incoming request - I left out this step for simplicity - and send out the response by writing to the output stream of the Response object.

With the HttpListener class, handling HTTP requests independent of IIS is a no-brainer. You don't have to work with sockets or process HTTP protocol messages - all that heavy lifting is already done for you by the HttpListener class leaving you to focus on what really matters, the idea that will build a better tomorrow.

1 comment:

Nitin R.K. said...

If you get the message "Access is Denied" for the exception on calling the Start method of HttpListener, you ought to read this forum post that I came across:

As for the HttpListener's permission issue you mentioned, based on my research, it is caused by the URLACL of the windows xp or windows 2003's HTTP.SYS kernal modulet. By default only SYSTEM or the local Administrators group can listen to http prefixes.If you want to let other custom accounts listening on certain URL prefixes, you need to explicitly grant access to other accounts.

For this it is convenient to use the httpcfg.exe tool, for example:

httpcfg.exe set urlacl /u http://localhost:80/StevenCheng/ ; /a D:(A;;GX;;;WD)

In the above command, "set urlacl" means we'll add an URLACL configuration entry. And the URLACL's url is specified through /u switch, the security ACL is supplied through the /a switch(use SDDL string).

In the above example, "D:(A;;GX;;;WD)" means we grant(A) Generic Execute permission(GX) to everynoe(WD). If we want to grant permission to a specific user, we need to use that user account's SID (to replace the WD here ).

There is a tool named "GetSid.exe" in the platform sdk which can help conveniently get sid string of a specific user account.

The httpcfg.exe tool can be get through the windows XP sp2 support tools or windows 2003 SP1 support tools(getsid.exe is also included in the tools):

#Windows Server 2003 Service Pack 1 32-bit Support Tools

#Windows XP Service Pack 2 Support Tools;displaylang=en&familyid=49AE8576-9BB9-4126-9761-BA8011FABF38&displaylang=en