blob: 27b36f92ca67418748c6baff8f8883dc26303e53 [file] [log] [blame] [raw]

using RemoteView.PageHandlers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading;
namespace RemoteView
{
sealed class Server : IDisposable
{
/// <summary>
/// Keep list of all resources to be invoked according to received HTTP requests
/// </summary>
private Dictionary<String, AbstractPageHandler> decoder = new Dictionary<string, AbstractPageHandler>();
/// <summary>
/// HTTP listener for server
/// </summary>
private HttpListener listener = new HttpListener();
/// <summary>
/// Constructor
/// </summary>
public Server()
{
// Homepage
decoder.Add("", new HomePageHandler());
decoder.Add("home", new HomePageHandler());
// javascript page handles client side clicks and screen image updates
decoder.Add("script", new JavascriptPageHandler());
// information about the system
decoder.Add("info", new InfoPageHandler());
// this pages process clicks into server side windows events
decoder.Add("leftclick", new LeftClickPageHandler());
decoder.Add("rightclick", new RightClickPageHandler());
decoder.Add("mousemove", new MouseMovePageHandler());
// image of choosen device as a png
decoder.Add("screen", new ScreenPageHandler());
// image of choosen device as a png
decoder.Add("favicon.ico", new IconPageHandler());
// 404 error page
decoder.Add("404", new NotFoundPageHandler());
}
/// <summary>
/// Start server
/// </summary>
/// <param name="port">port to listen to</param>
public Server Start(int port)
{
try
{
listener.Prefixes.Add("http://*:" + port + "/");
listener.IgnoreWriteExceptions = true;
listener.Start();
new Thread(Start).Start();
}
catch
{
Console.WriteLine("Could not listen on port: {0}.", port);
}
return this;
}
/// <summary>
/// This where the server runs
/// </summary>
private void Start()
{
do
{
HttpListenerResponse response = null;
Stream output = null;
try
{
// Note: The GetContext method blocks while waiting for a request.
HttpListenerContext context = listener.GetContext();
String[] uri = context.Request.RawUrl.Split('/');
#if DEBUG
Console.WriteLine(context.Request.RawUrl);
#endif
AbstractPageHandler page;
bool found = decoder.TryGetValue(uri[1], out page);
if (!found)
{
// if page not found display 404 page
page = decoder["404"];
}
response = context.Response;
byte[] buffer = page.HandleRequest(response, uri);
// Get a response stream and write the response to it.
response.ContentLength64 = buffer.Length;
output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
}
catch (Exception e)
{
if (listener.IsListening) Console.WriteLine(e.Message);
}
finally
{
if (response != null)
{
try
{
if (output != null) output.Close();
}
catch { }
response.Close();
}
}
}
while (listener.IsListening);
}
/// <summary>
/// Stop server
/// </summary>
public void Stop()
{
this.listener.Stop();
}
/// <summary>
/// is server running?
/// </summary>
/// <returns></returns>
public bool IsRunning()
{
return listener.IsListening;
}
public void Dispose()
{
if (listener != null) listener.Close();
// some page handlers might need to be disposed
foreach (AbstractPageHandler page in decoder.Values)
{
if (page is IDisposable)
{
((IDisposable)page).Dispose();
}
}
}
}
}