예제 #1
0
        public void Configuration(IAppBuilder app)
        {
            var corsPolicy = new CorsPolicy()
            {
                AllowAnyHeader      = true,
                AllowAnyMethod      = true,
                AllowAnyOrigin      = true,
                SupportsCredentials = true,
            };

            // Enable CORS so Karma works
            app.UseCors(new CorsOptions()
            {
                PolicyProvider = new CorsPolicyProvider()
                {
                    PolicyResolver = context => Task.FromResult(corsPolicy),
                }
            });

            Initializer.ConfigureRoutes(app, GlobalHost.DependencyResolver);

            app.Use((context, next) =>
            {
                if (context.Request.Path.StartsWithSegments(new PathString("/status")))
                {
                    context.Response.StatusCode = 200;
                    return(Task.CompletedTask);
                }
                return(next());
            });

            // Valid redirect chain
            // Overload detection doesn't like it when we use this as an extension method
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect", "/redirect2"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect2", "/redirect3"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect3", "/redirect4"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect4", "/signalr"));

            // Looping redirect chain
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect-loop", "/redirect-loop2"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect-loop2", "/redirect-loop"));

            // Wrong protocol version
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect-old-proto", "/signalr", protocolVersion: "1.5"));

            app.UseFileServer(new FileServerOptions()
            {
                EnableDefaultFiles = true,
                FileSystem         = new PhysicalFileSystem(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot"))
            });
        }
        public async Task ExceptionHandlerMustSaveExceptionToLogStoreBecauseOfExceptionInRequest()
        {
            using (BitOwinTestEnvironment testEnvironment = new BitOwinTestEnvironment(new TestEnvironmentArgs
            {
                AdditionalDependencies = manager =>
                {
                    manager.RegisterOwinMiddlewareUsing(owinApp =>
                    {
                        owinApp.Map("/Exception", innerApp =>
                        {
                            AppBuilderUseExtensions.Use <ExceptionThrownMiddleware>(innerApp);
                        });
                    });
                }
            }))
            {
                try
                {
                    TokenResponse token = await testEnvironment.Server.Login("ValidUserName", "ValidPassword", clientId : "TestResOwner");

                    await testEnvironment.Server.GetHttpClient(token)
                    .GetAsync("/Exception");

                    Assert.Fail();
                }
                catch
                {
                    IScopeStatusManager scopeStatusManager = TestDependencyManager.CurrentTestDependencyManager
                                                             .Objects.OfType <IScopeStatusManager>()
                                                             .Last();

                    A.CallTo(() => scopeStatusManager.MarkAsFailed())
                    .MustHaveHappened(Repeated.Exactly.Once);

                    ILogger logger = TestDependencyManager.CurrentTestDependencyManager
                                     .Objects.OfType <ILogger>()
                                     .Last();

                    A.CallTo(() => logger.LogExceptionAsync(A <Exception> .That.Matches(e => e is InvalidOperationException), A <string> .Ignored))
                    .MustHaveHappened(Repeated.Exactly.Once);

                    LogData[] logData = logger.LogData.ToArray();

                    logData.Single(c => c.Key == "ExceptionType" && ((string)c.Value).Contains("InvalidOperationException"));
                    logData.Single(c => c.Key == nameof(IRequestInformationProvider.HttpMethod) && (string)c.Value == "GET");
                    logData.Single(c => c.Key == "UserId" && (string)c.Value == "ValidUserName");
                }
            }
        }
예제 #3
0
        public static void ConfigureRoutes(IAppBuilder app, IDependencyResolver resolver, string azureSignalRConnectionString = null)
        {
            var hubConfig = new HubConfiguration
            {
                Resolver             = resolver,
                EnableDetailedErrors = true
            };

            if (!string.IsNullOrEmpty(azureSignalRConnectionString))
            {
#if AZURE_SIGNALR
                // We can't register all the other SignalR endpoints when testing with Azure SignalR.
                app.Map("/signalr", subapp =>
                {
                    subapp.RunAzureSignalR(typeof(Initializer).FullName, azureSignalRConnectionString, hubConfig);
                });
#else
                throw new NotSupportedException("Cannot use Azure SignalR unless the tests were built with the AzureSignalRTests MSBuild property set to 'true'.");
#endif
            }
            else
            {
                RegisterSignalREndpoints(app, resolver, hubConfig);
            }

            // Redirectors:

            // Valid redirect chain
            // Overload detection doesn't like it when we use this as an extension method
            // We *intentionally* use paths that do NOT end in a trailing '/' in some places as the client needs to support both
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect", "/redirect2"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect2", "/redirect3/"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect3", "/redirect4"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect4", "/signalr/"));

            // Looping redirect chain
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect-loop", "/redirect-loop2"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect-loop2", "/redirect-loop"));

            // Wrong protocol version
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect-old-proto", "/signalr", protocolVersion: "1.5"));
        }
