Hardcode IPEndpoint gives Exception using ServicePoint.BindIPEndPointDelegate in ASP.Net - asp.net

I am trying to Bind my Outbound IP for my webRequest
HttpWebRequest reqhttp = (HttpWebRequest)req;
reqhttp.ServicePoint.BindIPEndPointDelegate = new System.Net.BindIPEndPoint(BindIPEndPointCallback);
reqhttp.Credentials = null;
reqhttp.AuthenticationLevel = AuthenticationLevel.None;
reqhttp.Method = "POST";
reqhttp.ContentLength = send.Length;
reqhttp.ContentType = "text/xml";
Stream dataStream = reqhttp.GetRequestStream();
dataStream.Write(send, 0, send.Length);
dataStream.Close();
public delegate IPEndPoint BindIPEndPoint(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount);
private IPEndPoint BindIPEndPointCallback(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount)
{
return new IPEndPoint(IPAddress.Parse("111.111.11.11"), 0); //bind to a specific ip address on your server
}
for some reason when i do this, it is throwing an error
if fails to execute this line
Stream dataStream = reqhttp.GetRequestStream();
An existing connection was forcibly closed by the remote host
i don't understand what is wrong in here.
Can any one help to understand whats wrong in this code and fix the issue.

The GetRequestStream() method will first trigger BindIPEndPointDelegat, then it will try to connect to the remote server. If you bind to a local end point that does not exists, or the remote server is unavailable, you will get an exception.

try something like this
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(myIP);
request.Proxy = myProxy;
ServicePoint sp = ServicePointManager.FindServicePoint(new Uri(myIP), myProxy);
sp.BindIpEndPointDelegate = new BindIpEndPoint(BindIpEndPointCallback);
HttpWebResponse = (HttpWebResponse)request.GetResponse();

Related

Getting exception "Socket read operation has timed out" while using SSH.NET although the can connect to the sftp by using filezilla

I am trying to upload files using Renci.SshNet, but the connection times out each time, although i can connect successfully using SFTP client (filezilla).
I have used the below code and each time I get exception in the line (sftp.Connect). I get an exception "An exception of type 'Renci.SshNet.Common.SshOperationTimeoutException' occurred in Renci.SshNet.dll"
{"Socket read operation has timed out"}
ConnectionInfo connectionInfo = new PasswordConnectionInfo(host, port, username, password);
using (var client = new SftpClient(host, port, username, password))
{
client.Connect();
//Log.Info("Connected to SFTP", this);
// byte[] byteArray = Encoding.UTF8.GetBytes(csv);
FileStream streams = File.OpenRead(#"c:\sftp\Test.csv");
byte[] fileBytes = new byte[streams.Length];
streams.Read(fileBytes, 0, fileBytes.Length);
MemoryStream stream = new MemoryStream(fileBytes);
using (var file = stream)
{
// sftp.BufferSize = 4 * 1024;
client.UploadFile(file, uploadFile + "/" + Path.GetFileName(path));
// Log.Info("Upload to SFTP success", this);
}
streams.Close();
client.Disconnect();
// Log.Info("Disconnected from SFTP", this);
}

Serializing using protobuf-net and sending as postdata in http

I'm using Protobuf-net to try and send a serialized object to a webapplication that I'm running in another project. The Serializer.Serialize<T>() method takes a Stream (to write to) and and instance of T (in this case, a list of a few objects that I set up to work with protobuf-net)
How do I go about doing this? Do I need to write to a file or can I send the stream as postdata somehow? Below you can see I'm using a string as the postdata.
My execute post method
public static void ExecuteHttpWebPostRequest(Uri uri,string postdata, int requestTimeOut, ref string responseContent)
{
if (string.IsNullOrEmpty(uri.Host))// || !IsConnectedToInternet(uri))
return;
var httpWebReq = (HttpWebRequest)WebRequest.Create(uri);
var bytePostData = Encoding.UTF8.GetBytes(postdata);
httpWebReq.Timeout = requestTimeOut*1000;
httpWebReq.Method = "POST";
httpWebReq.ContentLength = bytePostData.Length;
//httpWebReq.ContentType = "text/xml;charset=utf-8";
httpWebReq.ContentType = "application/octet-stream";
//httpWebReq.TransferEncoding=
//httpWebReq.ContentType = "application/xml";
//httpWebReq.Accept = "application/xml";
var dataStream = httpWebReq.GetRequestStream();
dataStream.Write(bytePostData, 0, bytePostData.Length);
dataStream.Close();
var httpWebResponse = (HttpWebResponse)httpWebReq.GetResponse();
// Get the stream associated with the response.
var receiveStream = httpWebResponse.GetResponseStream();
// Pipes the stream to a higher level stream reader with the required encoding format.
var readStream = new StreamReader(receiveStream,Encoding.Default);
responseContent = readStream.ReadToEnd();
httpWebResponse.Close();
}
You can just serialize to the request:
Serializer.Serialize(dataStream, obj);
And equally, you can deserialize from receiveStream, if you choose.
Note, however, that protobuf data is not text, and should not be treated as such - very bad things happen if you try that.

HttpComponents - Connect to different Port

I have to write an android client, in which i should use HttpComponents to connect to a specific Server on Port 8080.
For now, all i've found, was the Examplecode from the Apache-site, which is nearly perfect for what i need, except the Port it connects to:
if (isSet)
{
throw new IOException("Hostname or Port are not set!");
}
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(serverURL + ":" + serverPort + "/maps");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null)
{
InputStream instream = entity.getContent();
int l;
byte[] tmp = new byte[2048];
while ((l = instream.read(tmp)) != -1)
{
}
}
Is there any way to change the Port?
Any help would be appreciated.
I know a little about HttpComponents, but I find an example code from Apache-site, which may help you. You can try to modify the code like below for your problem.
HttpHost target = new HttpHost("issues.apache.org", 443, "https");
HttpGet request = new HttpGet("/");
CloseableHttpResponse response = httpclient.execute(target, request);

