Skip to content

Commit 6ea0926

Browse files
authored
Enable nullable in Kestrel.Core (#28050)
1 parent d05e4fe commit 6ea0926

File tree

143 files changed

+1482
-1127
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

143 files changed

+1482
-1127
lines changed

src/Hosting/Hosting/src/Internal/HostingApplication.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public HostingApplication(
4040
// Set up the request
4141
public Context CreateContext(IFeatureCollection contextFeatures)
4242
{
43-
Context hostContext;
43+
Context? hostContext;
4444
if (contextFeatures is IHostContextContainer<Context> container)
4545
{
4646
hostContext = container.HostContext;
@@ -88,7 +88,7 @@ public Task ProcessRequestAsync(Context context)
8888
}
8989

9090
// Clean up the request
91-
public void DisposeContext(Context context, Exception exception)
91+
public void DisposeContext(Context context, Exception? exception)
9292
{
9393
var httpContext = context.HttpContext!;
9494
_diagnostics.RequestEnd(httpContext, exception, context);

src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public void BeginRequest(HttpContext httpContext, HostingApplication.Context con
8686
}
8787

8888
[MethodImpl(MethodImplOptions.AggressiveInlining)]
89-
public void RequestEnd(HttpContext httpContext, Exception exception, HostingApplication.Context context)
89+
public void RequestEnd(HttpContext httpContext, Exception? exception, HostingApplication.Context context)
9090
{
9191
// Local cache items resolved multiple items, in order of use so they are primed in cpu pipeline when used
9292
var startTimestamp = context.StartTimestamp;

src/Hosting/Server.Abstractions/src/IHostContextContainer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ public interface IHostContextContainer<TContext> where TContext : notnull
1313
/// <summary>
1414
/// Represents the <typeparamref name="TContext"/> of the host.
1515
/// </summary>
16-
TContext HostContext { get; set; }
16+
TContext? HostContext { get; set; }
1717
}
1818
}

src/Hosting/Server.Abstractions/src/IHttpApplication.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ public interface IHttpApplication<TContext> where TContext : notnull
3131
/// </summary>
3232
/// <param name="context">The TContext to be disposed.</param>
3333
/// <param name="exception">The Exception thrown when processing did not complete successfully, otherwise null.</param>
34-
void DisposeContext(TContext context, Exception exception);
34+
void DisposeContext(TContext context, Exception? exception);
3535
}
3636
}

src/Hosting/Server.Abstractions/src/PublicAPI.Shipped.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#nullable enable
22
Microsoft.AspNetCore.Hosting.Server.Abstractions.IHostContextContainer<TContext>
3-
Microsoft.AspNetCore.Hosting.Server.Abstractions.IHostContextContainer<TContext>.HostContext.get -> TContext
3+
Microsoft.AspNetCore.Hosting.Server.Abstractions.IHostContextContainer<TContext>.HostContext.get -> TContext?
44
Microsoft.AspNetCore.Hosting.Server.Abstractions.IHostContextContainer<TContext>.HostContext.set -> void
55
Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature
66
Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature.Addresses.get -> System.Collections.Generic.ICollection<string!>!
77
Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature.PreferHostingUrls.get -> bool
88
Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature.PreferHostingUrls.set -> void
99
Microsoft.AspNetCore.Hosting.Server.IHttpApplication<TContext>
1010
Microsoft.AspNetCore.Hosting.Server.IHttpApplication<TContext>.CreateContext(Microsoft.AspNetCore.Http.Features.IFeatureCollection! contextFeatures) -> TContext
11-
Microsoft.AspNetCore.Hosting.Server.IHttpApplication<TContext>.DisposeContext(TContext context, System.Exception! exception) -> void
11+
Microsoft.AspNetCore.Hosting.Server.IHttpApplication<TContext>.DisposeContext(TContext context, System.Exception? exception) -> void
1212
Microsoft.AspNetCore.Hosting.Server.IHttpApplication<TContext>.ProcessRequestAsync(TContext context) -> System.Threading.Tasks.Task!
1313
Microsoft.AspNetCore.Hosting.Server.IServer
1414
Microsoft.AspNetCore.Hosting.Server.IServer.Features.get -> Microsoft.AspNetCore.Http.Features.IFeatureCollection!

src/Http/Http.Features/src/IHttpResponseTrailersFeature.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
namespace Microsoft.AspNetCore.Http.Features

src/Http/Http.Features/src/PublicAPI.Shipped.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.ReasonPhrase.set -> void
132132
Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.StatusCode.get -> int
133133
Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.StatusCode.set -> void
134134
Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature
135-
Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature.Trailers.get -> Microsoft.AspNetCore.Http.IHeaderDictionary!
136135
Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature.Trailers.set -> void
136+
Microsoft.AspNetCore.Http.Features.IHttpResponseTrailersFeature.Trailers.get -> Microsoft.AspNetCore.Http.IHeaderDictionary!
137137
Microsoft.AspNetCore.Http.Features.IHttpSendFileFeature
138138
Microsoft.AspNetCore.Http.Features.IHttpSendFileFeature.SendFileAsync(string! path, long offset, long? count, System.Threading.CancellationToken cancellation) -> System.Threading.Tasks.Task!
139139
Microsoft.AspNetCore.Http.Features.IHttpUpgradeFeature
@@ -233,6 +233,7 @@ Microsoft.AspNetCore.Http.ISession.Keys.get -> System.Collections.Generic.IEnume
233233
Microsoft.AspNetCore.Http.ISession.LoadAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
234234
Microsoft.AspNetCore.Http.ISession.Remove(string! key) -> void
235235
Microsoft.AspNetCore.Http.ISession.Set(string! key, byte[]! value) -> void
236+
Microsoft.AspNetCore.Http.ISession.TryGetValue(string! key, out byte[]? value) -> bool
236237
Microsoft.AspNetCore.Http.SameSiteMode
237238
Microsoft.AspNetCore.Http.SameSiteMode.Lax = 1 -> Microsoft.AspNetCore.Http.SameSiteMode
238239
Microsoft.AspNetCore.Http.SameSiteMode.None = 0 -> Microsoft.AspNetCore.Http.SameSiteMode
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
11
#nullable enable
2-
Microsoft.AspNetCore.Http.ISession.TryGetValue(string! key, out byte[]? value) -> bool
3-

src/Http/Http/src/BindingAddress.cs

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,24 @@ public class BindingAddress
1212
{
1313
private const string UnixPipeHostPrefix = "unix:/";
1414

15-
public string Host { get; private set; } = default!;
16-
public string PathBase { get; private set; } = default!;
17-
public int Port { get; internal set; }
18-
public string Scheme { get; private set; } = default!;
15+
private BindingAddress(string host, string pathBase, int port, string scheme)
16+
{
17+
Host = host;
18+
PathBase = pathBase;
19+
Port = port;
20+
Scheme = scheme;
21+
}
22+
23+
[Obsolete("This constructor is obsolete and will be removed in a future version. Use BindingAddress.Parse(address) to create a BindingAddress instance.")]
24+
public BindingAddress()
25+
{
26+
throw new InvalidOperationException("This constructor is obsolete and will be removed in a future version. Use BindingAddress.Parse(address) to create a BindingAddress instance.");
27+
}
28+
29+
public string Host { get; }
30+
public string PathBase { get; }
31+
public int Port { get; }
32+
public string Scheme { get; }
1933

2034
public bool IsUnixPipe
2135
{
@@ -34,16 +48,20 @@ public string UnixPipePath
3448
throw new InvalidOperationException("Binding address is not a unix pipe.");
3549
}
3650

37-
var unixPipeHostPrefixLength = UnixPipeHostPrefix.Length;
38-
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
39-
{
40-
// "/" character in unix refers to root. Windows has drive letters and volume separator (c:)
41-
unixPipeHostPrefixLength--;
42-
}
43-
return Host.Substring(unixPipeHostPrefixLength);
51+
return GetUnixPipePath(Host);
4452
}
4553
}
4654

