Notes On Using HttpListener
The current implementation of Grapevine relies on the features exposed by System.Net.HttpListener
. As such, being familiar with its usage and documentation will help resolve many questions you may encounter when using Grapevine. This document outlines the most common and problematic issues reported when using HttpListener
and, by extension, Grapevine.
Access Denied
When you try to run your server for the first time, you might see an Access Denied
exception occur. While annoying, this is rather easy to overcome. If you want to use HTTP.SYS to listen on a URI, you either need administrative privileges or an administrator that reserves the URI for normal users.
Run As Administrator
For development purposes, assuming you are an administrator on your Widows instance, you can simply run Visual Studio as administrator. Likewise, you can run the Windows command line as administrator if you want to test it outside of Visual Studio.
Configure Namespace Reservations
For obvious reasons, counting on your application running as administrator in production is unwise. In these instances, you'll want to configure a namespace reservation.
This reservation can be made by using the netsh
utility.
$ netsh http add urlacl url=http://+:1234/ user=DOMAIN\user
This can be done programatically, but the implementation is outside the scope of this document. It's important that the value of the url
argument is an exact match, or the exception will still be thrown.
server.Host = "+";
server.Port = "1234";
See the documentation for the add urlacl
for a description of the parameters.
This documentation does not cover Windows operating systems earlier than Vista. For help with XP or Server 2003, see the documentation for httpcfg.
The process cannot access the file
This exception can be puzzling because it isn't immediately apparent what the problem actually is. This actually means that there is already an application bound to the same port Grapevine is trying to use. Change the port your application is using to an open port and this exception goes away.
You can use the built-in PortFinder
class to help with this.
// Assigns the next open port, which is commonly "1"
server.Port = PortFinder.FindNextLocalOpenPort();
// Assigns the next open port starting at the integer specified (inclusive)
server.Port = PortFinder.FindNextLocalOpenPort(1234);
If you are interested in seeing what ports are in use, you can the Windows command line utility netstat.
$ netstat -a -b -n
You can also use Resource Monitor, the the native Windows GUI by running resmon
.
Connecting from another computer
If you want to be able to reach your Grapevine server from another computer, you will need to open a port in your Windows firewall. The firewall blocks all incoming communications unless you open a port in the Windows firewall to let other computers communicate with your computer.
Opening ports in your firewall can leave your system exposed to malicious attacks. Be sure to understand firewall systems before opening ports. Consult the documentation specific to your firewall software.
To open a port in the Windows 7 Firewall
On the Start menu, click Control Panel
Click on the System and Security category, then Windows Firewall. If you are not viewing by category, you can simply click on the Window Firewall item.
Click on the Advanced Settings link on the left hand side. This will open the Windows Firewall with Advanced Security Management Console application.
Click on Inbound Rules on the left hand menu. Under the Actions on the right hand side, click on New Rule. This opens the New Inbound Rule Wizard.
Select the Port option and click Next.
Select TCP and Specific local ports, then enter a comma-separated list of port numbers you want to open and click Next.
Select Allow the connection and click Next.
Check the boxes next to the desired network types and click Next.
Enter a name for your rule - and optionally a description - and click Finish.
Your inbound rule should now be displayed on the Inbound Rules list. To remove this rule, simply delete it from the list when you are done.
Setting up SSL
Setting up SSL (so that you can use the HTTPS protocol) depends greatly on which certificate provide you choose to use. On the code side, it's pretty straight forward:
server.UseHttps = true;
Beyond that, I'm going to refer you to a great post on StackOverflow for setting up HTTPS support for HttpListener. There are examples there for using MakeCert or OpenSSL or Let's Encrypt, along with lots of great links and research. I'm not going to reproduce all of that here right now, but maybe in the future someone can contribute some more detailed instruction specific to Grapevine.