Skip to content
This repository was archived by the owner on Nov 20, 2018. It is now read-only.

Commit 5d8231e

Browse files
committed
OwinExtensions.UseBuilder() should not leave ApplicationServices or RequestServices null
Also correct tests to avoid warnings and to ensure scenarios are actually tested - tests previously went `async` without waiting for completion nit: add parameter `null` checks
1 parent cb09ffc commit 5d8231e

File tree

2 files changed

+140
-19
lines changed

2 files changed

+140
-19
lines changed

src/Microsoft.AspNetCore.Owin/OwinExtensions.cs

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,25 @@
1212

1313
namespace Microsoft.AspNetCore.Builder
1414
{
15+
using AddMiddleware = Action<Func<
16+
Func<IDictionary<string, object>, Task>,
17+
Func<IDictionary<string, object>, Task>
18+
>>;
1519
using AppFunc = Func<IDictionary<string, object>, Task>;
1620
using CreateMiddleware = Func<
1721
Func<IDictionary<string, object>, Task>,
1822
Func<IDictionary<string, object>, Task>
1923
>;
20-
using AddMiddleware = Action<Func<
21-
Func<IDictionary<string, object>, Task>,
22-
Func<IDictionary<string, object>, Task>
23-
>>;
2424

2525
public static class OwinExtensions
2626
{
2727
public static AddMiddleware UseOwin(this IApplicationBuilder builder)
2828
{
29+
if (builder == null)
30+
{
31+
throw new ArgumentNullException(nameof(builder));
32+
}
33+
2934
AddMiddleware add = middleware =>
3035
{
3136
Func<RequestDelegate, RequestDelegate> middleware1 = next1 =>
@@ -61,6 +66,15 @@ public static AddMiddleware UseOwin(this IApplicationBuilder builder)
6166

6267
public static IApplicationBuilder UseOwin(this IApplicationBuilder builder, Action<AddMiddleware> pipeline)
6368
{
69+
if (builder == null)
70+
{
71+
throw new ArgumentNullException(nameof(builder));
72+
}
73+
if (pipeline == null)
74+
{
75+
throw new ArgumentNullException(nameof(pipeline));
76+
}
77+
6478
pipeline(builder.UseOwin());
6579
return builder;
6680
}
@@ -72,6 +86,18 @@ public static IApplicationBuilder UseBuilder(this AddMiddleware app)
7286

7387
public static IApplicationBuilder UseBuilder(this AddMiddleware app, IServiceProvider serviceProvider)
7488
{
89+
if (app == null)
90+
{
91+
throw new ArgumentNullException(nameof(app));
92+
}
93+
94+
// Do not set ApplicationBuilder.ApplicationServices to null. May fail later due to missing services but
95+
// at least that results in a more useful Exception than a NRE.
96+
if (serviceProvider == null)
97+
{
98+
serviceProvider = new EmptyProvider();
99+
}
100+
75101
// Adapt WebSockets by default.
76102
app(OwinWebSocketAcceptAdapter.AdaptWebSockets);
77103
var builder = new ApplicationBuilder(serviceProvider: serviceProvider);
@@ -125,9 +151,26 @@ public static AddMiddleware UseBuilder(this AddMiddleware app, Action<IApplicati
125151

126152
public static AddMiddleware UseBuilder(this AddMiddleware app, Action<IApplicationBuilder> pipeline, IServiceProvider serviceProvider)
127153
{
154+
if (app == null)
155+
{
156+
throw new ArgumentNullException(nameof(app));
157+
}
158+
if (pipeline == null)
159+
{
160+
throw new ArgumentNullException(nameof(pipeline));
161+
}
162+
128163
var builder = app.UseBuilder(serviceProvider);
129164
pipeline(builder);
130165
return app;
131166
}
167+
168+
private class EmptyProvider : IServiceProvider
169+
{
170+
public object GetService(Type serviceType)
171+
{
172+
return null;
173+
}
174+
}
132175
}
133176
}

test/Microsoft.AspNetCore.Owin.Tests/OwinExtensionTests.cs

Lines changed: 93 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,30 @@
66
using System.Linq;
77
using System.Threading.Tasks;
88
using Microsoft.AspNetCore.Builder;
9+
using Microsoft.AspNetCore.Builder.Internal;
10+
using Microsoft.AspNetCore.Http;
11+
using Microsoft.AspNetCore.Http.Internal;
912
using Microsoft.Extensions.DependencyInjection;
1013
using Xunit;
1114

1215
namespace Microsoft.AspNetCore.Owin
1316
{
17+
using AddMiddleware = Action<Func<
18+
Func<IDictionary<string, object>, Task>,
19+
Func<IDictionary<string, object>, Task>
20+
>>;
1421
using AppFunc = Func<IDictionary<string, object>, Task>;
1522
using CreateMiddleware = Func<
1623
Func<IDictionary<string, object>, Task>,
1724
Func<IDictionary<string, object>, Task>
1825
>;
19-
using AddMiddleware = Action<Func<
20-
Func<IDictionary<string, object>, Task>,
21-
Func<IDictionary<string, object>, Task>
22-
>>;
2326

2427
public class OwinExtensionTests
2528
{
2629
static AppFunc notFound = env => new Task(() => { env["owin.ResponseStatusCode"] = 404; });
2730

2831
[Fact]
29-
public void OwinConfigureServiceProviderAddsServices()
32+
public async Task OwinConfigureServiceProviderAddsServices()
3033
{
3134
var list = new List<CreateMiddleware>();
3235
AddMiddleware build = list.Add;
@@ -36,24 +39,30 @@ public void OwinConfigureServiceProviderAddsServices()
3639
var builder = build.UseBuilder(applicationBuilder =>
3740
{
3841
serviceProvider = applicationBuilder.ApplicationServices;
39-
applicationBuilder.Run(async context =>
42+
applicationBuilder.Run(context =>
4043
{
4144
fakeService = context.RequestServices.GetService<FakeService>();
45+
return Task.FromResult(0);
4246
});
43-
}, new ServiceCollection().AddSingleton(new FakeService()).BuildServiceProvider());
47+
},
48+
new ServiceCollection().AddSingleton(new FakeService()).BuildServiceProvider());
4449

4550
list.Reverse();
46-
list.Aggregate(notFound, (next, middleware) => middleware(next)).Invoke(new Dictionary<string, object>());
51+
await list
52+
.Aggregate(notFound, (next, middleware) => middleware(next))
53+
.Invoke(new Dictionary<string, object>());
4754

48-
Assert.NotNull(fakeService);
55+
Assert.NotNull(serviceProvider);
4956
Assert.NotNull(serviceProvider.GetService<FakeService>());
57+
Assert.NotNull(fakeService);
5058
}
5159

5260
[Fact]
53-
public void OwinDefaultNoServices()
61+
public async Task OwinDefaultNoServices()
5462
{
5563
var list = new List<CreateMiddleware>();
5664
AddMiddleware build = list.Add;
65+
IServiceProvider expectedServiceProvider = new ServiceCollection().BuildServiceProvider();
5766
IServiceProvider serviceProvider = null;
5867
FakeService fakeService = null;
5968
bool builderExecuted = false;
@@ -63,25 +72,94 @@ public void OwinDefaultNoServices()
6372
{
6473
builderExecuted = true;
6574
serviceProvider = applicationBuilder.ApplicationServices;
66-
applicationBuilder.Run(async context =>
75+
applicationBuilder.Run(context =>
6776
{
6877
applicationExecuted = true;
6978
fakeService = context.RequestServices.GetService<FakeService>();
79+
return Task.FromResult(0);
7080
});
71-
});
81+
},
82+
expectedServiceProvider);
7283

7384
list.Reverse();
74-
list.Aggregate(notFound, (next, middleware) => middleware(next)).Invoke(new Dictionary<string, object>());
85+
await list
86+
.Aggregate(notFound, (next, middleware) => middleware(next))
87+
.Invoke(new Dictionary<string, object>());
7588

7689
Assert.True(builderExecuted);
90+
Assert.Equal(expectedServiceProvider, serviceProvider);
91+
Assert.True(applicationExecuted);
7792
Assert.Null(fakeService);
93+
}
94+
95+
[Fact]
96+
public async Task OwinDefaultNullServiceProvider()
97+
{
98+
var list = new List<CreateMiddleware>();
99+
AddMiddleware build = list.Add;
100+
IServiceProvider serviceProvider = null;
101+
FakeService fakeService = null;
102+
bool builderExecuted = false;
103+
bool applicationExecuted = false;
104+
105+
var builder = build.UseBuilder(applicationBuilder =>
106+
{
107+
builderExecuted = true;
108+
serviceProvider = applicationBuilder.ApplicationServices;
109+
applicationBuilder.Run(context =>
110+
{
111+
applicationExecuted = true;
112+
fakeService = context.RequestServices.GetService<FakeService>();
113+
return Task.FromResult(0);
114+
});
115+
});
116+
117+
list.Reverse();
118+
await list
119+
.Aggregate(notFound, (next, middleware) => middleware(next))
120+
.Invoke(new Dictionary<string, object>());
121+
122+
Assert.True(builderExecuted);
123+
Assert.NotNull(serviceProvider);
78124
Assert.True(applicationExecuted);
79-
Assert.Null(serviceProvider);
125+
Assert.Null(fakeService);
80126
}
81127

82-
private class FakeService
128+
[Fact]
129+
public async Task UseOwin()
83130
{
131+
var serviceProvider = new ServiceCollection().BuildServiceProvider();
132+
var builder = new ApplicationBuilder(serviceProvider);
133+
IDictionary<string, object> environment = null;
134+
var context = new DefaultHttpContext();
135+
136+
builder.UseOwin(addToPipeline =>
137+
{
138+
addToPipeline(next =>
139+
{
140+
Assert.NotNull(next);
141+
return async env =>
142+
{
143+
environment = env;
144+
await next(env);
145+
};
146+
});
147+
});
148+
await builder.Build().Invoke(context);
149+
150+
// Dictionary contains context but does not contain "websocket.Accept" or "websocket.AcceptAlt" keys.
151+
Assert.NotNull(environment);
152+
var value = Assert.Single(
153+
environment,
154+
kvp => string.Equals(typeof(HttpContext).FullName, kvp.Key, StringComparison.Ordinal))
155+
.Value;
156+
Assert.Equal(context, value);
157+
Assert.False(environment.ContainsKey("websocket.Accept"));
158+
Assert.False(environment.ContainsKey("websocket.AcceptAlt"));
159+
}
84160

161+
private class FakeService
162+
{
85163
}
86164
}
87165
}

0 commit comments

Comments
 (0)