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