public void SendUrlTriggersReceivedEvent()
        {
            var tcs = new TaskCompletionSource<string>();
            var request = new Mock<IRequest>();
            var form = new NameValueCollection();
            form["data"] = "This is my data";
            var qs = new NameValueCollection();
            qs["connectionId"] = "1";
            request.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(qs));
            request.Setup(m => m.ReadForm()).Returns(Task.FromResult<INameValueCollection>(new NameValueCollectionWrapper(form)));
            request.Setup(m => m.LocalPath).Returns("/test/echo/send");
            var counters = new Mock<IPerformanceCounterManager>();
            var heartBeat = new Mock<ITransportHeartbeat>();
            var json = JsonUtility.CreateDefaultSerializer();
            var hostContext = new HostContext(request.Object, null);
            var transportConnection = new Mock<ITransportConnection>();
            var traceManager = new Mock<ITraceManager>();
            counters.SetupGet(m => m.ConnectionsConnected).Returns(new NoOpPerformanceCounter());
            traceManager.Setup(m => m[It.IsAny<string>()]).Returns(new System.Diagnostics.TraceSource("foo"));
            var transport = new Mock<ForeverTransport>(hostContext, json, heartBeat.Object, counters.Object, traceManager.Object)
            {
                CallBase = true
            };

            transport.Object.Received = data =>
            {
                tcs.TrySetResult(data);
                return TaskAsyncHelper.Empty;
            };

            transport.Object.ProcessRequest(transportConnection.Object).Wait();

            Assert.Equal("This is my data", tcs.Task.Result);
        }
        public void AbortUrlTriggersConnectionAbort()
        {
            var request = new Mock<IRequest>();
            var qs = new NameValueCollection();
            request.Setup(m => m.QueryString).Returns(qs);
            request.Setup(m => m.Url).Returns(new Uri("http://test/echo/abort"));
            string abortedConnectionId = null;
            var counters = new Mock<IPerformanceCounterManager>();
            var heartBeat = new Mock<ITransportHeartbeat>();
            var json = new JsonNetSerializer();
            var hostContext = new HostContext(request.Object, null);
            var transportConnection = new Mock<ITransportConnection>();
            var traceManager = new Mock<ITraceManager>();
            traceManager.Setup(m => m[It.IsAny<string>()]).Returns(new System.Diagnostics.TraceSource("foo"));
            transportConnection.Setup(m => m.Send(It.IsAny<ConnectionMessage>()))
                               .Callback<ConnectionMessage>(m =>
                               {
                                   abortedConnectionId = m.Signal;
                                   var command = m.Value as Command;
                                   Assert.NotNull(command);
                                   Assert.Equal(CommandType.Abort, command.CommandType);
                               })
                               .Returns(TaskAsyncHelper.Empty);

            var transport = new Mock<ForeverTransport>(hostContext, json, heartBeat.Object, counters.Object, traceManager.Object)
            {
                CallBase = true
            };

            transport.Object.ConnectionId = "1";
            transport.Object.ProcessRequest(transportConnection.Object).Wait();

            Assert.Equal("c-1", abortedConnectionId);
        }
示例#3
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.ProcessRequest(hostContext);
        }
        protected TransportDisconnectBase(HostContext context, ITransportHeartbeat heartbeat, IPerformanceCounterManager performanceCounterManager, ITraceManager traceManager)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (heartbeat == null)
            {
                throw new ArgumentNullException("heartbeat");
            }

            if (performanceCounterManager == null)
            {
                throw new ArgumentNullException("performanceCounterManager");
            }

            if (traceManager == null)
            {
                throw new ArgumentNullException("traceManager");
            }

            _context = context;
            _heartbeat = heartbeat;
            _counters = performanceCounterManager;

            // Queue to protect against overlapping writes to the underlying response stream
            WriteQueue = new TaskQueue();

            _trace = traceManager["SignalR.Transports." + GetType().Name];
        }
        public override Task ProcessRequest(HostContext context)
        {
            string alterWhen = "____Never____";
            int statusCode = 200;

            if (!String.IsNullOrEmpty(context.Request.QueryString["alterWhen"]))
            {
                alterWhen = context.Request.QueryString["alterWhen"];
            }

            if (!String.IsNullOrEmpty(context.Request.QueryString["statusCode"]))
            {
                statusCode = Int32.Parse(context.Request.QueryString["statusCode"]);
            }

            var owinRequest = new OwinRequest(context.Environment);

            if (owinRequest.Path.Value.Contains("/" + alterWhen))
            {
                var response = new OwinResponse(context.Environment);

                // Alter status code
                response.StatusCode = statusCode;

                using (var sw = new StreamWriter(response.Body))
                {
                    sw.WriteLine("Hello world");
                    sw.Flush();
                }

                return TaskAsyncHelper.Empty;
            }

            return base.ProcessRequest(context);
        }
