Skip to content

Commit ecbcbb7

Browse files
authored
Merge pull request #33 from nblumhardt/request-uri-bug
Correctly follow relative redirect locations
2 parents 4aa0c71 + e4cc71b commit ecbcbb7

File tree

6 files changed

+48
-28
lines changed

6 files changed

+48
-28
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,3 @@ Periodically GET an HTTP resource and write response metrics to Seq. These can t
1616
- if the URL is an HTTPS URL, the Seq server must trust the SSL certificate used by the server
1717
- the response will be fully downloaded on every check, so ideally the resource won't be more than a few kB
1818
7. Enter a probing interval in seconds; each event is stored internally in Seq, so be aware that shorter intervals will consume more space
19-

src/Seq.Input.HealthCheck/HttpHealthCheck.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public async Task<HealthCheckResult> CheckNow(CancellationToken cancel)
7171
var redirectCount = 0;
7272

7373
var probeId = Nonce.Generate(12);
74-
var probedUrl = _bypassHttpCaching ? UrlHelper.AppendParameter(_targetUrl, ProbeIdParameterName, probeId) : _targetUrl;
74+
var probedUrl = _bypassHttpCaching ? UriHelper.AppendParameter(_targetUrl, ProbeIdParameterName, probeId) : _targetUrl;
7575

7676
var finalUrl = probedUrl;
7777

@@ -80,7 +80,7 @@ public async Task<HealthCheckResult> CheckNow(CancellationToken cancel)
8080

8181
try
8282
{
83-
(var response, finalUrl, redirectCount) = await SendRequest(cancel, probedUrl, probeId);
83+
(var response, finalUrl, redirectCount) = await SendRequest(probedUrl, probeId, cancel);
8484

8585
statusCode = (int) response.StatusCode;
8686
contentType = response.Content.Headers.ContentType?.ToString();
@@ -136,25 +136,25 @@ void AddHeadersToRequest(HttpRequestMessage request, string probeId)
136136
request.Headers.CacheControl = new CacheControlHeaderValue {NoStore = true};
137137
}
138138

139-
async Task<(HttpResponseMessage, string, int)> SendRequest(CancellationToken cancel, string requestUri, string correlationId)
139+
async Task<(HttpResponseMessage, string, int)> SendRequest(string requestUri, string correlationId, CancellationToken cancel)
140140
{
141141
HttpResponseMessage response = null!;
142142
var totalRedirects = 0;
143143

144-
for (int i = 0; i <= MaxRedirectCount; i++)
144+
for (var i = 0; i <= MaxRedirectCount; i++)
145145
{
146146
var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
147147
AddHeadersToRequest(request, correlationId);
148148

149149
response = await _httpClient.SendAsync(request, cancel);
150150
var statusCode = (int) response.StatusCode;
151151

152-
if (_shouldFollowRedirects && statusCode is >= 300 and <= 399)
152+
if (_shouldFollowRedirects && statusCode is >= 300 and < 400)
153153
{
154154
var locationHeader = response.Headers.Location;
155155
if (locationHeader is not null)
156156
{
157-
requestUri = locationHeader.ToString();
157+
requestUri = UriHelper.MakeAbsoluteLocation(requestUri, locationHeader.ToString());
158158
continue;
159159
}
160160
}

src/Seq.Input.HealthCheck/Util/UrlHelper.cs renamed to src/Seq.Input.HealthCheck/Util/UriHelper.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
namespace Seq.Input.HealthCheck.Util;
2020

21-
static class UrlHelper
21+
static class UriHelper
2222
{
2323
public static string AppendParameter(string targetUrl, string name, string value)
2424
{
@@ -31,4 +31,13 @@ public static string AppendParameter(string targetUrl, string name, string value
3131
[name] = value
3232
});
3333
}
34+
35+
public static string MakeAbsoluteLocation(string requestUri, string locationHeader)
36+
{
37+
var location = new Uri(locationHeader, UriKind.RelativeOrAbsolute);
38+
if (location.IsAbsoluteUri) return locationHeader;
39+
40+
var baseUri = new Uri(requestUri, UriKind.Absolute);
41+
return new Uri(baseUri, location).ToString();
42+
}
3443
}

test/Seq.Input.HealthCheck.Tests/Seq.Input.HealthCheck.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFramework>net8.0</TargetFramework>
5-
5+
<Nullable>enable</Nullable>
66
<IsPackable>false</IsPackable>
77
</PropertyGroup>
88

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using Seq.Input.HealthCheck.Util;
2+
using Xunit;
3+
4+
namespace Seq.Input.HealthCheck.Tests.Util;
5+
6+
public class UriHelperTests
7+
{
8+
[Theory]
9+
[InlineData("https://example.com", "https://example.com?q=42")]
10+
[InlineData("https://example.com/p", "https://example.com/p?q=42")]
11+
[InlineData("https://example.com/p/", "https://example.com/p/?q=42")]
12+
[InlineData("https://example.com?a", "https://example.com?a&q=42")]
13+
[InlineData("https://example.com?a=1", "https://example.com?a=1&q=42")]
14+
public void ParametersAreAppendedCorrectly(string initial, string expected)
15+
{
16+
var actual = UriHelper.AppendParameter(initial, "q", "42");
17+
Assert.Equal(expected, actual);
18+
}
19+
20+
[Theory]
21+
[InlineData("https://example.com", "https://www.example.com", null)]
22+
[InlineData("https://example.com", "https://example.datalust.co", null)]
23+
[InlineData("https://example.com", "https://example.com:1234/test?x=y", null)]
24+
[InlineData("https://example.com", "/test", "https://example.com/test")]
25+
[InlineData("https://example.com/health?x=y", "/test", "https://example.com/test")]
26+
public void LocationHeadersAreMadeAbsolute(string requestUri, string locationHeader, string? expected)
27+
{
28+
var actual = UriHelper.MakeAbsoluteLocation(requestUri, locationHeader);
29+
Assert.Equal(expected ?? locationHeader, actual);
30+
}
31+
}

test/Seq.Input.HealthCheck.Tests/Util/UrlHelperTests.cs

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)