Beispiel #1
0
        public void HandleRequest_Should_Throw_ArgumentNullException_When_Given_A_Null_Request()
        {
            var exception = Record.Exception(() => engine.HandleRequest(null));

            // Then
            exception.ShouldBeOfType <ArgumentNullException>();
        }
Beispiel #2
0
        public async Task InvokeAsync(HttpContext context)
        {
            var request = CreateNancyRequest(context);

            try
            {
                if (_logger.IsEnabled(LogLevel.Information))
                {
                    _logger.LogInformation($"Nancy: received request {request.Method}: {request.Url}");
                }

                using var nancyContext = await _engine.HandleRequest(request).ConfigureAwait(false);

                if (_logger.IsEnabled(LogLevel.Information) && nancyContext.Response.StatusCode == HttpStatusCode.OK)
                {
                    _logger.LogInformation($"Nancy response: OK, content-type: {nancyContext.Response.ContentType}");
                }
                else if (_logger.IsEnabled(LogLevel.Error))
                {
                    _logger.LogError($"Nancy response: {nancyContext.Response.StatusCode}, content-type: {nancyContext.Response.ContentType}, error: {nancyContext.Response.ReasonPhrase}");
                }

                SetNancyResponseToHttpResponse(context, nancyContext.Response);
                if (_options.PerformPassThrough(nancyContext))
                {
                    await _next(context);
                }
            }
            finally
            {
                _urlPool.Enqueue(request.Url);
            }
        }
Beispiel #3
0
        public C1NancyResponse ProcessRequest(HttpContextBase context, string path, ParameterList parameters)
        {
            var request = CreateNancyRequest(context, path);

            C1NancyResponse c1NancyResponse = null;
            Exception       exception       = null;

            Engine.HandleRequest(request,
                                 ctx => PreRequest(ctx, parameters),
                                 ctx =>
            {
                c1NancyResponse = ResponseComplete(ctx);
            },
                                 exc =>
            {
                exception = exc;
            },
                                 new CancellationToken());

            if (exception != null)
            {
                throw exception;
            }

            return(c1NancyResponse);
        }
        private void RequestHandler(EventHttpRequest req)
        {
            ThreadPool.QueueUserWorkItem(_ =>
            {
                PreProcessRequest(req);
                var pairs = req.Uri.Split(new[] { '?' }, 2);
                var path  = Uri.UnescapeDataString(pairs[0]);
                var query = pairs.Length == 2 ? pairs[1] : string.Empty;
                var nreq  = CreateRequest(req.Method, path, req.Headers,
                                          RequestStream.FromStream(new MemoryStream(req.RequestBody)), "http", query, req.UserHostAddress);
                _engine.HandleRequest(
                    nreq,
                    ctx =>
                {
                    PostProcessNancyResponse(nreq, ctx.Response);

                    var ms = new MemoryStream();
                    ctx.Response.Contents(ms);
                    req.Respond((System.Net.HttpStatusCode)ctx.Response.StatusCode, ctx.Response.Headers, ms.ToArray());
                },
                    exception =>
                {
                    req.Respond(System.Net.HttpStatusCode.InternalServerError, new Dictionary <string, string>(), new byte[0]);
                    if (Error != null)
                    {
                        Error(this, new ErrorEventArgs(exception));
                    }
                    else
                    {
                        Console.WriteLine(exception);
                    }
                });
            });
        }
Beispiel #5
0
        private void Process(HttpListenerContext ctx)
        {
            var nancyRequest = ConvertRequestToNancyRequest(ctx.Request);

            using (var nancyContext = engine.HandleRequest(nancyRequest))
            {
                ConvertNancyResponseToResponse(nancyContext.Response, ctx.Response);
            }
        }
Beispiel #6
0
        public void Call(
            IDictionary <string, object> env,
            Action <Exception> fault,
            ResultDelegate result)
        {
            var nancyRequest = CreateNancyRequestFromEnvironment(env);
            var nancyContext = _engine.HandleRequest(nancyRequest);

            SendNancyResponseToResult(nancyContext.Response, result);
        }
