I have a windows service that I am trying to get running on a server. It just posts data to a php page and has further logic based on the response back. This works 100% on my machine and 100% on the server WHEN Anonymous Authenication is turned on for the website(IIS).
What I want to accomplish is to run the site with Windows Authenication turned ON and have my service still work... except when I try this I receive a nice EventLog entry.
"System.IO.IOException: Unable to read data from the transport
connection: An existing connection was forcibly closed by the remote
host"
I am running the service under an account that has all required permissions. So I understand that "CredentialCache.DefaultCredentials" should use this account for authentication( I am not receiving a 401 error ,but not ruling it out )
Below is my HttpPost code, I have set quite a few options from other posts trying to find a solution.
string postData = xml;
//--------------
HttpRequestCachePolicy policy = new HttpRequestCachePolicy MontgP02(HttpRequestCacheLevel.NoCacheNoStore);
HttpWebRequest.DefaultCachePolicy = policy;
byte[] buffer = Encoding.UTF8.GetBytes(postData);
//Initialisation
System.Net.ServicePointManager.Expect100Continue = false;
HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(url);
//Credentials
WebReq.UseDefaultCredentials = true;
WebReq.PreAuthenticate = true;
WebReq.Credentials = CredentialCache.DefaultCredentials;
//Request Settings
WebReq.ProtocolVersion = HttpVersion.Version11;
//WebReq.ServicePoint.ConnectionLimit = 1;
WebReq.Method = "POST";
WebReq.ContentType = "application/x-www-form-urlencoded";
//The length of the buffer
WebReq.ContentLength = buffer.Length;
//Set timeout
WebReq.Timeout = 25000;
//Use Proxy or Not
if (useproxy == "ON")
{
WebProxy myProxy = new WebProxy();
// Create a new Uri object.
Uri newUri = new Uri(proxy);
// Associate the new Uri object to the myProxy object.
myProxy.Address = newUri;
WebReq.Proxy = myProxy;
}
try
{
//Send Data
using (Stream requestStream = WebReq.GetRequestStream())
{
// write to stream
//write, and close.
requestStream.Write(buffer, 0, buffer.Length);
}
}
catch (WebException ex) {
MessageLog("ERROR: Sending Data : " + ex.ToString() + ":", "ERROR");
}
//Get Response
try
{
using (System.Net.WebResponse response = WebReq.GetResponse())
{
Stream Answer = response.GetResponseStream();
// read from stream
StreamReader _Answer = new StreamReader(Answer);
PostResponse = _Answer.ReadToEnd();
}
}
catch (WebException ex)
{
MessageLog("ERROR: Receiving Response : " + ex.ToString() + ":" , "ERROR");
}
}
catch (WebException ex)
{
MessageLog("ERROR Posting " + ex.ToString() + ":" + PostResponse, "ERROR");
}
}
I understand from the error that the server is cutting the connection before I can complete the request. This happens everytime on the server negating thoughts of timeouts I would think.
Having looked around other fourms, I am at a loss , having tried other variations etc the fact that it does work fine with authenication off leads me to think it may be a setting in IIS or something else down the authenication route.
Any insight welcome
Related
I have a simple part of the code that creates a http listener for a specific url. Everything works perfectly, untill I turn on Xampp - Apache Web Server. At that moment, whenever I try to run the listener, I get Address already in use exeption.
I did some research and found a possible cause: I guess it won't work because Apache is listening to http port(idk if it is a proper term, it is what I got from running lsof-i:http command.), therefore my app cannot start the listener on http. But it is weird, since I have full url specified, so I suppose if request matches the url, Apache should stay away from it... Maybe I am wrong...
Does anyone know a solution how I could run Apache and my http listener at the same time?
Also I am running Debian 10 if it helps. Thanks in advance!
HttpListener listener2 = new HttpListener();
listener2.Prefixes.Clear();
listener2.Prefixes.Add("http://xxxx.xxxx.eu/");
listener2.Start();
LogWriteLine("http listener started listening to: " +listener2.Prefixes);
try
{
while (true)
{
HttpListenerContext context = listener2.GetContext();
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
System.IO.Stream body = request.InputStream;
System.Text.Encoding encoding = request.ContentEncoding;
System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding);
if (!request.HasEntityBody)
{
LogWriteLine("No client data was sent with the request.");
Thread.Sleep(300);
}
if (request.ContentType != null)
{
LogWriteLine("Client data content type " + request.ContentType);
}
LogWriteLine("Client data content length " + request.ContentLength64);
LogWriteLine("Start of client data:");
string s = reader.ReadToEnd();
var bytes = default(byte[]);
using (var reader1 = new StreamReader(request.InputStream,
request.ContentEncoding))
{
text = reader1.ReadToEnd();
using (var memstream = new MemoryStream())
{
memstream.Position = 0;
reader1.BaseStream.CopyTo(memstream);
bytes = memstream.ToArray();
memstream.Position = 0;
Console.WriteLine("memstream length: " + memstream.Length);
}
Console.WriteLine("bytes:" + bytes.Length); //output: bytes: 0
}
LogWriteLine("End of client data:");
response.StatusCode = (int)HttpStatusCode.OK;
response.Close();
body.Close();
reader.Close();
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
We currently have a third party client that we send some XML too. then we get a return to download a file. I first had to generate a CSR in which we gave to them and they gave us a pb7 file in return that I installed on our server and paired with the private key. I have a C# test that continually fails when trying to send the POST request with GetRequestStream. I have tried to set it to TLs 1.2 and ensured it was enabled on the Server. port 443 is open and listening on the server. The certificate I want is sent, so I am not sure why I cant get the request to go through. The piece of Code causing issue is below. The WebResponse is RecieveFailure. I also did a wireshark trace and I can see it connects over http from their server to ours, but then when ours goes over tcp to theirs it immediately fails.
private const string DTTM_PATTERN = "yyyy-MM-ddTHH:mm:ss.FZ";
private const string SS_API_URL = "https://www.example.com/v_6?id=";
private static string Proxy_Address = "My.Domain.Com";
static void Main(string[] args)
{
var messageID = Guid.NewGuid().ToString().Replace("-", "");
var currDate = DateTime.UtcNow.ToString(DTTM_PATTERN);
string xmlMessage =
#"The XML is here"
string url = SS_API_URL + messageID;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection collection =
store.Certificates.Find(X509FindType.FindBySubjectName, "my.certifcate.com", true);
request.ClientCertificates = collection;
byte[] requestInFormOfBytes =
System.Text.Encoding.ASCII.GetBytes(xmlMessage);
request.Method = "POST";
request.ContentType = "text/xml;charset=utf-8";
request.ContentLength = requestInFormOfBytes.Length;
request.Proxy = new WebProxy(Proxy_Address, 443);
request.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
try
{
//The error appears here on request.GetRequestStream
using (var requestStream = request.GetRequestStream())
{
requestStream.Write(requestInFormOfBytes, 0, requestInFormOfBytes.Length);
requestStream.Close();
}
}
catch (WebException webExcp)
{
// If you reach this point, an exception has been caught.
Console.WriteLine("A WebException has been caught.");
// Write out the WebException message.
Console.WriteLine(webExcp.ToString());
// Get the WebException status code.
WebExceptionStatus status = webExcp.Status;
// If status is WebExceptionStatus.ProtocolError,
// there has been a protocol error and a WebResponse
// should exist. Display the protocol error.
if (status == WebExceptionStatus.ProtocolError)
{
Console.Write("The server returned protocol error ");
// Get HttpWebResponse so that you can check the HTTP status code.
HttpWebResponse httpResponse = (HttpWebResponse)webExcp.Response;
Console.WriteLine((int)httpResponse.StatusCode + " - "
+ httpResponse.StatusCode);
}
}
I have been running a C# TCP server, which is transferring data to another server via HTTP POST calls for 2 years with no issues.
After switching from Windows server 2008 to 2012, the requests are taking forever. On the "receiving" side, it is so slow, that I am running out of threads and getting 508 errors back. I have timed the scripts which is requested via HTTP. It takes around 30-40 ms to execute. No worries.
If I time the amount of time it takes to make the HttpWebRequest it is around 2 seconds, which must be why I am running out of threads on the web server.
This is my request code:
public static string WRequest(string URL, string method, string postData)
{
string responseData = "";
try
{
ServicePointManager.Expect100Continue = false;
ServicePointManager.UseNagleAlgorithm = false;
ServicePointManager.CheckCertificateRevocationList = false;
// System.Net.CookieContainer cookieJar = new System.Net.CookieContainer();
System.Net.HttpWebRequest hwrequest =
(System.Net.HttpWebRequest)System.Net.WebRequest.Create(URL);
// hwrequest.CookieContainer = cookieJar;
hwrequest.Accept = "*/*";
hwrequest.AllowAutoRedirect = true;
hwrequest.UserAgent = "http_requester/0.1";
hwrequest.Timeout = 60000;
hwrequest.Proxy = null;
hwrequest.Method = method;
if (hwrequest.Method == "POST")
{
hwrequest.ContentType = "application/x-www-form-urlencoded";
// Use UTF8Encoding instead of ASCIIEncoding for XML requests:
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] postByteArray = encoding.GetBytes(postData);
hwrequest.ContentLength = postByteArray.Length;
System.IO.Stream postStream = hwrequest.GetRequestStream();
postStream.Write(postByteArray, 0, postByteArray.Length);
postStream.Close();
}
System.Net.HttpWebResponse hwresponse =
(System.Net.HttpWebResponse)hwrequest.GetResponse();
if (hwresponse.StatusCode == System.Net.HttpStatusCode.OK)
{
System.IO.Stream responseStream = hwresponse.GetResponseStream();
System.IO.StreamReader myStreamReader =
new System.IO.StreamReader(responseStream);
responseData = myStreamReader.ReadToEnd();
// MessageBox.Show(responseData);
}
hwresponse.Close();
}
catch (Exception e)
{
responseData = "An error occurred: " + e.Message;
Console.WriteLine(e.ToString());
}
Console.WriteLine(responseData);
return responseData;
}
I have tested this on my windows 10 machine, and the server 2012, with the same timing problems (2 seconds).
Any ideas to where the problem might be? I feel like I have tried everything.
Can someone please take a look at the code below and tell me what I am doing wrong. I am just going in circles,,, any pointers greatly appreciated
public class FtpWebRequestUtil
{
private static string RemoteHost;
private static string RemoteFtpPath;
public static NetworkCredential Credential = new NetworkCredential();
public FtpWebRequestUtil()
{
}
public FtpWebRequestUtil(string RemoteAddress, string RemotePath, string RemoteUser, string RemotePwd)
{
Credential.UserName = RemoteUser;
Credential.Password = RemotePwd;
RemoteHost = RemoteAddress;
RemoteFtpPath = RemotePath;
}
public string UploadFile(string localFilePath)
{
int startTime = Environment.TickCount;
// Console.WriteLine("Uploading File " + localFilePath);
try
{
FileInfo localFile = new FileInfo(localFilePath); //e.g.: c:\\Test.txt
byte[] buf = new byte[2048];
int iWork;
string remoteFile = "ftp://" + RemoteHost + "/" + RemoteFtpPath + "/" + localFile.Name;
FtpWebRequest req = (FtpWebRequest) FtpWebRequest.Create(remoteFile);
// req.Proxy =
req.Credentials = Credential;
// FtpWebRequest req = (FtpWe
req.UseBinary = true;
req.KeepAlive = true;
req.Method = WebRequestMethods.Ftp.UploadFile;
StreamWriter myStreamWriter = new StreamWriter(req.GetRequestStream());
myStreamWriter.Write(new StreamReader("TestFiles\\" + localFile.Name).ReadToEnd());
myStreamWriter.Close();
FtpWebResponse myFtpWebResponse = (FtpWebResponse) req.GetResponse();
Console.WriteLine("Upload File Complete, status: " + myFtpWebResponse.StatusDescription);
myFtpWebResponse.Close();
return "SUCCESS";
}
catch (Exception ex)
{
Console.WriteLine("There was an error connecting to the FTP Server.");
Console.WriteLine(ex.Message);
throw ex;
}
Console.WriteLine("Time taken for downloading file is " + (Environment.TickCount - startTime).ToString());
return "FAILURE";
}
************************ *********************************
FtpWebRequestUtil ftpClient = new FtpWebRequestUtil(FtpUrl, InputFolder, FtpUser, FtpPassword);
try
{
Thread.Sleep(5000);
ftpClient.UploadFile(UploadingFileName);
}
catch (Exception exception)
{
Assert.Fail(exception.Message);
}
finally
{
ftpClient = null;
}
}
}
req.Proxy = new WebProxy(); // initialize this FtpWebRequest property
It turns out that only the RETR, LIST, and NLST methods are supported by System.Net.FtpWebRequest when a HTTP proxy is configured and it doesn't matter that you are not setting a proxy in your code: if a HTTP proxy (not FTP proxy) is configured in the system proxy settings (in i.e. : Internet Options\Connections\LAN setting\Proxy Server\ Use a proxy server for your LAN), then you will get this error when trying to upload to the FTP server.
The workaround is use IE to change the system settings to switch off the use of the HTTP proxy. However if you have access to the affected code the solution is to set the Proxy property of the request to null, for example:
request.Proxy = null;
The exceptions itself is the answer - it is not supported. Probably you have some HTTP proxy that is preventing direct connection to FTP. According to MS documentation, if the specified proxy is an HTTP proxy, only the DownloadFile, ListDirectory, and ListDirectoryDetails commands are supported - so UploadFile is not.
I was trying to use httpwebrequest to use a rest like service on a remote server and from the first execution itself, my code was hanging the program. Then I tried it as a console application to make sure it has nothing to do with the program itself but no luck!
string credentialsJson = #"{""username"":""test"",
""password"":""test""
}";
int tmp = ServicePointManager.DefaultConnectionLimit;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(#"https://qrua.com/qr/service" + #"/auth/login");
request.Method = "POST";
request.KeepAlive = true;
request.Timeout = 50000 ;
request.CookieContainer = new CookieContainer();
request.ContentType = "application/json";
try
{
StreamWriter writer = new StreamWriter(request.GetRequestStream());
writer.Write(credentialsJson);
}
catch (Exception e)
{
Console.WriteLine("EXCEPTION:" + e.Message);
}
//WebResponse response = request.GetResponse();
try
{
using (WebResponse response = (HttpWebResponse)request.GetResponse())
{
Console.WriteLine("request:\n" + request.ToString() + "\nresponse:\n" + response.ContentLength);
response.Close();
}
}
catch (Exception e)
{
Console.WriteLine("EXCEPTION: in sending http request:" + " \nError message:" + e.Message);
}
Tried several things from different forums but it doesnt help. Even a simple console app with the above code hangs the console indefinitely! Any help would be great..
Thanks
You're never closing the StreamWriter... so I suspect it's not being flushed. Admittedly I'd expect an error from the server instead of just a hang, but it's worth looking at.
Btw, you don't need to close the response and dispose it. Just the using statement is enough.
There's not much you can do if the remote server is not responding other than defining a Timeout and catch the exception as you did in order to inform the user that the operation cannot complete because the remote site didn't respond:
var request = (HttpWebRequest)WebRequest.Create("https://qrua.com/qr/service/auth/login");
request.Timeout = 5000;
// If the server doesn't respond within 5 seconds you might catch the timeout exception
using (var response = request.GetResponse())
{
}
If you don't want to freeze the UI you could use the async version: BeginGetResponse
Try specifying request.ContentLength.
Before doing:
StreamWriter writer = new StreamWriter(request.GetRequestStream());
writer.Write(credentialsJson);
Try something like this:
using (MemoryStream stream = new MemoryStream())
{
using (var writer = StreamWriter writer = new StreamWriter(stream))
{
writer.Write(credentialsJson);
writer.Close();
}
request.ContentLength = stream.Length;
}