HttpWebRequest NameResolutionFailure exception in .NET (with Mono on Ubuntu) - c#

I have a .NET program running on Ubuntu via Mono 2.10
The program downloads a webpage via an HttpWebRequest every minute or so which works fine most of the time:
String result;
WebResponse objResponse;
WebRequest objRequest = System.Net.HttpWebRequest.Create(url);
using (objResponse = objRequest.GetResponse())
{
using (StreamReader sr =
new StreamReader(objResponse.GetResponseStream()))
{
result = sr.ReadToEnd();
// Close and clean up the StreamReader
sr.Close();
}
}
The problem is that after few days I start getting exceptions thrown:
DateTime: 01/25/2012 08:15:41
Type: System.Net.WebException
Error: Error: NameResolutionFailure
Stack:
at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0
at System.Net.HttpWebRequest.GetResponse () [0x00000] in <filename unknown>:0
at socks_server.Program.readHtmlPage (System.String url) [0x00000] in <filename unknown>:0
at socks_server.Program.getAccessKeysProc () [0x00000] in <filename unknown>:0
The server is still abel to resolve DNS, for example
wget http://www.google.com
Will return the file without any probelm as will ping and other commands that resolve DNS.
My program however will continue to throw that exception until I restart it. After restarting the application it will start working again as it should.
I have checked open file counts on the system (400 ish), memory usage (327mb of 4gb), CPU usage (2-3%) and all are OK.
Any ideas?

You can solve it by translating the host name to ip and add the host name to Headers collection or to Host property.
If your url is http://example.com/uri. Resolve the host yourself. Suppose its 1.2.3.4. It'll be http://1.2.3.4/uri. Now add Host: example.com header to your request. I think it can be done by setting HttpWebRequest.Host property.

I know this is an old post, but was facing the same error, so thought to share the solution.
The best solution I found, when that exception occurs while the Wifi
is connected, is just to retry my server call with a slight sleep in
between. It works most of the time, otherwise if the second call
fails I cancel the request.
This error can also raise if the user's Wifi is very unstable or the
signal is very low. The same error occurs if there is no internet
connection at all, even if connected to Wifi.
This is in line with my ans on :
System.Net.WebException: Error: NameResolutionFailure when Calling WCF Services throwing exception in mono android application

