asternet/Asterisk.2013/Asterisk.NET/FastAGI/AGIConnectionHandler.cs

122 lines
3.5 KiB
C#
Raw Normal View History

using System;
using System.IO;
using System.Threading;
namespace Asterisk.NET.FastAGI
{
/// <summary>
/// An AGIConnectionHandler is created and run by the AGIServer whenever a new
/// socket connection from an Asterisk Server is received.<br/>
/// It reads the request using an AGIReader and runs the AGIScript configured to
/// handle this type of request. Finally it closes the socket connection.
/// </summary>
public class AGIConnectionHandler
{
#if LOGGER
private Logger logger = Logger.Instance();
#endif
private static readonly LocalDataStoreSlot channel = Thread.AllocateDataSlot();
private IO.SocketConnection socket;
2013-08-21 10:31:26 +00:00
private IMappingStrategy mappingStrategy;
private bool _SC511_CAUSES_EXCEPTION = false;
private bool _SCHANGUP_CAUSES_EXCEPTION = false;
#region Channel
/// <summary>
/// Returns the AGIChannel associated with the current thread.
/// </summary>
/// <returns>the AGIChannel associated with the current thread or <code>null</code> if none is associated.</returns>
internal static AGIChannel Channel
{
get
{
return (AGIChannel) Thread.GetData(AGIConnectionHandler.channel);
}
}
#endregion
#region AGIConnectionHandler(socket, mappingStrategy)
/// <summary>
/// Creates a new AGIConnectionHandler to handle the given socket connection.
/// </summary>
/// <param name="socket">the socket connection to handle.</param>
/// <param name="mappingStrategy">the strategy to use to determine which script to run.</param>
2013-08-21 10:31:26 +00:00
public AGIConnectionHandler(IO.SocketConnection socket, IMappingStrategy mappingStrategy, bool SC511_CAUSES_EXCEPTION, bool SCHANGUP_CAUSES_EXCEPTION)
{
this.socket = socket;
this.mappingStrategy = mappingStrategy;
2013-08-21 10:31:26 +00:00
this._SC511_CAUSES_EXCEPTION = SC511_CAUSES_EXCEPTION;
this._SCHANGUP_CAUSES_EXCEPTION = SCHANGUP_CAUSES_EXCEPTION;
}
#endregion
public void Run()
{
try
{
AGIReader reader = new AGIReader(socket);
AGIWriter writer = new AGIWriter(socket);
AGIRequest request = reader.ReadRequest();
2013-08-21 10:31:26 +00:00
AGIChannel channel = new AGIChannel(writer, reader, this._SC511_CAUSES_EXCEPTION, this._SCHANGUP_CAUSES_EXCEPTION);
AGIScript script = mappingStrategy.DetermineScript(request);
Thread.SetData(AGIConnectionHandler.channel, channel);
if (script != null)
{
#if LOGGER
logger.Info("Begin AGIScript " + script.GetType().FullName + " on " + Thread.CurrentThread.Name);
#endif
script.Service(request, channel);
#if LOGGER
logger.Info("End AGIScript " + script.GetType().FullName + " on " + Thread.CurrentThread.Name);
#endif
}
else
{
string error;
error = "No script configured for URL '" + request.RequestURL + "' (script '" + request.Script + "')";
channel.SendCommand(new Command.VerboseCommand(error, 1));
#if LOGGER
logger.Error(error);
#endif
}
}
catch (AGIHangupException)
{
}
catch (IOException)
{
}
catch (AGIException ex)
{
#if LOGGER
logger.Error("AGIException while handling request", ex);
#else
throw ex;
#endif
}
catch (Exception ex)
{
#if LOGGER
logger.Error("Unexpected Exception while handling request", ex);
#else
throw ex;
#endif
}
Thread.SetData(AGIConnectionHandler.channel, null);
try
{
socket.Close();
}
#if LOGGER
catch(IOException ex)
{
logger.Error("Error on close socket", ex);
}
#else
catch { }
#endif
}
}
}