PageRenderTime 90ms CodeModel.GetById 83ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/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//
 24using System;
 25using System.Collections;
 26using System.Collections.Concurrent;
 27using System.Collections.Generic;
 28using System.Runtime.InteropServices;
 29
 30using Manos.IO;
 31using Manos.Http;
 32using Manos.Caching;
 33using Manos.Logging;
 34
 35using Libev;
 36using Manos.Threading;
 37
 38namespace Manos
 39{
 40	/// <summary>
 41	/// The app runner. This is where the magic happens.
 42	/// </summary>
 43	public static class AppHost
 44	{
 45		private static ManosApp app;
 46		private static bool started;
 47		private static List<IPEndPoint> listenEndPoints = new List<IPEndPoint> ();
 48		private static Dictionary<IPEndPoint, Tuple<string, string>> secureListenEndPoints =
 49			new Dictionary<IPEndPoint, Tuple<string, string>> ();
 50		private static List<HttpServer> servers = new List<HttpServer> ();
 51		private static IManosCache cache;
 52		private static IManosLogger log;
 53		private static List<IManosPipe> pipes;
 54		private static Context context;
 55
 56		static AppHost ()
 57		{
 58			context = Context.Create ();
 59		}
 60
 61		public static ManosApp App {
 62			get { return app; }	
 63		}
 64
 65		public static IManosCache Cache {
 66			get {
 67				if (cache == null)
 68					cache = new ManosInProcCache ();
 69				return cache;
 70			}
 71		}
 72
 73		public static IManosLogger Log {
 74			get {
 75				if (log == null)
 76					log = new Manos.Logging.ManosConsoleLogger ("manos", LogLevel.Debug);
 77				return log;
 78			}
 79		}
 80
 81		public static Context Context {
 82			get { return context; }	
 83		}
 84
 85		public static IList<IManosPipe> Pipes {
 86			get { return pipes; }
 87		}
 88
 89		public static ICollection<IPEndPoint> ListenEndPoints {
 90			get {
 91				return listenEndPoints.AsReadOnly ();
 92			}
 93		}
 94
 95		public static void ListenAt (IPEndPoint endPoint)
 96		{
 97			if (endPoint == null)
 98				throw new ArgumentNullException ("endPoint");
 99			
100			if (listenEndPoints.Contains (endPoint) || secureListenEndPoints.ContainsKey (endPoint))
101				throw new InvalidOperationException ("Endpoint already registered");
102			
103			listenEndPoints.Add (endPoint);
104		}
105
106		public static void SecureListenAt (IPEndPoint endPoint, string cert, string key)
107		{
108			if (endPoint == null)
109				throw new ArgumentNullException ("endPoint");
110			if (cert == null)
111				throw new ArgumentNullException ("cert");
112			if (key == null)
113				throw new ArgumentNullException ("key");
114			
115			if (secureListenEndPoints.ContainsKey (endPoint) || listenEndPoints.Contains (endPoint))
116				throw new InvalidOperationException ("Endpoint already registered");
117			
118			secureListenEndPoints.Add (endPoint,
119				Tuple.Create (cert, key));
120		}
121
122		public static void InitializeTLS (string priorities)
123		{
124#if !DISABLETLS
125			manos_tls_global_init (priorities);
126			RegenerateDHParams (1024);
127#endif
128		}
129
130		public static void RegenerateDHParams (int bits)
131		{
132#if !DISABLETLS
133			manos_tls_regenerate_dhparams (bits);
134#endif
135		}
136
137#if !DISABLETLS
138		[DllImport ("libmanos", CallingConvention = CallingConvention.Cdecl)]
139		private static extern int manos_tls_global_init (string priorities);
140
141		[DllImport ("libmanos", CallingConvention = CallingConvention.Cdecl)]
142		private static extern int manos_tls_regenerate_dhparams (int bits);
143
144#endif
145
146		public static void Start (ManosApp application)
147		{
148			if (application == null)
149				throw new ArgumentNullException ("application");
150			
151			app = application;
152
153			app.StartInternal ();
154
155			started = true;
156			
157			foreach (var ep in listenEndPoints) {
158				var server = new HttpServer (Context, HandleTransaction, Context.CreateTcpServerSocket (ep.AddressFamily));
159				server.Listen (ep.Address.ToString (), ep.Port);
160				
161				servers.Add (server);
162			}
163			foreach (var ep in secureListenEndPoints.Keys) {
164//				var keypair = secureListenEndPoints [ep];
165//				var socket = Context.CreateSecureSocket (keypair.Item1, keypair.Item2);
166//				var server = new HttpServer (context, HandleTransaction, socket);
167//				server.Listen (ep.Address.ToString (), ep.Port);
168//				
169//				servers.Add (server);
170			}
171
172			context.Start ();
173		}
174
175		public static void Stop ()
176		{
177			context.Stop ();
178		}
179
180		public static void HandleTransaction (IHttpTransaction con)
181		{
182			app.HandleTransaction (app, con);
183		}
184
185		public static void AddPipe (IManosPipe pipe)
186		{
187			if (pipes == null)
188				pipes = new List<IManosPipe> ();
189			pipes.Add (pipe);
190		}
191
192		public static Timeout AddTimeout (TimeSpan timespan, IRepeatBehavior repeat, object data, TimeoutCallback callback)
193		{
194			return AddTimeout (timespan, timespan, repeat, data, callback);
195		}
196
197		public static Timeout AddTimeout (TimeSpan begin, TimeSpan timespan, IRepeatBehavior repeat, object data, TimeoutCallback callback)
198		{
199			Timeout t = new Timeout (begin, timespan, repeat, data, callback);
200			
201			ITimerWatcher timer = null;
202			timer = context.CreateTimerWatcher (begin, timespan, delegate {
203				t.Run (app);
204				if (!t.ShouldContinueToRepeat ()) {
205					t.Stop ();
206					timer.Dispose ();
207				}
208			});
209
210			timer.Start ();
211
212			return t;
213		}
214	}
215}
216