示例#1
0
 public IServer CreateServer(IConfiguration configuration)
 {
     var information = new ServerInformation(configuration);
     var serverFeatures = new FeatureCollection();
     serverFeatures.Set<IServerInformation>(information);
     serverFeatures.Set<IServerAddressesFeature>(information);
     return new Server(serverFeatures, _appLifetime, _loggerFactory.CreateLogger(Server.ConfigServerAssembly));
 }
 public IServer CreateServer(IConfiguration configuration)
 {
     var information = new KestrelServerInformation(configuration);
     var serverFeatures = new FeatureCollection();
     serverFeatures.Set<IKestrelServerInformation>(information);
     serverFeatures.Set<IServerAddressesFeature>(information);
     return new KestrelServer(serverFeatures, _appLifetime, _loggerFactory.CreateLogger("Microsoft.AspNet.Server.Kestrel"));
 }
 public IFeatureCollection Initialize(IConfiguration configuration)
 {
     var information = new KestrelServerInformation();
     information.Initialize(configuration);
     var serverFeatures = new FeatureCollection();
     serverFeatures.Set<IKestrelServerInformation>(information);
     serverFeatures.Set<IServerAddressesFeature>(information);
     return serverFeatures;
 }
        public IServer CreateServer(IConfiguration configuration)
        {
            var information = new RioSharpServerInformation();
            information.Initialize(configuration);

            var serverFeatures = new FeatureCollection();
            serverFeatures.Set<IRioSharpServerInformation>(information);
            serverFeatures.Set<IServerAddressesFeature>(information);

            return new RioSharpServer(serverFeatures, _appLifetime, _loggerFactory.CreateLogger("RioSharp.Aspnet"), _httpContextFactory);
        }
 public IFeatureCollection Initialize(IConfiguration configuration)
 {
     // TODO: Parse config
     var builder = ServerBuilder.New()
         .SetAddress(IPAddress.Any)
         .SetPort(configuration["port"] != null ? Int32.Parse(configuration["port"]) : 8080)
         .SetOwinApp(OwinWebSocketAcceptAdapter.AdaptWebSockets(HandleRequest));
     var serverFeatures = new FeatureCollection();
     serverFeatures.Set<NowinServerInformation>(new NowinServerInformation(builder));
     return serverFeatures;
 }
        public IFeatureCollection Initialize(IConfiguration configuration)
        {
            var builder = ServerBuilder.New()
                        .SetAddress(IPAddress.Any)
                        .SetPort(5000)
                        .SetOwinApp(HandleRequest);

            var serverFeatures = new FeatureCollection();
            serverFeatures.Set<INowinServerInformation>(new NowinServerInformation(builder));
            return serverFeatures;
        }
        private static KestrelServer CreateServer(Func<IConfiguration, IKestrelServerInformation> serverInformationFactory)
        {
            var configuration = new ConfigurationBuilder().Build();
            var information = serverInformationFactory(configuration);

            var features = new FeatureCollection();
            features.Set(information);

            var lifetime = new LifetimeNotImplemented();
            var logger = new TestKestrelTrace.TestLogger();

            return new KestrelServer(features, lifetime, logger);
        }
