Skip to content
This repository was archived by the owner on Mar 19, 2019. It is now read-only.

Commit e69cb5c

Browse files
committed
Use a static feature collection.
1 parent 161fdbb commit e69cb5c

File tree

2 files changed

+122
-28
lines changed

2 files changed

+122
-28
lines changed

src/Microsoft.AspNet.Server.WebListener/FeatureContext.cs

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ internal class FeatureContext :
4949
private static Func<object,Task> OnStartDelegate = OnStart;
5050

5151
private RequestContext _requestContext;
52-
private FeatureCollection _features;
52+
private IFeatureCollection _features;
5353
private bool _enableResponseCaching;
5454

5555
private Stream _requestBody;
@@ -76,18 +76,22 @@ internal class FeatureContext :
7676
internal FeatureContext(RequestContext requestContext, bool enableResponseCaching)
7777
{
7878
_requestContext = requestContext;
79-
_features = new FeatureCollection();
79+
_features = new StandardFeatureCollection(this);
8080
_authHandler = new AuthenticationHandler(requestContext);
8181
_enableResponseCaching = enableResponseCaching;
8282
requestContext.Response.OnStarting(OnStartDelegate, this);
83-
PopulateFeatures();
8483
}
8584

8685
internal IFeatureCollection Features
8786
{
8887
get { return _features; }
8988
}
9089

90+
internal object RequestContext
91+
{
92+
get { return _requestContext; }
93+
}
94+
9195
private Request Request
9296
{
9397
get { return _requestContext.Request; }
@@ -98,31 +102,6 @@ private Response Response
98102
get { return _requestContext.Response; }
99103
}
100104

101-
private void PopulateFeatures()
102-
{
103-
_features[typeof(IHttpRequestFeature)] = this;
104-
_features[typeof(IHttpConnectionFeature)] = this;
105-
_features[typeof(IHttpResponseFeature)] = this;
106-
_features[typeof(IHttpSendFileFeature)] = this;
107-
_features[typeof(IHttpBufferingFeature)] = this;
108-
_features[typeof(IHttpRequestLifetimeFeature)] = this;
109-
_features[typeof(IHttpAuthenticationFeature)] = this;
110-
_features[typeof(IHttpRequestIdentifierFeature)] = this;
111-
112-
if (Request.IsSecureConnection)
113-
{
114-
_features[typeof(ITlsConnectionFeature)] = this;
115-
_features[typeof(ITlsTokenBindingFeature)] = this;
116-
}
117-
118-
// Win8+
119-
if (WebSocketHelpers.AreWebSocketsSupported)
120-
{
121-
_features[typeof(IHttpUpgradeFeature)] = this;
122-
_features[typeof(IHttpWebSocketFeature)] = this;
123-
}
124-
}
125-
126105
Stream IHttpRequestFeature.Body
127106
{
128107
get
@@ -326,6 +305,11 @@ async Task<X509Certificate2> ITlsConnectionFeature.GetClientCertificateAsync(Can
326305
return _clientCert;
327306
}
328307

308+
internal ITlsConnectionFeature GetTlsConnectionFeature()
309+
{
310+
return Request.IsSecureConnection ? this : null;
311+
}
312+
329313
byte[] ITlsTokenBindingFeature.GetProvidedTokenBindingId()
330314
{
331315
return Request.GetProvidedTokenBindingId();
@@ -336,6 +320,11 @@ byte[] ITlsTokenBindingFeature.GetReferredTokenBindingId()
336320
return Request.GetReferredTokenBindingId();
337321
}
338322

323+
internal ITlsTokenBindingFeature GetTlsTokenBindingFeature()
324+
{
325+
return Request.IsSecureConnection ? this : null;
326+
}
327+
339328
void IHttpBufferingFeature.DisableRequestBuffering()
340329
{
341330
// There is no request buffering.
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright (c) .NET Foundation.
2+
// All Rights Reserved
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
11+
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
12+
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
13+
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
14+
// NON-INFRINGEMENT.
15+
// See the Apache 2 License for the specific language governing
16+
// permissions and limitations under the License.
17+
18+
using System;
19+
using System.Collections;
20+
using System.Collections.Generic;
21+
using Microsoft.AspNet.Http.Features;
22+
using Microsoft.AspNet.Http.Features.Authentication;
23+
using Microsoft.Net.Http.Server;
24+
25+
namespace Microsoft.AspNet.Server.WebListener
26+
{
27+
internal sealed class StandardFeatureCollection : IFeatureCollection
28+
{
29+
private static readonly Func<FeatureContext, object> _identityFunc = ReturnIdentity;
30+
private static readonly Dictionary<Type, Func<FeatureContext, object>> _featureFuncLookup = new Dictionary<Type, Func<FeatureContext, object>>()
31+
{
32+
{ typeof(IHttpRequestFeature), _identityFunc },
33+
{ typeof(IHttpConnectionFeature), _identityFunc },
34+
{ typeof(IHttpResponseFeature), _identityFunc },
35+
{ typeof(IHttpSendFileFeature), _identityFunc },
36+
{ typeof(ITlsConnectionFeature), ctx => ctx.GetTlsConnectionFeature() },
37+
{ typeof(ITlsTokenBindingFeature), ctx => ctx.GetTlsTokenBindingFeature() },
38+
{ typeof(IHttpBufferingFeature), _identityFunc },
39+
{ typeof(IHttpRequestLifetimeFeature), _identityFunc },
40+
{ typeof(IHttpUpgradeFeature), _identityFunc },
41+
{ typeof(IHttpWebSocketFeature), _identityFunc },
42+
{ typeof(IHttpAuthenticationFeature), _identityFunc },
43+
{ typeof(IHttpRequestIdentifierFeature), _identityFunc },
44+
{ typeof(RequestContext), ctx => ctx.RequestContext },
45+
};
46+
47+
private readonly FeatureContext _featureContext;
48+
49+
public StandardFeatureCollection(FeatureContext featureContext)
50+
{
51+
_featureContext = featureContext;
52+
}
53+
54+
public bool IsReadOnly
55+
{
56+
get { return true; }
57+
}
58+
59+
public int Revision
60+
{
61+
get { return 0; }
62+
}
63+
64+
public object this[Type key]
65+
{
66+
get
67+
{
68+
Func<FeatureContext, object> lookupFunc;
69+
_featureFuncLookup.TryGetValue(key, out lookupFunc);
70+
return lookupFunc?.Invoke(_featureContext);
71+
}
72+
set
73+
{
74+
throw new InvalidOperationException("The collection is read-only");
75+
}
76+
}
77+
78+
private static object ReturnIdentity(FeatureContext featureContext)
79+
{
80+
return featureContext;
81+
}
82+
83+
IEnumerator IEnumerable.GetEnumerator()
84+
{
85+
return ((IEnumerable<KeyValuePair<Type, object>>)this).GetEnumerator();
86+
}
87+
88+
IEnumerator<KeyValuePair<Type, object>> IEnumerable<KeyValuePair<Type, object>>.GetEnumerator()
89+
{
90+
foreach (var featureFunc in _featureFuncLookup)
91+
{
92+
var feature = featureFunc.Value(_featureContext);
93+
if (feature != null)
94+
{
95+
yield return new KeyValuePair<Type, object>(featureFunc.Key, feature);
96+
}
97+
}
98+
}
99+
100+
void IDisposable.Dispose()
101+
{
102+
// nothing to dispose of
103+
}
104+
}
105+
}

0 commit comments

Comments
 (0)