private void RequestHandler(IAsyncResult ar) { HttpListenerContext httpContext = null; Action <string> activity = null; HttpListener listener = (HttpListener)ar.AsyncState; // try to finish getting the current context try { httpContext = listener.EndGetContext(ar); } catch (Exception e) { _log.WarnExceptionFormat(e, "unable to finish acquiring the request context, unable to handle request"); } // start listening for next request if (!listener.IsListening) { _log.Debug("dropping out of request handler, since the listener is no longer listening"); return; } try { listener.BeginGetContext(RequestHandler, listener); } catch (Exception e) { _log.WarnExceptionFormat(e, "unable to re-aquire context, dropping out of request handler"); return; } // if we didn't succeed in ending the GetContext call, drop out if (httpContext == null) { return; } DreamMessage request = null; try { // finish listening for current context string[] prefixes = new string[listener.Prefixes.Count]; listener.Prefixes.CopyTo(prefixes, 0); XUri requestUri = HttpUtil.FromHttpContext(httpContext); _log.DebugMethodCall("RequestHandler", httpContext.Request.HttpMethod, requestUri); // create request message request = new DreamMessage(DreamStatus.Ok, new DreamHeaders(httpContext.Request.Headers), MimeType.New(httpContext.Request.ContentType), httpContext.Request.ContentLength64, httpContext.Request.InputStream); DreamUtil.PrepareIncomingMessage(request, httpContext.Request.ContentEncoding, prefixes[0], httpContext.Request.RemoteEndPoint.ToString(), httpContext.Request.UserAgent); requestUri = requestUri.AuthorizeDreamInParams(request, _dreamInParamAuthtoken); // check if the request was forwarded through Apache mod_proxy string hostname = requestUri.GetParam(DreamInParam.HOST, null) ?? request.Headers.ForwardedHost ?? request.Headers.Host ?? requestUri.HostPort; activity = new ActivityState(_env, httpContext.Request.HttpMethod, httpContext.Request.Url.ToString(), hostname).Message; activity("RequestHandler"); // process message _env.UpdateInfoMessage(_sourceExternal, null); string verb = httpContext.Request.HttpMethod; _env.SubmitRequestAsync(verb, requestUri, httpContext.User, request, new Result <DreamMessage>(TimeSpan.MaxValue)) .WhenDone(result => Coroutine.Invoke(ResponseHandler, request, result, httpContext, activity, new Result(TimeSpan.MaxValue))); } catch (Exception ex) { _log.ErrorExceptionMethodCall(ex, "RequestHandler"); if (request != null) { request.Close(); } try { DreamMessage response = DreamMessage.InternalError(ex); httpContext.Response.StatusCode = (int)response.Status; Stream stream = response.ToStream(); httpContext.Response.Headers.Clear(); foreach (KeyValuePair <string, string> pair in response.Headers) { HttpUtil.AddHeader(httpContext.Response, pair.Key, pair.Value); } httpContext.Response.KeepAlive = false; long size = response.ContentLength; if (((size == -1) || (size > 0)) && (stream != Stream.Null)) { CopyStream(delegate { }, stream, httpContext.Response.OutputStream, size, new Result <long>(DreamHostService.MAX_REQUEST_TIME)).Block(); } httpContext.Response.OutputStream.Flush(); } catch { httpContext.Response.StatusCode = (int)DreamStatus.InternalError; } httpContext.Response.Close(); if (activity != null) { activity(null); } } }
/// <summary> /// Update the host's info message. /// </summary> /// <param name="source">Message source.</param> /// <param name="message">Info message.</param> public void UpdateInfoMessage(string source, string message) { _env.UpdateInfoMessage(source, message); }