Beispiel #7
0
        /// <summary>
        /// Handles an incoming <see cref="Request"/>.
        /// </summary>
        /// <param name="nancyEngine">The <see cref="INancyEngine"/> instance.</param>
        /// <param name="request">An <see cref="Request"/> instance, containing the information about the current request.</param>
        /// <param name="preRequest">Delegate to call before the request is processed</param>
        /// <returns>A <see cref="NancyContext"/> instance containing the request/response context.</returns>
        public static NancyContext HandleRequest(this INancyEngine nancyEngine, Request request, Func <NancyContext, NancyContext> preRequest)
        {
            var task = nancyEngine.HandleRequest(request, preRequest, CancellationToken.None);

            task.Wait();
            if (task.IsFaulted)
            {
                throw task.Exception ?? new Exception("Request task faulted");
            }
            return(task.Result);
        }
        public Message HandleRequests(Stream requestBody)
        {
            var webContext = WebOperationContext.Current;

            var nancyRequest = CreateNancyRequestFromIncomingWebRequest(webContext.IncomingRequest, requestBody);
            var nancyContext = engine.HandleRequest(nancyRequest);

            SetNancyResponseToOutgoingWebResponse(webContext.OutgoingResponse, nancyContext.Response);

            return(webContext.CreateStreamResponse(nancyContext.Response.Contents, nancyContext.Response.ContentType));
        }
Beispiel #9
0
        public async Task HandleRequest_Should_Throw_ArgumentNullException_When_Given_A_Null_Request()
        {
            // Given,
            Request request = null;

            // When
            var exception = await RecordAsync.Exception(async() => await engine.HandleRequest(request));

            // Then
            exception.ShouldBeOfType <ArgumentNullException>();
        }
Beispiel #10
0
        private void RequestHandler(EventHttpRequest req)
        {
            if (req.Uri == null)
            {
                req.Respond(System.Net.HttpStatusCode.BadRequest, new Dictionary <string, string>(), new byte[0]);
                return;
            }
            ThreadPool.QueueUserWorkItem(_ =>
            {
                Request nreq;
                try
                {
                    PreProcessRequest(req);
                    var pairs = req.Uri.Split(new[] { '?' }, 2);
                    var path  = Uri.UnescapeDataString(pairs[0]);
                    var query = pairs.Length == 2 ? pairs[1] : string.Empty;

                    nreq = CreateRequest(req.Method, req.Host, path, req.Headers,
                                         RequestStream.FromStream(new MemoryStream(req.RequestBody)), "http", query, req.UserHostAddress);
                }
                catch (Exception e)
                {
                    DoRespond(req, GetExceptionResponse(e));
                    return;
                }
                try
                {
                    _engine.HandleRequest(
                        nreq,
                        ctx =>
                    {
                        ResponseData resp;
                        try
                        {
                            var ms = new MemoryStream();
                            PostProcessNancyResponse(nreq, ctx.Response);
                            ctx.Response.Contents(ms);
                            resp = new ResponseData(ctx.Response.StatusCode, ms.ToArray(), ctx.Response.Headers);
                        }
                        catch (Exception e)
                        {
                            resp = GetExceptionResponse(e);
                        }
                        DoRespond(req, resp);
                    },
                        exception => DoRespond(req, GetExceptionResponse(exception)));
                }
                catch (Exception e)
                {
                    DoRespond(req, GetExceptionResponse(e));
                }
            });
        }
