public void If_connects_after_disposal_should_redispose_underlying_connection()
        {
            var logger            = MockRepository.GenerateMock <IEasyNetQLogger>();
            var eventBus          = MockRepository.GenerateMock <IEventBus>();
            var connectionFactory = MockRepository.GenerateMock <IConnectionFactory>();
            var mockConnection    = MockRepository.GenerateMock <IConnection>();
            PersistentConnection mockPersistentConnection = MockRepository.GenerateMock <PersistentConnection>(connectionFactory, logger, eventBus);

            // This test is constructed using small delays, such that the IConnectionFactory will return a connection just _after the IPersistentConnection has been disposed.
            TimeSpan shimDelay = TimeSpan.FromSeconds(0.5);

            connectionFactory.Expect(cf => cf.CreateConnection()).WhenCalled(a =>
            {
                Thread.Sleep(shimDelay.Double());
                a.ReturnValue = mockConnection;
            }).Repeat.Once();

            Task.Factory.StartNew(() => { mockPersistentConnection.Initialize(); }); // Start the persistent connection attempting to connect.

            Thread.Sleep(shimDelay);                                                 // Allow some time for the persistent connection code to try to create a connection.

            // First call to dispose.  Because CreateConnection() is stubbed to delay for shimDelay.Double(), it will not yet have returned a connection.  So when the PersistentConnection is disposed, no underlying IConnection should yet be disposed.
            mockPersistentConnection.Dispose();
            mockConnection.AssertWasNotCalled(underlyingConnection => underlyingConnection.Dispose());

            Thread.Sleep(shimDelay.Double()); // Allow time for persistent connection code to _return its connection ...

            // Assert that the connection returned from connectionFactory.CreateConnection() (_after the PersistentConnection was disposed), still gets disposed.
            mockConnection.AssertWasCalled(latedCreatedUnderlyingConnection => latedCreatedUnderlyingConnection.Dispose());

            // Ensure that PersistentConnection also did not flag (eg to IPersistentChannel) the late-made connection as successful.
            connectionFactory.AssertWasNotCalled(c => c.Success());
            // Ensure that PersistentConnection does not retry after was disposed.
            connectionFactory.AssertWasNotCalled(c => c.Next());
        }
Пример #2
0
        public void Should_retry_connection_for_expected_connection_types_OnConnected(Type exceptionType)
        {
            var mockBuilder = new MockBuilder();

            using (mockBuilder.Bus)
            {
                var first     = true;
                var succeeded = false;
                mockBuilder.ConnectionFactory.Succeeded.Returns(c => succeeded);
                mockBuilder.ConnectionFactory.When(x => x.Success()).Do(c => succeeded = true);
                mockBuilder.ConnectionFactory.Configuration.ConnectIntervalAttempt     = TimeSpan.FromSeconds(1);
                var connection = new PersistentConnection(mockBuilder.ConnectionFactory, mockBuilder.EventBus);
                mockBuilder.EventBus.Subscribe <ConnectionCreatedEvent>(e => {
                    if (first)
                    {
                        first = false;
                        ThrowException(exceptionType);
                    }
                });

                connection.Initialize();
                Thread.Sleep(TimeSpan.FromSeconds(2));
                mockBuilder.ConnectionFactory.Received(3).CreateConnection();
                first.ShouldEqual(false);
            }
        }
Пример #3
0
        public void If_connects_after_disposal_should_redispose_underlying_connection()
        {
            var eventBus          = Substitute.For <IEventBus>();
            var connectionFactory = Substitute.For <IConnectionFactory>();
            var mockConnection    = Substitute.For <IConnection>();
            PersistentConnection mockPersistentConnection = Substitute.For <PersistentConnection>(connectionFactory, eventBus);

            // This test is constructed using small delays, such that the IConnectionFactory will return a connection just _after the IPersistentConnection has been disposed.
            TimeSpan shimDelay = TimeSpan.FromSeconds(0.5);

            connectionFactory.CreateConnection().Returns(a =>
            {
                Thread.Sleep(shimDelay.Double());
                return(mockConnection);
            });

            Task.Factory.StartNew(() => { mockPersistentConnection.Initialize(); }); // Start the persistent connection attempting to connect.

            Thread.Sleep(shimDelay);                                                 // Allow some time for the persistent connection code to try to create a connection.

            // First call to dispose.  Because CreateConnection() is stubbed to delay for shimDelay.Double(), it will not yet have returned a connection.  So when the PersistentConnection is disposed, no underlying IConnection should yet be disposed.
            mockPersistentConnection.Dispose();
            mockConnection.DidNotReceive().Dispose();

            Thread.Sleep(shimDelay.Double()); // Allow time for persistent connection code to _return its connection ...

            // Assert that the connection returned from connectionFactory.CreateConnection() (_after the PersistentConnection was disposed), still gets disposed.
            mockConnection.Received().Dispose();

            // Ensure that PersistentConnection also did not flag (eg to IPersistentChannel) the late-made connection as successful.
            connectionFactory.DidNotReceive().Success();
            // Ensure that PersistentConnection does not retry after was disposed.
            connectionFactory.DidNotReceive().Next();
        }