Well I use the HttpClient - but it might be a similar problem. I had the same issue on a Android device (it worked on a Windows Phone)... But after I added the Host to the header it worked!
client.DefaultRequestHeaders.Host = "mydomain.com";
You can still use the name in the url (you don't have to use the IP address)

I was experiencing the same issue in my mono application on raspbian. I've tried different solutions described in this and other threads but none worked. Eventually, I was able to fix the problem by changing the name servers in /etc/resolv.conf to the google ones https://developers.google.com/speed/public-dns/
Mirko

I was getting this error when I started the mobile app (android or iOS it does not matter) without internet connection. After restored the connection every request returns "NameResolutionFailure exception". I had to wait 120 seconds for having the http request working again. Setting the following line of code anywhere in the app startup the error was finally gone.
System.Net.ServicePointManager.DnsRefreshTimeout = 0;
The default DnsRefreshTimeout value is 120 seconds.

Related

Xamarin Android FTP authentication problem on startup

I'm developing an Android application in C# language with Xamarin.
In this application I need a service that starts after the device boot and upload files in a FTP server.
If I start this service with a button click action all works good, but if I use a BroadcastReceiver and I intercept the BOOT_COMPLETED event to start the FTP connection, I receive this error:
ex.Message: The authentication or decryption has failed.
ex.StackTrace: at System.Net.FtpWebRequest.EndGetRequestStream (System.IAsyncResult asyncResult)
at System.Net.FtpWebRequest.GetRequestStream ()
at TestProject.FTPUtility.upload (System.String userName, System.String password, System.String sourceFile, System.String targetFile)
I don't understand why I receive the authentication or decryption error only if the service starts on startup. I tried also to start the connection only after a ping success (to wait the device internet connection) but nothing is changed.
I solved the problem with this line of code:
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

Mono HTTPS Error - "Error Writing Headers"

Scope:
I am trying to integrate with an external centralized Logging service provider, using HTTPS requests to post the logs to it.
We are running C# on top of Mono, using Ubuntu 14.04 LTS as the OS.
We have been using mono for years already, so we are somehow familiar with it's behaviors and potential flaws / issues.
Previous Setup
When you google this issue, you find basically two solutions to it, and none of them worked to me, for this case. Here's what I have done so far
Basic Mono-Complete Setup + ca-certificates-mono (that would potentially solve HTTPS related issues).
Other than that, I know that mono does not trust any certificate by default, having it's own certificates-chain, and that we have to import them to it. To do that I ran mozroots --import --sync --ask-remove and it printed me that "140 certificates were downloaded and installed".
Aditionally, we overrode the CertificateValidationCallback using this nasty one-liner:
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => { return true; };
None of the above solved our issue.
Errors, Errors and more Errors:
Note that all of the codes below do work on Windows.
So far we have tried:
Using Native .NET WebClient Async Calls (PostAsync).
As the result, we get errors such as Cant find file system.net.http.dll, and once we actually copy the one from our windows system to it, we get another error Task Exception (can't remember the exact message there).
Using ModernHttpClient
Apparently, using this client on Xamarin programs tend to solve the issues people have, but we still get the same errors listed above, using the standard HttpClient class from .NET
Writing our own WebRequests Wrapper
This was the closest we got to an actual solution, that leads to Error Writing Headers when running it on Mono.
Small Code Sample:
using (WebRequests webClient = new WebRequests ())
{
// Client Configuration
webClient.BufferSize = 32 * 1024;
webClient.Accept = "application/json";
webClient.ContentType = "application/json; charset=" + Encoding.UTF8.HeaderName;
webClient.Timeout = 60000;
webClient.ReadWriteTimeout = 60000;
webClient.Encoding = Encoding.UTF8.WebName;
// Dummy Logz Payload - One Json Per Line
string LogzPayload = "{id:'1', value='1'}\n{id:'2', value='2'}";
// Request to Logz
webClient.Post ("https://listener-4.logz.io:8071/?token=OUR_TOKEN&type=json", LogzPayload);
}
Update 1:
Just tried running the following command and got an exception right away:
certmgr --ssl https://listener-4.logz.io:8071/?token=OUR_TOKEN&type=json --machine
Exception:
Unhandled Exception:
System.IO.IOException: The authentication or decryption has failed. ---> System.IO.IOException: The authentication or decryption has failed. ---> Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed.
at Mono.Security.Protocol.Tls.RecordProtocol.EndReceiveRecord (IAsyncResult asyncResult) <0x4192e470 + 0x00132> in <filename unknown>:0
at Mono.Security.Protocol.Tls.SslClientStream.SafeEndReceiveRecord (IAsyncResult ar, Boolean ignoreEmpty) <0x4192e3a0 + 0x00031> in <filename unknown>:0
at Mono.Security.Protocol.Tls.SslClientStream.NegotiateAsyncWorker (IAsyncResult result) <0x4192abb0 + 0x00225> in <filename unknown>:0
--- End of inner exception stack trace ---
I'm not very familiar with Mono but I know that they use their own TLS stack whereas .NET uses the TLS stack from the OS. If I'm correct than the available cipher suites are defined in CipherSuiteFactory.cs which shows that no ECDHE and no DHE ciphers are available. But from what I can see the server supports only ECDHE and DHE ciphers and thus there will be no shared ciphers and the TLS handshake will fail. The ciphers supported by the server are:
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-RSA-AES128-GCM-SHA256
DHE-RSA-AES256-GCM-SHA384
DHE-RSA-AES128-GCM-SHA256
ECDHE-RSA-AES256-SHA384
ECDHE-RSA-AES256-SHA
DHE-RSA-AES256-SHA256
DHE-RSA-AES256-SHA
Most of these are ciphers need TLS 1.2 which is not supported by Mono at all (see State of TLS in Mono). But even the rest is DHE or ECDHE only which Mono does not seem to support. They are actively working on a new TLS stack but it looks like it is not done yet.
If you have access to the server you might try to configure the cipher AES256-SHA which is probably the best cipher currently supported by Mono.
I recommend you to switch to Ubuntu 16.04 because that brings a version of Mono's packages that syncs certificates by default and therefore you don't need to run mozroots, and you will more likely to not have problems around this area.

ParseExceptions not getting thrown for CallFunctionAsync

I recently updated my client sdk to parse 1.6.2 for xamarin, and I noticed that ParseExceptions are no longer getting thrown properly.
When calling something like this:
string result = await ParseCloud.CallFunctionAsync<string>( "function" )
If that function calls response.error I get:
System.Net.WebException The remote server returned an error: (400) Bad Request.
Raw
at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x0005e] in /Users/builder/data/lanes/2377/73229919/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:944
Where as in the pass it would generate a ParseException with the contents of the response.error. The WebException also does not have an inner exception to inspect.
I also thought it had something to do with my cloud code, but I find a similar problem with user login. A bad password generates this exception now:
System.Net.WebException The remote server returned an error: (404) Not Found.
Raw
at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x0005e] in /Users/builder/data/lanes/2377/73229919/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:944
A few other things were upgraded when I updated the parse sdk. I'm now using xamarin forms 2.* instead of 1.5.* and I think the mono system libraries were also updated.

YouTube Api Xamarin Android App PCL HttpClient issue

