public virtual void HandleRequest (HttpListenerContext context)
{
HttpListenerRequest request = context.Request;
using (HttpListenerResponse response = context.Response) {
OSHttpRequest req = new OSHttpRequest (context);
OSHttpResponse resp = new OSHttpResponse (context);
if (request.HttpMethod == string.Empty) // Can't handle empty requests, not wasting a thread
{
byte [] buffer = GetHTML500 (response);
response.ContentLength64 = buffer.LongLength;
response.Close (buffer, true);
return;
}
response.KeepAlive = false;
response.AddHeader ("X-Powered-By", "Universe Services");
string requestMethod = request.HttpMethod;
string uriString = request.RawUrl;
int requestStartTick = Environment.TickCount;
// Will be adjusted later on.
int requestEndTick = requestStartTick;
IStreamedRequestHandler requestHandler = null;
try {
System.Threading.Thread.CurrentThread.CurrentCulture =
new System.Globalization.CultureInfo ("en-US", true);
string path = request.RawUrl;
string handlerKey = GetHandlerKey (request.HttpMethod, path);
byte [] buffer = null;
if ((request.ContentType == "application/xml" || request.ContentType == "text/xml") && GetXmlRPCHandler (request.RawUrl) != null) {
buffer = HandleXmlRpcRequests (req, resp);
} else if (TryGetStreamHandler (handlerKey, out requestHandler)) {
response.ContentType = requestHandler.ContentType;
// Lets do this defaulting before in case handler has varying content type.
buffer = requestHandler.Handle (path, request.InputStream, req, resp);
}
request.InputStream.Close ();
try {
if (buffer != null) {
if (request.ProtocolVersion.Minor == 0) {
//HTTP 1.0... no chunking
response.ContentLength64 = buffer.Length;
using (Stream stream = response.OutputStream) {
HttpServerHandlerHelpers.WriteNonChunked (stream, buffer);
}
} else {
response.SendChunked = true;
using (Stream stream = response.OutputStream) {
HttpServerHandlerHelpers.WriteChunked (stream, buffer);
}
}
response.Close ();
} else
response.Close (new byte [0], true);
} catch (Exception ex) {
if (!(ex is HttpListenerException) ||
!HttpListenerManager.IGNORE_ERROR_CODES.Contains (((HttpListenerException)ex).ErrorCode)) {
MainConsole.Instance.WarnFormat ("[Base HTTP server]: HandleRequest failed to write all data to the stream: {0}", ex.ToString ());
}
response.Abort ();
}
requestEndTick = Environment.TickCount;
} catch (Exception e) {
MainConsole.Instance.ErrorFormat ("[Base HTTP server]: HandleRequest() threw {0} ", e.ToString ());
response.Abort ();
} finally {
// Every month or so this will wrap and give bad numbers, not really a problem
// since its just for reporting
int tickdiff = requestEndTick - requestStartTick;
if (tickdiff > 3000 && requestHandler != null) {
MainConsole.Instance.DebugFormat (
"[Base HTTP server]: Slow handling of {0} {1} took {2}ms",
requestMethod,
uriString,
tickdiff);
} else if (MainConsole.Instance.IsTraceEnabled) {
MainConsole.Instance.TraceFormat (
"[Base HTTP server]: Handling {0} {1} took {2}ms",
requestMethod,
uriString,
tickdiff);
}
}
}
}