Пример #4
0
        public Task Invoke(IDictionary <string, object> environment)
        {
            var serverRequest  = new ServerRequest(environment);
            var serverResponse = new ServerResponse(environment);
            var hostContext    = new HostContext(serverRequest, serverResponse);

            // Add CORS support
            var origins = serverRequest.RequestHeaders.GetHeaders("Origin");

            if (origins != null && origins.Any(origin => !String.IsNullOrEmpty(origin)))
            {
                serverResponse.ResponseHeaders["Access-Control-Allow-Origin"]      = origins;
                serverResponse.ResponseHeaders["Access-Control-Allow-Credentials"] = AllowCredentialsTrue;
            }

            hostContext.Items[HostConstants.SupportsWebSockets] = LazyInitializer.EnsureInitialized(
                ref _supportWebSockets,
                ref _supportWebSocketsInitialized,
                ref _supportWebSocketsLock,
                () => environment.SupportsWebSockets());

            hostContext.Items[HostConstants.ShutdownToken] = environment.GetShutdownToken();
            hostContext.Items[HostConstants.DebugMode]     = environment.GetIsDebugEnabled();

            serverRequest.DisableRequestBuffering();
            serverResponse.DisableResponseBuffering();

            _connection.Initialize(_resolver, hostContext);

            return(_connection.ProcessRequestAsync(hostContext));
        }
Пример #5
0
        public Task Invoke(IDictionary <string, object> environment)
        {
            var serverRequest  = new ServerRequest(environment);
            var serverResponse = new ServerResponse(environment);
            var hostContext    = new HostContext(serverRequest, serverResponse);

            string origin = serverRequest.RequestHeaders.GetHeader("Origin");

            if (_configuration.EnableCrossDomain)
            {
                // Add CORS response headers support
                if (!String.IsNullOrEmpty(origin))
                {
                    serverResponse.ResponseHeaders.SetHeader("Access-Control-Allow-Origin", origin);
                    serverResponse.ResponseHeaders.SetHeader("Access-Control-Allow-Credentials", "true");
                }
            }
            else
            {
                string callback = serverRequest.QueryString["callback"];

                // If it's a JSONP request and we're not allowing cross domain requests then block it
                // If there's an origin header and it's not a same origin request then block it.

                if (!String.IsNullOrEmpty(callback) ||
                    (!String.IsNullOrEmpty(origin) && !IsSameOrigin(serverRequest.Url, origin)))
                {
                    return(EndResponse(environment, 403, Resources.Forbidden_CrossDomainIsDisabled));
                }
            }

            // Add the nosniff header for all responses to prevent IE from trying to sniff mime type from contents
            serverResponse.ResponseHeaders.SetHeader("X-Content-Type-Options", "nosniff");

            // REVIEW: Performance
            hostContext.Items[HostConstants.SupportsWebSockets] = environment.SupportsWebSockets();
            hostContext.Items[HostConstants.ShutdownToken]      = environment.GetShutdownToken();
            hostContext.Items[HostConstants.DebugMode]          = environment.GetIsDebugEnabled();

            serverRequest.DisableRequestCompression();
            serverResponse.DisableResponseBuffering();

            _connection.Initialize(_configuration.Resolver, hostContext);

            if (!_connection.Authorize(serverRequest))
            {
                // If we failed to authorize the request then return a 403 since the request
                // can't do anything
                return(EndResponse(environment, 403, "Forbidden"));
            }
            else
            {
                return(_connection.ProcessRequest(hostContext));
            }
        }
Пример #6
0
        public void Should_not_retry_connection_for_unexpected_connection_types()
        {
            var mockBuilder = new MockBuilder();

            using (mockBuilder.Bus)
            {
                mockBuilder.ConnectionFactory.Configuration.ConnectIntervalAttempt = TimeSpan.FromSeconds(1);
                mockBuilder.ConnectionFactory.CreateConnection().Returns(c =>
                {
                    ThrowException(typeof(Exception));
                    return(null);
                });
                var connection = new PersistentConnection(mockBuilder.ConnectionFactory, mockBuilder.EventBus);
                Assert.Throws <Exception>(() => connection.Initialize());
            }
        }