예제 #4
0
        public static void ConfigureRoutes(IAppBuilder app, IDependencyResolver resolver)
        {
            var hubConfig = new HubConfiguration
            {
                Resolver             = resolver,
                EnableDetailedErrors = true
            };

            app.MapSignalR(hubConfig);

            app.MapSignalR("/signalr2/test", new HubConfiguration()
            {
                Resolver = resolver
            });

            var config = new ConnectionConfiguration
            {
                Resolver = resolver
            };

            app.Map("/multisend", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
                map.RunSignalR <MySendingConnection>(config);
            });

            app.Map("/echo", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
                map.RunSignalR <EchoConnection>(config);
            });

            app.Map("/redirectionConnection", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
                map.RunSignalR <RedirectionConnection>(config);
            });

            app.Map("/statusCodeConnection", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
                map.RunSignalR <StatusCodeConnection>(config);
            });

            app.Map("/jsonp", map =>
            {
                var jsonpConfig = new ConnectionConfiguration
                {
                    Resolver    = resolver,
                    EnableJSONP = true
                };

                map.MapSignalR <EchoConnection>("/echo", jsonpConfig);

                var jsonpHubsConfig = new HubConfiguration
                {
                    Resolver    = resolver,
                    EnableJSONP = true
                };

                map.MapSignalR(jsonpHubsConfig);
            });

            app.MapSignalR <MyBadConnection>("/ErrorsAreFun", config);
            app.MapSignalR <MyGroupEchoConnection>("/group-echo", config);
            app.MapSignalR <MyReconnect>("/my-reconnect", config);
            app.MapSignalR <ExamineHeadersConnection>("/examine-request", config);
            app.MapSignalR <ExamineReconnectPath>("/examine-reconnect", config);
            app.MapSignalR <MyGroupConnection>("/groups", config);
            app.MapSignalR <MyRejoinGroupsConnection>("/rejoin-groups", config);
            app.MapSignalR <BroadcastConnection>("/filter", config);
            app.MapSignalR <ConnectionThatUsesItems>("/items", config);
            app.MapSignalR <SyncErrorConnection>("/sync-error", config);
            app.MapSignalR <AddGroupOnConnectedConnection>("/add-group", config);
            app.MapSignalR <UnusableProtectedConnection>("/protected", config);
            app.MapSignalR <FallbackToLongPollingConnectionThrows>("/fall-back-throws", config);
            app.MapSignalR <PreserializedJsonConnection>("/preserialize", config);
            app.MapSignalR <AsyncOnConnectedConnection>("/async-on-connected", config);

            // This subpipeline is protected by basic auth
            app.Map("/basicauth", map =>
            {
                map.Use(async(context, next) =>
                {
                    var authorization = context.Request.Headers.Get("Authorization");
                    if (string.IsNullOrEmpty(authorization))
                    {
                        context.Response.StatusCode = 401;
                        context.Response.Headers.Add("WWW-Authenticate", new string[] { "Basic" });
                    }
                    else
                    {
                        var base64Encoded         = authorization.Replace("Basic ", "");
                        byte[] base64EncodedBytes = Convert.FromBase64String(base64Encoded);
                        var base64Decoded         = System.Text.ASCIIEncoding.ASCII.GetString(base64EncodedBytes);
                        var credentials           = base64Decoded.Split(':');
                        var identity = new ClaimsIdentity("Basic");
                        identity.AddClaim(new Claim(ClaimTypes.Name, credentials[0]));
                        context.Request.User = new ClaimsPrincipal(identity);
                        await next();
                    }
                });

                var subConfig = new ConnectionConfiguration
                {
                    Resolver = resolver
                };

                map.MapSignalR <AuthenticatedEchoConnection>("/echo", subConfig);

                var subHubsConfig = new HubConfiguration
                {
                    Resolver = resolver
                };

                map.MapSignalR(subHubsConfig);
            });

            // This subpipeline is protected by cookie auth
            app.Map("/cookieauth", map =>
            {
                var options = new CookieAuthenticationOptions()
                {
                    AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
                    LoginPath          = CookieAuthenticationDefaults.LoginPath,
                    LogoutPath         = CookieAuthenticationDefaults.LogoutPath,
                };

                map.UseCookieAuthentication(options);

                map.Use(async(context, next) =>
                {
                    if (context.Request.Path.Value.Contains(options.LoginPath.Value))
                    {
                        if (context.Request.Method == "POST")
                        {
                            var form     = await context.Request.ReadFormAsync();
                            var userName = form["UserName"];
                            var password = form["Password"];

                            var identity = new ClaimsIdentity(options.AuthenticationType);
                            identity.AddClaim(new Claim(ClaimTypes.Name, userName));
                            context.Authentication.SignIn(identity);
                        }
                    }
                    else
                    {
                        await next();
                    }
                });

                var subConfig = new ConnectionConfiguration
                {
                    Resolver = resolver
                };

                map.MapSignalR <AuthenticatedEchoConnection>("/echo", subConfig);

                var subHubsConfig = new HubConfiguration
                {
                    Resolver = resolver
                };

                map.MapSignalR(subHubsConfig);
            });

            app.Map("/fall-back", map =>
            {
                map.Use((context, next) =>
                {
                    if (!context.Request.Path.Value.Contains("negotiate") &&
                        !context.Request.QueryString.Value.Contains("longPolling"))
                    {
                        context.Response.Body = new MemoryStream();
                    }

                    return(next());
                });

                map.RunSignalR <FallbackToLongPollingConnection>();
            });

            app.Map("/no-init", map =>
            {
                map.Use((context, next) =>
                {
                    if (context.Request.Path.Value.Contains("connect"))
                    {
                        context.Response.Body = new MemoryStream();
                    }

                    return(next());
                });
            });

            app.Map("/force-lp-reconnect", map =>
            {
                var startReceived = new ManualResetEvent(false);

                map.Use((context, next) =>
                {
                    if (context.Request.QueryString.Value.Contains("transport=longPolling"))
                    {
                        // To test reconnect scenarios we need to make sure that the transport is
                        // successfully started before we disconnect the client. For long polling
                        // this means we need to make sure that we don't break the poll request
                        // before we send a response to the start request. Note that the first poll
                        // request is likely to arrive before the start request. The assumption here
                        // is that there is only one active long polling connection at a time.
                        if (context.Request.Path.Value.Contains("/connect"))
                        {
                            // a new connection was started
                            startReceived.Reset();
                        }
                        else if (context.Request.Path.Value.Contains("/start"))
                        {
                            // unblock breaking the poll after start request
                            return(next().ContinueWith(t => startReceived.Set()));
                        }
                        else if (context.Request.Path.Value.Contains("/poll"))
                        {
                            return(Task.Run(async() =>
                            {
                                // don't break the poll until start request is handled or a timeout
                                // if it is a subsequent poll
                                startReceived.WaitOne(3000);
                                // give the start request some additional head start
                                await Task.Delay(100);
                                //subsequent long polling request should not break immediately
                                startReceived.Reset();
                                context.Response.StatusCode = 500;
                                return TaskAsyncHelper.Empty;
                            }));
                        }
                    }

                    return(next());
                });
                map.MapSignalR <ExamineReconnectPath>("/examine-reconnect", config);
                map.MapSignalR(hubConfig);
            });

            // Perf/stress test related
            var performanceConfig = new ConnectionConfiguration
            {
                Resolver = resolver
            };

            app.MapSignalR <StressConnection>("/echo", performanceConfig);

            performanceConfig.Resolver.Register(typeof(IProtectedData), () => new EmptyProtectedData());

            // IMPORTANT: This needs to run last so that it runs in the "default" part of the pipeline

            // Session is enabled for ASP.NET on the session path
            app.Map("/session", map =>
            {
                map.MapSignalR();
            });

            // Redirectors:

            // Valid redirect chain
            // Overload detection doesn't like it when we use this as an extension method
            // We *intentionally* use paths that do NOT end in a trailing '/' in some places as the client needs to support both
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect", "/redirect2"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect2", "/redirect3/"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect3", "/redirect4"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect4", "/signalr/"));

            // Looping redirect chain
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect-loop", "/redirect-loop2"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect-loop2", "/redirect-loop"));

            // Wrong protocol version
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect-old-proto", "/signalr", protocolVersion: "1.5"));
        }