示例#6
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, "Forbidden");
                }
            }

            // 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");

            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.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);
            }
        }
 public LongPollingTransport(HostContext context, IDependencyResolver resolver)
     : this(context,
            resolver.Resolve<IJsonSerializer>(),
            resolver.Resolve<ITransportHeartbeat>(),
            resolver.Resolve<IPerformanceCounterManager>(),
            resolver.Resolve<ITraceManager>())
 {
 }
示例#8
0
 protected ForeverTransport(HostContext context, IDependencyResolver resolver)
     : this(context,
            resolver.Resolve<IJsonSerializer>(),
            resolver.Resolve<ITransportHeartbeat>(),
            resolver.Resolve<IPerformanceCounterManager>(),
            resolver.Resolve<ITraceManager>())
 {
 }
        public void ForeverFrameTransportEscapesTagsWithPersistentResponse(string data, string expected)
        {
            var request = MockRequest();
            var response = new CustomResponse();
            var context = new HostContext(request.Object, response);
            var fft = new ForeverFrameTransport(context, new DefaultDependencyResolver());

            AssertEscaped(fft, response, GetWrappedResponse(data), expected);
        }
示例#10
0
 public WebSocketTransport(HostContext context,
                           IJsonSerializer serializer,
                           ITransportHeartbeat heartbeat,
                           IPerformanceCounterManager performanceCounterWriter,
                           ITraceManager traceManager)
     : base(context, serializer, heartbeat, performanceCounterWriter, traceManager)
 {
     _context = context;
 }
        public void ForeverFrameTransportEscapesTags(string data, string expected)
        {
            var request = new Mock<IRequest>();
            var response = new CustomResponse();
            var context = new HostContext(request.Object, response);
            var fft = new ForeverFrameTransport(context, new DefaultDependencyResolver());

            AssertEscaped(fft, response, data, expected);
        }
        public void AvoidDeadlockIfCancellationTokenTriggeredBeforeSubscribing()
        {
            var response = new Mock<IResponse>();
            response.Setup(m => m.CancellationToken).Returns(CancellationToken.None);
            var request = new Mock<IRequest>();
            var qs = new NameValueCollection();
            qs["connectionId"] = "1";
            request.Setup(m => m.QueryString).Returns(qs);
            request.Setup(m => m.Url).Returns(new Uri("http://test/echo/connect"));
            var counters = new Mock<IPerformanceCounterManager>();
            var heartBeat = new Mock<ITransportHeartbeat>();
            var json = new JsonNetSerializer();
            var hostContext = new HostContext(request.Object, response.Object);
            var transportConnection = new Mock<ITransportConnection>();
            var traceManager = new Mock<ITraceManager>();
            traceManager.Setup(m => m[It.IsAny<string>()]).Returns(new System.Diagnostics.TraceSource("foo"));

            Func<PersistentResponse, object, Task<bool>> callback = null;
            object state = null;

            var disposable = new DisposableAction(() =>
            {
                callback(new PersistentResponse() { Terminal = true }, state);
            });

            transportConnection.Setup(m => m.Receive(It.IsAny<string>(),
                                                     It.IsAny<Func<PersistentResponse, object, Task<bool>>>(),
                                                     It.IsAny<int>(),
                                                     It.IsAny<object>())).Callback<string, Func<PersistentResponse, object, Task<bool>>, int, object>((id, cb, max, st) =>
                                                     {
                                                         callback = cb;
                                                         state = st;
                                                     })
                                                     .Returns(disposable);

            var transport = new Mock<ForeverTransport>(hostContext, json, heartBeat.Object, counters.Object, traceManager.Object)
            {
                CallBase = true
            };

            var wh = new ManualResetEventSlim();

            transport.Object.BeforeCancellationTokenCallbackRegistered = () =>
            {
                // Trip the cancellation token
                transport.Object.End();
            };

            // Act
            Task.Factory.StartNew(() =>
            {
                transport.Object.ProcessRequest(transportConnection.Object);
                wh.Set();
            });

            Assert.True(wh.Wait(TimeSpan.FromSeconds(2)), "Dead lock!");
        }