Пример #7
0
        public override Task ProcessRequestAsync(HttpContextBase context)
#endif
        {
            // https://developer.mozilla.org/En/HTTP_Access_Control
            string origin = context.Request.Headers["Origin"];

            if (!String.IsNullOrEmpty(origin))
            {
                context.Response.AddHeader("Access-Control-Allow-Origin", origin);
                context.Response.AddHeader("Access-Control-Allow-Credentials", "true");
            }

            var request     = new AspNetRequest(context);
            var response    = new AspNetResponse(context);
            var hostContext = new HostContext(request, response);

            // Determine if the client should bother to try a websocket request
#if NET45
            hostContext.Items[HostConstants.SupportsWebSockets] = HttpRuntime.IISVersion != null && HttpRuntime.IISVersion.Major >= 8 && !String.IsNullOrEmpty(context.Request.ServerVariables[WebSocketVersionServerVariable]);
#else
            hostContext.Items[HostConstants.SupportsWebSockets] = false;
#endif
            // Set the debugging flag
            hostContext.Items[HostConstants.DebugMode] = context.IsDebuggingEnabled;

            // Set the host shutdown token
            hostContext.Items[HostConstants.ShutdownToken] = AppDomainTokenSource.Token;

            // Stick the context in here so transports or other asp.net specific logic can
            // grab at it.
            hostContext.Items["System.Web.HttpContext"] = context;

            // Initialize the connection
            _connection.Initialize(_resolver, hostContext);

            try
            {
                return(_connection.ProcessRequestAsync(hostContext));
            }
            catch (NotSupportedException)          // WebSockets not supported
            {
                context.Response.StatusCode = 501; // HTTP 501 Not Implemented
                return(TaskAsyncHelper.Empty);
            }
        }
Пример #8
0
        public override Task Invoke(IOwinContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (JsonUtility.TryRejectJSONPRequest(_configuration, context))
            {
                return(TaskAsyncHelper.Empty);
            }

            var connectionFactory           = new PersistentConnectionFactory(_configuration.Resolver);
            PersistentConnection connection = connectionFactory.CreateInstance(_connectionType);

            connection.Initialize(_configuration.Resolver);

            return(connection.ProcessRequest(context.Environment));
        }
Пример #9
0
        public void Should_retry_connection_for_expected_connection_types_CreateConnection(Type exceptionType)
        {
            var mockBuilder = new MockBuilder();

            using (mockBuilder.Bus)
            {
                mockBuilder.ConnectionFactory.Configuration.ConnectIntervalAttempt = TimeSpan.FromSeconds(1);
                mockBuilder.ConnectionFactory.Succeeded.Returns(false, true);
                mockBuilder.ConnectionFactory.CreateConnection().Returns(c =>
                {
                    ThrowException(exceptionType);
                    return(null);
                }, c => mockBuilder.Connection);
                var connection = new PersistentConnection(mockBuilder.ConnectionFactory, mockBuilder.EventBus);
                connection.Initialize();
                connection.IsConnected.ShouldEqual(false);
                Thread.Sleep(TimeSpan.FromSeconds(2));
                connection.IsConnected.ShouldEqual(true);
                mockBuilder.ConnectionFactory.Received(3).CreateConnection();
            }
        }
Пример #10
0
        public Task Invoke(IDictionary <string, object> env)
        {
            var serverRequest  = new ServerRequest(env);
            var serverResponse = new ServerResponse(env);
            var hostContext    = new HostContext(serverRequest, serverResponse);

            var origins = serverRequest.RequestHeaders.GetHeaders("Origin");

            if (origins != null && origins.Any(origin => !String.IsNullOrEmpty(origin)))
            {
                serverResponse.ResponseHeaders["Access-Control-Allow-Origin"]      = origins;
                serverResponse.ResponseHeaders["Access-Control-Allow-Credentials"] = AllowCredentialsTrue;
            }

            hostContext.Items[HostConstants.SupportsWebSockets] = env.ContainsKey(OwinConstants.WebSocketSupport);

            serverRequest.DisableRequestBuffering();
            serverResponse.DisableResponseBuffering();

            _connection.Initialize(_resolver, hostContext);

            return(_connection.ProcessRequestAsync(hostContext));
        }