Reading and saving post data - c#

I have been assigned to take over someones position, however I do not really know C#. There is a server (192.268. something ect) that will post data to a site (unknown site, lets say bleh.com)
This is what the posting code snippet looks like:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(
"https://server-ip-here/postlistener?filename=filename.zlib");
req.UseNagleAlgorithm = true;
req.AllowWriteStreamBuffering = true;
req.Method = "POST";
req.Accept = "application/xml";
req.ServicePoint.Expect100Continue = false;
System.Net.ServicePointManager.CheckCertificateRevocationList = false;
req.Proxy = new WebProxy();
filename = "filename.dat";
byte[] postData = File.ReadAllBytes(filename);
Stream stream = req.GetRequestStream();
stream.Write(postData, 0, postData.Length);
stream.Flush();
stream.Close();
req.BeginGetResponse(new AsyncCallback(responseHandler), this);
Which I beleive I get the post request in this form
www.blah.com/upload?filename=file_1234_12389126495129847980.zlib
I am unsure how to listen for post requests and then get the data from them and save them as a file.
Currently I have tried this:
private void Form1_Load(object sender, EventArgs e)
{
listener = new HttpListener();
// listener.Prefixes.Add("http://localhost:8000/");
listener.Prefixes.Add("http://127.0.0.1:8000/");
listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
listener.Start();
listenThread1 = new Thread(new ParameterizedThreadStart(startlistener));
listenThread1.Start();
}
private void startlistener(object s)
{
while (true)
{
// blocks until a client has connected to the server
ProcessRequest();
}
}
private void ProcessRequest()
{
var result = listener.BeginGetContext(ListenerCallback, listener);
result.AsyncWaitHandle.WaitOne();
}
private void ListenerCallback(IAsyncResult result)
{
var context = listener.EndGetContext(result);
Thread.Sleep(1000);
var data_text = new StreamReader(
context.Request.InputStream,
context.Request.ContentEncoding).ReadToEnd();
var cleaned_data = System.Web.HttpUtility.UrlDecode(data_text);
context.Response.StatusCode = 200;
context.Response.StatusDescription = "OK";
MessageBox.Show(cleaned_data);
context.Response.Close();
}
Which listens on the local host (Would sub local host for the website once we establish what it will be).
Not sure how to grab the post though, right now I can only listen for it. Ideally I would only like to accept posts from a specific IP address also.
Any ideas how I can go about grabbing the post data (which will be binary) and saving it as a file?

Related

How do I prevent httpwebrequest opening a new tcp connection for each PUT request?

Whenever I have to PUT a json string to a server, I launch a new thread which has this code inside a class. It works fine, but the thing is that a TCP connection is opened for each request. When I checked the ServicePoint hashcode, its the same for each request.
When I looked in TCPView, I cannot find those connections - I think its because its opened and closed within ~50ms.
So, 2 questions -
Is it an issue if I leave it like this? A new request will be raised every second from the client.
How do I reuse the same TCP connection? What if I set ServicePoint.KeepAlive to true?
public void SendRequest()
{
string sOutput="";
try
{
HttpWebRequest myWebRequest = (HttpWebRequest)WebRequest.Create(_uri);
myWebRequest.Timeout = Timeout;
myWebRequest.ReadWriteTimeout = Timeout;
myWebRequest.ContentType = "application/json";
myWebRequest.Method = "PUT";
myWebRequest.Proxy = WebRequest.GetSystemWebProxy();
ServicePointManager.CheckCertificateRevocationList = true;
using (StreamWriter myStreamWriter = new StreamWriter(myWebRequest.GetRequestStream()))
{
myStreamWriter.Write(_json);
}
using (HttpWebResponse myWebResponse = (HttpWebResponse)myWebRequest.GetResponse())
{
using (StreamReader myStreamReader = new StreamReader(myWebResponse.GetResponseStream()))
{
sOutput = myStreamReader.ReadToEnd();
sOutput = sOutput.Length == 0 ? myWebResponse.StatusDescription : sOutput;
ServicePoint currentServicePoint = myWebRequest.ServicePoint;
sOutput = currentServicePoint.GetHashCode().ToString();
currentServicePoint.ConnectionLimit = 5;
}
}
}
catch (Exception Ex)
{
sOutput = Ex.Message;
}
finally
{
callback?.Invoke(sOutput);
}
}
And here is how I launch the thread -
HTTPClass hTTPClass = new HTTPClass(cuURI, json, 5000, new MyCallback(ResultCallBack));
Thread t = new Thread(new ThreadStart(hTTPClass.SendRequest));
t.Start();
Here is the code after switching to HttpClient -
static HttpClient client = new HttpClient();
public async Task Write()
{
await WriteAsync(cuURI, json);
}
private async Task WriteAsync(Uri uri, string json)
{
StringContent content = new StringContent(json,Encoding.UTF8,"application/json");
await client.PutAsync(uri, content);
}
Here is the wireshark trace screenshot which shows a new connection for every request.
The client is setting the FIN flag on its own, and the server is not sending a FIN from its side. What is happening is that I see a lot of connections in the TIME_WAIT state on the server side.