示例#13
0
 public WebSocketTransport(HostContext context,
                           IDependencyResolver resolver)
     : this(context,
            resolver.Resolve<JsonSerializer>(),
            resolver.Resolve<ITransportHeartbeat>(),
            resolver.Resolve<IPerformanceCounterManager>(),
            resolver.Resolve<ITraceManager>(),
            resolver.Resolve<IConfigurationManager>().MaxIncomingWebSocketMessageSize)
 {
 }
 public LongPollingTransport(HostContext context,
                             IJsonSerializer jsonSerializer,
                             ITransportHeartbeat heartbeat,
                             IPerformanceCounterManager performanceCounterManager,
                             ITraceManager traceManager)
     : base(context, heartbeat, performanceCounterManager, traceManager)
 {
     _jsonSerializer = jsonSerializer;
     _counters = performanceCounterManager;
 }
 public LongPollingTransport(HostContext context,
                             JsonSerializer jsonSerializer,
                             ITransportHeartbeat heartbeat,
                             IPerformanceCounterManager performanceCounterManager,
                             ITraceManager traceManager,
                             IConfigurationManager configurationManager)
     : base(context, jsonSerializer, heartbeat, performanceCounterManager, traceManager)
 {
     _configurationManager = configurationManager;
 }
 private TestLongPollingTransport(
     HostContext context,
     JsonSerializer json,
     ITransportHeartbeat heartBeat,
     IPerformanceCounterManager counters,
     ITraceManager traceManager,
     IConfigurationManager configuarionManager)
     : base(context, json, heartBeat, counters, traceManager, configuarionManager)
 {
 }
示例#17
0
 protected ForeverTransport(HostContext context,
                            IJsonSerializer jsonSerializer,
                            ITransportHeartbeat heartbeat,
                            IPerformanceCounterManager performanceCounterWriter,
                            ITraceManager traceManager)
     : base(context, jsonSerializer, heartbeat, performanceCounterWriter, traceManager)
 {
     _jsonSerializer = jsonSerializer;
     _counters = performanceCounterWriter;
 }
        public void ForeverFrameTransportEscapesTags()
        {
            var request = new Mock<IRequest>();
            var response = new CustomResponse();
            var context = new HostContext(request.Object, response);
            var fft = new ForeverFrameTransport(context, new DefaultDependencyResolver());

            AssertEscaped(fft, response, "</sCRiPT>", "\\u003c/sCRiPT\\u003e");
            AssertEscaped(fft, response, "</SCRIPT dosomething='false'>", "\\u003c/SCRIPT dosomething='false'\\u003e");
            AssertEscaped(fft, response, "<p>ELLO</p>", "\\u003cp\\u003eELLO\\u003c/p\\u003e");
        }
        public void ForeverFrameTransportThrowsOnInvalidFrameId(string frameId)
        {
            var request = new Mock<IRequest>();
            var qs = new NameValueCollection { { "frameId", frameId } };
            request.Setup(r => r.QueryString).Returns(new NameValueCollectionWrapper(qs));
            var response = new CustomResponse();
            var context = new HostContext(request.Object, response);
            var connection = new Mock<ITransportConnection>();
            var fft = new ForeverFrameTransport(context, new DefaultDependencyResolver());

            Assert.Throws(typeof(InvalidOperationException), () => fft.InitializeResponse(connection.Object));
        }
 protected ForeverTransport(HostContext context,
                            JsonSerializer jsonSerializer,
                            ITransportHeartbeat heartbeat,
                            IPerformanceCounterManager performanceCounterManager,
                            ITraceManager traceManager,
                            IMemoryPool pool)
     : base(context, heartbeat, performanceCounterManager, traceManager)
 {
     Pool = pool;
     _jsonSerializer = jsonSerializer;
     _counters = performanceCounterManager;
 }