예제 #5
0
        public static void ConfigureRoutes(IAppBuilder app, IDependencyResolver resolver, string azureSignalRConnectionString = null)
        {
            var hubConfig = new HubConfiguration
            {
                Resolver             = resolver,
                EnableDetailedErrors = true
            };

            if (!string.IsNullOrEmpty(azureSignalRConnectionString))
            {
#if AZURE_SIGNALR
                // We can't register all the other SignalR endpoints when testing with Azure SignalR.
                app.Map("/signalr", subapp =>
                {
                    subapp.RunAzureSignalR(typeof(Initializer).FullName, azureSignalRConnectionString, hubConfig);
                });
#else
                throw new NotSupportedException("Cannot use Azure SignalR unless the tests were built with the AzureSignalRTests MSBuild property set to 'true'.");
#endif
            }
            else
            {
                RegisterSignalREndpoints(app, resolver, hubConfig);
            }

            // Simulated ASP.NET Core SignalR negotiate endpoint
            app.Use((context, next) =>
            {
                if (context.Request.Path.StartsWithSegments(new PathString("/aspnetcore-signalr")))
                {
                    // Send an ASP.NET Core SignalR negotiate response
                    context.Response.StatusCode  = 200;
                    context.Response.ContentType = "application/json";
                    using (var writer = new JsonTextWriter(new StreamWriter(context.Response.Body)))
                    {
                        writer.WriteStartObject();
                        writer.WritePropertyName("connectionId");
                        writer.WriteValue("fakeConnectionId");
                        writer.WritePropertyName("availableTransports");
                        writer.WriteStartArray();
                        writer.WriteEndArray();
                        writer.WriteEndObject();
                    }
                    return(Task.CompletedTask);
                }
                return(next());
            });

            // Handle negotiate "Error" field
            app.Use((context, next) =>
            {
                if (context.Request.Path.StartsWithSegments(new PathString("/negotiate-error")))
                {
                    // Send an error response
                    context.Response.StatusCode  = 200;
                    context.Response.ContentType = "application/json";
                    using (var writer = new JsonTextWriter(new StreamWriter(context.Response.Body)))
                    {
                        writer.WriteStartObject();
                        writer.WritePropertyName("ProtocolVersion");
                        writer.WriteValue("2.0");
                        writer.WritePropertyName("Error");
                        writer.WriteValue("Server-provided negotiate error message!");
                        writer.WriteEndObject();
                    }
                    return(Task.CompletedTask);
                }
                return(next());
            });

            // Redirectors:

            // Valid redirect chain
            // Overload detection doesn't like it when we use this as an extension method
            // We *intentionally* use paths that do NOT end in a trailing '/' in some places as the client needs to support both
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect", "/redirect2"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect2", "/redirect3/"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect3", "/redirect4"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect4", "/signalr/"));

            // Looping redirect chain
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect-loop", "/redirect-loop2"));
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect-loop2", "/redirect-loop"));

            // Wrong protocol version
            AppBuilderUseExtensions.Use(app, CreateRedirector("/redirect-old-proto", "/signalr", protocolVersion: "1.5"));
        }
예제 #6
0
 public static IAppBuilder UseClientCertificateAuthentication(this IAppBuilder app,
                                                              ClientCertificateAuthenticationOptions options)
 {
     AppBuilderUseExtensions.Use <IAppBuilder>(app, options); // (app,new object());
     return(app);
 }