confusion about Certificates

I have WCF REST web service hosted by IIS, it works on HTTPS, I generate Certificate on IIS and assign Https to a port
I generate cer through IE browser. I create a test application and regardless Add a client certificate or not or even add a wrong certificate the connection take place and a I get correct response. I am wondering how the message was decrypted if there is no certificate sent.
Either the destination is not secured or I misunderstand the whole thing.
also
The error I have from the callback "CheckValidationResult()" is either
CertCN_NO_MATCH = 0x800B010F
or
"Unknown Certificate Problem" , the certificateProblem (parameter of CheckValidationResult) is 0 for this case
What is CertCN_NO_MATCH eror, what is CN?
See code below.
ServicePointManager.CertificatePolicy = new CertPolicy();
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(String.Format("https://{0}/uri", ip));
//request.ClientCertificates.Add(new X509Certificate("D:\\ThePubKey.cer"));
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
using (StreamWriter stream = new StreamWriter(request.GetRequestStream()))
{
stream.Write("RequestType=CheckStatus&ReportType=Fulfillment&ReportID=5");
}
using (StreamReader stream = new StreamReader(request.GetResponse().GetResponseStream()))
{
Response.ContentType = "text/xml";
Response.Output.Write(stream.ReadToEnd());
Response.End();
}
class CertPolicy : ICertificatePolicy
{
public enum CertificateProblem : uint
{
CertEXPIRED = 0x800B0101,
CertVALIDITYPERIODNESTING = 0x800B0102,
CertROLE = 0x800B0103,
CertPATHLENCONST = 0x800B0104,
CertCRITICAL = 0x800B0105,
CertPURPOSE = 0x800B0106,
CertISSUERCHAINING = 0x800B0107,
CertMALFORMED = 0x800B0108,
CertUNTRUSTEDROOT = 0x800B0109,
CertCHAINING = 0x800B010A,
CertREVOKED = 0x800B010C,
CertUNTRUSTEDTESTROOT = 0x800B010D,
CertREVOCATION_FAILURE = 0x800B010E,
CertCN_NO_MATCH = 0x800B010F,
CertWRONG_USAGE = 0x800B0110,
CertUNTRUSTEDCA = 0x800B0112
}
public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)
{
// You can do your own certificate checking.
// You can obtain the error values from WinError.h.
// Return true so that any certificate will work with this sample.
String error = "";
using (StringWriter writer = new StringWriter())
{
writer.WriteLine("Certificate Problem with accessing " + request.RequestUri);
writer.Write("Problem code 0x{0:X8},", (int)certificateProblem);
writer.WriteLine(GetProblemMessage((CertificateProblem)certificateProblem));
error = writer.ToString();
}
return true;
}
private String GetProblemMessage(CertificateProblem Problem)
{
String ProblemMessage = "";
CertificateProblem problemList = new CertificateProblem();
String ProblemCodeName = Enum.GetName(problemList.GetType(), Problem);
if (ProblemCodeName != null)
ProblemMessage = ProblemMessage + "-Certificateproblem:" +
ProblemCodeName;
else
ProblemMessage = "Unknown Certificate Problem";
return ProblemMessage;
}
}
I've just replied to this similar question (in Java).
CN is the "Common Name". It ought to be the hostname of the server to which you're connecting (unless it's in the subject alternative name). I guess from your code sample that you're using the IP address directly. In this case, the CN should be that IP address (it tends to be better to use a hostname rather than an IP address). See RFC 2818 (sec 3.1) for the specifications.
Note that the CN or subject alternative name is from the point of view of the client, so if you connect to https://some.example.com/, then the name in the cert should be some.example.com, if you connect to https://localhost/, then the name in the cert should be localhost, even if some.example.com and localhost may be the same server effectively.
(I guess that by default, IIS might generate a certificate for the external name, but you'd have to look at the certificate to know; this should be visible in the certificate properties somewhere.)

invoking web service using httprequest

i have a web service which contains a method like the following
[WebMethod]
public string UploadFile(byte[] bytes, string file_name)
{
}
i want to invoke this web service method using HttpWebRequest so that i can stream the file without buffering in memory. How can do it... i tried to invoke it as follows
HttpWebRequest hw = HttpWebRequest.Create("http://localhost/xxx/xxx.asmx/Upload") as HttpWebRequest;
hw.ContentType = "application/x-www-form-urlencoded";
hw.AllowWriteStreamBuffering = false;
hw.Method = "POST";
hw.UnsafeAuthenticatedConnectionSharing = true;
hw.UserAgent = "test type";
hw.Credentials = CredentialCache.DefaultCredentials;
FileInfo fi = new FileInfo("C:/Documents and Settings/Administrator/Desktop/a.txt");
string bytes = "bytes=";
byte[] by = UTF8Encoding.UTF8.GetBytes(bytes);
byte[] fn = UTF8Encoding.UTF8.GetBytes("&file_name=a.txt");
hw.ContentLength = by.Length+fi.Length+fn.Length;
using (Stream postStream = hw.GetRequestStream())
{
FileStream br = new FileStream("C:/Documents and Settings/Administrator/Desktop/a.txt", FileMode.Open, FileAccess.Read);
postStream.Write(by, 0, by.Length);
byte[] buffer = new byte[1024];
int bytesRead = 0;
while (true)
{
bytesRead = br.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
break;
postStream.Write(buffer, 0, bytesRead);
}
br.Close();
postStream.Write(fn, 0, fn.Length);
postStream.Write(ct, 0, ct.Length);
}
// HERE :
using (HttpWebResponse response = hw.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
string sssdd = reader.ReadToEnd();
}
but it show a message "The remote server returned an error: (500) Internal Server Error." while executing **// HERE : ** marked line.
btw: i am using asp.net 2.0 and i am not allowed to use proxy class as my requirement is to stream the data for large file. Thanks in advance
Open up http://localhost/xxx/xxx.asmx/Upload in your browser and ASP.NET will give you an example POST requrest you'll need to send in order to invoke the method. Start from there on.
It's been a while since I messed with this stuff, but I think you can get at the underlying HttpRequest in the proxy class. Probably alot easier than ginning up your own SOAP to POST.
If it says that the remote server returned an error, then you should look on the remote server to see what the error was. Look in the Event Log on the server for events at around the time you received the error.
Remove these lines:
postStream.Write(by, 0, by.Length);
.
.
.
postStream.Write(fn, 0, fn.Length);
postStream.Write(ct, 0, ct.Length);

Resources