55+
private static string GetUnixPipePath(string host)
56+
{
57+
var unixPipeHostPrefixLength = UnixPipeHostPrefix.Length;
58+
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
59+
{
60+
// "/" character in unix refers to root. Windows has drive letters and volume separator (c:)
61+
unixPipeHostPrefixLength--;
62+
}
63+
return host.Substring(unixPipeHostPrefixLength);
64+
}
4765

4866
public override string ToString()
4967
{
@@ -77,6 +95,7 @@ public override bool Equals(object? obj)
7795

7896
public static BindingAddress Parse(string address)
7997
{
98+
// A null/empty address will throw FormatException
8099
address = address ?? string.Empty;
81100

82101
int schemeDelimiterStart = address.IndexOf(Uri.SchemeDelimiter, StringComparison.Ordinal);
@@ -117,8 +136,9 @@ public static BindingAddress Parse(string address)
117136
pathDelimiterStart = pathDelimiterEnd = address.Length;
118137
}
119138

120-
var serverAddress = new BindingAddress();
121-
serverAddress.Scheme = address.Substring(0, schemeDelimiterStart);
139+
var scheme = address.Substring(0, schemeDelimiterStart);
140+
string? host = null;
141+
int port = 0;
122142

123143
var hasSpecifiedPort = false;
124144
if (!isUnixPipe)
@@ -133,49 +153,50 @@ public static BindingAddress Parse(string address)
133153
if (int.TryParse(portString, NumberStyles.Integer, CultureInfo.InvariantCulture, out portNumber))
134154
{
135155
hasSpecifiedPort = true;
136-
serverAddress.Host = address.Substring(schemeDelimiterEnd, portDelimiterStart - schemeDelimiterEnd);
137-
serverAddress.Port = portNumber;
156+
host = address.Substring(schemeDelimiterEnd, portDelimiterStart - schemeDelimiterEnd);
157+
port = portNumber;
138158
}
139159
}
140160

