Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The hostname could not be parsed #1040

Closed
WalterEbbers opened this issue Jun 17, 2020 · 13 comments
Closed

The hostname could not be parsed #1040

WalterEbbers opened this issue Jun 17, 2020 · 13 comments
Labels
invalid This doesn't seem right

Comments

@WalterEbbers
Copy link

WalterEbbers commented Jun 17, 2020

Hi,

In a production environment from one of our customers we recieve a message that MailKit produces a "UriFormatException: The hostname could not be parsed error".
They use a internal mailserver with the following SMTP server name: "servername.network.local" and are connecting to it through port 25.

We hoped that this would work but it seems that somehow MailKit does not support it.

In a previous release or our webservice where we were still using the SMTP client from the .NET Framework 4.6.1 it was working without issues.

The only thing between our product releases that was changed is that we replaced the default .NET Framework SMTP client with the MailKit implemententation.

Unfortunatly we don't have a internal mailserver our self(we use office365) and were are not able to reproduce the issue.

The webservice is build upon .NET Framework 4.6.1 and uses MailKit 2.2.0.
Upgrading MailKit to 2.7.0 wont be easy as the customer has a strict update policy which prevents us from delivering updates on the fly or only lets us deliver a update if we are certain that the update will fix the issue(by supplying changelogs and such).

Is this a known issue?
Or was this a known issue that has been patched?
Screenshot of the error as sent to us by the customer:

Unfortunatly we are not able to provide a log as this feature is not implemented(but we certenly will do in a future release).

image

We use the code below to create a connection:

                if (emailSettings.SmtpPort.Value == 25 || emailSettings.SmtpPort.Value == 587)
                {
                    client.Connect(emailSettings.SmtpHost, emailSettings.SmtpPort.Value,
                        emailSettings.SmtpEnableSsl ? MailKit.Security.SecureSocketOptions.StartTlsWhenAvailable : MailKit.Security.SecureSocketOptions.None);
                }
                else
                {
                    client.Connect(emailSettings.SmtpHost, emailSettings.SmtpPort.Value,
                        emailSettings.SmtpEnableSsl ? MailKit.Security.SecureSocketOptions.SslOnConnect : MailKit.Security.SecureSocketOptions.None);
                }

Kind regards,

Walter Ebbers

@jstedfast
Copy link
Owner

The exception is being thrown in new Uri (...), so the Uri parser in .NET does not like the hostname for some reason.

Does it have international characters in it?

What about the username they they are using? (the Uri string passed to the Uri .ctor is of the form imap://username@server.com so it's possible that the Uri parser is thinking that the username is the hostname).

It might be a bug in the Uri parser or it might be that MailKit needs to IDN-encode the hostname or perhaps it isn't hex-encoding the username correctly.

There's just way too many unknowns for me to have any idea what is wrong without more information.

@jstedfast
Copy link
Owner

Actually, looking at the stacktrace again, it looks like it's actually in the COmputeDefaultValues() method which does not take into consideration the username.

https://github.com/jstedfast/MailKit/blob/master/MailKit/Net/Imap/ImapClient.cs#L1175

BUT based on that code, it might be the port being serialized to a string (although I'm not sure about that because I would imagine that the error message in the Uri parser exception would have told us it was in the port or something other than claiming it was the hostname it couldn't parse).

@WalterEbbers
Copy link
Author

WalterEbbers commented Jun 18, 2020

Hi,
sorry for the late answer but the hostname they are using is "ms-ovt-003.netwerk.local".
Username and password are empty. We have a check on this, that if username or password is empty we will not call the authenticate. But the code does not come to this stage since it throws a exception at Connect().

The port we fill is of type "int" and is a requirement. It is always filled.

Hope this info helps :)

@jstedfast
Copy link
Owner

Right, but what is the port value? If their locale formats integers with commas, that could cause new Uri ($"imap://ms-ovt-003.netwerk.local:{port}"); to fail.

jstedfast added a commit that referenced this issue Jun 18, 2020
@WalterEbbers
Copy link
Author

WalterEbbers commented Jun 18, 2020

The value is 25 for their port.
We save the value of the int as the int value to our database.
If they fill in 25 then 25 will be saved to the db and retrieved as 25 from the db.
Not sure if this helps though, but its currently the only info i'm able to give regarding port.

Regarding locale, are you referring to the regional settings from the windows server for this? Or something else?

@jstedfast
Copy link
Owner

The .NET CultureInfo being used by the program.

I don't think port 25 would get written as anything other than "25" in any culture, would it? I have no idea, but the only cases I know of where it might be vary is when the integer value is >= 1000 (i.e. "1,000" or "1.000" vs "1000")

