Utilities/HttpServer.cs
author moel.mich
Sun, 23 Sep 2012 18:37:43 +0000
changeset 380 573f1fff48b2
parent 370 8e4dedc41924
child 386 7094d5dd924b
permissions -rw-r--r--
Fixed Issue 387. The new implementation does not try to start a ring 0 driver that already exists, but could not be opened. It tries to delete the driver and install it new. The driver is now stored temporarily in the application folder. The driver is not correctly removed on system shutdown.
     1 /*
     2  
     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/.
     6  
     7 	Copyright (C) 2012 Prince Samuel <prince.samuel@gmail.com>
     8 
     9 */
    10 
    11 using System;
    12 using System.Collections.Generic;
    13 using System.Text;
    14 using System.Net;
    15 using System.Threading;
    16 using System.IO;
    17 using OpenHardwareMonitor.GUI;
    18 using OpenHardwareMonitor.Hardware;
    19 using System.Reflection;
    20 using System.Drawing;
    21 using System.Drawing.Imaging;
    22 
    23 namespace OpenHardwareMonitor.Utilities
    24 {
    25     public class HttpServer
    26     {
    27         private HttpListener listener;
    28         private int listenerPort, nodeCount;
    29         private Thread listenerThread;
    30         private Node root;
    31 
    32         public HttpServer(Node r, int p)
    33         {
    34             root = r;
    35             listenerPort = p;
    36             //JSON node count. 
    37             nodeCount = 0;
    38             listener = new HttpListener();
    39         }
    40 
    41         public Boolean startHTTPListener()
    42         {
    43             try
    44             {
    45                 if (listener.IsListening)
    46                     return true;
    47 
    48                 string prefix = "http://+:" + listenerPort + "/";
    49                 listener.Prefixes.Clear();
    50                 listener.Prefixes.Add(prefix);
    51                 listener.Start();
    52 
    53                 if (listenerThread == null)
    54                 {
    55                     listenerThread = new Thread(HandleRequests);
    56                     listenerThread.Start();
    57                 }
    58             }
    59             catch (Exception e)
    60             {
    61                 return false;
    62             }
    63 
    64             return true;
    65         }
    66 
    67         public Boolean stopHTTPListener()
    68         {
    69             try
    70             {
    71                 listenerThread.Abort();
    72                 listener.Stop();
    73                 listenerThread = null;
    74             }
    75             catch (System.Net.HttpListenerException e)
    76             {
    77             }
    78             catch (System.Threading.ThreadAbortException e)
    79             {
    80             }
    81             catch (System.NullReferenceException e)
    82             {
    83             }
    84             catch (Exception e)
    85             {
    86             }
    87             return true;
    88         }
    89 
    90         public void HandleRequests()
    91         {
    92 
    93             while (listener.IsListening)
    94             {
    95                 var context = listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener);
    96                 context.AsyncWaitHandle.WaitOne();
    97             }
    98         }
    99 
   100         public void ListenerCallback(IAsyncResult result)
   101         {
   102             HttpListener listener = (HttpListener)result.AsyncState;
   103             if (listener == null || !listener.IsListening)
   104                 return;
   105             // Call EndGetContext to complete the asynchronous operation.
   106             HttpListenerContext context = listener.EndGetContext(result);
   107             HttpListenerRequest request = context.Request;
   108 
   109             var requestedFile = request.RawUrl.Substring(1);
   110             if (requestedFile == "data.json")
   111             {
   112                 sendJSON(context);
   113                 return;
   114             }
   115 
   116             if (requestedFile.Contains("images_icon"))
   117             {
   118                 serveResourceImage(context, requestedFile.Replace("images_icon/", ""));
   119                 return;
   120             }
   121 
   122             //default file to be served
   123             if (string.IsNullOrEmpty(requestedFile))
   124                 requestedFile = "index.html";
   125 
   126             string[] splits = requestedFile.Split('.');
   127             string ext = splits[splits.Length - 1];
   128             serveResourceFile(context, "Web." + requestedFile.Replace('/', '.'), ext);
   129         }
   130 
   131         private void serveResourceFile(HttpListenerContext context ,string name, string ext) {
   132 
   133           //hack! resource names do not support the hyphen
   134           name = "OpenHardwareMonitor.Resources." + name.Replace("custom-theme", "custom_theme");
   135     
   136           string[] names = 
   137             Assembly.GetExecutingAssembly().GetManifestResourceNames();
   138           for (int i = 0; i < names.Length; i++) {
   139             if (names[i].Replace('\\', '.') == name) {
   140               using (Stream stream = Assembly.GetExecutingAssembly().
   141                 GetManifestResourceStream(names[i])) {
   142                     context.Response.ContentType = getcontentType("." + ext);
   143                     context.Response.ContentLength64 = stream.Length;
   144                     byte[] buffer = new byte[512 * 1024];
   145                     int len;
   146                     while ((len = stream.Read(buffer, 0, buffer.Length)) > 0)
   147                     {
   148                         context.Response.OutputStream.Write(buffer, 0, len);
   149                     }
   150                     context.Response.OutputStream.Close();
   151                 }
   152               return;
   153             }
   154           }
   155           context.Response.OutputStream.Close();
   156           context.Response.StatusCode = 404;
   157           context.Response.Close();
   158         }
   159 
   160         private void serveResourceImage(HttpListenerContext context ,string name) {
   161           name = "OpenHardwareMonitor.Resources." + name;
   162     
   163           string[] names = 
   164             Assembly.GetExecutingAssembly().GetManifestResourceNames();
   165           for (int i = 0; i < names.Length; i++) {
   166             if (names[i].Replace('\\', '.') == name) {
   167               using (Stream stream = Assembly.GetExecutingAssembly().
   168                 GetManifestResourceStream(names[i])) {
   169     
   170                 Image image = Image.FromStream(stream);
   171                 context.Response.ContentType = "image/png";
   172                 using (MemoryStream ms = new MemoryStream())
   173                 {
   174                     image.Save(ms, ImageFormat.Png);
   175                     ms.WriteTo(context.Response.OutputStream);
   176                 }
   177                 context.Response.OutputStream.Close();
   178                 image.Dispose();
   179                 return;
   180               }
   181             }
   182           } 
   183           context.Response.OutputStream.Close();
   184           context.Response.StatusCode = 404;
   185           context.Response.Close();
   186         }
   187 
   188         private void sendJSON(HttpListenerContext context)
   189         {
   190 
   191             string JSON = "{\"id\": 0, \"Text\": \"Sensor\", \"Children\": [";
   192             nodeCount = 1;
   193             JSON += generateJSON(root);
   194             JSON += "]";
   195             JSON += ", \"Min\": \"Min\"";
   196             JSON += ", \"Value\": \"Value\"";
   197             JSON += ", \"Max\": \"Max\"";
   198             JSON += ", \"ImageURL\": \"\"";
   199             JSON += "}";
   200 
   201             var responseContent = JSON;
   202             byte[] buffer = Encoding.UTF8.GetBytes(responseContent);
   203 
   204             context.Response.ContentLength64 = buffer.Length;
   205             context.Response.ContentType = "application/json";
   206 
   207             Stream outputStream = context.Response.OutputStream;
   208             outputStream.Write(buffer, 0, buffer.Length);
   209             outputStream.Close();
   210 
   211         }
   212 
   213         private string generateJSON(Node n)
   214         {
   215             string JSON = "{\"id\": " + nodeCount + ", \"Text\": \"" + n.Text + "\", \"Children\": [";
   216             nodeCount++;
   217 
   218             foreach (Node child in n.Nodes)
   219                 JSON += generateJSON(child) + ", ";
   220             if (JSON.EndsWith(", "))
   221                 JSON = JSON.Remove(JSON.LastIndexOf(","));
   222             JSON += "]";
   223 
   224             if (n is SensorNode)
   225             {
   226                 JSON += ", \"Min\": \"" + ((SensorNode)n).Min + "\"";
   227                 JSON += ", \"Value\": \"" + ((SensorNode)n).Value + "\"";
   228                 JSON += ", \"Max\": \"" + ((SensorNode)n).Max + "\"";
   229                 JSON += ", \"ImageURL\": \"images/transparent.png\"";
   230             }
   231             else if (n is HardwareNode)
   232             {
   233                 JSON += ", \"Min\": \"\"";
   234                 JSON += ", \"Value\": \"\"";
   235                 JSON += ", \"Max\": \"\"";
   236                 JSON += ", \"ImageURL\": \"images_icon/" + getHardwareImageFile((HardwareNode)n) + "\"";
   237             }
   238             else if (n is TypeNode)
   239             {
   240                 JSON += ", \"Min\": \"\"";
   241                 JSON += ", \"Value\": \"\"";
   242                 JSON += ", \"Max\": \"\"";
   243                 JSON += ", \"ImageURL\": \"images_icon/" + getTypeImageFile((TypeNode)n) + "\"";
   244             }
   245             else
   246             {
   247                 JSON += ", \"Min\": \"\"";
   248                 JSON += ", \"Value\": \"\"";
   249                 JSON += ", \"Max\": \"\"";
   250                 JSON += ", \"ImageURL\": \"images_icon/computer.png\"";
   251             }
   252 
   253             JSON += "}";
   254             return JSON;
   255         }
   256 
   257         private static void returnFile(HttpListenerContext context, string filePath)
   258         {
   259             context.Response.ContentType = getcontentType(Path.GetExtension(filePath));
   260             const int bufferSize = 1024 * 512; //512KB
   261             var buffer = new byte[bufferSize];
   262             using (var fs = File.OpenRead(filePath))
   263             {
   264                 
   265                 context.Response.ContentLength64 = fs.Length;
   266                 int read;
   267                 while ((read = fs.Read(buffer, 0, buffer.Length)) > 0)
   268                     context.Response.OutputStream.Write(buffer, 0, read);
   269             }
   270 
   271             context.Response.OutputStream.Close();
   272         }
   273 
   274         private static string getcontentType(string extension)
   275         {
   276             switch (extension)
   277             {
   278                 case ".avi": return "video/x-msvideo";
   279                 case ".css": return "text/css";
   280                 case ".doc": return "application/msword";
   281                 case ".gif": return "image/gif";
   282                 case ".htm":
   283                 case ".html": return "text/html";
   284                 case ".jpg":
   285                 case ".jpeg": return "image/jpeg";
   286                 case ".js": return "application/x-javascript";
   287                 case ".mp3": return "audio/mpeg";
   288                 case ".png": return "image/png";
   289                 case ".pdf": return "application/pdf";
   290                 case ".ppt": return "application/vnd.ms-powerpoint";
   291                 case ".zip": return "application/zip";
   292                 case ".txt": return "text/plain";
   293                 default: return "application/octet-stream";
   294             }
   295         }
   296 
   297         private static string getHardwareImageFile(HardwareNode hn)
   298         {
   299 
   300             switch (hn.Hardware.HardwareType)
   301             {
   302                 case HardwareType.CPU:
   303                     return "cpu.png";
   304                 case HardwareType.GpuNvidia:
   305                     return "nvidia.png";
   306                 case HardwareType.GpuAti:
   307                     return "ati.png";
   308                 case HardwareType.HDD:
   309                     return "hdd.png";
   310                 case HardwareType.Heatmaster:
   311                     return "bigng.png";
   312                 case HardwareType.Mainboard:
   313                     return "mainboard.png";
   314                 case HardwareType.SuperIO:
   315                     return "chip.png";
   316                 case HardwareType.TBalancer:
   317                     return "bigng.png";
   318                 case HardwareType.RAM:
   319                     return "ram.png";
   320                 default:
   321                     return "cpu.png";
   322             }
   323 
   324         }
   325 
   326         private static string getTypeImageFile(TypeNode tn)
   327         {
   328 
   329             switch (tn.SensorType)
   330             {
   331                 case SensorType.Voltage:
   332                     return "voltage.png";
   333                 case SensorType.Clock:
   334                     return "clock.png";
   335                 case SensorType.Load:
   336                     return "load.png";
   337                 case SensorType.Temperature:
   338                     return "temperature.png";
   339                 case SensorType.Fan:
   340                     return "fan.png";
   341                 case SensorType.Flow:
   342                     return "flow.png";
   343                 case SensorType.Control:
   344                     return "control.png";
   345                 case SensorType.Level:
   346                     return "level.png";
   347                 case SensorType.Power:
   348                     return "power.png";
   349                 default:
   350                     return "power.png";
   351             }
   352 
   353         }
   354 
   355         public int ListenerPort
   356         {
   357             get { return listenerPort; }
   358             set { listenerPort = value; }
   359         }
   360 
   361         ~HttpServer()
   362         {
   363             stopHTTPListener();
   364             listener.Abort();
   365         }
   366 
   367         public void Quit()
   368         {
   369             stopHTTPListener();
   370             listener.Abort();
   371         }
   372     }
   373 }