示例#21
0
 public WebSocketTransport(HostContext context,
                           JsonSerializer serializer,
                           ITransportHeartbeat heartbeat,
                           IPerformanceCounterManager performanceCounterWriter,
                           ITraceManager traceManager)
     : base(context, serializer, heartbeat, performanceCounterWriter, traceManager)
 {
     _context = context;
     _message = OnMessage;
     _closed = OnClosed;
     _error = OnError;
 }
        public void ForeverFrameTransportSetsCorrectContentType()
        {
            var request = new Mock<IRequest>();
            var qs = new NameValueCollection { { "frameId", "1" } };
            request.Setup(r => r.QueryString).Returns(new NameValueCollectionWrapper(qs));
            var response = new CustomResponse();
            var context = new HostContext(request.Object, response);
            var connection = new Mock<ITransportConnection>();
            var fft = new ForeverFrameTransport(context, new DefaultDependencyResolver());

            fft.InitializeResponse(connection.Object).Wait();

            Assert.Equal("text/html; charset=UTF-8", response.ContentType);
        }
            public void UnknownTransportThrows()
            {
                var connection = new Mock<PersistentConnection>() { CallBase = true };
                var req = new Mock<IRequest>();
                req.Setup(m => m.Url).Returns(new Uri("http://foo"));
                var qs = new NameValueCollection();
                req.Setup(m => m.QueryString).Returns(qs);

                var dr = new DefaultDependencyResolver();
                var context = new HostContext(req.Object, null);
                connection.Object.Initialize(dr, context);

                Assert.Throws<InvalidOperationException>(() => connection.Object.ProcessRequest(context));
            }
            public void MissingConnectionTokenThrows()
            {
                var connection = new Mock<PersistentConnection>() { CallBase = true };
                var req = new Mock<IRequest>();
                req.Setup(m => m.Url).Returns(new Uri("http://foo"));
                req.Setup(m => m.LocalPath).Returns("");
                var qs = new NameValueCollection();
                qs["transport"] = "serverSentEvents";
                req.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(qs));

                var dr = new DefaultDependencyResolver();
                var context = new HostContext(req.Object, null);
                connection.Object.Initialize(dr);

                Assert.Throws<InvalidOperationException>(() => connection.Object.ProcessRequest(context));
            }
示例#25
0
            public void NullUnprotectedConnectionTokenThrows()
            {
                var connection = new Mock<PersistentConnection>() { CallBase = true };
                var req = new Mock<IRequest>();

                var protectedData = new Mock<IProtectedData>();
                protectedData.Setup(m => m.Protect(It.IsAny<string>(), It.IsAny<string>()))
                    .Returns<string, string>((value, purpose) => value);
                protectedData.Setup(m => m.Unprotect(It.IsAny<string>(), It.IsAny<string>())).Returns((string)null);

                var dr = new DefaultDependencyResolver();
                dr.Register(typeof(IProtectedData), () => protectedData.Object);
                var context = new HostContext(req.Object, null);
                connection.Object.Initialize(dr, context);

                Assert.Throws<InvalidOperationException>(() => connection.Object.GetConnectionId(context, "1"));
            }
示例#26
0
        public WebSocketTransport(HostContext context,
                                  JsonSerializer serializer,
                                  ITransportHeartbeat heartbeat,
                                  IPerformanceCounterManager performanceCounterManager,
                                  ITraceManager traceManager,
                                  int? maxIncomingMessageSize)
            : base(context, serializer, heartbeat, performanceCounterManager, traceManager)
        {
            _context = context;
            _maxIncomingMessageSize = maxIncomingMessageSize;

            _message = OnMessage;
            _closed = OnClosed;
            _error = OnSocketError;

            _counters = performanceCounterManager;
        }
