Пример #1
0
        public IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
        {
            var taskCompletionSource = new TaskCompletionSource<Action>(state);
            if (callback != null)
                taskCompletionSource.Task.ContinueWith(task => callback(task), TaskContinuationOptions.ExecuteSynchronously);

            var httpRequest = httpContext.Request;
            var serverVariables = new ServerVariables(httpRequest.ServerVariables);

            var pathBase = httpRequest.ApplicationPath;
            if (pathBase == "/" || pathBase == null)
                pathBase = "";

            var path = httpRequest.Path;
            if (path.StartsWith(pathBase))
                path = path.Substring(pathBase.Length);

            var requestHeaders = httpRequest.Headers.AllKeys
                .ToDictionary(x => x, x => httpRequest.Headers.Get(x), StringComparer.OrdinalIgnoreCase);

            var env = new Environment()
            {
                Version = "1.0",
                Method = httpRequest.HttpMethod,
                Scheme = httpRequest.Url.Scheme,
                PathBase = pathBase,
                Path = path,
                QueryString = serverVariables.QueryString,
                Headers = requestHeaders,
                Body = Body.FromStream(httpRequest.InputStream),
            };
            env["aspnet.HttpContextBase"] = httpContext;
            foreach (var kv in serverVariables.AddToEnvironment())
            {
                env["server." + kv.Key] = kv.Value;
            }

            _app.Invoke(
                env,
                (status, headers, body) =>
                {
                    try
                    {
                        httpContext.Response.BufferOutput = false;

                        httpContext.Response.Status = status;
                        foreach (var header in headers.SelectMany(kv => kv.Value.Split("\r\n".ToArray(), StringSplitOptions.RemoveEmptyEntries).Select(v => new {kv.Key, Value = v})))
                        {
                            httpContext.Response.AddHeader(header.Key, header.Value);
                        }

                        body.WriteToStream(
                            httpContext.Response.OutputStream,
                            taskCompletionSource.SetException,
                            () => taskCompletionSource.SetResult(() => httpContext.Response.End()));
                    }
                    catch (Exception ex)
                    {
                        taskCompletionSource.SetException(ex);
                    }
                },
                taskCompletionSource.SetException);
            return taskCompletionSource.Task;
        }
Пример #2
0
        public IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
        {
            var cancellationTokenSource = new CancellationTokenSource();
            var taskCompletionSource = new TaskCompletionSource<Action>(state);
            if (callback != null)
                taskCompletionSource.Task.ContinueWith(task => callback(task), TaskContinuationOptions.ExecuteSynchronously);

            var httpRequest = httpContext.Request;
            var serverVariables = new ServerVariables(httpRequest.ServerVariables);

            var pathBase = httpRequest.ApplicationPath;
            if (pathBase == "/" || pathBase == null)
                pathBase = "";

            var path = httpRequest.Path;
            if (path.StartsWith(pathBase))
                path = path.Substring(pathBase.Length);

            var requestHeaders = httpRequest.Headers.AllKeys
                .ToDictionary(x => x, x => (IEnumerable<string>)httpRequest.Headers.GetValues(x), StringComparer.OrdinalIgnoreCase);

            var env = new Dictionary<string, object>
            {
                {OwinConstants.Version, "1.0"},
                {OwinConstants.RequestMethod, httpRequest.HttpMethod},
                {OwinConstants.RequestScheme, httpRequest.Url.Scheme},
                {OwinConstants.RequestPathBase, pathBase},
                {OwinConstants.RequestPath, path},
                {OwinConstants.RequestQueryString, serverVariables.QueryString},
                {OwinConstants.RequestHeaders, requestHeaders},
                {OwinConstants.RequestBody, RequestBody(httpRequest.InputStream)},
                {"host.CallDisposed", cancellationTokenSource.Token},
                {"aspnet.HttpContextBase", httpContext},
            };
            foreach (var kv in serverVariables.AddToEnvironment())
            {
                env["server." + kv.Key] = kv.Value;
            }

            try
            {
                _app.Invoke(
                    env,
                    (status, headers, body) =>
                    {
                        try
                        {
                            httpContext.Response.BufferOutput = false;

                            httpContext.Response.Status = status;
                            foreach (var header in headers)
                            {
                                foreach (var value in header.Value)
                                {
                                    httpContext.Response.AddHeader(header.Key, value);
                                }
                            }

                            ResponseBody(
                                body,
                                httpContext.Response.OutputStream,
                                ex => taskCompletionSource.TrySetException(ex),
                                () => taskCompletionSource.TrySetResult(() => httpContext.Response.End()));
                        }
                        catch (Exception ex)
                        {
                            taskCompletionSource.TrySetException(ex);
                        }
                    },
                    ex => taskCompletionSource.TrySetException(ex));
            }
            catch(Exception ex)
            {
                taskCompletionSource.TrySetException(ex);
            }

            if (taskCompletionSource.Task.IsCompleted)
            {
                cancellationTokenSource.Cancel(false);
            }
            else
            {
                taskCompletionSource.Task.ContinueWith(t => cancellationTokenSource.Cancel(false));
            }

            return taskCompletionSource.Task;
        }
