diff --git a/GUI/MainForm.cs b/GUI/MainForm.cs index d574edc..e8724af 100644 --- a/GUI/MainForm.cs +++ b/GUI/MainForm.cs @@ -267,9 +267,9 @@ namespace OpenHardwareMonitor.GUI { runWebServerMenuItem, settings); runWebServer.Changed += delegate(object sender, EventArgs e) { if (runWebServer.Value) - runWebServer.Value = server.startHTTPListener(); + runWebServer.Value = server.StartHTTPListener(); else - server.stopHTTPListener(); + server.StopHTTPListener(); }; InitializePlotForm(); diff --git a/Utilities/HttpServer.cs b/Utilities/HttpServer.cs index 394771f..3f0c51e 100644 --- a/Utilities/HttpServer.cs +++ b/Utilities/HttpServer.cs @@ -5,369 +5,335 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. Copyright (C) 2012 Prince Samuel + Copyright (C) 2012 Michael Möller */ using System; -using System.Collections.Generic; -using System.Text; -using System.Net; -using System.Threading; -using System.IO; -using OpenHardwareMonitor.GUI; -using OpenHardwareMonitor.Hardware; -using System.Reflection; using System.Drawing; using System.Drawing.Imaging; +using System.IO; +using System.Net; +using System.Reflection; +using System.Text; +using System.Threading; +using OpenHardwareMonitor.GUI; +using OpenHardwareMonitor.Hardware; -namespace OpenHardwareMonitor.Utilities -{ - public class HttpServer - { - private HttpListener listener; - private int listenerPort, nodeCount; - private Thread listenerThread; - private Node root; +namespace OpenHardwareMonitor.Utilities { - public HttpServer(Node r, int p) - { - root = r; - listenerPort = p; - //JSON node count. - nodeCount = 0; - listener = new HttpListener(); - } + public class HttpServer { + private HttpListener listener; + private int listenerPort, nodeCount; + private Thread listenerThread; + private Node root; - public Boolean startHTTPListener() - { - try - { - if (listener.IsListening) - return true; + public HttpServer(Node r, int p) { + root = r; + listenerPort = p; - string prefix = "http://+:" + listenerPort + "/"; - listener.Prefixes.Clear(); - listener.Prefixes.Add(prefix); - listener.Start(); - - if (listenerThread == null) - { - listenerThread = new Thread(HandleRequests); - listenerThread.Start(); - } - } - catch (Exception e) - { - return false; - } - - return true; - } - - public Boolean stopHTTPListener() - { - try - { - listenerThread.Abort(); - listener.Stop(); - listenerThread = null; - } - catch (System.Net.HttpListenerException e) - { - } - catch (System.Threading.ThreadAbortException e) - { - } - catch (System.NullReferenceException e) - { - } - catch (Exception e) - { - } - return true; - } - - public void HandleRequests() - { - - while (listener.IsListening) - { - var context = listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener); - context.AsyncWaitHandle.WaitOne(); - } - } - - public void ListenerCallback(IAsyncResult result) - { - HttpListener listener = (HttpListener)result.AsyncState; - if (listener == null || !listener.IsListening) - return; - // Call EndGetContext to complete the asynchronous operation. - HttpListenerContext context = listener.EndGetContext(result); - HttpListenerRequest request = context.Request; - - var requestedFile = request.RawUrl.Substring(1); - if (requestedFile == "data.json") - { - sendJSON(context); - return; - } - - if (requestedFile.Contains("images_icon")) - { - serveResourceImage(context, requestedFile.Replace("images_icon/", "")); - return; - } - - //default file to be served - if (string.IsNullOrEmpty(requestedFile)) - requestedFile = "index.html"; - - string[] splits = requestedFile.Split('.'); - string ext = splits[splits.Length - 1]; - serveResourceFile(context, "Web." + requestedFile.Replace('/', '.'), ext); - } - - private void serveResourceFile(HttpListenerContext context ,string name, string ext) { - - //hack! resource names do not support the hyphen - name = "OpenHardwareMonitor.Resources." + name.Replace("custom-theme", "custom_theme"); - - string[] names = - Assembly.GetExecutingAssembly().GetManifestResourceNames(); - for (int i = 0; i < names.Length; i++) { - if (names[i].Replace('\\', '.') == name) { - using (Stream stream = Assembly.GetExecutingAssembly(). - GetManifestResourceStream(names[i])) { - context.Response.ContentType = getcontentType("." + ext); - context.Response.ContentLength64 = stream.Length; - byte[] buffer = new byte[512 * 1024]; - int len; - while ((len = stream.Read(buffer, 0, buffer.Length)) > 0) - { - context.Response.OutputStream.Write(buffer, 0, len); - } - context.Response.OutputStream.Close(); - } - return; - } - } - context.Response.OutputStream.Close(); - context.Response.StatusCode = 404; - context.Response.Close(); - } - - private void serveResourceImage(HttpListenerContext context ,string name) { - name = "OpenHardwareMonitor.Resources." + name; - - string[] names = - Assembly.GetExecutingAssembly().GetManifestResourceNames(); - for (int i = 0; i < names.Length; i++) { - if (names[i].Replace('\\', '.') == name) { - using (Stream stream = Assembly.GetExecutingAssembly(). - GetManifestResourceStream(names[i])) { - - Image image = Image.FromStream(stream); - context.Response.ContentType = "image/png"; - using (MemoryStream ms = new MemoryStream()) - { - image.Save(ms, ImageFormat.Png); - ms.WriteTo(context.Response.OutputStream); - } - context.Response.OutputStream.Close(); - image.Dispose(); - return; - } - } - } - context.Response.OutputStream.Close(); - context.Response.StatusCode = 404; - context.Response.Close(); - } - - private void sendJSON(HttpListenerContext context) - { - - string JSON = "{\"id\": 0, \"Text\": \"Sensor\", \"Children\": ["; - nodeCount = 1; - JSON += generateJSON(root); - JSON += "]"; - JSON += ", \"Min\": \"Min\""; - JSON += ", \"Value\": \"Value\""; - JSON += ", \"Max\": \"Max\""; - JSON += ", \"ImageURL\": \"\""; - JSON += "}"; - - var responseContent = JSON; - byte[] buffer = Encoding.UTF8.GetBytes(responseContent); - - context.Response.ContentLength64 = buffer.Length; - context.Response.ContentType = "application/json"; - - Stream outputStream = context.Response.OutputStream; - outputStream.Write(buffer, 0, buffer.Length); - outputStream.Close(); - - } - - private string generateJSON(Node n) - { - string JSON = "{\"id\": " + nodeCount + ", \"Text\": \"" + n.Text + "\", \"Children\": ["; - nodeCount++; - - foreach (Node child in n.Nodes) - JSON += generateJSON(child) + ", "; - if (JSON.EndsWith(", ")) - JSON = JSON.Remove(JSON.LastIndexOf(",")); - JSON += "]"; - - if (n is SensorNode) - { - JSON += ", \"Min\": \"" + ((SensorNode)n).Min + "\""; - JSON += ", \"Value\": \"" + ((SensorNode)n).Value + "\""; - JSON += ", \"Max\": \"" + ((SensorNode)n).Max + "\""; - JSON += ", \"ImageURL\": \"images/transparent.png\""; - } - else if (n is HardwareNode) - { - JSON += ", \"Min\": \"\""; - JSON += ", \"Value\": \"\""; - JSON += ", \"Max\": \"\""; - JSON += ", \"ImageURL\": \"images_icon/" + getHardwareImageFile((HardwareNode)n) + "\""; - } - else if (n is TypeNode) - { - JSON += ", \"Min\": \"\""; - JSON += ", \"Value\": \"\""; - JSON += ", \"Max\": \"\""; - JSON += ", \"ImageURL\": \"images_icon/" + getTypeImageFile((TypeNode)n) + "\""; - } - else - { - JSON += ", \"Min\": \"\""; - JSON += ", \"Value\": \"\""; - JSON += ", \"Max\": \"\""; - JSON += ", \"ImageURL\": \"images_icon/computer.png\""; - } - - JSON += "}"; - return JSON; - } - - private static void returnFile(HttpListenerContext context, string filePath) - { - context.Response.ContentType = getcontentType(Path.GetExtension(filePath)); - const int bufferSize = 1024 * 512; //512KB - var buffer = new byte[bufferSize]; - using (var fs = File.OpenRead(filePath)) - { - - context.Response.ContentLength64 = fs.Length; - int read; - while ((read = fs.Read(buffer, 0, buffer.Length)) > 0) - context.Response.OutputStream.Write(buffer, 0, read); - } - - context.Response.OutputStream.Close(); - } - - private static string getcontentType(string extension) - { - switch (extension) - { - case ".avi": return "video/x-msvideo"; - case ".css": return "text/css"; - case ".doc": return "application/msword"; - case ".gif": return "image/gif"; - case ".htm": - case ".html": return "text/html"; - case ".jpg": - case ".jpeg": return "image/jpeg"; - case ".js": return "application/x-javascript"; - case ".mp3": return "audio/mpeg"; - case ".png": return "image/png"; - case ".pdf": return "application/pdf"; - case ".ppt": return "application/vnd.ms-powerpoint"; - case ".zip": return "application/zip"; - case ".txt": return "text/plain"; - default: return "application/octet-stream"; - } - } - - private static string getHardwareImageFile(HardwareNode hn) - { - - switch (hn.Hardware.HardwareType) - { - case HardwareType.CPU: - return "cpu.png"; - case HardwareType.GpuNvidia: - return "nvidia.png"; - case HardwareType.GpuAti: - return "ati.png"; - case HardwareType.HDD: - return "hdd.png"; - case HardwareType.Heatmaster: - return "bigng.png"; - case HardwareType.Mainboard: - return "mainboard.png"; - case HardwareType.SuperIO: - return "chip.png"; - case HardwareType.TBalancer: - return "bigng.png"; - case HardwareType.RAM: - return "ram.png"; - default: - return "cpu.png"; - } - - } - - private static string getTypeImageFile(TypeNode tn) - { - - switch (tn.SensorType) - { - case SensorType.Voltage: - return "voltage.png"; - case SensorType.Clock: - return "clock.png"; - case SensorType.Load: - return "load.png"; - case SensorType.Temperature: - return "temperature.png"; - case SensorType.Fan: - return "fan.png"; - case SensorType.Flow: - return "flow.png"; - case SensorType.Control: - return "control.png"; - case SensorType.Level: - return "level.png"; - case SensorType.Power: - return "power.png"; - default: - return "power.png"; - } - - } - - public int ListenerPort - { - get { return listenerPort; } - set { listenerPort = value; } - } - - ~HttpServer() - { - stopHTTPListener(); - listener.Abort(); - } - - public void Quit() - { - stopHTTPListener(); - listener.Abort(); - } + //JSON node count. + nodeCount = 0; + listener = new HttpListener(); } + + public Boolean StartHTTPListener() { + try { + if (listener.IsListening) + return true; + + string prefix = "http://+:" + listenerPort + "/"; + listener.Prefixes.Clear(); + listener.Prefixes.Add(prefix); + listener.Start(); + + if (listenerThread == null) { + listenerThread = new Thread(HandleRequests); + listenerThread.Start(); + } + } catch (Exception) { + return false; + } + + return true; + } + + public Boolean StopHTTPListener() { + try { + listenerThread.Abort(); + listener.Stop(); + listenerThread = null; + } catch (HttpListenerException) { + } catch (ThreadAbortException) { + } catch (NullReferenceException) { + } catch (Exception) { + } + return true; + } + + public void HandleRequests() { + + while (listener.IsListening) { + var context = listener.BeginGetContext( + new AsyncCallback(ListenerCallback), listener); + context.AsyncWaitHandle.WaitOne(); + } + } + + public void ListenerCallback(IAsyncResult result) { + HttpListener listener = (HttpListener)result.AsyncState; + if (listener == null || !listener.IsListening) + return; + // Call EndGetContext to complete the asynchronous operation. + HttpListenerContext context = listener.EndGetContext(result); + HttpListenerRequest request = context.Request; + + var requestedFile = request.RawUrl.Substring(1); + if (requestedFile == "data.json") { + SendJSON(context); + return; + } + + if (requestedFile.Contains("images_icon")) { + ServeResourceImage(context, requestedFile.Replace("images_icon/", "")); + return; + } + + // default file to be served + if (string.IsNullOrEmpty(requestedFile)) + requestedFile = "index.html"; + + string[] splits = requestedFile.Split('.'); + string ext = splits[splits.Length - 1]; + ServeResourceFile(context, "Web." + requestedFile.Replace('/', '.'), ext); + } + + private void ServeResourceFile(HttpListenerContext context, string name, + string ext) + { + + // resource names do not support the hyphen + name = "OpenHardwareMonitor.Resources." + + name.Replace("custom-theme", "custom_theme"); + + string[] names = + Assembly.GetExecutingAssembly().GetManifestResourceNames(); + for (int i = 0; i < names.Length; i++) { + if (names[i].Replace('\\', '.') == name) { + using (Stream stream = Assembly.GetExecutingAssembly(). + GetManifestResourceStream(names[i])) { + context.Response.ContentType = GetcontentType("." + ext); + context.Response.ContentLength64 = stream.Length; + byte[] buffer = new byte[512 * 1024]; + int len; + while ((len = stream.Read(buffer, 0, buffer.Length)) > 0) { + context.Response.OutputStream.Write(buffer, 0, len); + } + context.Response.OutputStream.Close(); + } + return; + } + } + context.Response.OutputStream.Close(); + context.Response.StatusCode = 404; + context.Response.Close(); + } + + private void ServeResourceImage(HttpListenerContext context, string name) { + name = "OpenHardwareMonitor.Resources." + name; + + string[] names = + Assembly.GetExecutingAssembly().GetManifestResourceNames(); + for (int i = 0; i < names.Length; i++) { + if (names[i].Replace('\\', '.') == name) { + using (Stream stream = Assembly.GetExecutingAssembly(). + GetManifestResourceStream(names[i])) { + + Image image = Image.FromStream(stream); + context.Response.ContentType = "image/png"; + using (MemoryStream ms = new MemoryStream()) { + image.Save(ms, ImageFormat.Png); + ms.WriteTo(context.Response.OutputStream); + } + context.Response.OutputStream.Close(); + image.Dispose(); + return; + } + } + } + context.Response.OutputStream.Close(); + context.Response.StatusCode = 404; + context.Response.Close(); + } + + private void SendJSON(HttpListenerContext context) { + + string JSON = "{\"id\": 0, \"Text\": \"Sensor\", \"Children\": ["; + nodeCount = 1; + JSON += GenerateJSON(root); + JSON += "]"; + JSON += ", \"Min\": \"Min\""; + JSON += ", \"Value\": \"Value\""; + JSON += ", \"Max\": \"Max\""; + JSON += ", \"ImageURL\": \"\""; + JSON += "}"; + + var responseContent = JSON; + byte[] buffer = Encoding.UTF8.GetBytes(responseContent); + + context.Response.ContentLength64 = buffer.Length; + context.Response.ContentType = "application/json"; + + Stream outputStream = context.Response.OutputStream; + outputStream.Write(buffer, 0, buffer.Length); + outputStream.Close(); + + } + + private string GenerateJSON(Node n) { + string JSON = "{\"id\": " + nodeCount + ", \"Text\": \"" + n.Text + + "\", \"Children\": ["; + nodeCount++; + + foreach (Node child in n.Nodes) + JSON += GenerateJSON(child) + ", "; + if (JSON.EndsWith(", ")) + JSON = JSON.Remove(JSON.LastIndexOf(",")); + JSON += "]"; + + if (n is SensorNode) { + JSON += ", \"Min\": \"" + ((SensorNode)n).Min + "\""; + JSON += ", \"Value\": \"" + ((SensorNode)n).Value + "\""; + JSON += ", \"Max\": \"" + ((SensorNode)n).Max + "\""; + JSON += ", \"ImageURL\": \"images/transparent.png\""; + } else if (n is HardwareNode) { + JSON += ", \"Min\": \"\""; + JSON += ", \"Value\": \"\""; + JSON += ", \"Max\": \"\""; + JSON += ", \"ImageURL\": \"images_icon/" + + GetHardwareImageFile((HardwareNode)n) + "\""; + } else if (n is TypeNode) { + JSON += ", \"Min\": \"\""; + JSON += ", \"Value\": \"\""; + JSON += ", \"Max\": \"\""; + JSON += ", \"ImageURL\": \"images_icon/" + + GetTypeImageFile((TypeNode)n) + "\""; + } else { + JSON += ", \"Min\": \"\""; + JSON += ", \"Value\": \"\""; + JSON += ", \"Max\": \"\""; + JSON += ", \"ImageURL\": \"images_icon/computer.png\""; + } + + JSON += "}"; + return JSON; + } + + private static void ReturnFile(HttpListenerContext context, string filePath) + { + context.Response.ContentType = + GetcontentType(Path.GetExtension(filePath)); + const int bufferSize = 1024 * 512; //512KB + var buffer = new byte[bufferSize]; + using (var fs = File.OpenRead(filePath)) { + + context.Response.ContentLength64 = fs.Length; + int read; + while ((read = fs.Read(buffer, 0, buffer.Length)) > 0) + context.Response.OutputStream.Write(buffer, 0, read); + } + + context.Response.OutputStream.Close(); + } + + private static string GetcontentType(string extension) { + switch (extension) { + case ".avi": return "video/x-msvideo"; + case ".css": return "text/css"; + case ".doc": return "application/msword"; + case ".gif": return "image/gif"; + case ".htm": + case ".html": return "text/html"; + case ".jpg": + case ".jpeg": return "image/jpeg"; + case ".js": return "application/x-javascript"; + case ".mp3": return "audio/mpeg"; + case ".png": return "image/png"; + case ".pdf": return "application/pdf"; + case ".ppt": return "application/vnd.ms-powerpoint"; + case ".zip": return "application/zip"; + case ".txt": return "text/plain"; + default: return "application/octet-stream"; + } + } + + private static string GetHardwareImageFile(HardwareNode hn) { + + switch (hn.Hardware.HardwareType) { + case HardwareType.CPU: + return "cpu.png"; + case HardwareType.GpuNvidia: + return "nvidia.png"; + case HardwareType.GpuAti: + return "ati.png"; + case HardwareType.HDD: + return "hdd.png"; + case HardwareType.Heatmaster: + return "bigng.png"; + case HardwareType.Mainboard: + return "mainboard.png"; + case HardwareType.SuperIO: + return "chip.png"; + case HardwareType.TBalancer: + return "bigng.png"; + case HardwareType.RAM: + return "ram.png"; + default: + return "cpu.png"; + } + + } + + private static string GetTypeImageFile(TypeNode tn) { + + switch (tn.SensorType) { + case SensorType.Voltage: + return "voltage.png"; + case SensorType.Clock: + return "clock.png"; + case SensorType.Load: + return "load.png"; + case SensorType.Temperature: + return "temperature.png"; + case SensorType.Fan: + return "fan.png"; + case SensorType.Flow: + return "flow.png"; + case SensorType.Control: + return "control.png"; + case SensorType.Level: + return "level.png"; + case SensorType.Power: + return "power.png"; + default: + return "power.png"; + } + + } + + public int ListenerPort { + get { return listenerPort; } + set { listenerPort = value; } + } + + ~HttpServer() { + StopHTTPListener(); + listener.Abort(); + } + + public void Quit() { + StopHTTPListener(); + listener.Abort(); + } + } }