示例#27
0
        public void FailedWriteCompletesRequestAfterDisconnectTimeout()
        {
            var request = new Mock<IRequest>();
            var response = new Mock<IResponse>();
            var qs = new NameValueCollection();
            request.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(qs));
            var url = new Uri("http://test/echo/connect");
            request.Setup(m => m.Url).Returns(url);
            request.Setup(m => m.LocalPath).Returns(url.LocalPath);
            var cts = new CancellationTokenSource();
            response.Setup(m => m.CancellationToken).Returns(cts.Token);
            response.Setup(m => m.Flush()).Returns(TaskAsyncHelper.Empty);

            var resolver = new DefaultDependencyResolver();
            var config = resolver.Resolve<IConfigurationManager>();
            var hostContext = new HostContext(request.Object, response.Object);
            config.DisconnectTimeout = TimeSpan.FromSeconds(6);
            var transport = new Mock<ForeverTransport>(hostContext, resolver)
            {
                CallBase = true
            };
            transport.Object.ConnectionId = "1";
            transport.Setup(m => m.Send(It.IsAny<PersistentResponse>()))
                     .Returns(() =>
                     {
                         var task = TaskAsyncHelper.FromError(new Exception());
                         cts.Cancel();
                         return task;
                     });

            var connectionManager = new ConnectionManager(resolver);
            var connection = connectionManager.GetConnectionCore("Foo");
            var wh = new ManualResetEventSlim();

            transport.Object.ProcessRequest(connection).ContinueWith(task =>
            {
                wh.Set();
            });

            connection.Broadcast("Some message");

            // 6 second disconnect timeout + 5 second disconnect threshold
            // + up to 1 second for the heartbeat to check + 3 second leeway
            Assert.True(wh.Wait(TimeSpan.FromSeconds(15)));
        }
示例#28
0
            public void AuthenticatedUserNameMatches()
            {
                var connection = new Mock<PersistentConnection>() { CallBase = true };
                var req = new Mock<IRequest>();
                req.Setup(m => m.User).Returns(new GenericPrincipal(new GenericIdentity("Name"), new string[] { }));

                var protectedData = new Mock<IProtectedData>();
                protectedData.Setup(m => m.Protect(It.IsAny<string>(), It.IsAny<string>()))
                    .Returns<string, string>((value, purpose) => value);
                protectedData.Setup(m => m.Unprotect(It.IsAny<string>(), It.IsAny<string>())).Returns<string, string>((value, purpose) => value);

                var dr = new DefaultDependencyResolver();
                dr.Register(typeof(IProtectedData), () => protectedData.Object);
                var context = new HostContext(req.Object, null);
                connection.Object.Initialize(dr, context);

                var connectionId = connection.Object.GetConnectionId(context, "1:Name");

                Assert.Equal("1", connectionId);
            }
            public void UnknownTransportFails()
            {
                var connection = new Mock<PersistentConnection>() { CallBase = true };
                var req = new Mock<IRequest>();
                req.Setup(m => m.Url).Returns(new Uri("http://foo"));
                req.Setup(m => m.LocalPath).Returns("");
                var qs = new NameValueCollection();
                req.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(qs));

                var res = new Mock<IResponse>();
                res.SetupProperty(m => m.StatusCode);

                var dr = new DefaultDependencyResolver();
                var context = new HostContext(req.Object, res.Object);
                connection.Object.Initialize(dr);

                var task = connection.Object.ProcessRequest(context);

                Assert.True(task.IsCompleted);
                Assert.Equal(400, context.Response.StatusCode);
            }
        public void RequestingSignalrHubsUrlWithTrailingSlashReturnsProxy(string proxyUrl)
        {
            // Arrange
            var dispatcher = new HubDispatcher(new HubConfiguration());
            var request = GetRequestForUrl(proxyUrl);
            var response = new Mock<IResponse>();
            string contentType = null;
            var buffer = new List<string>();
            response.SetupSet(m => m.ContentType = It.IsAny<string>()).Callback<string>(type => contentType = type);
            response.Setup(m => m.Write(It.IsAny<ArraySegment<byte>>())).Callback<ArraySegment<byte>>(data => buffer.Add(Encoding.UTF8.GetString(data.Array, data.Offset, data.Count)));

            // Act
            var context = new HostContext(request.Object, response.Object);
            dispatcher.Initialize(new DefaultDependencyResolver());
            dispatcher.ProcessRequest(context).Wait();

            // Assert
            Assert.Equal("application/javascript; charset=UTF-8", contentType);
            Assert.Equal(1, buffer.Count);
            Assert.NotNull(buffer[0]);
            Assert.False(buffer[0].StartsWith("throw new Error("));
        }