Пример #3
0
        public IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
        {
            var taskCompletionSource = new TaskCompletionSource<Action>(state);
            if (callback != null)
                taskCompletionSource.Task.ContinueWith(task => callback(task), TaskContinuationOptions.ExecuteSynchronously);

            var call = new CallParameters();

            var httpRequest = httpContext.Request;
            var serverVariables = new ServerVariables(httpRequest.ServerVariables);

            var pathBase = httpRequest.ApplicationPath;
            if (pathBase == "/" || pathBase == null)
                pathBase = "";

            var path = httpRequest.Path;
            if (path.StartsWith(pathBase))
                path = path.Substring(pathBase.Length);

            call.Headers = httpRequest.Headers.AllKeys
                .ToDictionary(x => x, x => httpRequest.Headers.GetValues(x), StringComparer.OrdinalIgnoreCase);

            call.Body = httpRequest.InputStream;

            call.Environment = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)
            {
                {OwinConstants.Version, "1.0"},
                {OwinConstants.RequestMethod, httpRequest.HttpMethod},
                {OwinConstants.RequestScheme, httpRequest.Url.Scheme},
                {OwinConstants.RequestPathBase, pathBase},
                {OwinConstants.RequestPath, path},
                {OwinConstants.RequestQueryString, serverVariables.QueryString},
                {OwinConstants.RequestProtocol, serverVariables.ProtocolVersion},
                {"aspnet.HttpContextBase", httpContext},
                {OwinConstants.CallCompleted, taskCompletionSource.Task},
            };
            foreach (var kv in serverVariables.AddToEnvironment())
            {
                call.Environment["server." + kv.Key] = kv.Value;
            }

            try
            {
                _app.Invoke(call)
                    .Then(result =>
                    {
                        try
                        {
                            httpContext.Response.BufferOutput = false;

                            httpContext.Response.StatusCode = result.Status;
                            // TODO: Reason phrase
                            foreach (var header in result.Headers)
                            {
                                foreach (var value in header.Value)
                                {
                                    httpContext.Response.AddHeader(header.Key, value);
                                }
                            }

                            if (result.Body != null)
                            {
                                result.Body(httpContext.Response.OutputStream)
                                    .Then(() =>
                                    {
                                        taskCompletionSource.TrySetResult(() => { });
                                    })
                                    .Catch(errorInfo =>
                                    {
                                        taskCompletionSource.TrySetException(errorInfo.Exception);
                                        return errorInfo.Handled();
                                    });
                            }
                        }
                        catch (Exception ex)
                        {
                            taskCompletionSource.TrySetException(ex);
                        }
                    })
                    .Catch(errorInfo =>
                    {
                        taskCompletionSource.TrySetException(errorInfo.Exception);
                        return errorInfo.Handled();
                    });
            }
            catch (Exception ex)
            {
                taskCompletionSource.TrySetException(ex);
            }

            return taskCompletionSource.Task;
        }