示例#8
0
        public async Task IfHandledInternalServerError_ItLogsError()
        {
            // Arrange

            // Logger
            var loggerMock    = new Mock <ILogger <GlobalLoggerMiddleware> >();
            var loggerFactory = new Mock <ILoggerFactory>();

            loggerFactory.Setup(f => f.CreateLogger(It.IsAny <string>()))
            .Returns(loggerMock.Object);

            // Diagnostic
            var diagnoticSourceMock = new Mock <DiagnosticSource>();


            // Request
            var requestMock = new Mock <HttpRequest>();

            requestMock.Setup(x => x.Scheme).Returns("http");
            requestMock.Setup(x => x.Host).Returns(new HostString("localhost"));
            requestMock.Setup(x => x.Path).Returns(new PathString("/FooBar"));
            requestMock.Setup(x => x.PathBase).Returns(new PathString("/"));
            requestMock.Setup(x => x.Method).Returns("GET");
            requestMock.Setup(x => x.Body).Returns(new MemoryStream());

            // Response
            var responseMock = new Mock <HttpResponse>();

            responseMock.SetupGet(y => y.StatusCode).Returns(500);

            // Context
            var features  = new FeatureCollection();
            var exMessage = "I'm just exceptional";
            var exceptionHandlerFeature = new ExceptionHandlerFeature()
            {
                Error = new Exception(exMessage),
            };

            features.Set <IExceptionHandlerFeature>(exceptionHandlerFeature);

            var contextMock = new Mock <HttpContext>();

            contextMock.Setup(z => z.Request).Returns(requestMock.Object);
            contextMock.Setup(z => z.Response).Returns(responseMock.Object);

            contextMock.Setup(z => z.Features).Returns(features);

            // Middleware
            var logRequestMiddleware = new GlobalLoggerMiddleware(next: (innerHttpContext) => Task.FromResult(0), loggerFactory: loggerFactory.Object, diagnosticSource: diagnoticSourceMock.Object);

            // Act
            await logRequestMiddleware.Invoke(contextMock.Object);

            // Assert
            loggerMock.Verify(l => l.Log(
                                  LogLevel.Error,
                                  It.IsAny <EventId>(),
                                  It.Is <It.IsAnyType>((object fV, Type _) => fV.ToString().Equals(($"An internal handled exception has occurred: {exMessage}"))),
                                  It.IsAny <Exception>(),
                                  (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()));
        }
        /// <summary>
        /// Invokes batch request.
        /// </summary>
        /// <param name="httpContext">Source batch request context.</param>
        /// <param name="requests">Array of requests.</param>
        private async Task InvokeAsyncBatchAsync(HttpContext httpContext, JArray requests)
        {
            JArray responses = new JArray();
            int    i         = 1;

            foreach (JObject requestObj in requests)
            {
                var contextFeatures = new FeatureCollection(httpContext.Features);

                StringBuilder requestStringBuilder = new StringBuilder();
                await requestObj.WriteToAsync(new JsonTextWriter(new StringWriter(requestStringBuilder)));

                var requestFeature = new HttpRequestFeature()
                {
                    Body        = new MemoryStream(Encoding.UTF8.GetBytes(requestStringBuilder.ToString())),
                    Headers     = httpContext.Request.Headers,
                    Method      = httpContext.Request.Method,
                    Protocol    = httpContext.Request.Protocol,
                    Scheme      = httpContext.Request.Scheme,
                    QueryString = httpContext.Request.QueryString.Value
                };
                contextFeatures.Set <IHttpRequestFeature>(requestFeature);

                var responseMemoryStream = new MemoryStream();
                var responseFeature      = new HttpResponseFeature()
                {
                    Body = responseMemoryStream
                };
                contextFeatures.Set <IHttpResponseFeature>(responseFeature);

                contextFeatures.Set <IHttpRequestLifetimeFeature>(new HttpRequestLifetimeFeature());

                var context = this.httpContextFactory.Create(contextFeatures);

                try
                {
                    await this.next.Invoke(context).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    await this.HandleRpcInvokeExceptionAsync(context, ex);
                }

                responseMemoryStream.Position = 0;

                var response = (responseMemoryStream.Length == 0) ? CreateError(RPCErrorCode.RPC_METHOD_NOT_FOUND, "Method not found") : await JObject.LoadAsync(new JsonTextReader(new StreamReader(responseMemoryStream)));

                if (requestObj.ContainsKey("id"))
                {
                    response["id"] = requestObj["id"];
                }
                else
                {
                    response.Remove("id");
                }

                responses.Add(response);
                i++;
            }

            httpContext.Response.ContentType = "application/json; charset=utf-8";

            // Update the response with the array of responses.
            using (StreamWriter streamWriter = new StreamWriter(httpContext.Response.Body))
                using (JsonTextWriter textWriter = new JsonTextWriter(streamWriter))
                {
                    await responses.WriteToAsync(textWriter);
                }
        }
示例#10
0
        protected async Task <JObject> ExecuteBulkOperation(BulkOperationParameter scimBulkOperationRequest)
        {
            var router   = RouteData.Routers.OfType <IRouteCollection>().First();
            var features = new FeatureCollection();

            features.Set <IHttpRequestFeature>(new HttpRequestFeature());
            features.Set <IRoutingFeature>(new RoutingFeature
            {
                RouteData = RouteData
            });
            features.Set <IHttpResponseFeature>(new HttpResponseFeature());
            features.Set <IResponseCookiesFeature>(new ResponseCookiesFeature(features));
            var newHttpContext = new DefaultHttpContext(features);

            newHttpContext.Request.Path   = scimBulkOperationRequest.Path;
            newHttpContext.Request.Method = scimBulkOperationRequest.HttpMethod;
            if (scimBulkOperationRequest.Data != null && (scimBulkOperationRequest.HttpMethod.Equals("POST", StringComparison.InvariantCultureIgnoreCase) ||
                                                          scimBulkOperationRequest.HttpMethod.Equals("PUT", StringComparison.InvariantCultureIgnoreCase) ||
                                                          scimBulkOperationRequest.HttpMethod.Equals("PATCH", StringComparison.InvariantCultureIgnoreCase)))
            {
                newHttpContext.Request.ContentType = SCIMConstants.STANDARD_SCIM_CONTENT_TYPE;
                newHttpContext.Request.Body        = new MemoryStream(Encoding.UTF8.GetBytes(scimBulkOperationRequest.Data.ToString()));
            }

            newHttpContext.RequestServices = HttpContext.RequestServices;
            newHttpContext.Response.Body   = new MemoryStream();
            var routeContext = new RouteContext(newHttpContext)
            {
                RouteData = RouteData
            };
            await router.RouteAsync(routeContext);

            var ctx = routeContext.HttpContext;
            await routeContext.Handler.Invoke(newHttpContext);

            var result = new JObject
            {
                { SCIMConstants.StandardSCIMRepresentationAttributes.Method, scimBulkOperationRequest.HttpMethod },
                { SCIMConstants.StandardSCIMRepresentationAttributes.BulkId, scimBulkOperationRequest.BulkIdentifier }
            };
            var statusCode    = newHttpContext.Response.StatusCode;
            var statusContent = new JObject();

            statusContent.Add("code", statusCode);
            if (statusCode >= 400)
            {
                newHttpContext.Response.Body.Position = 0;
                using (var reader = new StreamReader(newHttpContext.Response.Body))
                {
                    var responseBody = await reader.ReadToEndAsync();

                    JObject json          = (JObject)JsonConvert.DeserializeObject(responseBody);
                    var     response      = new JObject();
                    var     scimTypeToken = json.SelectToken("response.scimType");
                    var     detailToken   = json.SelectToken("response.detail");
                    if (scimTypeToken != null)
                    {
                        response.Add("scimType", scimTypeToken.ToString());
                    }

                    if (detailToken != null)
                    {
                        response.Add("detail", detailToken.ToString());
                    }

                    statusContent.Add("response", response);
                }
            }

            result.Add("status", statusContent);
            if (newHttpContext.Response.Headers.ContainsKey("ETag"))
            {
                result.Add("version", newHttpContext.Response.Headers["ETag"].First());
            }

            if (newHttpContext.Response.Headers.ContainsKey("Location"))
            {
                result.Add("location", newHttpContext.Response.Headers["Location"].First());
            }

            return(result);
        }
        private static void CloneHttpContext(HttpContext context, HttpConnectionContext connection)
        {
            // The reason we're copying the base features instead of the HttpContext properties is
            // so that we can get all of the logic built into DefaultHttpContext to extract higher level
            // structure from the low level properties
            var existingRequestFeature = context.Features.Get <IHttpRequestFeature>() !;

            var requestFeature = new HttpRequestFeature();

            requestFeature.Protocol    = existingRequestFeature.Protocol;
            requestFeature.Method      = existingRequestFeature.Method;
            requestFeature.Scheme      = existingRequestFeature.Scheme;
            requestFeature.Path        = existingRequestFeature.Path;
            requestFeature.PathBase    = existingRequestFeature.PathBase;
            requestFeature.QueryString = existingRequestFeature.QueryString;
            requestFeature.RawTarget   = existingRequestFeature.RawTarget;
            var requestHeaders = new Dictionary <string, StringValues>(existingRequestFeature.Headers.Count, StringComparer.OrdinalIgnoreCase);

            foreach (var header in existingRequestFeature.Headers)
            {
                requestHeaders[header.Key] = header.Value;
            }
            requestFeature.Headers = new HeaderDictionary(requestHeaders);

            var existingConnectionFeature = context.Features.Get <IHttpConnectionFeature>();
            var connectionFeature         = new HttpConnectionFeature();

            if (existingConnectionFeature != null)
            {
                connectionFeature.ConnectionId    = existingConnectionFeature.ConnectionId;
                connectionFeature.LocalIpAddress  = existingConnectionFeature.LocalIpAddress;
                connectionFeature.LocalPort       = existingConnectionFeature.LocalPort;
                connectionFeature.RemoteIpAddress = existingConnectionFeature.RemoteIpAddress;
                connectionFeature.RemotePort      = existingConnectionFeature.RemotePort;
            }

            // The response is a dud, you can't do anything with it anyways
            var responseFeature = new HttpResponseFeature();

            var features = new FeatureCollection();

            features.Set <IHttpRequestFeature>(requestFeature);
            features.Set <IHttpResponseFeature>(responseFeature);
            features.Set <IHttpResponseBodyFeature>(new StreamResponseBodyFeature(Stream.Null));
            features.Set <IHttpConnectionFeature>(connectionFeature);

            // REVIEW: We could strategically look at adding other features but it might be better
            // if we expose a callback that would allow the user to preserve HttpContext properties.

            var newHttpContext = new DefaultHttpContext(features);

            newHttpContext.TraceIdentifier = context.TraceIdentifier;

            var endpointFeature = context.Features.Get <IEndpointFeature>();

            newHttpContext.SetEndpoint(endpointFeature?.Endpoint);

            CloneUser(newHttpContext, context);

            connection.ServiceScope        = context.RequestServices.CreateScope();
            newHttpContext.RequestServices = connection.ServiceScope.ServiceProvider;

            // REVIEW: This extends the lifetime of anything that got put into HttpContext.Items
            newHttpContext.Items = new Dictionary <object, object?>(context.Items);

            connection.HttpContext = newHttpContext;
        }
        public void UpdateFeatures_ClearsCachedFeatures()
        {
            var features = new FeatureCollection();
            features.Set<IHttpRequestFeature>(new HttpRequestFeature());
            features.Set<IHttpResponseFeature>(new HttpResponseFeature());
            features.Set<IHttpWebSocketFeature>(new TestHttpWebSocketFeature());

            // featurecollection is set. all cached interfaces are null.
            var context = new DefaultHttpContext(features);
            TestAllCachedFeaturesAreNull(context, features);
            Assert.Equal(3, features.Count());

            // getting feature properties populates feature collection with defaults
            TestAllCachedFeaturesAreSet(context, features);
            Assert.NotEqual(3, features.Count());

            // featurecollection is null. and all cached interfaces are null.
            // only top level is tested because child objects are inaccessible.
            context.Uninitialize();
            TestCachedFeaturesAreNull(context, null);


            var newFeatures = new FeatureCollection();
            newFeatures.Set<IHttpRequestFeature>(new HttpRequestFeature());
            newFeatures.Set<IHttpResponseFeature>(new HttpResponseFeature());
            newFeatures.Set<IHttpWebSocketFeature>(new TestHttpWebSocketFeature());

            // featurecollection is set to newFeatures. all cached interfaces are null.
            context.Initialize(newFeatures);
            TestAllCachedFeaturesAreNull(context, newFeatures);
            Assert.Equal(3, newFeatures.Count());

            // getting feature properties populates new feature collection with defaults
            TestAllCachedFeaturesAreSet(context, newFeatures);
            Assert.NotEqual(3, newFeatures.Count());
        }
示例#13
0
 public IFeatureCollection Initialize(IConfiguration configuration)
 {
     var features = new FeatureCollection();
     features.Set<IServerAddressesFeature>(new ServerAddressesFeature());
     return features;
 }
        public async Task EndMiddleware_PropagatesFullExceptionInfo_ToEarlierMiddleware()
        {
            // Arrange
            var services               = new ServiceCollection();
            var appBuilder             = new ApplicationBuilder(services.BuildServiceProvider());
            var pipelineBuilderService = new MiddlewareFilterBuilder(new MiddlewareFilterConfigurationProvider())
            {
                ApplicationBuilder = appBuilder,
            };

            Pipeline1.ConfigurePipeline = ab =>
            {
                ab.Use((ctx, next) =>
                {
                    return(next(ctx));
                });
            };

            var middlewareFilterFeature = new MiddlewareFilterFeature
            {
                ResourceExecutionDelegate = () =>
                {
                    ExceptionDispatchInfo exceptionInfo;
                    try
                    {
                        // Create a small stack trace.
                        throw new InvalidOperationException("Error!!!");
                    }
                    catch (Exception ex)
                    {
                        exceptionInfo = ExceptionDispatchInfo.Capture(ex);
                    }

                    var actionContext = new ActionContext(
                        new DefaultHttpContext(),
                        new RouteData(),
                        new ActionDescriptor(),
                        new ModelStateDictionary());
                    var context = new ResourceExecutedContext(actionContext, new List <IFilterMetadata>())
                    {
                        ExceptionDispatchInfo = exceptionInfo,
                    };

                    return(Task.FromResult(context));
                },
            };

            var features = new FeatureCollection();

            features.Set <IMiddlewareFilterFeature>(middlewareFilterFeature);
            var httpContext = new DefaultHttpContext(features);

            // Act
            var pipeline = pipelineBuilderService.GetPipeline(typeof(Pipeline1));

            // Assert
            Assert.NotNull(pipeline);

            var exception = await Assert.ThrowsAsync <InvalidOperationException>(() => pipeline(httpContext));

            Assert.Null(exception.InnerException);
            Assert.Equal("Error!!!", exception.Message);

            var stack = exception.StackTrace;

            Assert.Contains(typeof(MiddlewareFilterBuilder).FullName, stack);
            Assert.Contains(typeof(MiddlewareFilterBuilderTest).FullName, stack);
            Assert.Contains(nameof(EndMiddleware_PropagatesFullExceptionInfo_ToEarlierMiddleware), stack);
        }
示例#15
0
 public FakeServer()
 {
     Features = new FeatureCollection();
     Features.Set <IServerAddressesFeature>(new ServerAddressesFeature());
 }
示例#16
0
            internal RequestState(HttpRequestMessage request, PathString pathBase, IHttpApplication<Context> application)
            {
                _request = request;
                _application = application;
                _responseTcs = new TaskCompletionSource<HttpResponseMessage>();
                _requestAbortedSource = new CancellationTokenSource();
                _pipelineFinished = false;

                if (request.RequestUri.IsDefaultPort)
                {
                    request.Headers.Host = request.RequestUri.Host;
                }
                else
                {
                    request.Headers.Host = request.RequestUri.GetComponents(UriComponents.HostAndPort, UriFormat.UriEscaped);
                }

                var contextFeatures = new FeatureCollection();
                contextFeatures.Set<IHttpRequestFeature>(new RequestFeature());
                _responseFeature = new ResponseFeature();
                contextFeatures.Set<IHttpResponseFeature>(_responseFeature);
                Context = application.CreateContext(contextFeatures);
                var httpContext = Context.HttpContext;

                var serverRequest = httpContext.Request;
                serverRequest.Protocol = "HTTP/" + request.Version.ToString(2);
                serverRequest.Scheme = request.RequestUri.Scheme;
                serverRequest.Method = request.Method.ToString();

                var fullPath = PathString.FromUriComponent(request.RequestUri);
                PathString remainder;
                if (fullPath.StartsWithSegments(pathBase, out remainder))
                {
                    serverRequest.PathBase = pathBase;
                    serverRequest.Path = remainder;
                }
                else
                {
                    serverRequest.PathBase = PathString.Empty;
                    serverRequest.Path = fullPath;
                }

                serverRequest.QueryString = QueryString.FromUriComponent(request.RequestUri);

                foreach (var header in request.Headers)
                {
                    serverRequest.Headers.Append(header.Key, header.Value.ToArray());
                }
                var requestContent = request.Content;
                if (requestContent != null)
                {
                    foreach (var header in request.Content.Headers)
                    {
                        serverRequest.Headers.Append(header.Key, header.Value.ToArray());
                    }
                }

                _responseStream = new ResponseStream(ReturnResponseMessage, AbortRequest);
                httpContext.Response.Body = _responseStream;
                httpContext.Response.StatusCode = 200;
                httpContext.RequestAborted = _requestAbortedSource.Token;
            }
示例#17
0
        public static async Task <IHtmlContent> RenderComponentAsync(
            Type componentType,
            Action <IServiceCollection> configureServices = null,
            IDictionary <string, object> parameters       = null,
            RenderMode renderMode = RenderMode.Static)
        {
            var diContainer = new ServiceCollection();

            diContainer.AddLogging();
            diContainer.AddRazorPages();
            configureServices?.Invoke(diContainer);
            diContainer.TryAddScoped(sp => new HttpClient {
                BaseAddress = new Uri("http://localhost:5000/")
            });

            using var serviceProvider = diContainer.BuildServiceProvider();
            using var scope           = serviceProvider.CreateScope();

            var featureCollection = new FeatureCollection();

            featureCollection.Set <IHttpRequestFeature>(new HttpRequestFeature
            {
                Protocol    = "HTTP/2",
                Scheme      = "http",
                Method      = "GET",
                PathBase    = "",
                Path        = "/",
                QueryString = "",
                RawTarget   = "/",
                Headers     = { { "Host", "localhost:5000" } }
            });
            featureCollection.Set <IHttpResponseFeature>(new HttpResponseFeature());

            var httpContextFactory = new DefaultHttpContextFactory(scope.ServiceProvider);
            var httpContext        = httpContextFactory.Create(featureCollection);

            var attributes = new TagHelperAttributeList();

            var tagHelperContext = new TagHelperContext(attributes, new Dictionary <object, object>(), Guid.NewGuid().ToString("N"));

            var tagHelperOutput = new TagHelperOutput(
                tagName: string.Empty,
                attributes,
                getChildContentAsync: (_, _) => Task.FromResult(new DefaultTagHelperContent() as TagHelperContent));

            var componentTagHelper = new ComponentTagHelper
            {
                ComponentType = componentType,
                RenderMode    = renderMode,
                Parameters    = parameters,
                ViewContext   = new ViewContext {
                    HttpContext = httpContext
                }
            };

            await componentTagHelper.ProcessAsync(tagHelperContext, tagHelperOutput);

            httpContextFactory.Dispose(httpContext);

            return(tagHelperOutput.Content);
        }
示例#18
0
        public async Task TestNegotiateHandlerWithMultipleEndpointsAndCustomRouter()
        {
            var requestIdProvider = new TestRequestIdProvider("a");
            var config            = new ConfigurationBuilder().Build();
            var router            = new TestCustomRouter();
            var serviceProvider   = new ServiceCollection().AddSignalR()
                                    .AddAzureSignalR(
                o => o.Endpoints = new ServiceEndpoint[]
            {
                new ServiceEndpoint(ConnectionString2),
                new ServiceEndpoint(ConnectionString3, name: "chosen"),
                new ServiceEndpoint(ConnectionString4),
            })
                                    .Services
                                    .AddLogging()
                                    .AddSingleton <IEndpointRouter>(router)
                                    .AddSingleton <IConfiguration>(config)
                                    .AddSingleton <IConnectionRequestIdProvider>(requestIdProvider)
                                    .BuildServiceProvider();

            var requestFeature = new HttpRequestFeature
            {
                Path        = "/user/path/negotiate/",
                QueryString = "?endpoint=chosen"
            };
            var features = new FeatureCollection();

            features.Set <IHttpRequestFeature>(requestFeature);
            var httpContext = new DefaultHttpContext(features);

            var handler           = serviceProvider.GetRequiredService <NegotiateHandler>();
            var negotiateResponse = await handler.Process(httpContext, "chat");

            Assert.NotNull(negotiateResponse);
            Assert.Equal($"http://localhost3/client/?hub=chat&asrs.op=%2Fuser%2Fpath&endpoint=chosen&asrs_request_id=a", negotiateResponse.Url);

            // With no query string should return 400
            requestFeature = new HttpRequestFeature
            {
                Path = "/user/path/negotiate/",
            };

            var responseFeature = new HttpResponseFeature();

            features.Set <IHttpRequestFeature>(requestFeature);
            features.Set <IHttpResponseFeature>(responseFeature);
            httpContext = new DefaultHttpContext(features);

            handler           = serviceProvider.GetRequiredService <NegotiateHandler>();
            negotiateResponse = await handler.Process(httpContext, "chat");

            Assert.Null(negotiateResponse);

            Assert.Equal(400, responseFeature.StatusCode);

            // With no query string should return 400
            requestFeature = new HttpRequestFeature
            {
                Path        = "/user/path/negotiate/",
                QueryString = "?endpoint=notexists"
            };

            responseFeature = new HttpResponseFeature();
            features.Set <IHttpRequestFeature>(requestFeature);
            features.Set <IHttpResponseFeature>(responseFeature);
            httpContext = new DefaultHttpContext(features);

            handler = serviceProvider.GetRequiredService <NegotiateHandler>();
            await Assert.ThrowsAsync <InvalidOperationException>(() => handler.Process(httpContext, "chat"));
        }
示例#19
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FtpConnection"/> class.
        /// </summary>
        /// <param name="socketAccessor">The accessor to get the socket used to communicate with the client.</param>
        /// <param name="options">The options for the FTP connection.</param>
        /// <param name="portOptions">The <c>PORT</c> command options.</param>
        /// <param name="connectionAccessor">The accessor to get the connection that is active during the <see cref="FtpCommandHandler.Process"/> method execution.</param>
        /// <param name="catalogLoader">The catalog loader for the FTP server.</param>
        /// <param name="serverCommandExecutor">The executor for server commands.</param>
        /// <param name="serviceProvider">The service provider for the connection.</param>
        /// <param name="secureDataConnectionWrapper">Wraps a data connection into an SSL stream.</param>
        /// <param name="sslStreamWrapperFactory">The SSL stream wrapper factory.</param>
        /// <param name="logger">The logger for the FTP connection.</param>
        /// <param name="loggerFactory">The logger factory.</param>
        public FtpConnection(
            TcpSocketClientAccessor socketAccessor,
            IOptions <FtpConnectionOptions> options,
            IOptions <PortCommandOptions> portOptions,
            IFtpConnectionAccessor connectionAccessor,
            IFtpCatalogLoader catalogLoader,
            IServerCommandExecutor serverCommandExecutor,
            IServiceProvider serviceProvider,
            SecureDataConnectionWrapper secureDataConnectionWrapper,
            ISslStreamWrapperFactory sslStreamWrapperFactory,
            ILogger <FtpConnection>?logger = null,
            ILoggerFactory?loggerFactory   = null)
        {
            var socket = socketAccessor.TcpSocketClient ?? throw new InvalidOperationException("The socket to communicate with the client was not set");

            ConnectionServices = serviceProvider;

            ConnectionId = "FTP-" + Guid.NewGuid().ToString("N");

            _dataPort = portOptions.Value.DataPort;
#pragma warning disable 612
            _keepAlive = new FtpConnectionKeepAlive(this);
#pragma warning restore 612
            _idleCheck = new IdleCheck(this);
            var remoteEndPoint = _remoteEndPoint = (IPEndPoint)socket.Client.RemoteEndPoint;
#pragma warning disable 618
            RemoteAddress = new Address(remoteEndPoint.Address.ToString(), remoteEndPoint.Port);
#pragma warning restore 618

            var properties = new Dictionary <string, object?>
            {
                ["RemoteAddress"] = remoteEndPoint.ToString(),
                ["RemoteIp"]      = remoteEndPoint.Address.ToString(),
                ["RemotePort"]    = remoteEndPoint.Port,
                ["ConnectionId"]  = ConnectionId,
            };

            _loggerScope = logger?.BeginScope(properties);

            _socket                      = socket;
            _connectionAccessor          = connectionAccessor;
            _serverCommandExecutor       = serverCommandExecutor;
            _secureDataConnectionWrapper = secureDataConnectionWrapper;
            _serverCommandChannel        = Channel.CreateBounded <IServerCommand>(new BoundedChannelOptions(3));

            _logger = logger;

            var parentFeatures    = new FeatureCollection();
            var connectionFeature = new ConnectionFeature(
                (IPEndPoint)socket.Client.LocalEndPoint,
                remoteEndPoint);
            var secureConnectionFeature = new SecureConnectionFeature();

            var applicationInputPipe  = new Pipe();
            var applicationOutputPipe = new Pipe();
            var socketPipe            = new DuplexPipe(_socketCommandPipe.Reader, _socketResponsePipe.Writer);
            var connectionPipe        = new DuplexPipe(applicationOutputPipe.Reader, applicationInputPipe.Writer);

            var originalStream = socketAccessor.TcpSocketStream ?? socket.GetStream();
            _streamReaderService = new ConnectionClosingNetworkStreamReader(
                originalStream,
                _socketCommandPipe.Writer,
                _cancellationTokenSource,
                loggerFactory?.CreateLogger($"{nameof(StreamPipeWriterService)}:Socket:Receive"));
            _streamWriterService = new StreamPipeWriterService(
                originalStream,
                _socketResponsePipe.Reader,
                _cancellationTokenSource.Token,
                loggerFactory?.CreateLogger($"{nameof(StreamPipeWriterService)}:Socket:Transmit"));

            _networkStreamFeature = new NetworkStreamFeature(
                new SecureConnectionAdapter(
                    socketPipe,
                    connectionPipe,
                    sslStreamWrapperFactory,
                    _cancellationTokenSource.Token,
                    loggerFactory),
                applicationOutputPipe.Writer);

            parentFeatures.Set <IConnectionFeature>(connectionFeature);
            parentFeatures.Set <ISecureConnectionFeature>(secureConnectionFeature);
            parentFeatures.Set <IServerCommandFeature>(new ServerCommandFeature(_serverCommandChannel));
            parentFeatures.Set <INetworkStreamFeature>(_networkStreamFeature);
            parentFeatures.Set <IFtpConnectionEventHost>(this);
            parentFeatures.Set <IFtpConnectionStatusCheck>(_idleCheck);
#pragma warning disable 618
#pragma warning disable 612
            parentFeatures.Set <IFtpConnectionKeepAlive>(_keepAlive);
#pragma warning restore 612
#pragma warning restore 618

            var features = new FeatureCollection(parentFeatures);
#pragma warning disable 618
            Data = new FtpConnectionData(
                options.Value.DefaultEncoding ?? Encoding.ASCII,
                features,
                catalogLoader);
#pragma warning restore 618

            Features = features;

            _commandReader = ReadCommandsFromPipeline(
                applicationInputPipe.Reader,
                _ftpCommandChannel.Writer,
                _cancellationTokenSource.Token);
        }
        public async Task <AckResult> HandleMessageTask(IHandledMessage message)
        {
            if (_cancellationToken.IsCancellationRequested)
            {
                return(AckResult.NackRequeue);
            }
            try
            {
                var bytes = message.Body;

                //note: This may not be the correct way to implement the FeatureCollection.  In most of the available samples,
                //features are static and the HttpContext is customized so it can be manipulated directly within this method.
                //For the time being, this approach is very easy and provides better decoupling.  When things get more complicated
                //we may revert to the other approach.

                //Typical webserver is a lot more complicated because it needs to handle the http protocol.HttpProtocol.ProcessRequests
                //and can handle multiple requests via the same connection.  MsgNThen is entirely reliant on RabbitMQ client to handle all
                //such issues.
                //The Protocol can't directly access the HttpContext itself (which is really strange at first glance). Instead it implements
                //"IFeature"s that the HttpContext uses to implement its properties.

                var requestFeatures       = new FeatureCollection();
                var messageRequestFeature = new HttpRequestFeature
                {
                    Path = $"/{message.RoutingKey}",
                    //fix: use MemoryStream.WriteAsync(ReadOnlyMemory<Byte>)
                    Body    = new MemoryStream(bytes.ToArray()),
                    Method  = "GET",
                    Headers = new HeaderDictionary(),
                };
                if (message.Properties.Headers != null)
                {
                    foreach (var property in message.Properties.Headers)
                    {
                        messageRequestFeature.Headers[property.Key] = property.Value?.ToString();
                    }
                }

                var groupInfo = GetMessageGroupInfo(message);


                messageRequestFeature.Headers[HeaderConstants.MessageId]     = message.Properties.MessageId;
                messageRequestFeature.Headers[HeaderConstants.AppId]         = message.Properties.AppId;
                messageRequestFeature.Headers[HeaderConstants.ReplyTo]       = message.Properties.ReplyTo;
                messageRequestFeature.Headers[HeaderConstants.CorrelationId] = message.Properties.CorrelationId;
                //note: https://www.rabbitmq.com/validated-user-id.html
                messageRequestFeature.Headers[HeaderConstants.UserId]  = message.Properties.UserId;
                messageRequestFeature.Headers.ContentLength            = message.Body.Length;
                messageRequestFeature.Headers[HeaderNames.ContentType] = message.Properties.ContentType;

                var responseStream      = new MemoryStream();
                var responseBody        = new StreamResponseBodyFeature(responseStream);
                var httpResponseFeature = new HttpResponseFeature()
                {
                    Body = responseStream
                };
                requestFeatures.Set <IHttpResponseBodyFeature>(responseBody);
                requestFeatures.Set <IHttpRequestFeature>(messageRequestFeature);
                requestFeatures.Set <IHttpResponseFeature>(httpResponseFeature);
                var context = _application.CreateContext(requestFeatures);
                await _application.ProcessRequestAsync(context);

                if (groupInfo != null)
                {
                    _messageGroupHandler.MessageHandled(groupInfo.Value.messageGroupId, groupInfo.Value.messageId);
                }

                if (responseStream.Length > 0)
                {
                    if (groupInfo != null)
                    {
                        //when the application populated the response we could either
                        // - store this information so that the andThen processor can pick it up later or
                        // - stream this request as data to the ReplyTo address for the same reason.
                        //use Redis and S3 as result stores so that the final andThen can use the data collected from
                        //those requests.
                    }
                    else
                    {
                        //since this isn't an andThen request, we should send this to the ReplyTo address
                        //todo: XXXX implement result forwarding (using something like IAndThenMessageDeliverer)
                    }
                    //any/all of the above scenarios are handled by the following interface by using the
                    //replyHandler to interpret the response and the message.Properties.ReplyTo address.
                }

                return(AckResult.Ack);
            }
            catch (Exception e)
            {
                _logger.LogError(e, "HandleMessageTask Failed");
                return(AckResult.NackQuit);
            }
        }
示例#21
0
        /// <summary>
        /// Invokes single request.
        /// </summary>
        /// <param name="httpContext">Source batch request context.</param>
        /// <param name="requestObj">Single request object.</param>
        /// <returns>Single response objects.</returns>
        private async Task <JObject> InvokeSingleAsync(HttpContext httpContext, JObject requestObj)
        {
            var contextFeatures = new FeatureCollection(httpContext.Features);

            var requestFeature = new HttpRequestFeature()
            {
                Body        = new MemoryStream(Encoding.UTF8.GetBytes(requestObj.ToString())),
                Headers     = httpContext.Request.Headers,
                Method      = httpContext.Request.Method,
                Protocol    = httpContext.Request.Protocol,
                Scheme      = httpContext.Request.Scheme,
                QueryString = httpContext.Request.QueryString.Value
            };

            contextFeatures.Set <IHttpRequestFeature>(requestFeature);

            var responseMemoryStream = new MemoryStream();
            var responseFeature      = new StreamResponseBodyFeature(responseMemoryStream);

            contextFeatures.Set <IHttpResponseFeature>(new HttpResponseFeature());
            contextFeatures.Set <IHttpResponseBodyFeature>(responseFeature);

            contextFeatures.Set <IHttpRequestLifetimeFeature>(new HttpRequestLifetimeFeature());

            var     context = this.httpContextFactory.Create(contextFeatures);
            JObject response;

            try
            {
                await this.next.Invoke(context).ConfigureAwait(false);

                if (responseMemoryStream.Length == 0)
                {
                    throw new Exception("Method not found");
                }

                responseMemoryStream.Position = 0;
                using (var streamReader = new StreamReader(responseMemoryStream))
                    using (var textReader = new JsonTextReader(streamReader))
                    {
                        // Ensure floats are parsed as decimals and not as doubles.
                        textReader.FloatParseHandling = FloatParseHandling.Decimal;
                        response = await JObject.LoadAsync(textReader);
                    }
            }
            catch (Exception ex)
            {
                await this.HandleRpcInvokeExceptionAsync(context, ex);

                context.Response.Body.Position = 0;
                using (var streamReader = new StreamReader(context.Response.Body, Encoding.Default, true, 1024, true))
                    using (var textReader = new JsonTextReader(streamReader))
                    {
                        // Ensure floats are parsed as decimals and not as doubles.
                        textReader.FloatParseHandling = FloatParseHandling.Decimal;

                        string val = streamReader.ReadToEnd();
                        context.Response.Body.Position = 0;
                        response = await JObject.LoadAsync(textReader);
                    }
            }

            if (requestObj.ContainsKey("id"))
            {
                response["id"] = requestObj["id"];
            }
            else
            {
                response.Remove("id");
            }

            return(response);
        }
        public static T GetController <T>(long userId = 0, RouteData routeData = null, params object[] dbObjects)
        {
            //Create Inversion of Control container
            DIContainer = BuildContainerIoC(dbObjects);

            //Mock UserId as claim
            var claims = new List <Claim>();

            if (userId < 0)
            {
                User user = dbObjects.OfType <User>().FirstOrDefault();
                if (user == null)
                {
                    foreach (object item in dbObjects)
                    {
                        var enumerable = item as IEnumerable <object>;
                        if (enumerable != null)
                        {
                            user = enumerable.OfType <User>().FirstOrDefault();
                            if (user != null)
                            {
                                break;
                            }
                        }
                    }
                }

                userId = user.UserId;
            }


            if (userId != 0)
            {
                claims.Add(new Claim("sub", userId.ToString()));
            }

            var mockPrincipal = new Mock <ClaimsPrincipal>();

            mockPrincipal.Setup(m => m.Claims).Returns(claims);
            mockPrincipal.Setup(m => m.Identity.IsAuthenticated).Returns(userId > 0);
            if (userId > 0)
            {
                mockPrincipal.Setup(m => m.Identity.Name).Returns(userId.ToString());
            }

            //Set the Remote IP Address
            var features = new FeatureCollection();

            features.Set <IHttpConnectionFeature>(new HttpConnectionFeature {
                RemoteIpAddress = IPAddress.Parse("127.0.0.1")
            });

            //Mock HttpRequest
            var requestMock = new Mock <HttpRequest>();

            var httpContext    = new DefaultHttpContext();
            var requestCookies = httpContext.Request.Cookies.Append(new KeyValuePair <string, string>("cookie_settings", JsonConvert.SerializeObject(
                                                                                                          new CookieSettings
            {
                GoogleAnalyticsGpg   = true,
                GoogleAnalyticsGovUk = true,
                ApplicationInsights  = true,
                RememberSettings     = true
            }))) as IRequestCookieCollection;


            var requestHeaders = new HeaderDictionary();

            //requestMock.Setup(x => x.GetUri()).Returns(Uri);
            //var requestCookies = new RequestCookieCollection(
            //    new Dictionary<string, string> {
            //        {
            //            "cookie_settings",
            //            JsonConvert.SerializeObject(
            //                new CookieSettings {
            //                    GoogleAnalyticsGpg = true, GoogleAnalyticsGovUk = true, ApplicationInsights = true, RememberSettings = true
            //                })
            //        }
            //    });

            requestMock.SetupGet(x => x.Cookies).Returns(requestCookies);
            requestMock.SetupGet(x => x.Headers).Returns(requestHeaders);

            //Done:Added the queryString Dictionary property for mock object
            var queryString = new QueryString("?code=abcdefg");

            requestMock.SetupGet(x => x.QueryString).Returns(queryString);

            var query = new QueryCollection();

            //Mock HttpResponse
            var responseMock    = new Mock <HttpResponse>();
            var responseHeaders = new HeaderDictionary();
            var responseCookies = new Mock <IResponseCookies>();

            responseCookies.Setup(c => c.Append(It.IsAny <string>(), It.IsAny <string>())).Verifiable();
            responseCookies.Setup(c => c.Append(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <CookieOptions>())).Verifiable();
            responseCookies.Setup(c => c.Delete(It.IsAny <string>())).Verifiable();
            responseCookies.Setup(c => c.Delete(It.IsAny <string>(), It.IsAny <CookieOptions>())).Verifiable();
            responseMock.SetupGet(x => x.Headers).Returns(responseHeaders);
            responseMock.SetupGet(x => x.Cookies).Returns(responseCookies.Object);

            //Mock session
            var uri = new UriBuilder(Uri);

            //Mock HttpContext
            var httpContextMock = new Mock <HttpContext>();

            //contextMock.Setup(m => m.Cache).Returns(HttpRuntime.Cache);
            httpContextMock.Setup(ctx => ctx.User).Returns(mockPrincipal.Object);
            httpContextMock.SetupGet(ctx => ctx.Request.Headers).Returns(requestHeaders);
            httpContextMock.SetupGet(ctx => ctx.Request).Returns(requestMock.Object);
            httpContextMock.SetupGet(ctx => ctx.Request.Cookies).Returns(requestCookies);
            httpContextMock.SetupGet(ctx => ctx.Request.QueryString).Returns(queryString);
            httpContextMock.SetupGet(ctx => ctx.Request.Query).Returns(query);
            httpContextMock.SetupGet(ctx => ctx.Request.HttpContext).Returns(httpContextMock.Object);
            //contextMock.SetupGet(ctx => ctx.Request.GetUri()).Returns(Uri);
            //contextMock.Setup(ctx => ctx.GetUserHostAddress()).Returns("127.0.0.1");
            httpContextMock.SetupGet(ctx => ctx.Request.Scheme).Returns(uri.Scheme);
            httpContextMock.SetupGet(ctx => ctx.Request.Host).Returns(new HostString(uri.Host, uri.Port));
            httpContextMock.SetupGet(ctx => ctx.Request.Path).Returns(uri.Path);
            httpContextMock.SetupGet(ctx => ctx.Request.QueryString).Returns(new QueryString(uri.Query));

            httpContextMock.SetupGet(ctx => ctx.Response).Returns(responseMock.Object);
            httpContextMock.SetupGet(ctx => ctx.Response.Cookies).Returns(responseCookies.Object);
            httpContextMock.SetupGet(ctx => ctx.Response.Headers).Returns(responseHeaders);
            httpContextMock.SetupGet(ctx => ctx.Response.HttpContext).Returns(httpContextMock.Object);
            httpContextMock.SetupGet(ctx => ctx.Session).Returns(new MockHttpSession());
            httpContextMock.SetupGet(ctx => ctx.Features).Returns(features);

            //Mock the httpcontext to the controllercontext

            //var controllerContextMock = new Mock<ControllerContext>();
            var controllerContextMock = new ControllerContext {
                HttpContext = httpContextMock.Object, RouteData = routeData
            };

            if (routeData == null)
            {
                routeData = new RouteData();
            }

            //Mock IHttpContextAccessor
            Mock <IHttpContextAccessor> mockHttpContextAccessor = DIContainer.Resolve <IHttpContextAccessor>().GetMockFromObject();

            mockHttpContextAccessor.SetupGet(a => a.HttpContext).Returns(httpContextMock.Object);

            //Create and return the controller
            var controller = DIContainer.Resolve <T>();

            if (controller is BaseController baseController)
            {
                baseController.ControllerContext = controllerContextMock;

                var mockTempDataSerializer = new Mock <TempDataSerializer>();

                //Setup temp data
                baseController.TempData = new TempDataDictionary(httpContextMock.Object, new SessionStateTempDataProvider(mockTempDataSerializer.Object));

                //Setup the mockUrlHelper for the controller with the calling action from the Route Data
                if (baseController.RouteData != null &&
                    baseController.RouteData.Values.ContainsKey("Action") &&
                    !string.IsNullOrWhiteSpace(baseController.RouteData.Values["Action"].ToStringOrNull()))
                {
                    baseController.AddMockUriHelper(uri.ToString());
                }

                return((T)Convert.ChangeType(baseController, typeof(T)));
            }

            return(controller);
        }
        private static HttpContext CloneHttpContext(HttpContext context)
        {
            // The reason we're copying the base features instead of the HttpContext properties is
            // so that we can get all of the logic built into DefaultHttpContext to extract higher level
            // structure from the low level properties
            var existingRequestFeature = context.Features.Get <IHttpRequestFeature>();

            var requestFeature = new HttpRequestFeature();

            requestFeature.Protocol    = existingRequestFeature.Protocol;
            requestFeature.Method      = existingRequestFeature.Method;
            requestFeature.Scheme      = existingRequestFeature.Scheme;
            requestFeature.Path        = existingRequestFeature.Path;
            requestFeature.PathBase    = existingRequestFeature.PathBase;
            requestFeature.QueryString = existingRequestFeature.QueryString;
            requestFeature.RawTarget   = existingRequestFeature.RawTarget;
            var requestHeaders = new Dictionary <string, StringValues>(existingRequestFeature.Headers.Count, StringComparer.OrdinalIgnoreCase);

            foreach (var header in existingRequestFeature.Headers)
            {
                requestHeaders[header.Key] = header.Value;
            }
            requestFeature.Headers = new HeaderDictionary(requestHeaders);

            var existingConnectionFeature = context.Features.Get <IHttpConnectionFeature>();
            var connectionFeature         = new HttpConnectionFeature();

            if (existingConnectionFeature != null)
            {
                connectionFeature.ConnectionId    = existingConnectionFeature.ConnectionId;
                connectionFeature.LocalIpAddress  = existingConnectionFeature.LocalIpAddress;
                connectionFeature.LocalPort       = existingConnectionFeature.LocalPort;
                connectionFeature.RemoteIpAddress = existingConnectionFeature.RemoteIpAddress;
                connectionFeature.RemotePort      = existingConnectionFeature.RemotePort;
            }

            // The response is a dud, you can't do anything with it anyways
            var responseFeature = new HttpResponseFeature();

            var features = new FeatureCollection();

            features.Set <IHttpRequestFeature>(requestFeature);
            features.Set <IHttpResponseFeature>(responseFeature);
            features.Set <IHttpResponseBodyFeature>(new StreamResponseBodyFeature(Stream.Null));
            features.Set <IHttpConnectionFeature>(connectionFeature);

            // REVIEW: We could strategically look at adding other features but it might be better
            // if we expose a callback that would allow the user to preserve HttpContext properties.

            var newHttpContext = new DefaultHttpContext(features);

            newHttpContext.TraceIdentifier = context.TraceIdentifier;

            var endpointFeature = context.Features.Get <IEndpointFeature>();

            newHttpContext.SetEndpoint(endpointFeature?.Endpoint);

            CloneUser(newHttpContext, context);

            // Making request services function property could be tricky and expensive as it would require
            // DI scope per connection. It would also mean that services resolved in middleware leading up to here
            // wouldn't be the same instance (but maybe that's fine). For now, we just return an empty service provider
            newHttpContext.RequestServices = EmptyServiceProvider.Instance;

            // REVIEW: This extends the lifetime of anything that got put into HttpContext.Items
            newHttpContext.Items = new Dictionary <object, object>(context.Items);
            return(newHttpContext);
        }
示例#24
0
            public RequestState(Uri uri, PathString pathBase, CancellationToken cancellationToken, IHttpApplication<Context> application)
            {
                _clientWebSocketTcs = new TaskCompletionSource<WebSocket>();
                _application = application;

                // HttpContext
                var contextFeatures = new FeatureCollection();
                contextFeatures.Set<IHttpRequestFeature>(new RequestFeature());
                contextFeatures.Set<IHttpResponseFeature>(new ResponseFeature());
                Context = _application.CreateContext(contextFeatures);
                var httpContext = Context.HttpContext;

                // Request
                var request = httpContext.Request;
                request.Protocol = "HTTP/1.1";
                var scheme = uri.Scheme;
                scheme = (scheme == "ws") ? "http" : scheme;
                scheme = (scheme == "wss") ? "https" : scheme;
                request.Scheme = scheme;
                request.Method = "GET";
                var fullPath = PathString.FromUriComponent(uri);
                PathString remainder;
                if (fullPath.StartsWithSegments(pathBase, out remainder))
                {
                    request.PathBase = pathBase;
                    request.Path = remainder;
                }
                else
                {
                    request.PathBase = PathString.Empty;
                    request.Path = fullPath;
                }
                request.QueryString = QueryString.FromUriComponent(uri);
                request.Headers.Add("Connection", new string[] { "Upgrade" });
                request.Headers.Add("Upgrade", new string[] { "websocket" });
                request.Headers.Add("Sec-WebSocket-Version", new string[] { "13" });
                request.Headers.Add("Sec-WebSocket-Key", new string[] { CreateRequestKey() });
                request.Body = Stream.Null;

                // Response
                var response = httpContext.Response;
                response.Body = Stream.Null;
                response.StatusCode = 200;

                // WebSocket
                httpContext.Features.Set<IHttpWebSocketFeature>(this);
            }
示例#25
0
            internal RequestState(HttpRequestMessage request, PathString pathBase, IHttpApplication <Context> application)
            {
                _request              = request;
                _application          = application;
                _responseTcs          = new TaskCompletionSource <HttpResponseMessage>();
                _requestAbortedSource = new CancellationTokenSource();
                _pipelineFinished     = false;

                if (request.RequestUri.IsDefaultPort)
                {
                    request.Headers.Host = request.RequestUri.Host;
                }
                else
                {
                    request.Headers.Host = request.RequestUri.GetComponents(UriComponents.HostAndPort, UriFormat.UriEscaped);
                }

                var contextFeatures = new FeatureCollection();

                contextFeatures.Set <IHttpRequestFeature>(new RequestFeature());
                _responseFeature = new ResponseFeature();
                contextFeatures.Set <IHttpResponseFeature>(_responseFeature);
                Context = application.CreateContext(contextFeatures);
                var httpContext = Context.HttpContext;

                var serverRequest = httpContext.Request;

                serverRequest.Protocol = "HTTP/" + request.Version.ToString(2);
                serverRequest.Scheme   = request.RequestUri.Scheme;
                serverRequest.Method   = request.Method.ToString();

                var        fullPath = PathString.FromUriComponent(request.RequestUri);
                PathString remainder;

                if (fullPath.StartsWithSegments(pathBase, out remainder))
                {
                    serverRequest.PathBase = pathBase;
                    serverRequest.Path     = remainder;
                }
                else
                {
                    serverRequest.PathBase = PathString.Empty;
                    serverRequest.Path     = fullPath;
                }

                serverRequest.QueryString = QueryString.FromUriComponent(request.RequestUri);

                foreach (var header in request.Headers)
                {
                    serverRequest.Headers.Append(header.Key, header.Value.ToArray());
                }
                var requestContent = request.Content;

                if (requestContent != null)
                {
                    foreach (var header in request.Content.Headers)
                    {
                        serverRequest.Headers.Append(header.Key, header.Value.ToArray());
                    }
                }

                _responseStream                 = new ResponseStream(ReturnResponseMessage, AbortRequest);
                httpContext.Response.Body       = _responseStream;
                httpContext.Response.StatusCode = 200;
                httpContext.RequestAborted      = _requestAbortedSource.Token;
            }
        private Mock <HttpContext> GetMockContext(string path)
        {
            var contextMock = new Mock <HttpContext>(MockBehavior.Strict);

            contextMock
            .SetupGet(c => c.Request.Path)
            .Returns(new PathString(path));
            contextMock
            .SetupGet(c => c.Request.Host)
            .Returns(new HostString("localhost"));
            contextMock
            .SetupGet(c => c.Request.ContentType)
            .Returns("");
            contextMock
            .SetupGet(c => c.Request.Scheme)
            .Returns("http");
            contextMock
            .SetupGet(c => c.Request.Scheme)
            .Returns("http");
            contextMock
            .SetupGet(c => c.Response.StatusCode)
            .Returns(200);
            contextMock
            .SetupGet(c => c.Response.Body)
            .Returns(new Mock <Stream>().Object);
            contextMock
            .SetupGet(c => c.User)
            .Returns(new ClaimsPrincipal());
            contextMock
            .SetupGet(c => c.Request.Method)
            .Returns("GET");
            contextMock
            .SetupGet(c => c.Request.Protocol)
            .Returns("HTTP/1.1");
            contextMock
            .SetupGet(c => c.Request.Headers)
            .Returns(new Mock <IHeaderDictionary>().Object);
            contextMock
            .SetupGet(c => c.Request.QueryString)
            .Returns(new QueryString());
            contextMock
            .SetupGet(c => c.Request.Query)
            .Returns(new Mock <IReadableStringCollection>().Object);
            contextMock
            .SetupGet(c => c.Request.Cookies)
            .Returns(new Mock <IReadableStringCollection>().Object);
            contextMock
            .Setup(c => c.Request.ReadFormAsync(It.IsAny <System.Threading.CancellationToken>()))
            .Returns(Task.FromResult(new Mock <IFormCollection>().Object));
            contextMock
            .Setup(c => c.Request.HasFormContentType)
            .Returns(true);
            var requestIdentifier = new Mock <IHttpRequestIdentifierFeature>();

            requestIdentifier.Setup(f => f.TraceIdentifier).Returns(Guid.NewGuid().ToString());
            var featureCollection = new FeatureCollection();

            featureCollection.Set <IHttpRequestIdentifierFeature>(requestIdentifier.Object);
            contextMock
            .SetupGet(c => c.Features)
            .Returns(featureCollection);
            return(contextMock);
        }
示例#27
0
        public async Task PostMultiGet()
        {
            using (ContextPool.AllocateOperationContext(out JsonOperationContext context))
            {
                var input = await context.ReadForMemoryAsync(RequestBodyStream(), "multi_get");

                if (input.TryGet("Requests", out BlittableJsonReaderArray requests) == false)
                {
                    ThrowRequiredPropertyNameInRequest("Requests");
                }

                using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                {
                    writer.WriteStartObject();
                    writer.WritePropertyName("Results");
                    writer.WriteStartArray();
                    var resultProperty  = context.GetLazyStringForFieldWithCaching(nameof(GetResponse.Result));
                    var statusProperty  = context.GetLazyStringForFieldWithCaching(nameof(GetResponse.StatusCode));
                    var headersProperty = context.GetLazyStringForFieldWithCaching(nameof(GetResponse.Headers));

                    var features       = new FeatureCollection(HttpContext.Features);
                    var responseStream = new MultiGetHttpResponseStream(ResponseBodyStream());
                    features.Set <IHttpResponseFeature>(new MultiGetHttpResponseFeature(responseStream));
                    var httpContext = new DefaultHttpContext(features);

                    for (int i = 0; i < requests.Length; i++)
                    {
                        var request = (BlittableJsonReaderObject)requests[i];

                        if (i != 0)
                        {
                            writer.WriteComma();
                        }
                        writer.WriteStartObject();

                        if (request.TryGet("Url", out string url) == false || request.TryGet("Query", out string query) == false)
                        {
                            writer.WriteEndObject();
                            continue;
                        }

                        if (request.TryGet("Method", out string method) == false || string.IsNullOrEmpty(method))
                        {
                            method = HttpMethod.Get.Method;
                        }

                        httpContext.Request.Method = method;

                        var routeInformation = Server.Router.GetRoute(method, url, out RouteMatch localMatch);
                        if (routeInformation == null)
                        {
                            writer.WritePropertyName(statusProperty);
                            writer.WriteInteger((int)HttpStatusCode.BadRequest);
                            writer.WritePropertyName(resultProperty);
                            context.Write(writer, new DynamicJsonValue
                            {
                                ["Error"] = $"There is no handler for path: {method} {url}{query}"
                            });
                            writer.WriteEndObject();
                            continue;
                        }

                        var requestHandler = routeInformation.GetRequestHandler();
                        writer.WritePropertyName(resultProperty);
                        writer.Flush();

                        httpContext.Response.StatusCode = 0;
                        httpContext.Request.Headers.Clear();
                        httpContext.Response.Headers.Clear();
                        httpContext.Request.QueryString = new QueryString(query);
                        if (request.TryGet("Headers", out BlittableJsonReaderObject headers))
                        {
                            foreach (var header in headers.GetPropertyNames())
                            {
                                if (headers.TryGet(header, out string value) == false)
                                {
                                    continue;
                                }

                                if (string.IsNullOrWhiteSpace(value))
                                {
                                    continue;
                                }

                                httpContext.Request.Headers.Add(header, value);
                            }
                        }

                        if (method == HttpMethod.Post.Method && request.TryGet("Content", out object content))
                        {
                            if (content is LazyStringValue)
                            {
                                var requestBody = GetRequestBody(content.ToString());
                                HttpContext.Response.RegisterForDispose(requestBody);
                                httpContext.Request.Body = requestBody;
                            }
                            else
                            {
                                var requestBody   = new MemoryStream();
                                var contentWriter = new BlittableJsonTextWriter(context, requestBody);
                                context.Write(contentWriter, (BlittableJsonReaderObject)content);
                                contentWriter.Flush();
                                HttpContext.Response.RegisterForDispose(requestBody);
                                httpContext.Request.Body          = requestBody;
                                httpContext.Request.Body.Position = 0;
                            }
                        }

                        var bytesWrittenBeforeRequest = responseStream.BytesWritten;
                        int statusCode;
                        try
                        {
                            await requestHandler(new RequestHandlerContext
                            {
                                Database    = Database,
                                RavenServer = Server,
                                RouteMatch  = localMatch,
                                HttpContext = httpContext
                            });

                            if (bytesWrittenBeforeRequest == responseStream.BytesWritten)
                            {
                                writer.WriteNull();
                            }

                            statusCode = httpContext.Response.StatusCode == 0
                                ? (int)HttpStatusCode.OK
                                : httpContext.Response.StatusCode;
                        }
                        catch (Exception e)
                        {
                            if (bytesWrittenBeforeRequest != responseStream.BytesWritten)
                            {
                                throw;
                            }

                            statusCode = (int)HttpStatusCode.InternalServerError;

                            var djv = new DynamicJsonValue
                            {
                                [nameof(ExceptionDispatcher.ExceptionSchema.Url)]     = $"{url}{query}",
                                [nameof(ExceptionDispatcher.ExceptionSchema.Type)]    = e.GetType().FullName,
                                [nameof(ExceptionDispatcher.ExceptionSchema.Message)] = e.Message,
                                [nameof(ExceptionDispatcher.ExceptionSchema.Error)]   = e.ToString()
                            };

                            using (var json = context.ReadObject(djv, "exception"))
                                writer.WriteObject(json);
                        }

                        writer.WriteComma();
                        writer.WritePropertyName(statusProperty);
                        writer.WriteInteger(statusCode);
                        writer.WriteComma();

                        writer.WritePropertyName(headersProperty);
                        writer.WriteStartObject();
                        bool headerStart = true;
                        foreach (var header in httpContext.Response.Headers)
                        {
                            foreach (var value in header.Value)
                            {
                                if (headerStart == false)
                                {
                                    writer.WriteComma();
                                }
                                headerStart = false;
                                writer.WritePropertyName(header.Key);
                                writer.WriteString(value);
                            }
                        }
                        writer.WriteEndObject();

                        writer.WriteEndObject();
                    }
                    writer.WriteEndArray();
                    writer.WriteEndObject();
                }
            }
        }