ftp-ssl fails after "Expecting TLS Negotiation" - c#

The following code for simple secure-ftp fails on my Windows 7 computer but succeeds on a Server 2012 computer on a different network: If I remove the EnableSsl = true it works fine.
public static string TheContent(string url, string username, string password)
{
ServicePointManager.ServerCertificateValidationCallback = OnValidateCertificate;//returns true.
string result = "";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
request.Timeout = 7000;
request.EnableSsl = true;
request.UsePassive = true;
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.Credentials = new NetworkCredential(username, password);
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
result = reader.ReadToEnd();
return result;
}
I've tried many things. Some of them:
Disabling the firewall. (Though I'm using passive mode)
Setting port forwarding on my router.
Using "active".
Using FileZilla (fails the same way)
Connecting to the modem by cable
Much longer timeout
And more.
I always get an exception at (FtpWebResponse)request.GetResponse()
"Unable to read data from the transport connection: A connection
attempt failed because the connected party did not properly respond
after a period of time, or established connection failed because
connected host has failed to respond."
When using Microsoft Network Monitor 3.4 I see that the error seems to be:
FTP:Response to Port , '234 AUTH command ok. Expecting
TLS Negotiation.'
FTP:Response to Port , '451 The parameter is incorrect.
'
Any ideas? Can it be that the non-server Windows aren't capable for this by default and something has to be enabled first?

Related

What is the role of my machine's Application pool in Windows service development when consuming third party rest services [duplicate]

I am working on Windows Service in visual studio 2017. In the rest api's call, getting exceptions while debugging code. Sometimes first 2 3 calls working after that getting exceptions.
System.Net.WebException: 'The remote server returned an error: (503)
Server Unavailable.'
The remote server returned an error: (429)
Unable to connect to the remote server
When calling same api's from Postman, getting response successfully.
This is my code
private void timer1_Tick(object sender, ElapsedEventArgs e)
{
WriteToFile("timer1_Tick method called..");
try
{
string jsonString = "";
string jsonstring2 = "";
string prodfetchurl = HOST;
var req = WebRequest.Create(prodfetchurl) as HttpWebRequest;
req.Method = "GET";
InitializeRequest(req);
req.Accept = MIME_TYPE;
//System.Threading.Thread.Sleep(5000);
var response = (HttpWebResponse)req.GetResponse();
WriteToFile("First service called...");
if (response.StatusCode == HttpStatusCode.OK)
{
Stream responseStream = response.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream);
jsonString = responseReader.ReadToEnd();
}
var deserialsseobj = JsonConvert.DeserializeObject<ProductList>(jsonString).Products.Where(i => i.Failed > 0).ToList();
foreach (var a in deserialsseobj)
{
var pid = a.ID;
string url = FailedDevicesUrl + pid.Value + "/failed";
var req2 = WebRequest.Create(url) as HttpWebRequest;
req2.Method = "GET";
InitializeRequest(req2);
req2.Timeout = 300000;
req2.Accept = MIME_TYPE;
var response1 = (HttpWebResponse)req2.GetResponse();
Stream responsestream2 = response1.GetResponseStream();
WriteToFile("Second service called...");
if (response1.StatusCode == HttpStatusCode.OK)
{
StreamReader responsereader1 = new StreamReader(responsestream2);
jsonstring2 = responsereader1.ReadToEnd();
}
var output = JsonConvert.DeserializeObject<List<FailedDeviceList>>(jsonstring2); // Will get List of the Failed devices
List<int> deviceids = new List<int>();
Reprocessdata reproc = new Reprocessdata();
Reprocessdata.DeviceId rprod = new Reprocessdata.DeviceId();
reproc.ForceFlag = true;
reproc.ProductID = pid.Value;
foreach (var dd in output)
{
rprod.ID = dd.DeviceId;
reproc.DeviceIds.Add(rprod);
}
// Reprocess the Product in Devices
var req3 = WebRequest.Create(ReprocessUrl) as HttpWebRequest;
req3.Method = "POST";
InitializeRequest(req3);
req3.Accept = MIME_TYPE;
req3.Timeout = 300000;
req3.ContentType = "application/json";
using (StreamWriter writer = new StreamWriter(req3.GetRequestStream()))
{
string json = new JavaScriptSerializer().Serialize(reproc);
writer.Write(json);
writer.Close();
}
System.Threading.Thread.Sleep(5000);
var response5 = (HttpWebResponse)req3.GetResponse();
WriteToFile("Third service called...");
if (response5.StatusCode == HttpStatusCode.OK)
{
string result;
using (StreamReader rdr = new StreamReader(response5.GetResponseStream()))
{
result = rdr.ReadToEnd();
}
}
}
response.Close();
}
catch (Exception ex)
{
WriteToFile("Simple Service Error on: {0} " + ex.Message + ex.StackTrace);
}
}
Methods used in above code
protected override void OnStart(string[] args)
{
base.OnStart(args);
timer1 = new System.Timers.Timer();
timer1.Interval = 60000; //every 1 min
timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Tick);
timer1.Enabled = true;
WriteToFile("Service has started..");
}
public void InitializeRequest(HttpWebRequest request)
{
request.Headers.Add("aw-tenant-code", API_TENANT_CODE);
request.Credentials = new NetworkCredential(USER_NAME, PASSWORD);
request.KeepAlive = false;
request.AddRange(1024);
}
When I contacted service provide they said everything fine from there side. Is this my code is buggy or windows service not reliable? How can I fix this issue?
Note: All APIS are working fine from Angular application using Visual Studio Code. It means my code is not working.
Edit1: Three below services I am using from this document of VMware.
private const string HOST = "https:host/api/mdm/products/search?";
private const string FailedDevicesUrl = "https:host/api/mdm/products/";
private const string ReprocessUrl = "https:host/api/mdm/products/reprocessProduct";
Response http code 429 indicates that you sending too many requests on target web service.
This means service you trying to send requests has a policies that blocks some requests by request-per-time limit.
Also I admit that external service can be manually configured to throw 403 code in specific cases that you can't know about. If that, this information can be explained in external service documentation... or not :)
What you can do with this?
Fit in limitations
You can make detailed research what limits target webservice has and set up your code to fit in this limitations. For example if service has limitation for receiving only one request per 10 minutes - you must set up your timer to send one request each 10 or more minutes. If documentation not provide such information - you can test it manually by finding some patterns with external service responses.
Use proxy
Every limitation policy based on information about requests senders. Usually this information consists of IP address of sender only. This means if you send 2 requests from two different IP addresses - limitation policy will perceive that like 2 different computers sending these requests. So you can find/buy/rent some proxy IP addresses and send requests through there on target web server.
How to connect through proxy in C# using WebRequest you can see in this answer.
Negotiate with external service provider
If you have possibility to communicate with external service developers or help center, you can ask their to reduce limitations for your IP address (if it static) or provide some mechanisms to avoid limitation policy for you. If for some reason they cannot provide this opportunity, at least you can ask detailed information about limitations.
Repetition mechanism
Some times 503 error code that is outer exception you received may be caused by service unavailable. It means that server can be under maintenance or temporary overloaded. So you can write repetition mechanism to make continious sending requests to server until it'll be accessible.
Polly library may help you with repetition mechanism creation
The inner error of that 503 is:
The remote server returned an error: (429)
HTTP 429 indicates too many requests. Maybe your upstream server can’t process all requests sent.
This can happen when you reached rate limiting / throttling value if you’re calling a third party API.
UPDATE
As per page 28 in the API docs, you could configure throttling when creating a new API. Check if the throttling is too small or maybe turn off the throttling and see if that could fix the error?

