Changed the source formatting of the HttpServer class to match the rest of the project.
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 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 r, int p) {
37 listener = new HttpListener();
40 public Boolean StartHTTPListener() {
42 if (listener.IsListening)
45 string prefix = "http://+:" + listenerPort + "/";
46 listener.Prefixes.Clear();
47 listener.Prefixes.Add(prefix);
50 if (listenerThread == null) {
51 listenerThread = new Thread(HandleRequests);
52 listenerThread.Start();
61 public Boolean StopHTTPListener() {
63 listenerThread.Abort();
65 listenerThread = null;
66 } catch (HttpListenerException) {
67 } catch (ThreadAbortException) {
68 } catch (NullReferenceException) {
74 public void HandleRequests() {
76 while (listener.IsListening) {
77 var context = listener.BeginGetContext(
78 new AsyncCallback(ListenerCallback), listener);
79 context.AsyncWaitHandle.WaitOne();
83 public void ListenerCallback(IAsyncResult result) {
84 HttpListener listener = (HttpListener)result.AsyncState;
85 if (listener == null || !listener.IsListening)
87 // Call EndGetContext to complete the asynchronous operation.
88 HttpListenerContext context = listener.EndGetContext(result);
89 HttpListenerRequest request = context.Request;
91 var requestedFile = request.RawUrl.Substring(1);
92 if (requestedFile == "data.json") {
97 if (requestedFile.Contains("images_icon")) {
98 ServeResourceImage(context, requestedFile.Replace("images_icon/", ""));
102 // default file to be served
103 if (string.IsNullOrEmpty(requestedFile))
104 requestedFile = "index.html";
106 string[] splits = requestedFile.Split('.');
107 string ext = splits[splits.Length - 1];
108 ServeResourceFile(context, "Web." + requestedFile.Replace('/', '.'), ext);
111 private void ServeResourceFile(HttpListenerContext context, string name,
115 // resource names do not support the hyphen
116 name = "OpenHardwareMonitor.Resources." +
117 name.Replace("custom-theme", "custom_theme");
120 Assembly.GetExecutingAssembly().GetManifestResourceNames();
121 for (int i = 0; i < names.Length; i++) {
122 if (names[i].Replace('\\', '.') == name) {
123 using (Stream stream = Assembly.GetExecutingAssembly().
124 GetManifestResourceStream(names[i])) {
125 context.Response.ContentType = GetcontentType("." + ext);
126 context.Response.ContentLength64 = stream.Length;
127 byte[] buffer = new byte[512 * 1024];
129 while ((len = stream.Read(buffer, 0, buffer.Length)) > 0) {
130 context.Response.OutputStream.Write(buffer, 0, len);
132 context.Response.OutputStream.Close();
137 context.Response.OutputStream.Close();
138 context.Response.StatusCode = 404;
139 context.Response.Close();
142 private void ServeResourceImage(HttpListenerContext context, string name) {
143 name = "OpenHardwareMonitor.Resources." + name;
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])) {
152 Image image = Image.FromStream(stream);
153 context.Response.ContentType = "image/png";
154 using (MemoryStream ms = new MemoryStream()) {
155 image.Save(ms, ImageFormat.Png);
156 ms.WriteTo(context.Response.OutputStream);
158 context.Response.OutputStream.Close();
164 context.Response.OutputStream.Close();
165 context.Response.StatusCode = 404;
166 context.Response.Close();
169 private void SendJSON(HttpListenerContext context) {
171 string JSON = "{\"id\": 0, \"Text\": \"Sensor\", \"Children\": [";
173 JSON += GenerateJSON(root);
175 JSON += ", \"Min\": \"Min\"";
176 JSON += ", \"Value\": \"Value\"";
177 JSON += ", \"Max\": \"Max\"";
178 JSON += ", \"ImageURL\": \"\"";
181 var responseContent = JSON;
182 byte[] buffer = Encoding.UTF8.GetBytes(responseContent);
184 context.Response.ContentLength64 = buffer.Length;
185 context.Response.ContentType = "application/json";
187 Stream outputStream = context.Response.OutputStream;
188 outputStream.Write(buffer, 0, buffer.Length);
189 outputStream.Close();
193 private string GenerateJSON(Node n) {
194 string JSON = "{\"id\": " + nodeCount + ", \"Text\": \"" + n.Text
195 + "\", \"Children\": [";
198 foreach (Node child in n.Nodes)
199 JSON += GenerateJSON(child) + ", ";
200 if (JSON.EndsWith(", "))
201 JSON = JSON.Remove(JSON.LastIndexOf(","));
204 if (n is SensorNode) {
205 JSON += ", \"Min\": \"" + ((SensorNode)n).Min + "\"";
206 JSON += ", \"Value\": \"" + ((SensorNode)n).Value + "\"";
207 JSON += ", \"Max\": \"" + ((SensorNode)n).Max + "\"";
208 JSON += ", \"ImageURL\": \"images/transparent.png\"";
209 } else if (n is HardwareNode) {
210 JSON += ", \"Min\": \"\"";
211 JSON += ", \"Value\": \"\"";
212 JSON += ", \"Max\": \"\"";
213 JSON += ", \"ImageURL\": \"images_icon/" +
214 GetHardwareImageFile((HardwareNode)n) + "\"";
215 } else if (n is TypeNode) {
216 JSON += ", \"Min\": \"\"";
217 JSON += ", \"Value\": \"\"";
218 JSON += ", \"Max\": \"\"";
219 JSON += ", \"ImageURL\": \"images_icon/" +
220 GetTypeImageFile((TypeNode)n) + "\"";
222 JSON += ", \"Min\": \"\"";
223 JSON += ", \"Value\": \"\"";
224 JSON += ", \"Max\": \"\"";
225 JSON += ", \"ImageURL\": \"images_icon/computer.png\"";
232 private static void ReturnFile(HttpListenerContext context, string filePath)
234 context.Response.ContentType =
235 GetcontentType(Path.GetExtension(filePath));
236 const int bufferSize = 1024 * 512; //512KB
237 var buffer = new byte[bufferSize];
238 using (var fs = File.OpenRead(filePath)) {
240 context.Response.ContentLength64 = fs.Length;
242 while ((read = fs.Read(buffer, 0, buffer.Length)) > 0)
243 context.Response.OutputStream.Write(buffer, 0, read);
246 context.Response.OutputStream.Close();
249 private static string GetcontentType(string extension) {
251 case ".avi": return "video/x-msvideo";
252 case ".css": return "text/css";
253 case ".doc": return "application/msword";
254 case ".gif": return "image/gif";
256 case ".html": return "text/html";
258 case ".jpeg": return "image/jpeg";
259 case ".js": return "application/x-javascript";
260 case ".mp3": return "audio/mpeg";
261 case ".png": return "image/png";
262 case ".pdf": return "application/pdf";
263 case ".ppt": return "application/vnd.ms-powerpoint";
264 case ".zip": return "application/zip";
265 case ".txt": return "text/plain";
266 default: return "application/octet-stream";
270 private static string GetHardwareImageFile(HardwareNode hn) {
272 switch (hn.Hardware.HardwareType) {
273 case HardwareType.CPU:
275 case HardwareType.GpuNvidia:
277 case HardwareType.GpuAti:
279 case HardwareType.HDD:
281 case HardwareType.Heatmaster:
283 case HardwareType.Mainboard:
284 return "mainboard.png";
285 case HardwareType.SuperIO:
287 case HardwareType.TBalancer:
289 case HardwareType.RAM:
297 private static string GetTypeImageFile(TypeNode tn) {
299 switch (tn.SensorType) {
300 case SensorType.Voltage:
301 return "voltage.png";
302 case SensorType.Clock:
304 case SensorType.Load:
306 case SensorType.Temperature:
307 return "temperature.png";
310 case SensorType.Flow:
312 case SensorType.Control:
313 return "control.png";
314 case SensorType.Level:
316 case SensorType.Power:
324 public int ListenerPort {
325 get { return listenerPort; }
326 set { listenerPort = value; }