.net http webclient to nodejs server. How to access data?

I have a .net c# client software that sends data like this:
using(WebClient client = new WebClient())
{
string serialisedData = "";
serialisedData = JsonConvert.SerializeObject(myData);
client.Credentials = new NetworkCredential(config.UserData.Username, config.UserData.Password);
byte[] responsebyte = client.UploadData(config.ServerAddress, System.Text.Encoding.UTF8.GetBytes(serialisedData));
}
In nodejs, I currently have this kind of https setup:
_server = https.createServer({
key: fs.readFileSync(`${__dirname}\\bin\\cert\\${_config.sslkey}`, "utf8"),
cert: fs.readFileSync(`${__dirname}\\bin\\cert\\${_config.sslcert}`, "utf8")
}, _listener);
_server.listen(_config.port, "0.0.0.0");
function _listener(req, res) {
let data = []
req.on('data', chunk => {
data.push(chunk)
})
req.on('end', () => {
JSON.parse(data)
})
}
Now my problem. I cant get any data of the req or res object. Both "on" functionts dont fire and I dont know what to do now. Whats the right way to do this in NodeJS? (c# Code cant be changed)
Edit:
Here is the c# Server Code that works. How can I translate that into nodejs?
HttpListener listener = new HttpListener();
listener.Prefixes.Add($"https://+:{Config.Port}/");
listener.AuthenticationSchemes = AuthenticationSchemes.Basic;
listener.Start();
for (; ; )
{
Console.WriteLine("Listening...");
IAsyncResult result = listener.BeginGetContext(new AsyncCallback(DoWork), listener);
result.AsyncWaitHandle.WaitOne();
result = null;
}
private void DoWork(IAsyncResult asyncResult)
{
HttpListener listener = (HttpListener)asyncResult.AsyncState;
HttpListenerContext context = listener.EndGetContext(asyncResult);
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
HttpListenerBasicIdentity identity = (HttpListenerBasicIdentity)context.User.Identity;
string data;
using (var reader = new StreamReader(request.InputStream, request.ContentEncoding))
{
data = reader.ReadToEnd();
}
....
More Code
....
string responseSerial = JsonConvert.SerializeObject(responseData);
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseSerial);
response.ContentLength64 = buffer.Length;
System.IO.Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
output.Close();
}
You lack res.end() somewhere to let node's server know that it should send response back. Before that you can write your actual response. Tested that on your exact C# code and a simplified version of the node server:
var http = require('http');
var _server = http.createServer(_listener);
_server.listen(1234);
console.log( 'started' );
function _listener(req, res) {
let data = []
req.on('data', chunk => {
data.push(chunk)
})
req.on('end', () => {
JSON.parse(data);
res.write('response')
res.end()
})
}

C# VS2008 HttpsClient Post Data How-To

I am trying to write an https Post with the data duration=300. I am new to C# and am writing in a sandbox for another program called Crestron Simpl#. If anyone could help point me in the right direction for adding the data to the Post. Thanks
public void post(String postVar)
{
try
{
var httpsSet = new HttpsClient();
httpsSet.KeepAlive = false;
httpsSet.Accept = "application/xml";
httpsSet.UserName = username;
httpsSet.Password = password;
httpsSet.HostVerification = false;
httpsSet.PeerVerification = false;
HttpsClientRequest sRequest = new HttpsClientRequest();
sRequest.RequestType = RequestType.Post;
sRequest.Url.Parse("https://" + ipaddress + postVar);
HttpsClientResponse response = httpsSet.Dispatch(sRequest);
string responseRx = response.ContentString;
ushort iRepsonse = myRx(responseRx);
}
catch (Exception e)
{
CrestronConsole.PrintLine(String.Format("{0} exception", e.Message));
}
}
Here's a sample C# snippet for a PUT request.
HttpWebRequest HttpWReq = (HttpWebRequest) WebRequest.Create("http:\\YourDomain.com");
ASCIIEncoding Encoding = new ASCIIEncoding();
byte[] data = Encoding.GetBytes("Put you data here");
HttpWReq.Method = "PUT";
HttpWReq.ContentType = "Enter your MIME type";
HttpWReq.ContentLength = data.Length;
//Then when you actually want to write the request, perform these functions:
Stream NewStream = HttpWReq.GetRequestStream();
NewStream.Write(data, 0, data.Length);
NewStream.Close();
You can read more into other answers here.