I have created a PCL in Visual Studio targeting: .NET 4.5, Windows Phone 8, Windows Store Apps, Xamarin Android and Xamarin iOS.
This PCL integrates with the YouTube Data API v3 via HttpClient requests (have some issues using the client library directly).
I have written and successfully run unit tests which test this integration in Visual Studio (test project referencing PCL project), however, when I consume those methods in a Xamarin Android project (in Xamarin Studio) I am getting a Forbidden 403 error on one of the GET methods (search.list - GetStringAsync below), POST methods appear to work fine.
The method in question is as follows:-
public async Task<Google.Apis.YouTube.v3.Data.SearchListResponse> GetVideosForChannelManual(string channelId, string apiKey, string pageToken)
{
var requestString = "https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=50";
requestString += "&channelId=" + channelId;
requestString += "&key=" + apiKey;
if (!String.IsNullOrEmpty(pageToken))
{
requestString += "&pageToken=" + pageToken;
}
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var task = await client.GetStringAsync(requestString);
var deserializedResponse = JsonConvert.DeserializeObject<Google.Apis.YouTube.v3.Data.SearchListResponse>(task);
return deserializedResponse;
}
}
The detail of the exception is below:-
[0] {System.Net.Http.HttpRequestException: 403 (Forbidden)
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode () [0x00000] in <filename unknown>:0
at System.Net.Http.HttpClient+<GetStringAsync>c__async5.MoveNext () [0x00000] in <filename unknown>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0
at System.Runtime.CompilerServices.TaskAwaiter`1[System.String].GetResult () [0x00000] in <filename unknown>:0
at YouTubeHelpers.YouTubeRepository+<GetVideosForChannelManual>d__27.MoveNext () [0x000fa] in c:\...\YouTubeRepository.cs:187
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0
at System.Runtime.CompilerServices.TaskAwaiter`1[Google.Apis.YouTube.v3.Data.SearchListResponse].GetResult () [0x00000] in <filename unknown>:0
at YouTubeHelpers.YouTubeRepository+<GetAllVideosForChannelManual>d__20.MoveNext () [0x00061] in c:\..\YouTubeRepository.cs:160 } System.Net.Http.HttpRequestException
My initial thoughts are that the Http request headers are different when running it on Android compared to directly in VS and so attempted to compare in Fiddler using a reverse proxy on the emulator (problem exists in emulator and on hardware device), but I was unable to get the app to send web traffic through the proxy (even though browser traffic was sent to fiddler correctly).
Presumably the HttpClient handler would have to be set for this proxy, but with limited access to System.Net libraries in the PCL it wasn't clear how to achieve this.
Is there something which I should be setting additionally for these GET requests bearing in mind that in the POST requests (insert like, insert subscription for example) where I explicitly send an OAuth2 token as an authentication header (required) work fine?
Any advice would be appreciated.
UPDATE
Tried using ModernHttpClient, but the exception still persists. Still feel this is something to do with the request headers, but no smoking gun as yet.
So the issue was limited to the YouTube data API and not a generic PCL issue (thankfully). It seems that when making an unauthenticated request to the YouTube API (such as search etc) then you need to use the Web API Key, rather than an Android API key?! Even though when making an authenticated request (using OAuth2) you need to use the Android Key and associate the request with the solutions SHA1 key. Hopefully this may help someone else if they encounter this issue too.
I suppose this does raise the question of why there is an option to add an Android API key for the Public API access when it doesn't appear to work and the Web API key should be used?

ClientHttpWebRequest: ArgumentNullException s

I'm using Silverlight 4.0, and am trying to get a request trough https. All I get is the exception below, which is not really helpful, because no search engine finds any related solution...
request = WebRequest.Create( new Uri("https://myurl.com/myfile" ) );
asyncResult = request.BeginGetResponse();
...
request.EndGetResponse( asyncResult );
{System.ArgumentNullException ---> System.ArgumentNullException: Value cannot be null.
Parameter name: s
at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4(Object sendState)
at System.Net.Browser.AsyncHelper.<>c__DisplayClass2.<BeginOnUI>b__0(Object sendState)
--- End of inner exception stack trace ---
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
It works when I use http instead of https. It works when I use the browser via https. But not like this. Any hints where to look for an answer, or even an answer would be very much appreciated.
[EDIT]
Ok, I found out what seems to be the problem: apparently it has something to do with Firefox and certificates. When I run the xap in IE, it asks me to trust a certificate, and then it works. In Firefox I never get such a question, and it never works (even though I downloaded the xap over that very address.) So now the question is: How do I get working https, Firefox and Silverlight to work together?
[EDIT2]
I'm still on the same problem, but there is something more to it. Not only Firefox has the problem, but also out-of-browser (even if installed from IE). There is someone with a similar exception, but no answer: http://forums.silverlight.net/forums/p/210114/494451.aspx
Got it.
The problem was that the Root CA Certificate of the Server was untrusted. Because I had IE 6 installed, I did not really see the message. The exception added to Firefox did not propagate to Silverlight (because Silverlight apparently always the Global Windows Certificates).
Installing IE 8 reveals that the Root CA Certificate was untrusted right beside the address bar. Click that message, add the Root CA Certificate to the ones used by Windows and voilĂ , everything works, IE, OOB and Firefox.

Categories

Resources