Beispiel #11
0
 private void Process(HttpListenerContext ctx)
 {
     try
     {
         _engine.HandleRequest(ConvertRequestToNancyRequest(ctx.Request), c =>
         {
             c.Items["RequestPrincipal"] = ctx.User;
             return(c);
         }, c => ConvertNancyResponseToResponse(c, c.Response, ctx.Response), e => _configuration.UnhandledExceptionCallback(e), CancellationToken.None);
     }
     catch (Exception ex)
     {
         _configuration.UnhandledExceptionCallback(ex);
     }
 }
        /// <summary>
        /// Handles an incoming <see cref="Request"/>.
        /// </summary>
        /// <param name="nancyEngine">The <see cref="INancyEngine"/> instance.</param>
        /// <param name="request">An <see cref="Request"/> instance, containing the information about the current request.</param>
        /// <param name="preRequest">Delegate to call before the request is processed</param>
        /// <returns>A <see cref="NancyContext"/> instance containing the request/response context.</returns>
        public static NancyContext HandleRequest(this INancyEngine nancyEngine, Request request, Func <NancyContext, NancyContext> preRequest)
        {
            var task = nancyEngine.HandleRequest(request, preRequest, CancellationToken.None);

            try
            {
                task.Wait();
            }
            catch (Exception ex)
            {
                throw ex.FlattenInnerExceptions();
            }

            return(task.Result);
        }
        protected static void ProcessRequest()
        {
            if (!Req.Cookies.ContainsKey("NerdGuid"))
            {
                Req.Cookies.Add("NerdGuid", "xxx");
            }
            ctx = Engine.HandleRequest(Req);
            var ms = new MemoryStream();

            ctx.Response.Contents(ms);
            ms.Position = 0;
            var buf = new byte[ms.Length];
            var l   = ms.Read(buf, 0, (int)ms.Length);

            RenderedContent = System.Text.ASCIIEncoding.ASCII.GetString(buf);
        }
        /// <summary>
        /// Handles an incoming <see cref="Request"/> async.
        /// </summary>
        /// <param name="nancyEngine">The <see cref="INancyEngine"/> instance.</param>
        /// <param name="request">An <see cref="Request"/> instance, containing the information about the current request.</param>
        /// <param name="preRequest">Delegate to call before the request is processed</param>
        /// <param name="onComplete">Delegate to call when the request is complete</param>
        /// <param name="onError">Delegate to call when any errors occur</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        public static void HandleRequest(
            this INancyEngine nancyEngine,
            Request request,
            Func <NancyContext, NancyContext> preRequest,
            Action <NancyContext> onComplete,
            Action <Exception> onError,
            CancellationToken cancellationToken)
        {
            if (nancyEngine == null)
            {
                throw new ArgumentNullException("nancyEngine");
            }

            nancyEngine
            .HandleRequest(request, preRequest, cancellationToken)
            .WhenCompleted(t => onComplete(t.Result), t => onError(t.Exception));
        }
        public async Task Invoke(HttpContext environment)
        {
            var aspnetCoreRequestMethod      = environment.Request.Method;
            var aspnetCoreRequestScheme      = environment.Request.Scheme;
            var aspnetCoreRequestHeaders     = environment.Request.Headers;
            var aspnetCoreRequestPathBase    = environment.Request.PathBase;
            var aspnetCoreRequestPath        = environment.Request.Path;
            var aspnetCoreRequestQueryString = environment.Request.QueryString.Value ?? string.Empty;
            var aspnetCoreRequestBody        = environment.Request.Body;
            var aspnetCoreRequestProtocol    = environment.Request.Protocol;
            var aspnetCoreCallCancelled      = environment.RequestAborted;
            var aspnetCoreRequestHost        = environment.Request.Host.Value ?? Dns.GetHostName();
            var aspnetCoreUser = environment.User;

            X509Certificate2 certificate = null;

            if (_options.EnableClientCertificates)
            {
                var clientCertificate = new X509Certificate2(environment.Connection.ClientCertificate.Export(X509ContentType.Cert));
                certificate = clientCertificate ?? null;
            }

            var serverClientIp = environment.Connection.RemoteIpAddress.ToString();

            var url = CreateUrl(aspnetCoreRequestHost, aspnetCoreRequestScheme, aspnetCoreRequestPathBase, aspnetCoreRequestPath, aspnetCoreRequestQueryString);

            var nancyRequestStream = new RequestStream(aspnetCoreRequestBody, ExpectedLength(aspnetCoreRequestHeaders), StaticConfiguration.DisableRequestStreamSwitching ?? false);

            var nancyRequest = new Request(
                aspnetCoreRequestMethod,
                url,
                nancyRequestStream,
                aspnetCoreRequestHeaders.ToDictionary(kv => kv.Key, kv => (IEnumerable <string>)kv.Value, StringComparer.OrdinalIgnoreCase),
                serverClientIp,
                certificate,
                aspnetCoreRequestProtocol);

            var nancyContext = await _engine.HandleRequest(
                nancyRequest,
                StoreEnvironment(environment, aspnetCoreUser),
                aspnetCoreCallCancelled).ConfigureAwait(false);

            await RequestComplete(nancyContext, environment, _options.PerformPassThrough, _next).ConfigureAwait(false);
        }
        public Message HandleRequests(Stream requestBody)
        {
            var webContext = WebOperationContext.Current;

            var nancyRequest =
                CreateNancyRequestFromIncomingWebRequest(webContext.IncomingRequest, requestBody, OperationContext.Current);

            var nancyContext =
                engine.HandleRequest(nancyRequest);

            SetNancyResponseToOutgoingWebResponse(webContext.OutgoingResponse, nancyContext.Response);

            return(webContext.CreateStreamResponse(
                       stream =>
            {
                nancyContext.Response.Contents(stream);
                nancyContext.Dispose();
            },
                       nancyContext.Response.ContentType ?? "none/none")); // Stupid WCF forces us to specify a content type
        }
