Skip to content

Commit a542e3e

Browse files
committed
Fixes
Ensure that we copy response headers only once. It appears that response headers related to content can vanish after we've read the content stream, so to avoid this, we read just once on initial response. Fixes an issue where the Headers property of HttpMessageInfo objects can be null, which causes null reference exceptions when calling various methods. Changed to always initialize this property with a valid reference, and to perform null checks when accessing internally.
1 parent ae0025c commit a542e3e

File tree

3 files changed

+18
-23
lines changed

3 files changed

+18
-23
lines changed

CitadelCore/CitadelCore.csproj

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,15 @@
1212
<PackageIconUrl />
1313
<RepositoryUrl>https://github.com/TechnikEmpire/CitadelCore</RepositoryUrl>
1414
<PackageTags>proxy filtering content-filtering transparent-proxy</PackageTags>
15-
<PackageReleaseNotes>Upgrades core deps.
16-
Enables HTTP/2 on the proxy front-end, but backend fulfillment is still HTTP/1.x.
17-
Strips all compression methods from the front end.
18-
Configures Kestrel for optimal throughput.
19-
Ensures that headers are replaced if they exist. This ensures that client changes always apply.
20-
Removes arbitrary limits, such as max length on request strings.
21-
Fixes an issue where ASP.NET Core incorrectly decodes some URL's, which causes some things to randomly fail as bad requests. Google maps is an example of what suffered in previous versions.
22-
Now builds out the full URL based on the raw values sent by the browser. This applies to websockets as well.
23-
Adds the ability to inspect individual websocket messages.
24-
Fixes an issue where the whole body inspection callback was invoked on websockets even if not requested.
25-
Everything is now extremely fast, and stable. No more public changes or additions will be made.</PackageReleaseNotes>
15+
<PackageReleaseNotes>Ensure that we copy response headers only once. It appears that response headers related to content can vanish after we've read the content stream, so to avoid this, we read just once on initial response.
16+
17+
Fixes an issue where the Headers property of HttpMessageInfo objects can be null, which causes null reference exceptions when calling various methods. Changed to always initialize this property with a valid reference, and to perform null checks when accessing internally.</PackageReleaseNotes>
2618
<Title>CitadelCore</Title>
2719
<Summary>Transparent filtering HTTP/S and Websocket/WebsocketSecure proxy.</Summary>
2820
<Description>Transparent filtering HTTP/S and Websocket/WebsocketSecure proxy.</Description>
29-
<Version>4.2.3</Version>
30-
<AssemblyVersion>4.2.3.0</AssemblyVersion>
31-
<FileVersion>4.2.3.0</FileVersion>
21+
<Version>4.2.5</Version>
22+
<AssemblyVersion>4.2.5.0</AssemblyVersion>
23+
<FileVersion>4.2.5.0</FileVersion>
3224
</PropertyGroup>
3325

3426
<ItemGroup Label="dotnet pack instructions">

CitadelCore/Net/Handlers/FilterHttpResponseHandler.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ public override async Task Handle(HttpContext context)
431431
MessageId = requestMessageNfo.MessageId,
432432
BodyContentType = response?.Content?.Headers?.ContentType?.ToString() ?? string.Empty,
433433
IsEncrypted = context.Request.IsHttps,
434-
Headers = response.ExportAllHeaders(),
434+
Headers = responseHeaders,
435435
MessageProtocol = MessageProtocol.Http,
436436
HttpVersion = upstreamReqVersionMatch ?? new Version(1, 0),
437437
StatusCode = response.StatusCode,
@@ -483,7 +483,7 @@ public override async Task Handle(HttpContext context)
483483
MessageId = requestMessageNfo.MessageId,
484484
BodyContentType = response?.Content?.Headers?.ContentType?.ToString() ?? string.Empty,
485485
IsEncrypted = context.Request.IsHttps,
486-
Headers = response.ExportAllHeaders(),
486+
Headers = responseHeaders,
487487
MessageProtocol = MessageProtocol.Http,
488488
HttpVersion = upstreamReqVersionMatch ?? new Version(1, 0),
489489
StatusCode = response.StatusCode,
@@ -553,7 +553,7 @@ public override async Task Handle(HttpContext context)
553553
MessageId = requestMessageNfo.MessageId,
554554
BodyContentType = response?.Content?.Headers?.ContentType?.ToString() ?? string.Empty,
555555
IsEncrypted = context.Request.IsHttps,
556-
Headers = response.ExportAllHeaders(),
556+
Headers = responseHeaders,
557557
MessageProtocol = MessageProtocol.Http,
558558
StatusCode = response.StatusCode,
559559
HttpVersion = upstreamReqVersionMatch ?? new Version(1, 0),
@@ -590,7 +590,7 @@ public override async Task Handle(HttpContext context)
590590
MessageId = requestMessageNfo.MessageId,
591591
BodyContentType = response?.Content?.Headers?.ContentType?.ToString() ?? string.Empty,
592592
IsEncrypted = context.Request.IsHttps,
593-
Headers = response.ExportAllHeaders(),
593+
Headers = responseHeaders,
594594
MessageProtocol = MessageProtocol.Http,
595595
StatusCode = response.StatusCode,
596596
HttpVersion = upstreamReqVersionMatch ?? new Version(1, 0),
@@ -652,7 +652,7 @@ public override async Task Handle(HttpContext context)
652652
using (var responseStream = await response?.Content.ReadAsStreamAsync())
653653
{
654654
context.Response.StatusCode = (int)response.StatusCode;
655-
context.Response.PopulateHeaders(response.ExportAllHeaders(), s_emptyExemptedHeaders);
655+
context.Response.PopulateHeaders(responseHeaders, s_emptyExemptedHeaders);
656656

657657
if (!responseHasZeroContentLength && (upstreamIsHttp1 || responseIsFixedLength))
658658
{

CitadelCore/Net/Http/HttpMessageInfo.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public NameValueCollection Headers
132132
{
133133
get;
134134
internal set;
135-
} = null;
135+
} = new NameValueCollection();
136136

137137
/// <summary>
138138
/// Gets or sets the body content type.
@@ -355,7 +355,7 @@ public void MakeTemporaryRedirect(string location)
355355
{
356356
StatusCode = HttpStatusCode.Redirect;
357357
MessageType = MessageType.Response;
358-
Headers.Clear();
358+
Headers?.Clear();
359359
BodyContentType = string.Empty;
360360

361361
if (_body != null && _body.Length > 0)
@@ -365,8 +365,11 @@ public void MakeTemporaryRedirect(string location)
365365

366366
Body = new Memory<byte>();
367367

368-
Headers["Expires"] = TimeUtil.UnixEpochString;
369-
Headers["Location"] = location;
368+
if (Headers != null)
369+
{
370+
Headers["Expires"] = TimeUtil.UnixEpochString;
371+
Headers["Location"] = location;
372+
}
370373
}
371374

372375
/// <summary>

0 commit comments

Comments
 (0)