Skip to content

Commit cfd4f8b

Browse files
Merge pull request #25 from martincostello/Fix-Port-Handling
Fix default port handling
2 parents 3e5610d + 8348da1 commit cfd4f8b

File tree

6 files changed

+91
-1
lines changed

6 files changed

+91
-1
lines changed

src/HttpClientInterception/HttpClientInterceptorOptions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,11 @@ private static string BuildKey(HttpInterceptionResponse interceptor)
410410
keyPrefix += "IGNOREQUERY;";
411411
}
412412

413+
if (!interceptor.HasCustomPort)
414+
{
415+
builderForKey.Port = -1;
416+
}
417+
413418
return $"{keyPrefix};{interceptor.Method.Method}:{builderForKey}";
414419
}
415420

src/HttpClientInterception/HttpInterceptionResponse.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ internal sealed class HttpInterceptionResponse
3434

3535
internal IEnumerable<KeyValuePair<string, IEnumerable<string>>> ContentHeaders { get; set; }
3636

37+
internal bool HasCustomPort { get; set; }
38+
3739
internal bool IgnoreHost { get; set; }
3840

3941
internal bool IgnorePath { get; set; }

src/HttpClientInterception/HttpRequestInterceptionBuilder.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public class HttpRequestInterceptionBuilder
4343

4444
private Version _version;
4545

46+
private bool _hasCustomPort;
47+
4648
private bool _ignoreHost;
4749

4850
private bool _ignorePath;
@@ -135,6 +137,7 @@ public HttpRequestInterceptionBuilder ForHost(string host)
135137
public HttpRequestInterceptionBuilder ForPort(int port)
136138
{
137139
_uriBuilder.Port = port;
140+
_hasCustomPort = port != -1;
138141
return this;
139142
}
140143

@@ -629,6 +632,7 @@ internal HttpInterceptionResponse Build()
629632
ContentFactory = _contentFactory ?? EmptyContentFactory,
630633
ContentStream = _contentStream,
631634
ContentMediaType = _mediaType,
635+
HasCustomPort = _hasCustomPort,
632636
IgnoreHost = _ignoreHost,
633637
IgnorePath = _ignorePath,
634638
IgnoreQuery = _ignoreQuery,

src/HttpClientInterception/Matching/RegistrationMatcher.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ private static string GetUriStringForMatch(HttpInterceptionResponse registration
6565
{
6666
var builder = new UriBuilder(uri ?? registration.RequestUri);
6767

68+
if (!registration.HasCustomPort)
69+
{
70+
builder.Port = -1;
71+
}
72+
6873
if (registration.IgnoreHost)
6974
{
7075
builder.Host = "*";

tests/HttpClientInterception.Benchmarks/InterceptionBenchmarks.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ public InterceptionBenchmarks()
3939
builder
4040
.Requests()
4141
.ForHttps()
42-
.ForPort(443)
4342
.ForHost("files.domain.com")
4443
.ForPath("setup.exe")
4544
.ForQuery(string.Empty)

tests/HttpClientInterception.Tests/HttpRequestInterceptionBuilderTests.cs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,81 @@ public static void RegisterWith_Validates_Parameters()
10401040
Assert.Throws<ArgumentNullException>("options", () => builder.RegisterWith(null));
10411041
}
10421042

1043+
[Fact]
1044+
public static async Task Using_The_Same_Builder_For_Multiple_Registrations_On_The_Same_Host_Retains_Default_Port()
1045+
{
1046+
// Arrange
1047+
var options = new HttpClientInterceptorOptions()
1048+
{
1049+
ThrowOnMissingRegistration = true
1050+
};
1051+
1052+
var builder = new HttpRequestInterceptionBuilder()
1053+
.ForHttps()
1054+
.ForHost("api.github.com")
1055+
.ForPath("orgs/justeat")
1056+
.RegisterWith(options);
1057+
1058+
// Change to a different scheme without an explicit port
1059+
builder = builder
1060+
.ForHttp()
1061+
.RegisterWith(options);
1062+
1063+
// Act and Assert
1064+
await HttpAssert.GetAsync(options, "http://api.github.com/orgs/justeat");
1065+
await HttpAssert.GetAsync(options, "http://api.github.com:80/orgs/justeat");
1066+
await HttpAssert.GetAsync(options, "https://api.github.com/orgs/justeat");
1067+
await HttpAssert.GetAsync(options, "https://api.github.com:443/orgs/justeat");
1068+
}
1069+
1070+
[Fact]
1071+
public static async Task Using_The_Same_Builder_For_Multiple_Registrations_With_Custom_Ports()
1072+
{
1073+
// Arrange
1074+
var options = new HttpClientInterceptorOptions()
1075+
{
1076+
ThrowOnMissingRegistration = true
1077+
};
1078+
1079+
var builder = new HttpRequestInterceptionBuilder()
1080+
.ForPort(123)
1081+
.ForHttps()
1082+
.ForHost("api.github.com")
1083+
.ForPath("orgs/justeat")
1084+
.RegisterWith(options);
1085+
1086+
// Change to a different scheme without changing the port
1087+
builder = builder
1088+
.ForHttp()
1089+
.RegisterWith(options);
1090+
1091+
// Change the port and not the scheme
1092+
builder = builder
1093+
.ForPort(456)
1094+
.RegisterWith(options);
1095+
1096+
// Change the scheme and use an explicit port
1097+
builder = builder
1098+
.ForHttps()
1099+
.ForPort(443)
1100+
.RegisterWith(options);
1101+
1102+
// Restore default scheme and port
1103+
builder = builder
1104+
.ForHttp()
1105+
.ForPort(-1)
1106+
.RegisterWith(options);
1107+
1108+
// Act and Assert
1109+
await HttpAssert.GetAsync(options, "https://api.github.com:123/orgs/justeat");
1110+
await HttpAssert.GetAsync(options, "http://api.github.com:123/orgs/justeat");
1111+
await HttpAssert.GetAsync(options, "http://api.github.com:456/orgs/justeat");
1112+
await HttpAssert.GetAsync(options, "https://api.github.com/orgs/justeat");
1113+
await HttpAssert.GetAsync(options, "https://api.github.com:443/orgs/justeat");
1114+
await HttpAssert.GetAsync(options, "http://api.github.com/orgs/justeat");
1115+
await HttpAssert.GetAsync(options, "http://api.github.com:80/orgs/justeat");
1116+
}
1117+
10431118
private sealed class CustomObject
10441119
{
10451120
internal enum Color

0 commit comments

Comments
 (0)