Beispiel #17
0
 private void Listen()
 {
     while (shouldContinue)
     {
         HttpListenerContext requestContext;
         try
         {
             requestContext = listener.GetContext();
         }
         catch (HttpListenerException)
         {
             // this will be thrown when listener is closed while waiting for a request
             return;
         }
         var nancyRequest = ConvertRequestToNancyRequest(requestContext.Request);
         using (var nancyContext = engine.HandleRequest(nancyRequest))
         {
             ConvertNancyResponseToResponse(nancyContext.Response, requestContext.Response);
         }
     }
 }
Beispiel #18
0
        public ProcessingResult  Process(RequestContext context)
        {
            IRequest  request  = context.Request;
            IResponse response = context.Response;

            var nancyRequest = ConvertRequestToNancyRequest(request);

            using (var nancyContext = engine.HandleRequest(nancyRequest))
            {
                using (MemoryStream mstream = new MemoryStream())
                {
                    nancyContext.Response.Contents.Invoke(mstream);

                    response.ContentType.Value   = nancyContext.Response.ContentType;
                    response.ContentLength.Value = mstream.Length;
                    var generator = HttpFactory.Current.Get <ResponseWriter>();
                    generator.SendHeaders(context.HttpContext, response);
                    generator.SendBody(context.HttpContext, mstream);
                }
            }
            return(ProcessingResult.Abort);
        }
        public async Task HandleRequest(CancellationToken ct, IHttpServerRequest request, string relativePath)
        {
            // TODO: Request body for POST requests
            var nancyRequest = new Request(request.Method, request.Url, headers: GetNancyHeaders(request.Headers));

            Start();

            using (var nancyContext = await _engine.HandleRequest(nancyRequest, x => x, ct))
            {
                var    response    = nancyContext.Response;
                string contentType = response?.ContentType ?? "text/plain";
                var    resultCode  = (uint?)response?.StatusCode ?? 200;
                var    resultText  = response?.ReasonPhrase ?? "OK";
                IDictionary <string, ImmutableList <string> > headers = GetResponseHeaders(response);

                var stream = new MemoryStream();
                response.Contents(stream);
                stream.Position = 0;                 // seek back to beginning

                request.SetResponse(contentType, _ => Task.FromResult(stream as Stream), resultCode, resultText, headers);
            }
        }
Beispiel #20
0
 private void Process(HttpListenerContext ctx)
 {
     try
     {
         var nancyRequest = ConvertRequestToNancyRequest(ctx.Request);
         using (var nancyContext = engine.HandleRequest(nancyRequest))
         {
             try
             {
                 ConvertNancyResponseToResponse(nancyContext.Response, ctx.Response);
             }
             catch (Exception e)
             {
                 this.configuration.UnhandledExceptionCallback.Invoke(e);
             }
         }
     }
     catch (Exception e)
     {
         this.configuration.UnhandledExceptionCallback.Invoke(e);
     }
 }
