private void ProcessSocket(Socket socket, HttpSocketContext ctx, IPrincipal principal)
{
ctx.Reset();
try
{
while (ctx.Parse(socket))
{
RouteMatch match;
var route = Routes.Find(ctx.HttpMethod, ctx.RawUrl, ctx.AbsolutePath, out match);
if (route == null)
{
var unknownRoute = "Unknown route " + ctx.RawUrl + " on method " + ctx.HttpMethod;
ctx.ReturnError(socket, 404, unknownRoute, false);
break;
}
var auth = Authentication.TryAuthorize(ctx.GetRequestHeader("authorization"), ctx.RawUrl, route);
if (auth.Principal != null)
{
ctx.ForRouteWithAuth(match, auth.Principal);
ThreadContext.Request = ctx;
ThreadContext.Response = ctx;
if (principal != auth.Principal)
Thread.CurrentPrincipal = principal = auth.Principal;
using (var stream = route.Handle(match.OrderedArgs, ctx.Stream))
{
var keepAlive = ctx.Return(stream, socket);
if (keepAlive)
{
if (ctx.Pipeline) continue;
else if (socket.Connected)
{
if (Requests.TryAdd(new RequestInfo(socket, socket.Available > 0)))
return;
}
}
socket.Close();
return;
}
}
else if (auth.SendAuthenticate)
{
ctx.AddHeader("WWW-Authenticate", MissingBasicAuth);
ctx.ReturnError(socket, (int)auth.ResponseCode, auth.Error, true);
return;
}
else
{
ctx.ReturnError(socket, (int)auth.ResponseCode, auth.Error, true);
return;
}
}
}
catch (SecurityException sex)
{
try { ctx.ReturnError(socket, (int)HttpStatusCode.Forbidden, sex.Message, true); }
catch (Exception ex)
{
Console.WriteLine(ex.Message);
TraceSource.TraceEvent(TraceEventType.Error, 5404, "{0}", ex);
}
}
catch (ActionNotSupportedException anse)
{
try { ctx.ReturnError(socket, 404, anse.Message, true); }
catch (Exception ex)
{
Console.WriteLine(ex.Message);
TraceSource.TraceEvent(TraceEventType.Error, 5404, "{0}", ex);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
TraceSource.TraceEvent(TraceEventType.Error, 5403, "{0}", ex);
try { ctx.ReturnError(socket, 500, ex.Message, false); }
catch (Exception ex2)
{
Console.WriteLine(ex2.Message);
TraceSource.TraceEvent(TraceEventType.Error, 5404, "{0}", ex2);
}
}
}