-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Fix Uri.Host for IPv6 Link-local address #29829
Conversation
@dotnet-bot test Outerloop Linux x64 Release Build please |
@@ -2616,6 +2618,10 @@ private static string CreateHostStringHelper(string str, ushort idx, ushort end, | |||
{ | |||
flags |= Flags.LoopbackHost; | |||
} | |||
if(linkLocalAddress) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add space after 'if'
if(linkLocalAddress) | ||
{ | ||
flags |= Flags.LinkLocalAddress; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add newline after closing brace
[Fact] | ||
public void IdnDnsSafeHost_IPv6HostLinkLocalAddress_ScopeIdButNoBrackets() | ||
{ | ||
Uri test = new Uri("http://[fe80::e077:c9a3:eeba:b8e9%18]/"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should refactor this duplicated string, "fe80::e077:c9a3:eeba:b8e9%18" into a constant in this test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i copied the pattern from test above https://github.com/MarcoRossignoli/corefx/blob/2d9eddafdf568afab7a8bb730415bfce9b885a15/src/System.Private.Uri/tests/FunctionalTests/IdnDnsSafeHostTest.cs#L41 do you confirm this refactoring?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i copied the pattern from test above https://github.com/MarcoRossignoli/corefx/blob/2d9eddafdf568afab7a8bb730415bfce9b885a15/src/System.Private.Uri/tests/FunctionalTests/IdnDnsSafeHostTest.cs#L41 do you confirm this refactoring?
Following existing code and test patterns can be useful. But it doesn't work in all cases. Sometimes there are bad patterns in the code. And we don't change them all, but try to add better code for new PRs. Also, the pattern you cited uses simpler IP literals. This test uses a long IPv6 literal. So, for code cleanliness and ease of maintenance, it's better to consolidate if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done with [Theory]
could be useful for future new data, if you like.
@dotnet-bot test Outerloop Linux x64 Release Build please |
@@ -2617,11 +2617,12 @@ private static string CreateHostStringHelper(string str, ushort idx, ushort end, | |||
if (loopback) | |||
{ | |||
flags |= Flags.LoopbackHost; | |||
} | |||
if(linkLocalAddress) | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There seems to be extra whitespace (space or tabs) after this closing brace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@dotnet-bot test Outerloop Linux x64 Release Build please, on my Ubuntu 18.04 outerloop works well, i want to understand if the issue is related to SO version. |
@dotnet-bot test Linux x64 Release Build please |
@dotnet-bot test Outerloop Linux x64 Release Build please |
GetAsync_IPv6LinkLocalAddressUri_Success is failing with this change with CurlHandler on several distros: |
@stephentoub i need to setup an Ubuntu 14.04, i think depends on SO version(on my 18.04 it's ok, also on CI), let me try! EDIT(22/5): i repro issue with Ubuntu 14.04, i think depends on curl version, i'm checking fix/releases |
@dotnet-bot test Windows x64 Debug Build |
UPDATE: after some research i discovered that there is a difference in ipv6 parsing between curl versions, this PR change the way of parsing Fixed in 7.37.0 - May 21 2014 Ubuntu 14.04 use curl ver 7.35.0( |
@dotnet-bot test Outerloop Linux x64 Release Build please |
string url = requestUri.Host == idnHost ? | ||
requestUri.AbsoluteUri : | ||
new UriBuilder(requestUri) { Host = idnHost }.Uri.AbsoluteUri; | ||
string url = requestUri.Host == idnHost ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as the tests would catch that break, I think the change is probably okay. The fix to add brackets on idnHost
is risky enough that it will require more investigation.
@@ -263,7 +263,8 @@ private void SetUrl() | |||
Uri requestUri = _requestMessage.RequestUri; | |||
|
|||
long scopeId; | |||
if (IsLinkLocal(requestUri, out scopeId)) | |||
bool isLinkLocal = false; | |||
if ((isLinkLocal = IsLinkLocal(requestUri, out scopeId))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: indentation is off
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
new UriBuilder(requestUri) { Host = idnHost }.Uri.AbsoluteUri; | ||
string url = requestUri.Host == idnHost ? | ||
requestUri.AbsoluteUri : | ||
new UriBuilder(requestUri){ Host = isLinkLocal && (scopeIdIndex = idnHost.IndexOf("%", StringComparison.OrdinalIgnoreCase)) != -1 ? idnHost.Substring(0, scopeIdIndex) : idnHost}.Uri.AbsoluteUri; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The IndexOf can just be idnHost.IndexOf('%')
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you're right
@@ -31,7 +31,8 @@ internal static string ParseCanonicalName(string str, int start, ref bool isLoop | |||
((long*)numbers)[0] = 0L; | |||
((long*)numbers)[1] = 0L; | |||
isLoopback = Parse(str, numbers, start, ref scopeId); | |||
return '[' + CreateCanonicalName(numbers) + ']'; | |||
linkLocalAddress = numbers[0] == 0xfe80; | |||
return '[' + CreateCanonicalName(numbers) + (linkLocalAddress ? scopeId : "") + ']'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: the compiler will help fix this up, but it'd be better to use "["
and "]"
rather than '['
and ']'
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enlighten me...why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we want this to compile down to the efficient string.Concat(string, string, string, string)
call. If the compiler didn't help here, this would end up being a call to string.Concat(params object[] args)
, which would result in an object[] allocation, the chars getting boxed (so two more allocations), and then having ToString called on them (so two more allocations), plus having a string array allocated in the Concat implementation to store the ToString on each input. As of dotnet/roslyn#415, the C# compiler should do the conversion from e.g. '[' to "[" for you, but why make it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
understood TYVM!
@@ -114,6 +114,7 @@ private enum Flags : ulong | |||
FragmentIriCanonical = 0x40000000000, | |||
IriCanonical = 0x78000000000, | |||
UnixPath = 0x100000000000, | |||
LinkLocalAddress = 0x200000000000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"LinkLocalAddress -> "IPv6LinkLocalAddress"
@@ -2616,6 +2618,11 @@ private static string CreateHostStringHelper(string str, ushort idx, ushort end, | |||
{ | |||
flags |= Flags.LoopbackHost; | |||
} | |||
if (linkLocalAddress) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add newline above this 'if' statement.
[Theory] | ||
[SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] | ||
[InlineData("fe80::e077:c9a3:eeba:b8e9", "%18")] | ||
public void IdnDnsSafeHost_IPv6HostLinkLocalAddress_ScopeIdButNoBrackets(string address, string zoneIndex) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"ScopeIdButNoBrackets" part of the test name isn't quite right since there is an Assert in this test that validates for brackets.
Normally we don't have a single test method that test multiple properties. But I see that there is already other tests that do this in this file.
I suggest, though, that you rename the test like this:
"IdnDnsSafeHost_IPv6HostLinkLocalAddress_ScopeIdCorrectlyFormatted"
[SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] | ||
public void Host_IPv6LinkLocalAddress_HasScopeId(string address, string zoneIndex) | ||
{ | ||
string scopedLiteralIpv6 = "[" + address + zoneIndex + "]"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"scopedLiteralIpv6" -> "scopedLiteralIpv6Brackets" to be more consistent with variable naming in the tests above.
[InlineData("fe81::e077:c9a3:eeba:b8e9", "%18")] | ||
public void Host_NonIPv6LinkLocalAddress_NoScopeId(string address, string zoneIndex) | ||
{ | ||
string scopedLiteralIpv6 = "[" + address + zoneIndex + "]"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"scopedLiteralIpv6" -> "scopedLiteralIpv6Brackets" to be more consistent with variable naming in the tests above.
@dotnet-bot test Outerloop Linux x64 Release Build please |
@@ -45,6 +45,21 @@ public void IdnDnsSafeHost_IPv6Host_ScopeIdButNoBrackets() | |||
Assert.Equal("[::1]", test.Host); | |||
} | |||
|
|||
[Theory] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We usually use [Theory]
for multiple test data. So here
- you can add more test data (
[InlineData]
) - or use
[Fact]
, without taking any parameters, and create a constant in the test. As David mentioned here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
@dotnet-bot test this please @dotnet-bot test Outerloop Windows x64 Debug Build |
@dotnet-bot test Outerloop Windows x64 Debug Build |
{ | ||
string address = "fe80::e077:c9a3:eeba:b8e9"; | ||
string zoneIndex = "%18"; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use
const string ScopedLiteralIpv6 = "fe80::e077:c9a3:eeba:b8e9%18";
since address
and zoneIndex
is not used anywhere else in the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh yes i missed it sorry
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, updated also other test with constants.
@dotnet-bot test Outerloop Windows x64 Debug Build |
LGTM once CI is green. |
@dotnet-bot test Outerloop Windows x64 Debug Build |
1 similar comment
@dotnet-bot test Outerloop Windows x64 Debug Build |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
@dotnet/ncl Any additional feedback?
@@ -1193,7 +1194,7 @@ public string DnsSafeHost | |||
if (HostType == Flags.IPv6HostType) | |||
{ | |||
ret = ret.Substring(1, ret.Length - 2); | |||
if ((object)_info.ScopeId != null) | |||
if ((object)_info.ScopeId != null && (_flags & Flags.IPv6LinkLocalAddress) == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: We can add a comment here to explain the purpose for the new flag. i,e,. to avoid duplicated ScopeId
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added, with new line before for readability, let me know if it's ok.
@dotnet-bot test Outerloop Windows x64 Debug Build |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a solid, well scoped change to me. It's unfortunate that we have to special case the behavior on Curl, but I think that the change you made there is correct. Pending approval from either @davidsh or @stephentoub, this looks good to me.
This reverts commit f7a8cf1.
Contributes to dotnet/corefx#28863 Replace PR dotnet/corefx#29769 after revert dotnet/corefx#29818 for Outerloop CI fail This PR address the second part of issue: Uri.Host LLA (Link-local address) IPv6 address doesn't contain %number part. Currently it returns [fe80::e077:c9a3:eeba:b8e9], it should return [fe80::e077:c9a3:eeba:b8e9%18]. Note: Uri.IdnHost correctly contains the %number part. Commit migrated from dotnet/corefx@f7a8cf1
…" (dotnet/corefx#30062) This reverts commit dotnet/corefx@f7a8cf1. Commit migrated from dotnet/corefx@e5bb0b5
contributes to #28863
replace PR #29769 after revert #29818 for Outerloop CI fail
this PR address the second part of issue:
Uri.Host
LLA (Link-local address) IPv6 address doesn't contain%number
part.[fe80::e077:c9a3:eeba:b8e9]
, it should return[fe80::e077:c9a3:eeba:b8e9%18]
.Uri.IdnHost
correctly contains the%number
part.cc: @rmkerr @Caesar1995 @davidsh @stephentoub