/
DefaultHttpRequest.cs
192 lines (157 loc) · 6.61 KB
/
DefaultHttpRequest.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.IO.Pipelines;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Routing;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Http
{
internal sealed class DefaultHttpRequest : HttpRequest
{
private const string Http = "http";
private const string Https = "https";
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
private readonly static Func<IFeatureCollection, IHttpRequestFeature?> _nullRequestFeature = f => null;
private readonly static Func<IFeatureCollection, IQueryFeature?> _newQueryFeature = f => new QueryFeature(f);
private readonly static Func<DefaultHttpRequest, IFormFeature> _newFormFeature = r => new FormFeature(r, r._context.FormOptions ?? FormOptions.Default);
private readonly static Func<IFeatureCollection, IRequestCookiesFeature> _newRequestCookiesFeature = f => new RequestCookiesFeature(f);
private readonly static Func<IFeatureCollection, IRouteValuesFeature> _newRouteValuesFeature = f => new RouteValuesFeature();
private readonly static Func<HttpContext, IRequestBodyPipeFeature> _newRequestBodyPipeFeature = context => new RequestBodyPipeFeature(context);
private readonly DefaultHttpContext _context;
private FeatureReferences<FeatureInterfaces> _features;
public DefaultHttpRequest(DefaultHttpContext context)
{
_context = context;
_features.Initalize(context.Features);
}
public void Initialize()
{
_features.Initalize(_context.Features);
}
public void Initialize(int revision)
{
_features.Initalize(_context.Features, revision);
}
public void Uninitialize()
{
_features = default;
}
public override HttpContext HttpContext => _context;
private IHttpRequestFeature HttpRequestFeature =>
_features.Fetch(ref _features.Cache.Request, _nullRequestFeature)!;
private IQueryFeature QueryFeature =>
_features.Fetch(ref _features.Cache.Query, _newQueryFeature)!;
private IFormFeature FormFeature =>
_features.Fetch(ref _features.Cache.Form, this, _newFormFeature)!;
private IRequestCookiesFeature RequestCookiesFeature =>
_features.Fetch(ref _features.Cache.Cookies, _newRequestCookiesFeature)!;
private IRouteValuesFeature RouteValuesFeature =>
_features.Fetch(ref _features.Cache.RouteValues, _newRouteValuesFeature)!;
private IRequestBodyPipeFeature RequestBodyPipeFeature =>
_features.Fetch(ref _features.Cache.BodyPipe, this.HttpContext, _newRequestBodyPipeFeature)!;
public override PathString PathBase
{
get { return new PathString(HttpRequestFeature.PathBase); }
set { HttpRequestFeature.PathBase = value.Value ?? string.Empty; }
}
public override PathString Path
{
get { return new PathString(HttpRequestFeature.Path); }
set { HttpRequestFeature.Path = value.Value ?? string.Empty; }
}
public override QueryString QueryString
{
get { return new QueryString(HttpRequestFeature.QueryString); }
set { HttpRequestFeature.QueryString = value.Value ?? string.Empty; }
}
public override long? ContentLength
{
get { return Headers.ContentLength; }
set { Headers.ContentLength = value; }
}
public override Stream Body
{
get { return HttpRequestFeature.Body; }
set { HttpRequestFeature.Body = value; }
}
public override string Method
{
get { return HttpRequestFeature.Method; }
set { HttpRequestFeature.Method = value; }
}
public override string Scheme
{
get { return HttpRequestFeature.Scheme; }
set { HttpRequestFeature.Scheme = value; }
}
public override bool IsHttps
{
get { return string.Equals(Https, Scheme, StringComparison.OrdinalIgnoreCase); }
set { Scheme = value ? Https : Http; }
}
public override HostString Host
{
get { return HostString.FromUriComponent(Headers[HeaderNames.Host]); }
set { Headers[HeaderNames.Host] = value.ToUriComponent(); }
}
public override IQueryCollection Query
{
get { return QueryFeature.Query; }
set { QueryFeature.Query = value; }
}
public override string Protocol
{
get { return HttpRequestFeature.Protocol; }
set { HttpRequestFeature.Protocol = value; }
}
public override IHeaderDictionary Headers
{
get { return HttpRequestFeature.Headers; }
}
public override IRequestCookieCollection Cookies
{
get { return RequestCookiesFeature.Cookies; }
set { RequestCookiesFeature.Cookies = value; }
}
public override string ContentType
{
get { return Headers[HeaderNames.ContentType]; }
set { Headers[HeaderNames.ContentType] = value; }
}
public override bool HasFormContentType
{
get { return FormFeature.HasFormContentType; }
}
public override IFormCollection Form
{
get { return FormFeature.ReadForm(); }
set { FormFeature.Form = value; }
}
public override Task<IFormCollection> ReadFormAsync(CancellationToken cancellationToken)
{
return FormFeature.ReadFormAsync(cancellationToken);
}
public override RouteValueDictionary RouteValues
{
get { return RouteValuesFeature.RouteValues; }
set { RouteValuesFeature.RouteValues = value; }
}
public override PipeReader BodyReader
{
get { return RequestBodyPipeFeature.Reader; }
}
struct FeatureInterfaces
{
public IHttpRequestFeature? Request;
public IQueryFeature? Query;
public IFormFeature? Form;
public IRequestCookiesFeature? Cookies;
public IRouteValuesFeature? RouteValues;
public IRequestBodyPipeFeature? BodyPipe;
}
}
}