How To Add Web Site Content |
The IWebServer interface wraps a web server that raises an event called RequestReceived whenever a web browser connects and requests some content. To add your own content you need to hook this event and respond whenever any requests arrive for content you want to expose.
The IWebServer that Virtual Radar Server uses is wrapped in another interface, IAutoConfigWebServer. This is a singleton object that automatically applies the configuration settings to the web server. You would usually want to hook events raised by the IWebServer that the auto-config object exposes.
This is as simple as getting hold of the singleton IAutoConfigWebServer and referencing its WebServer property.
using VirtualRadar.Interface.WebServer; public void Startup(PluginStartupParameters parameters) { var webServer = Factory.Singleton.Resolve<IAutoConfigWebServer>().Singleton.WebServer; }
There are actually three RequestReceived events: BeforeRequestReceived, RequestReceived and AfterRequestReceived. Virtual Radar Server hooks RequestReceived. If you hook BeforeRequestReceived then you will see requests before the built-in web site and if you hook AfterRequestReceived you see them afterwards.
Normally you would use BeforeRequestReceived if you wanted to change the default web site in some way, usually by processing a request for a page before the standard website had a chance to.
You would use AfterRequestReceived to add new content onto the site in such a way that you cannot accidentally conflict with the standard site. You can check to see whether the standard site has already handled the request before you attempt to fulfill it yourself.
public void Startup(PluginStartupParameters parameters) { var webServer = Factory.Singleton.Resolve<IAutoConfigWebServer>().Singleton.WebServer; webServer.AfterRequestReceived += WebServer_AfterRequestReceived; }
When a request comes in from the browser the web server passes a RequestReceivedEventArgs object to the event handlers. The Handled property indicates whether another event handler has already served content for the request - if one has then you should always ignore the event. Bear in mind that even though Virtual Radar Server may not be using the event you're hooking other plugins could be, so you need to play nicely with them.
The RequestReceivedEventArgs carries a number of read-only properties that tell you about the request that was received. It also has a property called Response that you can use to send a response back to the browser.
The response generally needs a few properties setting up and it only exposes a stream on which to send the response. The IResponder interface simplifies filling out response objects for you.
The response object includes the MimeType property. There is a class in VirtualRadar.Interface.WebServer called MimeType that exposes some common mime types for you to use.
The RequestReceivedEventArgs object also has a Classification property that you should fill in for successful requests. It is used by the connection logger, content is classified according to the ContentClassification enum. If you don't classify your content then it appears in the logs as "Other" content. No attempt is made by the server to infer the classification from the MIME type.
The example event handler here will listen for an unhandled request for the page /HelloWorld.html. When that request comes in it will send a small HTML page back to the browser. To access the page from a web browser on the same machine as Virtual Radar Server you would enter the address http://127.0.0.1/VirtualRadar/HelloWorld.html. When we look at the page requested by the browser we ignore the case entered, so 'HelloWorld.html' and 'HELLOWORLD.HTML' would both work.
private void WebServer_AfterRequestReceived(object sender, RequestReceivedEventArgs args) { if(!args.Handled && args.PathAndFile.Equals("/HelloWorld.html", StringComparison.OrdinalIgnoreCase)) { var responder = Factory.Singleton.Resolve<IResponder>(); responder.SendText(args.Response, "<html><body>Hello World!</body></html>", Encoding.UTF8, MimeType.Html); args.Classification = ContentClassification.Html; args.Handled = true; } }