@WalterEbbers
Copy link
Author

The .NET CultureInfo being used by the program.

I don't think port 25 would get written as anything other than "25" in any culture, would it? I have no idea, but the only cases I know of where it might be vary is when the integer value is >= 1000 (i.e. "1,000" or "1.000" vs "1000")

yeah i would also think 25 would just be 25 :)
I saw you referenced this topic in a commit.
Do you think that commit could be the fix?

@jstedfast
Copy link
Owner

It's possible, but I have no idea if it actually fixes the issue. I can't replicate the exception with the information you've given me.

@WalterEbbers
Copy link
Author

hmmm Okay,
Is there any information you need?
.NET CultureInfo would be one i probably won't be able to retrieve immediately as we don't log this data and we would need to create that logging.

@jstedfast
Copy link
Owner

You could write a test program for them that prints out what the port looks like when formatted as a string.

If you wanted to get fancy, you could print out all of the CultureInfo.CurrentCulture.NumberFormat values like this (en-us):

NumberFormatInfo { CurrencyDecimalDigits=2, CurrencyDecimalSeparator=".", CurrencyGroupSeparator=",", CurrencyGroupSizes=int[1] { 3 }, CurrencyNegativePattern=0, CurrencyPositivePattern=0, CurrencySymbol="$", DigitSubstitution=None, IsReadOnly=true, NaNSymbol="NaN", NativeDigits=string[10] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, NegativeInfinitySymbol="-∞", NegativeSign="-", NumberDecimalDigits=2, NumberDecimalSeparator=".", NumberGroupSeparator=",", NumberGroupSizes=int[1] { 3 }, NumberNegativePattern=1, PercentDecimalDigits=2, PercentDecimalSeparator=".", PercentGroupSeparator=",", PercentGroupSizes=int[1] { 3 }, PercentNegativePattern=1, PercentPositivePattern=1, PercentSymbol="%", PerMilleSymbol="‰", PositiveInfinitySymbol="∞", PositiveSign="+" }

The most important info is:

NumberGroupSeparator=","

and

NumberGroupSizes=int[1] { 3 }

@WalterEbbers
Copy link
Author

WalterEbbers commented Jun 19, 2020

You could write a test program for them that prints out what the port looks like when formatted as a string.

If you wanted to get fancy, you could print out all of the CultureInfo.CurrentCulture.NumberFormat values like this (en-us):

NumberFormatInfo { CurrencyDecimalDigits=2, CurrencyDecimalSeparator=".", CurrencyGroupSeparator=",", CurrencyGroupSizes=int[1] { 3 }, CurrencyNegativePattern=0, CurrencyPositivePattern=0, CurrencySymbol="$", DigitSubstitution=None, IsReadOnly=true, NaNSymbol="NaN", NativeDigits=string[10] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, NegativeInfinitySymbol="-∞", NegativeSign="-", NumberDecimalDigits=2, NumberDecimalSeparator=".", NumberGroupSeparator=",", NumberGroupSizes=int[1] { 3 }, NumberNegativePattern=1, PercentDecimalDigits=2, PercentDecimalSeparator=".", PercentGroupSeparator=",", PercentGroupSizes=int[1] { 3 }, PercentNegativePattern=1, PercentPositivePattern=1, PercentSymbol="%", PerMilleSymbol="‰", PositiveInfinitySymbol="∞", PositiveSign="+" }

The most important info is:

NumberGroupSeparator=","

and

NumberGroupSizes=int[1] { 3 }

Once i get back monday i'll whip up a test console app and get our support department to make contact with the customer to try it.

edit 22-06-2020
@jstedfast i have made a console app that will read out the culture info on the service. Once placed and executed they will provide me with a log file.

edit 29-06-2020
@jstedfast unfortunatly my collegue from the support department who has this customer under his wing has not been able to use the logging. Will keep this post updated when i hear something new :)

@WalterEbbers
Copy link
Author

@jstedfast some happy news here.
We were able to look in the software and we saw that the smtp addres(.local) had a extra space at the end. When we removed that, everything worked out okay.

It seems that microsofts old smtp implementation was okay with this since the settings where never changed according to the servermanager.

I have made a bugreport for our frontend developers(internal) to add extra validation for this for the next patch or our wpf client.

Thnx for all the help!

@jstedfast
Copy link
Owner

No problem and glad you figured out the issue!

@jstedfast jstedfast added the invalid This doesn't seem right label Jul 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid This doesn't seem right
Projects
None yet
Development

No branches or pull requests

2 participants