Beispiel #21
0
 private void Process(HttpListenerContext ctx)
 {
     try
     {
         var nancyRequest = ConvertRequestToNancyRequest(ctx.Request);
         using (var nancyContext = engine.HandleRequest(nancyRequest))
         {
             try
             {
                 ConvertNancyResponseToResponse(nancyContext.Response, ctx.Response);
             }
             catch (Exception ex)
             {
                 nancyContext.Trace.TraceLog.WriteLog(s => s.AppendLine(string.Concat("[SelfHost] Exception while rendering response: ", ex)));
                 //TODO - the content of the tracelog is not used in this case
             }
         }
     }
     catch (Exception)
     {
         //TODO -  this swallows the exception so that it doesn't kill the host
         // pass it to the host process for handling by the caller ?
     }
 }
 /// <summary>
 /// Handles an incoming <see cref="Request"/>.
 /// </summary>
 /// <param name="nancyEngine">The <see cref="INancyEngine"/> instance.</param>
 /// <param name="request">An <see cref="Request"/> instance, containing the information about the current request.</param>
 /// <returns>A <see cref="NancyContext"/> instance containing the request/response context.</returns>
 public static Task <NancyContext> HandleRequest(this INancyEngine nancyEngine, Request request)
 {
     return(nancyEngine.HandleRequest(request, context => context, CancellationToken.None));
 }
Beispiel #23
0
        public dynamic Execute(dynamic parameters, INancyModule module)
        {
            var contentType = module.Request.Headers["content-type"].First();
            var mimeType    = contentType.Split(';').First();

            if (mimeType != "multipart/batch" && mimeType != "multipart/mixed")
            {
                return((int)HttpStatusCode.BadRequest);
            }

            var multipartBoundry = Regex.Match(contentType, @"boundary=(?<token>[^\n\; ]*)").Groups["token"].Value.Replace("\"", "");

            if (string.IsNullOrEmpty(multipartBoundry))
            {
                return((int)HttpStatusCode.BadRequest);
            }



            var multipart = new HttpMultipart(module.Request.Body, multipartBoundry);

            IDictionary <string, IEnumerable <string> > headers = module.Request.Headers.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);


            string batchResponseGuid = Guid.NewGuid().ToString().ToLower();

            var response = new Response
            {
                ContentType = string.Format("{0}; boundary=batchresponse_{1}", mimeType, batchResponseGuid),
                StatusCode  = HttpStatusCode.Accepted
            };

            _responseBuilder.Append(string.Format("--batchresponse_{0}\r\n", batchResponseGuid));
            _responseBuilder.Append("Content-Type: application/http\r\n");
            _responseBuilder.Append("Content-Transfer-Encoding: binary\r\n\r\n");

            foreach (var boundry in multipart.GetBoundaries())
            {
                using (var httpRequest = new StreamReader(boundry.Value))
                {
                    var httpRequestText = httpRequest.ReadToEnd();

                    var rawRequestStream = new MemoryStream(Encoding.UTF8.GetBytes(httpRequestText));
                    var nancyRequest     = rawRequestStream.ReadAsRequest(headers);

                    _engine.HandleRequest(nancyRequest, OnSuccess, OnError);
                }
            }

            _responseBuilder.Append(string.Format("\r\n--batchresponse_{0}--", batchResponseGuid));

            var responseText = _responseBuilder.ToString();
            var byteData     = Encoding.UTF8.GetBytes(responseText);

            response.Headers.Add("Content-Length", byteData.Length.ToString());

            response.Contents = contentStream =>
            {
                contentStream.Write(byteData, 0, byteData.Length);
            };

            return(response);
        }
