/src/Manos/Manos/AppHost.cs

http://github.com/jacksonh/manos · C# · 216 lines · 147 code · 37 blank · 32 comment · 21 complexity · 28c8e28d29f2153dceb058cdf775ca0a MD5 · raw file

  1. //
  2. // Copyright (C) 2010 Jackson Harper (jackson@manosdemono.com)
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining
  5. // a copy of this software and associated documentation files (the
  6. // "Software"), to deal in the Software without restriction, including
  7. // without limitation the rights to use, copy, modify, merge, publish,
  8. // distribute, sublicense, and/or sell copies of the Software, and to
  9. // permit persons to whom the Software is furnished to do so, subject to
  10. // the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be
  13. // included in all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  19. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  20. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  21. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. //
  23. //
  24. using System;
  25. using System.Collections;
  26. using System.Collections.Concurrent;
  27. using System.Collections.Generic;
  28. using System.Runtime.InteropServices;
  29. using Manos.IO;
  30. using Manos.Http;
  31. using Manos.Caching;
  32. using Manos.Logging;
  33. using Libev;
  34. using Manos.Threading;
  35. namespace Manos
  36. {
  37. /// <summary>
  38. /// The app runner. This is where the magic happens.
  39. /// </summary>
  40. public static class AppHost
  41. {
  42. private static ManosApp app;
  43. private static bool started;
  44. private static List<IPEndPoint> listenEndPoints = new List<IPEndPoint> ();
  45. private static Dictionary<IPEndPoint, Tuple<string, string>> secureListenEndPoints =
  46. new Dictionary<IPEndPoint, Tuple<string, string>> ();
  47. private static List<HttpServer> servers = new List<HttpServer> ();
  48. private static IManosCache cache;
  49. private static IManosLogger log;
  50. private static List<IManosPipe> pipes;
  51. private static Context context;
  52. static AppHost ()
  53. {
  54. context = Context.Create ();
  55. }
  56. public static ManosApp App {
  57. get { return app; }
  58. }
  59. public static IManosCache Cache {
  60. get {
  61. if (cache == null)
  62. cache = new ManosInProcCache ();
  63. return cache;
  64. }
  65. }
  66. public static IManosLogger Log {
  67. get {
  68. if (log == null)
  69. log = new Manos.Logging.ManosConsoleLogger ("manos", LogLevel.Debug);
  70. return log;
  71. }
  72. }
  73. public static Context Context {
  74. get { return context; }
  75. }
  76. public static IList<IManosPipe> Pipes {
  77. get { return pipes; }
  78. }
  79. public static ICollection<IPEndPoint> ListenEndPoints {
  80. get {
  81. return listenEndPoints.AsReadOnly ();
  82. }
  83. }
  84. public static void ListenAt (IPEndPoint endPoint)
  85. {
  86. if (endPoint == null)
  87. throw new ArgumentNullException ("endPoint");
  88. if (listenEndPoints.Contains (endPoint) || secureListenEndPoints.ContainsKey (endPoint))
  89. throw new InvalidOperationException ("Endpoint already registered");
  90. listenEndPoints.Add (endPoint);
  91. }
  92. public static void SecureListenAt (IPEndPoint endPoint, string cert, string key)
  93. {
  94. if (endPoint == null)
  95. throw new ArgumentNullException ("endPoint");
  96. if (cert == null)
  97. throw new ArgumentNullException ("cert");
  98. if (key == null)
  99. throw new ArgumentNullException ("key");
  100. if (secureListenEndPoints.ContainsKey (endPoint) || listenEndPoints.Contains (endPoint))
  101. throw new InvalidOperationException ("Endpoint already registered");
  102. secureListenEndPoints.Add (endPoint,
  103. Tuple.Create (cert, key));
  104. }
  105. public static void InitializeTLS (string priorities)
  106. {
  107. #if !DISABLETLS
  108. manos_tls_global_init (priorities);
  109. RegenerateDHParams (1024);
  110. #endif
  111. }
  112. public static void RegenerateDHParams (int bits)
  113. {
  114. #if !DISABLETLS
  115. manos_tls_regenerate_dhparams (bits);
  116. #endif
  117. }
  118. #if !DISABLETLS
  119. [DllImport ("libmanos", CallingConvention = CallingConvention.Cdecl)]
  120. private static extern int manos_tls_global_init (string priorities);
  121. [DllImport ("libmanos", CallingConvention = CallingConvention.Cdecl)]
  122. private static extern int manos_tls_regenerate_dhparams (int bits);
  123. #endif
  124. public static void Start (ManosApp application)
  125. {
  126. if (application == null)
  127. throw new ArgumentNullException ("application");
  128. app = application;
  129. app.StartInternal ();
  130. started = true;
  131. foreach (var ep in listenEndPoints) {
  132. var server = new HttpServer (Context, HandleTransaction, Context.CreateTcpServerSocket (ep.AddressFamily));
  133. server.Listen (ep.Address.ToString (), ep.Port);
  134. servers.Add (server);
  135. }
  136. foreach (var ep in secureListenEndPoints.Keys) {
  137. // var keypair = secureListenEndPoints [ep];
  138. // var socket = Context.CreateSecureSocket (keypair.Item1, keypair.Item2);
  139. // var server = new HttpServer (context, HandleTransaction, socket);
  140. // server.Listen (ep.Address.ToString (), ep.Port);
  141. //
  142. // servers.Add (server);
  143. }
  144. context.Start ();
  145. }
  146. public static void Stop ()
  147. {
  148. context.Stop ();
  149. }
  150. public static void HandleTransaction (IHttpTransaction con)
  151. {
  152. app.HandleTransaction (app, con);
  153. }
  154. public static void AddPipe (IManosPipe pipe)
  155. {
  156. if (pipes == null)
  157. pipes = new List<IManosPipe> ();
  158. pipes.Add (pipe);
  159. }
  160. public static Timeout AddTimeout (TimeSpan timespan, IRepeatBehavior repeat, object data, TimeoutCallback callback)
  161. {
  162. return AddTimeout (timespan, timespan, repeat, data, callback);
  163. }
  164. public static Timeout AddTimeout (TimeSpan begin, TimeSpan timespan, IRepeatBehavior repeat, object data, TimeoutCallback callback)
  165. {
  166. Timeout t = new Timeout (begin, timespan, repeat, data, callback);
  167. ITimerWatcher timer = null;
  168. timer = context.CreateTimerWatcher (begin, timespan, delegate {
  169. t.Run (app);
  170. if (!t.ShouldContinueToRepeat ()) {
  171. t.Stop ();
  172. timer.Dispose ();
  173. }
  174. });
  175. timer.Start ();
  176. return t;
  177. }
  178. }
  179. }