HttpWebRequest works with windows form but not with Web API

I need to call HTTPS POST service from WEB API method.
I am using HttpWebRequest to call this API, however i am getting error as
"A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond x.x.x.x:443"
When I tried to call this API in Windows Form then it works well.
HttpWebRequest r = null;
HttpWebResponse rsp = null;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
r = (HttpWebRequest)System.Net.WebRequest.Create("url");
String d = "Serialize JSON"
r.Method = "POST";
r.ContentType = "application/json";
StreamWriter wr = new StreamWriter(r.GetRequestStream());
wr.WriteLine(d);
wr.Close();
rsp = (HttpWebResponse)r.GetResponse();
StreamReader reader = new StreamReader(rsp.GetResponseStream());
String dd = reader.ReadToEnd();
Might be because you are trying to use SSL, from the last part - x.x.x.x:443. My understanding is that 443 is used for SSL. Happy for someone to correct me if I incorrect.
Have a look at the following, this may help you out:
https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/working-with-ssl-in-web-api

FTPWebRequest: Unable to connect to server

I've written a site in ASP.NET which uses FTPWebRequest to download a text file from an FTP server every 15 seconds. When I run it on my computer, it works just fine. When I upload it to our server, the FTP download fails. No exception, it just returns 0 values.
I thought there might be an issue with the firewall, so I disabled the Windows firewall, and disabled outgoing firewall, same problem. Tried both active and passive FTP. Is it possible I need to change some settings in IIS Manager?
Running IIS 10 on Server 2012 R2, on the same VM with Exchange 2016.
Part of the code:
public static string[] GetTXT()
{
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("FTP address");
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.UsePassive = false; //tried it with true as well
request.Credentials = new NetworkCredential("user", "pass");
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string result = (reader.ReadToEnd());
}
Eventually discovered I was publishing the site in a subfolder.
The root folder probably contained an older version.
Anyway, thanks for the help!
If just a download from the server FTP, I recommend this class WebClient implemented by Microsoft for your method.
It maybe resolves your problem.
public static string[] GetTXT()
{
using (WebClient client = new WebClient())
{
var path = #"C:\local\path\file.txt";
client.Credentials = new NetworkCredential("log", "pass");
client.DownloadFile("ftp://ftp.example.com/remote/path/file.txt", path);
}
if (File.Exists(path))
{
return File.ReadAllLines(path);
}
//return something
}

