MTSC  1.0.5
Build TCP servers out of modules with handlers for communication, exception and logging.
FileServerModule.cs
1 using System;
2 using System.Collections.Concurrent;
3 using System.Collections.Generic;
4 using System.IO;
5 using System.Text;
6 using MTSC.Server;
7 using MTSC.Server.Handlers;
8 
10 {
12  {
13  private string rootFolder;
14  ConcurrentDictionary<string, Tuple<byte[], DateTime>> fileCache = new ConcurrentDictionary<string, Tuple<byte[], DateTime>>();
15  List<string> toRemoveCache = new List<string>();
16  public FileServerModule(string rootFolder = "src")
17  {
18  this.rootFolder = Path.GetFullPath(rootFolder);
19  }
20  #region Interface Implementation
21  bool IHttpModule.HandleRequest(Server.Server server, HttpHandler handler, ClientData client, HttpMessage request, ref HttpMessage response)
22  {
23  if(request.Method == HttpMessage.MethodEnum.Get)
24  {
25  if(request.RequestURI == @"/")
26  {
27  request.RequestURI = @"/index.html";
28  }
29  string requestFile = this.rootFolder + request.RequestURI;
30  if(requestFile.IsSubPathOf(this.rootFolder) && File.Exists(requestFile))
31  {
32  /*
33  * If file is in cache, retrieve it from cache.
34  */
35  byte[] bodyData;
36  if (fileCache.ContainsKey(requestFile))
37  {
38  bodyData = fileCache[requestFile].Item1;
39  }
40  else
41  {
42  bodyData = File.ReadAllBytes(requestFile);
43  }
44  /*
45  * Insert or update cache with the requested file.
46  */
47  Tuple<byte[], DateTime> tuple = new Tuple<byte[], DateTime>(bodyData, DateTime.Now);
48  fileCache.AddOrUpdate(requestFile, tuple, (key, oldValue) => oldValue = tuple);
49  /*
50  * Build the response packet.
51  */
52  response.Body = bodyData;
53  response.StatusCode = HttpMessage.StatusCodes.OK;
54  response[HttpMessage.EntityHeadersEnum.ContentType] = "text/html";
55  if (!fileCache.ContainsKey(requestFile))
56  {
57  server.LogDebug("Adding " + requestFile + " to server cache.");
58  }
59  return true;
60  }
61  else
62  {
63  server.LogDebug("File not found: " + requestFile);
64  response.StatusCode = HttpMessage.StatusCodes.NotFound;
65  }
66  }
67  return false;
68  }
69 
70  void IHttpModule.Tick(Server.Server server, HttpHandler handler)
71  {
72  foreach(KeyValuePair<string, Tuple<byte[], DateTime>> keyValuePair in fileCache)
73  {
74  if((DateTime.Now - keyValuePair.Value.Item2).TotalSeconds > 60)
75  {
76  toRemoveCache.Add(keyValuePair.Key);
77  }
78  }
79  foreach(string fileName in toRemoveCache)
80  {
81  Tuple<byte[], DateTime> tp;
82  while(!fileCache.TryRemove(fileName, out tp)) { };
83  server.LogDebug("Removed " + fileName + " from cache.");
84  }
85  toRemoveCache.Clear();
86  }
87 
88  #endregion
89  }
90 }
void Tick(Server.Server server, HttpHandler handler)
Perform periodic operations.
Structure containing client information.
Definition: Server.cs:402
Handler for handling server http requests.
Definition: HttpHandler.cs:15
Server()
Creates an instance of server with default values.
Definition: Server.cs:68
Basic server class to handle TCP connections.
Definition: Server.cs:20
bool HandleRequest(Server.Server server, HttpHandler handler, ClientData client, HttpMessage request, ref HttpMessage response)
Handle the received request.
Definition: Client.cs:14
Interface for Http modules used by the server http handler.
Definition: IHttpModule.cs:13