Beispiel #24
0
        public static byte[] HandleRequest(string method, string uri, string query, Dictionary <string, string> headers, IPAddress ip)
        {
            var nuri = new Url
            {
                Scheme   = "http",
                HostName = GetHeader(headers, "Host"),
                Port     = null,
                BasePath = "",
                Path     = uri,
                Query    = query
            };

            var contentLength = ExpectedLength(headers);
            var bodyStream    = Stream.Null;

            if (contentLength > 0)
            {
                var bodyBytes = GameInterface.ReadHTTPBody((int)contentLength);
                bodyStream = new MemoryStream(bodyBytes);
            }

            var body = new RequestStream(bodyStream, contentLength, false);

            var headerDictionary = headers.ToDictionary(kv => kv.Key, kv => (IEnumerable <string>) new[] { kv.Value }, StringComparer.OrdinalIgnoreCase);
            var request          = new Request(method, nuri, body, headerDictionary, ip.ToString());

            var context            = _engine.HandleRequest(request);
            var responseStatusCode = context.Response.StatusCode;
            var responseStream     = new MemoryStream();

            context.Response.Contents(responseStream);
            responseStream.Position = 0;

            var response = new StringBuilder();

            response.Append("HTTP/1.0 ");
            response.Append(((int)responseStatusCode).ToString());
            response.Append(" ");
            response.Append(_statusCodes[(int)responseStatusCode]);
            response.Append("\r\n");

            foreach (var header in context.Response.Headers)
            {
                response.Append(header.Key);
                response.Append(": ");
                response.Append(string.Join(", ", header.Value));
                response.Append("\r\n");
            }

            if (context.Response.ContentType != null)
            {
                response.Append("Content-Type: ");
                response.Append(context.Response.ContentType);
                response.Append("\r\n");
            }

            if (context.Response.Cookies != null && context.Response.Cookies.Count != 0)
            {
                var cookies = context.Response.Cookies.Select(cookie => cookie.ToString()).ToArray();

                response.Append("Set-Cookie: ");
                response.Append(string.Join(", ", cookies));
                response.Append("\r\n");
            }


            response.Append("\r\n");

            var headerBytes = Encoding.UTF8.GetBytes(response.ToString());
            var dataBytes   = new byte[responseStream.Length + headerBytes.Length];

            Array.Copy(headerBytes, dataBytes, headerBytes.Length);

            responseStream.Read(dataBytes, headerBytes.Length, (int)responseStream.Length);

            //Log.Debug(context.Trace.TraceLog.ToString());
            context.Dispose();

            return(dataBytes);
        }
Beispiel #25
0
        public Task Invoke(IDictionary <string, object> env)
        {
            var owinRequestMethod      = Get <string>(env, OwinConstants.RequestMethod);
            var owinRequestScheme      = Get <string>(env, OwinConstants.RequestScheme);
            var owinRequestHeaders     = Get <IDictionary <string, string[]> >(env, OwinConstants.RequestHeaders);
            var owinRequestPathBase    = Get <string>(env, OwinConstants.RequestPathBase);
            var owinRequestPath        = Get <string>(env, OwinConstants.RequestPath);
            var owinRequestQueryString = Get <string>(env, OwinConstants.RequestQueryString);
            var owinRequestBody        = Get <Stream>(env, OwinConstants.RequestBody);
            var serverClientIp         = Get <string>(env, OwinConstants.RemoteIpAddress);

            var owinResponseHeaders = Get <IDictionary <string, string[]> >(env, OwinConstants.ResponseHeaders);
            var owinResponseBody    = Get <Stream>(env, OwinConstants.ResponseBody);

            var url = new Url
            {
                Scheme   = owinRequestScheme,
                HostName = GetHeader(owinRequestHeaders, "Host"),
                Port     = null,
                BasePath = owinRequestPathBase,
                Path     = owinRequestPath,
                Query    = owinRequestQueryString,
            };

            var body = new RequestStream(owinRequestBody, ExpectedLength(owinRequestHeaders), false);

            var nancyRequest = new Request(
                owinRequestMethod,
                url,
                body,
                owinRequestHeaders.ToDictionary(kv => kv.Key, kv => (IEnumerable <string>)kv.Value, StringComparer.OrdinalIgnoreCase),
                serverClientIp);

            var tcs = new TaskCompletionSource <object>();

            _engine.HandleRequest(
                nancyRequest,
                context =>
            {
                var nancyResponse = context.Response;

                if (_next != null && nancyResponse.StatusCode == HttpStatusCode.NotFound)
                {
                    _next(env).CopyResultToCompletionSource(tcs, null);
                }
                else
                {
                    env[OwinConstants.ResponseStatusCode] = (int)nancyResponse.StatusCode;
                    foreach (var header in nancyResponse.Headers)
                    {
                        owinResponseHeaders.Add(header.Key, new string[] { header.Value });
                    }

                    if (!string.IsNullOrWhiteSpace(nancyResponse.ContentType))
                    {
                        owinResponseHeaders["Content-Type"] = new[] { nancyResponse.ContentType };
                    }
                    if (nancyResponse.Cookies != null && nancyResponse.Cookies.Count != 0)
                    {
                        owinResponseHeaders["Set-Cookie"] = nancyResponse.Cookies.Select(cookie => cookie.ToString()).ToArray();
                    }

                    nancyResponse.Contents(owinResponseBody);
                    context.Dispose();
                    tcs.TrySetResult(null);
                }
            },
                tcs.SetException);
            return(tcs.Task);
        }
