1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/Utilities/HttpServer.cs Sun May 27 20:15:32 2012 +0000
1.3 @@ -0,0 +1,371 @@
1.4 +/*
1.5 +
1.6 + This Source Code Form is subject to the terms of the Mozilla Public
1.7 + License, v. 2.0. If a copy of the MPL was not distributed with this
1.8 + file, You can obtain one at http://mozilla.org/MPL/2.0/.
1.9 +
1.10 + Copyright (C) 2012 Prince Samuel <prince.samuel@gmail.com>
1.11 +
1.12 +*/
1.13 +
1.14 +using System;
1.15 +using System.Collections.Generic;
1.16 +using System.Text;
1.17 +using System.Net;
1.18 +using System.Threading;
1.19 +using System.IO;
1.20 +using OpenHardwareMonitor.GUI;
1.21 +using OpenHardwareMonitor.Hardware;
1.22 +using System.Reflection;
1.23 +using System.Drawing;
1.24 +using System.Drawing.Imaging;
1.25 +
1.26 +namespace OpenHardwareMonitor.Utilities
1.27 +{
1.28 + public class HttpServer
1.29 + {
1.30 + private HttpListener listener;
1.31 + private int listenerPort, nodeCount;
1.32 + private Thread listenerThread;
1.33 + private Node root;
1.34 +
1.35 + public HttpServer(Node r, int p)
1.36 + {
1.37 + root = r;
1.38 + listenerPort = p;
1.39 + //JSON node count.
1.40 + nodeCount = 0;
1.41 + listener = new HttpListener();
1.42 + }
1.43 +
1.44 + public Boolean startHTTPListener()
1.45 + {
1.46 + try
1.47 + {
1.48 + if (listener.IsListening)
1.49 + return true;
1.50 +
1.51 + string prefix = "http://+:" + listenerPort + "/";
1.52 + listener.Prefixes.Clear();
1.53 + listener.Prefixes.Add(prefix);
1.54 + listener.Start();
1.55 +
1.56 + if (listenerThread == null)
1.57 + {
1.58 + listenerThread = new Thread(HandleRequests);
1.59 + listenerThread.Start();
1.60 + }
1.61 + }
1.62 + catch (Exception e)
1.63 + {
1.64 + return false;
1.65 + }
1.66 +
1.67 + return true;
1.68 + }
1.69 +
1.70 + public Boolean stopHTTPListener()
1.71 + {
1.72 + try
1.73 + {
1.74 + listenerThread.Abort();
1.75 + listener.Stop();
1.76 + listenerThread = null;
1.77 + }
1.78 + catch (System.Net.HttpListenerException e)
1.79 + {
1.80 + }
1.81 + catch (System.Threading.ThreadAbortException e)
1.82 + {
1.83 + }
1.84 + catch (System.NullReferenceException e)
1.85 + {
1.86 + }
1.87 + catch (Exception e)
1.88 + {
1.89 + }
1.90 + return true;
1.91 + }
1.92 +
1.93 + public void HandleRequests()
1.94 + {
1.95 +
1.96 + while (listener.IsListening)
1.97 + {
1.98 + var context = listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener);
1.99 + context.AsyncWaitHandle.WaitOne();
1.100 + }
1.101 + }
1.102 +
1.103 + public void ListenerCallback(IAsyncResult result)
1.104 + {
1.105 + HttpListener listener = (HttpListener)result.AsyncState;
1.106 + if (listener == null || !listener.IsListening)
1.107 + return;
1.108 + // Call EndGetContext to complete the asynchronous operation.
1.109 + HttpListenerContext context = listener.EndGetContext(result);
1.110 + HttpListenerRequest request = context.Request;
1.111 +
1.112 + var requestedFile = request.RawUrl.Substring(1);
1.113 + if (requestedFile == "data.json")
1.114 + {
1.115 + sendJSON(context);
1.116 + return;
1.117 + }
1.118 +
1.119 + if (requestedFile.Contains("images_icon"))
1.120 + {
1.121 + serveResourceImage(context, requestedFile.Replace("images_icon/", ""));
1.122 + return;
1.123 + }
1.124 +
1.125 + //default file to be served
1.126 + if (string.IsNullOrEmpty(requestedFile))
1.127 + requestedFile = "index.html";
1.128 +
1.129 + string[] splits = requestedFile.Split('.');
1.130 + string ext = splits[splits.Length - 1];
1.131 + serveResourceFile(context, "Web." + requestedFile.Replace('/', '.'), ext);
1.132 + }
1.133 +
1.134 + private void serveResourceFile(HttpListenerContext context ,string name, string ext) {
1.135 +
1.136 + //hack! resource names do not support the hyphen
1.137 + name = "OpenHardwareMonitor.Resources." + name.Replace("custom-theme", "custom_theme");
1.138 +
1.139 + string[] names =
1.140 + Assembly.GetExecutingAssembly().GetManifestResourceNames();
1.141 + for (int i = 0; i < names.Length; i++) {
1.142 + if (names[i].Replace('\\', '.') == name) {
1.143 + using (Stream stream = Assembly.GetExecutingAssembly().
1.144 + GetManifestResourceStream(names[i])) {
1.145 + context.Response.ContentType = getcontentType("." + ext);
1.146 + context.Response.ContentLength64 = stream.Length;
1.147 + byte[] buffer = new byte[512 * 1024];
1.148 + int len;
1.149 + while ((len = stream.Read(buffer, 0, buffer.Length)) > 0)
1.150 + {
1.151 + context.Response.OutputStream.Write(buffer, 0, len);
1.152 + }
1.153 + context.Response.OutputStream.Close();
1.154 + }
1.155 + return;
1.156 + }
1.157 + }
1.158 + context.Response.OutputStream.Close();
1.159 + context.Response.StatusCode = 404;
1.160 + context.Response.Close();
1.161 + }
1.162 +
1.163 + private void serveResourceImage(HttpListenerContext context ,string name) {
1.164 + name = "OpenHardwareMonitor.Resources." + name;
1.165 +
1.166 + string[] names =
1.167 + Assembly.GetExecutingAssembly().GetManifestResourceNames();
1.168 + for (int i = 0; i < names.Length; i++) {
1.169 + if (names[i].Replace('\\', '.') == name) {
1.170 + using (Stream stream = Assembly.GetExecutingAssembly().
1.171 + GetManifestResourceStream(names[i])) {
1.172 +
1.173 + Image image = Image.FromStream(stream);
1.174 + context.Response.ContentType = "image/png";
1.175 + using (MemoryStream ms = new MemoryStream())
1.176 + {
1.177 + image.Save(ms, ImageFormat.Png);
1.178 + ms.WriteTo(context.Response.OutputStream);
1.179 + }
1.180 + context.Response.OutputStream.Close();
1.181 + image.Dispose();
1.182 + return;
1.183 + }
1.184 + }
1.185 + }
1.186 + context.Response.OutputStream.Close();
1.187 + context.Response.StatusCode = 404;
1.188 + context.Response.Close();
1.189 + }
1.190 +
1.191 + private void sendJSON(HttpListenerContext context)
1.192 + {
1.193 +
1.194 + string JSON = "{\"id\": 0, \"Text\": \"Sensor\", \"Children\": [";
1.195 + nodeCount = 1;
1.196 + JSON += generateJSON(root);
1.197 + JSON += "]";
1.198 + JSON += ", \"Min\": \"Min\"";
1.199 + JSON += ", \"Value\": \"Value\"";
1.200 + JSON += ", \"Max\": \"Max\"";
1.201 + JSON += ", \"ImageURL\": \"\"";
1.202 + JSON += "}";
1.203 +
1.204 + var responseContent = JSON;
1.205 + byte[] buffer = Encoding.UTF8.GetBytes(responseContent);
1.206 +
1.207 + context.Response.ContentLength64 = buffer.Length;
1.208 + context.Response.ContentType = "application/json";
1.209 +
1.210 + Stream outputStream = context.Response.OutputStream;
1.211 + outputStream.Write(buffer, 0, buffer.Length);
1.212 + outputStream.Close();
1.213 +
1.214 + }
1.215 +
1.216 + private string generateJSON(Node n)
1.217 + {
1.218 + string JSON = "{\"id\": " + nodeCount + ", \"Text\": \"" + n.Text + "\", \"Children\": [";
1.219 + nodeCount++;
1.220 +
1.221 + foreach (Node child in n.Nodes)
1.222 + JSON += generateJSON(child) + ", ";
1.223 + if (JSON.EndsWith(", "))
1.224 + JSON = JSON.Remove(JSON.LastIndexOf(","));
1.225 + JSON += "]";
1.226 +
1.227 + if (n is SensorNode)
1.228 + {
1.229 + JSON += ", \"Min\": \"" + ((SensorNode)n).Min + "\"";
1.230 + JSON += ", \"Value\": \"" + ((SensorNode)n).Value + "\"";
1.231 + JSON += ", \"Max\": \"" + ((SensorNode)n).Max + "\"";
1.232 + JSON += ", \"ImageURL\": \"images/transparent.png\"";
1.233 + }
1.234 + else if (n is HardwareNode)
1.235 + {
1.236 + JSON += ", \"Min\": \"\"";
1.237 + JSON += ", \"Value\": \"\"";
1.238 + JSON += ", \"Max\": \"\"";
1.239 + JSON += ", \"ImageURL\": \"images_icon/" + getHardwareImageFile((HardwareNode)n) + "\"";
1.240 + }
1.241 + else if (n is TypeNode)
1.242 + {
1.243 + JSON += ", \"Min\": \"\"";
1.244 + JSON += ", \"Value\": \"\"";
1.245 + JSON += ", \"Max\": \"\"";
1.246 + JSON += ", \"ImageURL\": \"images_icon/" + getTypeImageFile((TypeNode)n) + "\"";
1.247 + }
1.248 + else
1.249 + {
1.250 + JSON += ", \"Min\": \"\"";
1.251 + JSON += ", \"Value\": \"\"";
1.252 + JSON += ", \"Max\": \"\"";
1.253 + JSON += ", \"ImageURL\": \"images_icon/computer.png\"";
1.254 + }
1.255 +
1.256 + JSON += "}";
1.257 + return JSON;
1.258 + }
1.259 +
1.260 + private static void returnFile(HttpListenerContext context, string filePath)
1.261 + {
1.262 + context.Response.ContentType = getcontentType(Path.GetExtension(filePath));
1.263 + const int bufferSize = 1024 * 512; //512KB
1.264 + var buffer = new byte[bufferSize];
1.265 + using (var fs = File.OpenRead(filePath))
1.266 + {
1.267 +
1.268 + context.Response.ContentLength64 = fs.Length;
1.269 + int read;
1.270 + while ((read = fs.Read(buffer, 0, buffer.Length)) > 0)
1.271 + context.Response.OutputStream.Write(buffer, 0, read);
1.272 + }
1.273 +
1.274 + context.Response.OutputStream.Close();
1.275 + }
1.276 +
1.277 + private static string getcontentType(string extension)
1.278 + {
1.279 + switch (extension)
1.280 + {
1.281 + case ".avi": return "video/x-msvideo";
1.282 + case ".css": return "text/css";
1.283 + case ".doc": return "application/msword";
1.284 + case ".gif": return "image/gif";
1.285 + case ".htm":
1.286 + case ".html": return "text/html";
1.287 + case ".jpg":
1.288 + case ".jpeg": return "image/jpeg";
1.289 + case ".js": return "application/x-javascript";
1.290 + case ".mp3": return "audio/mpeg";
1.291 + case ".png": return "image/png";
1.292 + case ".pdf": return "application/pdf";
1.293 + case ".ppt": return "application/vnd.ms-powerpoint";
1.294 + case ".zip": return "application/zip";
1.295 + case ".txt": return "text/plain";
1.296 + default: return "application/octet-stream";
1.297 + }
1.298 + }
1.299 +
1.300 + private static string getHardwareImageFile(HardwareNode hn)
1.301 + {
1.302 +
1.303 + switch (hn.Hardware.HardwareType)
1.304 + {
1.305 + case HardwareType.CPU:
1.306 + return "cpu.png";
1.307 + case HardwareType.GpuNvidia:
1.308 + return "nvidia.png";
1.309 + case HardwareType.GpuAti:
1.310 + return "ati.png";
1.311 + case HardwareType.HDD:
1.312 + return "hdd.png";
1.313 + case HardwareType.Heatmaster:
1.314 + return "bigng.png";
1.315 + case HardwareType.Mainboard:
1.316 + return "mainboard.png";
1.317 + case HardwareType.SuperIO:
1.318 + return "chip.png";
1.319 + case HardwareType.TBalancer:
1.320 + return "bigng.png";
1.321 + default:
1.322 + return "cpu.png";
1.323 + }
1.324 +
1.325 + }
1.326 +
1.327 + private static string getTypeImageFile(TypeNode tn)
1.328 + {
1.329 +
1.330 + switch (tn.SensorType)
1.331 + {
1.332 + case SensorType.Voltage:
1.333 + return "voltage.png";
1.334 + case SensorType.Clock:
1.335 + return "clock.png";
1.336 + case SensorType.Load:
1.337 + return "load.png";
1.338 + case SensorType.Temperature:
1.339 + return "temperature.png";
1.340 + case SensorType.Fan:
1.341 + return "fan.png";
1.342 + case SensorType.Flow:
1.343 + return "flow.png";
1.344 + case SensorType.Control:
1.345 + return "control.png";
1.346 + case SensorType.Level:
1.347 + return "level.png";
1.348 + case SensorType.Power:
1.349 + return "power.png";
1.350 + default:
1.351 + return "power.png";
1.352 + }
1.353 +
1.354 + }
1.355 +
1.356 + public int ListenerPort
1.357 + {
1.358 + get { return listenerPort; }
1.359 + set { listenerPort = value; }
1.360 + }
1.361 +
1.362 + ~HttpServer()
1.363 + {
1.364 + stopHTTPListener();
1.365 + listener.Abort();
1.366 + }
1.367 +
1.368 + public void Quit()
1.369 + {
1.370 + stopHTTPListener();
1.371 + listener.Abort();
1.372 + }
1.373 + }
1.374 +}