C# PHP communication

I'm writing an app that will authenticate user from a MySQL database.
I have written it in Java (android) but am now porting to Windows phone.
the PHP file uses $get and then echoes the response:
$localhost = mysql_connect($hostname_localhost,$username_localhost,$password_localhost)
or
trigger_error(mysql_error(),E_USER_ERROR);
mysql_select_db($database_localhost, $localhost);
$username = $_POST['username'];
$query_search = "select * from users where user = '".$username."'";
//$query_search = "select * from users where username = '".$username."' AND password = '".$password. "'";
$query_exec = mysql_query($query_search) or die(mysql_error());
$rows = mysql_num_rows($query_exec);
//echo $rows;
if($rows == 0) {
echo "No Such User Found";
} else {
echo "User Found";
}
How can I pass the username variable to PHP and then receive the result?
YOUR CODE IS VULNERABLE TO SQL-INJECTION METHOD USE PDO/MYSQLi to AVOID THIS
Create loaded event handler:
using System;
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
System.Uri myUri = new System.Uri("Your php page url");
HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(myUri);
myRequest.Method = "POST";
myRequest.ContentType = "application/x-www-form-urlencoded";
myRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback),myRequest);
}
creating "POST" data stream:
void GetRequestStreamCallback(IAsyncResult callbackResult)
{
HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
// End the stream request operation
Stream postStream = myRequest.EndGetRequestStream(callbackResult);
// Create the post data
string postData = "username=value";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Add the post data to the web request
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
// Start the web request
myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallback), myRequest);
}
receive response:
void GetResponsetStreamCallback(IAsyncResult callbackResult)
{
HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
{
string result = httpWebStreamReader.ReadToEnd();
//For debug: show results
Debug.WriteLine(result);
}
}
use a in-linky stuff like I have a script in my server and you just write: "example.com/save.php?username=textbox1.text&score=points"

Deleting cookies / looping login & logout request

I'm making a project to log into a website than instantly log out and do it all over again. Well my problem is cookies I'm quite unsure how to log out correctly and than resend. Closing the app and restarting it logs the user back in again so its obvious cookies are being cleared then.
private void Form1_Load(object sender, EventArgs e)
{
WebRequest request;
string postData;
byte[] byteArray;
Stream dataStream;
while (true)
{
try
{
HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create("http://www.********/index.php");
ASCIIEncoding encoding = new ASCIIEncoding();
postData = "param=example&param=0&param=bigboy";
byte[] data = encoding.GetBytes(postData);
httpWReq.Method = "POST";
httpWReq.ContentType = "application/x-www-form-urlencoded";
httpWReq.ContentLength = data.Length;
httpWReq.KeepAlive = false;
httpWReq.CookieContainer = new CookieContainer();
using (Stream stream = httpWReq.GetRequestStream())
{
stream.Write(data, 0, data.Length);
stream.Close();
}
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
}
}
What can be done to achieve such a looping process?
Something like the following psuedocode should work for you.
Note the reuse of the same CookieContainer object on the login AND the logout requests.
static void Main(string[] args)
{
while (true)
{
try
{
CookieContainer cookies = new CookieContainer();
HttpWebRequest loginRequest = (HttpWebRequest)WebRequest.Create("http://www.********/index.php");
loginRequest.CookieContainer = cookies;
// Configure login request headers and data, write to request stream, etc.
HttpWebResponse loginResponse = (HttpWebResponse)loginRequest.GetResponse();
HttpWebRequest logoutRequest = (HttpWebRequest)WebRequest.Create("http://www.********/logout.php");
logoutRequest.CookieContainer = cookies;
// Configure logout request headers and data, write to request stream, etc.
HttpWebResponse logoutResponse = (HttpWebResponse)logoutRequest.GetResponse();
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
}
}
Give something like this a try and let me know how it goes.
Also: Try debugging the response objects' Cookie property. It's a CookieCollection, not a CookieContainer as per the request. But it should still provide useful debug information if you need to take a closer look at exactly what's going on. Example here: http://goo.gl/L2MMrj

Categories