A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed

I am having an issue :
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond URL.
Also I get issue like:
System.IO.IOException: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host
and
System.Net.WebException: The operation has timed out at System.Net.WebClient.UploadFile(Uri address, String method, String fileName)
I know that this question has asked before but believe me I tried almost every single resolution at my end.
Weird thing is this issue does not appear at my end at all and only when client try to use which is not constant. Some time my application works fine at their end too.
What I am trying to accomplish is I have created an desktop application (Win Forms & C#) and trying to login client while sending request to my php api server which is hosted on GODaddy.
var request = (HttpWebRequest)WebRequest.Create("url");
if (request != null)
{
#region System.Net.WebException
request.Method = "POST";
if (!string.IsNullOrEmpty(body))
{
var requestBody = Encoding.UTF8.GetBytes(body);
request.ContentLength = requestBody.Length;
request.ContentType = "application/json";
using (var requestStream = request.GetRequestStream())
{
requestStream.Write(requestBody, 0, requestBody.Length);
}
}
else
{
request.ContentLength = 0;
}
request.Timeout = 15000;
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
string output = string.Empty;
try
{
using (var response = (HttpWebResponse)request.GetResponse())
{
using (var stream = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(1252)))
{
if (response.StatusCode == HttpStatusCode.OK)
{
while (!stream.EndOfStream)
{
output += stream.ReadLine();
}
output = stream.ReadToEnd();
}
}
}
}
catch
{
// Excaption Caught here
}
}
Please help me out.
Thanks in advance.
Try adding this...
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
request.ServicePoint.ConnectionLimit = 12;
MSDN article recommends 12 connections per CPU hence the limit of 12 because it's hosted by GoDaddy so I'm sure the server resources are limited.
I think I got the answer. Thought to post it so that it could help anyone else.
It most probably the particular machine issue or server issue but in my case, I tried to set Request.proxy = null and it worked like a charm.
I faced this problem at today. I set Timeout property of HttpWebRequest to 1 200 000 milliseconds (20 minute), but I got this error after 5 minute. I researched many sites at google and I found ReadWriteTimeout property of HttpWebRequest. Default value of ReadWriteTimeout is 5 minute. I increased value of ReadWriteTimeout and problem solved for me.
...
httpWebRequest.Timeout = 1200000;
httpWebRequest.ReadWriteTimeout = 1200000;
...

How to fix this error call google location to address Service "target machine actively refused it"

When trying to call Google location to address Service, it gives me this message:
No connection could be made because the target machine actively
refused it 173.194.66.95:80
I use ASP.net 4 with C#.
This is my code:
protected void btn_FindAddress_Click(object sender, EventArgs e)
{
url = "http://maps.googleapis.com/maps/api/geocode/xml?latlng=";
query = LatY.Text + "," + LongX.Text + "&sensor=true";
Address.Text = url;
Uri uri = new Uri (url + query);
// Create a request for the URL.
WebRequest request = WebRequest.Create(uri);
//// If required by the server, set the credentials.
request.Credentials = CredentialCache.DefaultCredentials;
// Get the response.
WebResponse response = request.GetResponse();
// Display the status.
Status.Text = (((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.
Address.Text = responseFromServer;
// Clean up the streams and the response.
reader.Close();
response.Close();
}
Most commonly, the outbound connection can be established (the remote server could be reached and a response was sent in a timely fashion) but the port you're trying to use is being blocked (a firewall or a proxy are the two most likely options I can think of).
It also might derive from the fact that there is no server on the other side of the connection: this may happen for example if you NAT port 80 to a system which doesn't have a web server. Being that you're invoking Google's url, I doubt it's the case, but I thought it worth of pointing out.

Categories