public virtual string Start() { string ret = null; LOG.Debug("Starting HTTP server listening on port {0}...", Port); try { Listener.Start(); int timeoutSeconds = 3; bool isListening = CheckIsListening(timeoutSeconds); if (!isListening) { LOG.Error("Failed to start HTTP server listening on port {0}.", Port); return("Failed to start HTTP server"); } LOG.Debug("Calling Listener.BeginGetContext from main thread..."); RequestProcessorParameter arguments = new RequestProcessorParameter(this.Listener, this.RequestHandler); Listener.BeginGetContext(ProcessHttpRequest, arguments); LOG.Debug("Continuing main thread after Listener.BeginGetContext..."); LOG.Debug("HTTP server listening on port {0} has started.", Port); return("OK"); } catch (Exception e) { LOG.Error(e, "Failed to start HTTP server listening on port {0}.", Port); return("Failed to start HTTP server: " + e.Message); } }
void ProcessHttpRequest(IAsyncResult result) { RequestProcessorParameter arguments = (RequestProcessorParameter)result.AsyncState; HttpListener listener = arguments.Listener; IHttpRequestHandler requestHandler = arguments.RequestHandler; LOG.Debug("Handling HTTP request..."); if (listener == null) { LOG.Error("Unable to handle HTTP request: No listener supplied."); return; } if (requestHandler == null) { LOG.Error("Unable to handle HTTP request: No request handler supplied."); // No point in calling listener.BeginGetContext since there is no request handler // to pass in as argument. return; } if (requestHandler.MethodHandlers == null || requestHandler.MethodHandlers.Count == 0) { LOG.Error("Unable to handle HTTP request: No HTTP method handlers supplied."); // No point in calling listener.BeginGetContext since there is no method handler // to pass in as argument. return; } HttpListenerContext context = null; try { context = listener.EndGetContext(result); LOG.Debug("Listener.EndGetContext complete."); } catch (Exception ex) { LOG.Debug("{0}: {1}", ex.GetType().Name, ex.Message); // If the main thread has closed the listener then Listener.EndGetContext throws // an ObjectDisposedException or an HttpListenerException. There is no neat way // around this, such as checking IsDisposed or IsDisposing, since HttpListener // doesn't have any properties like that. So the only way to deal with it is to // catch the exception and do nothing with it, allowing execution to continue. if (ex is ObjectDisposedException || ex is HttpListenerException) { LOG.Debug("Exiting ProcessHttpRequest method."); return; } } LOG.Debug("Calling HttpRequestHandler to process request..."); requestHandler.ProcessHttpRequest(context); LOG.Debug("Completed handling HTTP of request."); LOG.Debug("Calling listener.BeginGetContext from within request handler..."); listener.BeginGetContext(ProcessHttpRequest, arguments); LOG.Debug("Request handler finished."); }