Beispiel #26
0
        /// <summary>
        /// OWIN App Action
        /// </summary>
        /// <param name="environment">Application environment</param>
        /// <returns>Returns result</returns>
        public Task ProcessRequest(IDictionary <string, object> environment)
        {
            var owinRequestMethod      = Get <string>(environment, "owin.RequestMethod");
            var owinRequestScheme      = Get <string>(environment, "owin.RequestScheme");
            var owinRequestHeaders     = Get <IDictionary <string, string[]> >(environment, "owin.RequestHeaders");
            var owinRequestPathBase    = Get <string>(environment, "owin.RequestPathBase");
            var owinRequestPath        = Get <string>(environment, "owin.RequestPath");
            var owinRequestQueryString = Get <string>(environment, "owin.RequestQueryString");
            var owinRequestBody        = Get <Stream>(environment, "owin.RequestBody");
            var serverClientIp         = Get <string>(environment, "server.CLIENT_IP");
            //var callCancelled = Get<CancellationToken>(environment, "owin.RequestBody");

            var url = new Url
            {
                Scheme   = owinRequestScheme,
                HostName = GetHeader(owinRequestHeaders, "Host"),
                Port     = null,
                BasePath = owinRequestPathBase,
                Path     = owinRequestPath,
                Query    = owinRequestQueryString,
            };

            var nancyRequestStream = new RequestStream(owinRequestBody, ExpectedLength(owinRequestHeaders), false);

            var nancyRequest = new Request(
                owinRequestMethod,
                url,
                nancyRequestStream,
                owinRequestHeaders.ToDictionary(kv => kv.Key, kv => (IEnumerable <string>)kv.Value, StringComparer.OrdinalIgnoreCase),
                serverClientIp);

            var tcs = new TaskCompletionSource <int>();

            engine.HandleRequest(
                nancyRequest,
                context =>
            {
                environment["nancy.NancyContext"]    = context;
                context.Items[RequestEnvironmentKey] = environment;
                return(context);
            },
                context =>
            {
                var owinResponseHeaders = Get <IDictionary <string, string[]> >(environment, "owin.ResponseHeaders");
                var owinResponseBody    = Get <Stream>(environment, "owin.ResponseBody");

                var nancyResponse = context.Response;
                environment["owin.ResponseStatusCode"] = (int)nancyResponse.StatusCode;

                foreach (var responseHeader in nancyResponse.Headers)
                {
                    owinResponseHeaders[responseHeader.Key] = new[] { responseHeader.Value };
                }

                if (!string.IsNullOrWhiteSpace(nancyResponse.ContentType))
                {
                    owinResponseHeaders["Content-Type"] = new[] { nancyResponse.ContentType };
                }

                if (nancyResponse.Cookies != null && nancyResponse.Cookies.Count != 0)
                {
                    owinResponseHeaders["Set-Cookie"] =
                        nancyResponse.Cookies.Select(cookie => cookie.ToString()).ToArray();
                }

                nancyResponse.Contents(owinResponseBody);

                context.Dispose();

                tcs.TrySetResult(0);
            }, tcs.SetException);

            return(tcs.Task);
        }