141161
if (!hasSpecifiedPort)
142162
{
143-
if (string.Equals(serverAddress.Scheme, "http", StringComparison.OrdinalIgnoreCase))
163+
if (string.Equals(scheme, "http", StringComparison.OrdinalIgnoreCase))
144164
{
145-
serverAddress.Port = 80;
165+
port = 80;
146166
}
147-
else if (string.Equals(serverAddress.Scheme, "https", StringComparison.OrdinalIgnoreCase))
167+
else if (string.Equals(scheme, "https", StringComparison.OrdinalIgnoreCase))
148168
{
149-
serverAddress.Port = 443;
169+
port = 443;
150170
}
151171
}
152172
}
153173

154174
if (!hasSpecifiedPort)
155175
{
156-
serverAddress.Host = address.Substring(schemeDelimiterEnd, pathDelimiterStart - schemeDelimiterEnd);
176+
host = address.Substring(schemeDelimiterEnd, pathDelimiterStart - schemeDelimiterEnd);
157177
}
158178

159-
if (string.IsNullOrEmpty(serverAddress.Host))
179+
if (string.IsNullOrEmpty(host))
160180
{
161181
throw new FormatException($"Invalid url: '{address}'");
162182
}
163183

164-
if (isUnixPipe && !Path.IsPathRooted(serverAddress.UnixPipePath))
184+
if (isUnixPipe && !Path.IsPathRooted(GetUnixPipePath(host)))
165185
{
166186
throw new FormatException($"Invalid url, unix socket path must be absolute: '{address}'");
167187
}
168188

189+
string pathBase;
169190
if (address[address.Length - 1] == '/')
170191
{
171-
serverAddress.PathBase = address.Substring(pathDelimiterEnd, address.Length - pathDelimiterEnd - 1);
192+
pathBase = address.Substring(pathDelimiterEnd, address.Length - pathDelimiterEnd - 1);
172193
}
173194
else
174195
{
175-
serverAddress.PathBase = address.Substring(pathDelimiterEnd);
196+
pathBase = address.Substring(pathDelimiterEnd);
176197
}
177198

178-
return serverAddress;
199+
return new BindingAddress(host: host, pathBase: pathBase, port: port, scheme: scheme);
179200
}
180201
}
181202
}

src/Servers/Kestrel/Core/src/AnyIPListenOptions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5+
using System.Diagnostics;
56
using System.IO;
67
using System.Net;
78
using System.Threading.Tasks;
@@ -19,6 +20,8 @@ internal AnyIPListenOptions(int port)
1920

2021
internal override async Task BindAsync(AddressBindContext context)
2122
{
23+
Debug.Assert(IPEndPoint != null);
24+
2225
// when address is 'http://hostname:port', 'http://*:port', or 'http://+:port'
2326
try
2427
{

0 commit comments

Comments
 (0)