Front View plug-in does not init if no sensor added.
Fixing some format to make strings shorter.
Now trying to start SoundGraphAccess.exe process from same directory.
Packed mode now can display three sensors along with the current time.
3 This Source Code Form is subject to the terms of the Mozilla Public
4 License, v. 2.0. If a copy of the MPL was not distributed with this
5 file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 Copyright (C) 2012 Prince Samuel <prince.samuel@gmail.com>
8 Copyright (C) 2012-2013 Michael Möller <mmoeller@openhardwaremonitor.org>
14 using System.Drawing.Imaging;
17 using System.Reflection;
19 using System.Threading;
20 using OpenHardwareMonitor.GUI;
21 using OpenHardwareMonitor.Hardware;
23 namespace OpenHardwareMonitor.Utilities {
25 public class HttpServer {
26 private HttpListener listener;
27 private int listenerPort, nodeCount;
28 private Thread listenerThread;
31 public HttpServer(Node node, int port) {
39 listener = new HttpListener();
40 listener.IgnoreWriteExceptions = true;
41 } catch (PlatformNotSupportedException) {
46 public bool PlatformNotSupported {
48 return listener == null;
52 public Boolean StartHTTPListener() {
53 if (PlatformNotSupported)
57 if (listener.IsListening)
60 string prefix = "http://+:" + listenerPort + "/";
61 listener.Prefixes.Clear();
62 listener.Prefixes.Add(prefix);
65 if (listenerThread == null) {
66 listenerThread = new Thread(HandleRequests);
67 listenerThread.Start();
76 public Boolean StopHTTPListener() {
77 if (PlatformNotSupported)
81 listenerThread.Abort();
83 listenerThread = null;
84 } catch (HttpListenerException) {
85 } catch (ThreadAbortException) {
86 } catch (NullReferenceException) {
92 private void HandleRequests() {
94 while (listener.IsListening) {
95 var context = listener.BeginGetContext(
96 new AsyncCallback(ListenerCallback), listener);
97 context.AsyncWaitHandle.WaitOne();
101 private void ListenerCallback(IAsyncResult result) {
102 HttpListener listener = (HttpListener)result.AsyncState;
103 if (listener == null || !listener.IsListening)
106 // Call EndGetContext to complete the asynchronous operation.
107 HttpListenerContext context;
109 context = listener.EndGetContext(result);
110 } catch (Exception) {
114 HttpListenerRequest request = context.Request;
116 var requestedFile = request.RawUrl.Substring(1);
117 if (requestedFile == "data.json") {
118 SendJSON(context.Response);
122 if (requestedFile.Contains("images_icon")) {
123 ServeResourceImage(context.Response,
124 requestedFile.Replace("images_icon/", ""));
128 // default file to be served
129 if (string.IsNullOrEmpty(requestedFile))
130 requestedFile = "index.html";
132 string[] splits = requestedFile.Split('.');
133 string ext = splits[splits.Length - 1];
134 ServeResourceFile(context.Response,
135 "Web." + requestedFile.Replace('/', '.'), ext);
138 private void ServeResourceFile(HttpListenerResponse response, string name,
141 // resource names do not support the hyphen
142 name = "OpenHardwareMonitor.Resources." +
143 name.Replace("custom-theme", "custom_theme");
146 Assembly.GetExecutingAssembly().GetManifestResourceNames();
147 for (int i = 0; i < names.Length; i++) {
148 if (names[i].Replace('\\', '.') == name) {
149 using (Stream stream = Assembly.GetExecutingAssembly().
150 GetManifestResourceStream(names[i])) {
151 response.ContentType = GetcontentType("." + ext);
152 response.ContentLength64 = stream.Length;
153 byte[] buffer = new byte[512 * 1024];
156 Stream output = response.OutputStream;
157 while ((len = stream.Read(buffer, 0, buffer.Length)) > 0) {
158 output.Write(buffer, 0, len);
163 } catch (HttpListenerException) {
164 } catch (InvalidOperationException) {
171 response.StatusCode = 404;
175 private void ServeResourceImage(HttpListenerResponse response, string name) {
176 name = "OpenHardwareMonitor.Resources." + name;
179 Assembly.GetExecutingAssembly().GetManifestResourceNames();
180 for (int i = 0; i < names.Length; i++) {
181 if (names[i].Replace('\\', '.') == name) {
182 using (Stream stream = Assembly.GetExecutingAssembly().
183 GetManifestResourceStream(names[i])) {
185 Image image = Image.FromStream(stream);
186 response.ContentType = "image/png";
188 Stream output = response.OutputStream;
189 using (MemoryStream ms = new MemoryStream()) {
190 image.Save(ms, ImageFormat.Png);
194 } catch (HttpListenerException) {
203 response.StatusCode = 404;
207 private void SendJSON(HttpListenerResponse response) {
209 string JSON = "{\"id\": 0, \"Text\": \"Sensor\", \"Children\": [";
211 JSON += GenerateJSON(root);
213 JSON += ", \"Min\": \"Min\"";
214 JSON += ", \"Value\": \"Value\"";
215 JSON += ", \"Max\": \"Max\"";
216 JSON += ", \"ImageURL\": \"\"";
219 var responseContent = JSON;
220 byte[] buffer = Encoding.UTF8.GetBytes(responseContent);
222 response.AddHeader("Cache-Control", "no-cache");
224 response.ContentLength64 = buffer.Length;
225 response.ContentType = "application/json";
228 Stream output = response.OutputStream;
229 output.Write(buffer, 0, buffer.Length);
231 } catch (HttpListenerException) {
237 private string GenerateJSON(Node n) {
238 string JSON = "{\"id\": " + nodeCount + ", \"Text\": \"" + n.Text
239 + "\", \"Children\": [";
242 foreach (Node child in n.Nodes)
243 JSON += GenerateJSON(child) + ", ";
244 if (JSON.EndsWith(", "))
245 JSON = JSON.Remove(JSON.LastIndexOf(","));
248 if (n is SensorNode) {
249 JSON += ", \"Min\": \"" + ((SensorNode)n).Min + "\"";
250 JSON += ", \"Value\": \"" + ((SensorNode)n).Value + "\"";
251 JSON += ", \"Max\": \"" + ((SensorNode)n).Max + "\"";
252 JSON += ", \"ImageURL\": \"images/transparent.png\"";
253 } else if (n is HardwareNode) {
254 JSON += ", \"Min\": \"\"";
255 JSON += ", \"Value\": \"\"";
256 JSON += ", \"Max\": \"\"";
257 JSON += ", \"ImageURL\": \"images_icon/" +
258 GetHardwareImageFile((HardwareNode)n) + "\"";
259 } else if (n is TypeNode) {
260 JSON += ", \"Min\": \"\"";
261 JSON += ", \"Value\": \"\"";
262 JSON += ", \"Max\": \"\"";
263 JSON += ", \"ImageURL\": \"images_icon/" +
264 GetTypeImageFile((TypeNode)n) + "\"";
266 JSON += ", \"Min\": \"\"";
267 JSON += ", \"Value\": \"\"";
268 JSON += ", \"Max\": \"\"";
269 JSON += ", \"ImageURL\": \"images_icon/computer.png\"";
276 private static void ReturnFile(HttpListenerContext context, string filePath)
278 context.Response.ContentType =
279 GetcontentType(Path.GetExtension(filePath));
280 const int bufferSize = 1024 * 512; //512KB
281 var buffer = new byte[bufferSize];
282 using (var fs = File.OpenRead(filePath)) {
284 context.Response.ContentLength64 = fs.Length;
286 while ((read = fs.Read(buffer, 0, buffer.Length)) > 0)
287 context.Response.OutputStream.Write(buffer, 0, read);
290 context.Response.OutputStream.Close();
293 private static string GetcontentType(string extension) {
295 case ".avi": return "video/x-msvideo";
296 case ".css": return "text/css";
297 case ".doc": return "application/msword";
298 case ".gif": return "image/gif";
300 case ".html": return "text/html";
302 case ".jpeg": return "image/jpeg";
303 case ".js": return "application/x-javascript";
304 case ".mp3": return "audio/mpeg";
305 case ".png": return "image/png";
306 case ".pdf": return "application/pdf";
307 case ".ppt": return "application/vnd.ms-powerpoint";
308 case ".zip": return "application/zip";
309 case ".txt": return "text/plain";
310 default: return "application/octet-stream";
314 private static string GetHardwareImageFile(HardwareNode hn) {
316 switch (hn.Hardware.HardwareType) {
317 case HardwareType.CPU:
319 case HardwareType.GpuNvidia:
321 case HardwareType.GpuAti:
323 case HardwareType.HDD:
325 case HardwareType.Heatmaster:
327 case HardwareType.Mainboard:
328 return "mainboard.png";
329 case HardwareType.SuperIO:
331 case HardwareType.TBalancer:
333 case HardwareType.RAM:
341 private static string GetTypeImageFile(TypeNode tn) {
343 switch (tn.SensorType) {
344 case SensorType.Voltage:
345 return "voltage.png";
346 case SensorType.Clock:
348 case SensorType.Load:
350 case SensorType.Temperature:
351 return "temperature.png";
354 case SensorType.Flow:
356 case SensorType.Control:
357 return "control.png";
358 case SensorType.Level:
360 case SensorType.Power:
368 public int ListenerPort {
369 get { return listenerPort; }
370 set { listenerPort = value; }
374 if (PlatformNotSupported)
382 if (PlatformNotSupported)