c# HTTPS proxy (just relaying from browser -> proxy -> website -> proxy -> browser) - c#

so I have this code where I relay all connections to the destination server, I get the response back from it in a byte[] called result, but when dealing with SSL/HTTPS the end server always return an empty response
public static byte[] ForwardRequest(byte[] requestBytes)
{
byte[] result = new byte[0];
try
{
string requestString = Encoding.UTF8.GetString(requestBytes);
string[] requestLines = requestString.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
string host = "";
int port = 80;
if (requestString.Contains("CONNECT"))
{
string connectLine = requestLines[0];
string hostWithPort = connectLine.Split(' ')[1];
host = hostWithPort.Split(':')[0];
port = Convert.ToInt32(hostWithPort.Split(':')[1]);
}
else
{
host = requestLines[1].Split(' ')[1];
if (host.Contains(":"))
{
string[] split = host.Split(':');
host = split[0];
port = Convert.ToInt32(split[1]);
}
}
Console.WriteLine("HOST:" + host + "#PORT:" + port);
TcpClient client = new TcpClient();
client.Connect(host, port);
if(client.Connected == true && requestString.Contains("CONNECT"))
{
Console.WriteLine("client connected to ssl");
}
Network.WriteBytes(client, requestBytes);
result = Network.ReadBytes(client, 10000);
if (requestString.Contains("CONNECT"))
{
string resultString = Encoding.UTF8.GetString(result);
Console.WriteLine("############BROWSER REQUEST################" + Environment.NewLine + requestString + Environment.NewLine + "############BROWSER REQUEST################");
Console.WriteLine("############WEBSITE RESPONSE###############" + Environment.NewLine + resultString + Environment.NewLine + "############WEBSITE RESPONSE###############");
Console.WriteLine("responseLenght: " + result.Length);
}
}
catch (Exception ex)
{
Console.WriteLine("Network.Forward() -> " + ex.Message);
}
return result;
}
I thought that it should work because I'm just sending raw data from browser to server and back. Again, all the other code works fine because with HTTP websites it works.
this is my console window after sending trying to talk to HTTPS

Related

How to allow the user to use his HTML code in c# . net http server

I am creating a software to help the user to create his own http server. But the site isn't loading if he uses his own input. I tried to use this:
private void startListeningForConnection()
{
while (true)
{
DateTime time = DateTime.Now;
String data = "";
byte[] bytes = new byte[2048];
Socket client = httpServer.Accept(); // Blocking Statement
// Reading the inbound connection data
while (true)
{
int numBytes = client.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, numBytes);
if (data.IndexOf("\r\n") > -1)
break;
}
// Data Read
serverLogsText.Invoke((MethodInvoker)delegate
{
// Runs inside the UI Thread
serverLogsText.Text += "\r\n\r\n";
serverLogsText.Text += data;
serverLogsText.Text += "\n\n------ End of Request -------";
});
// Send back the Response
String resHeader = "HTTP/1.1 200 Everything is Fine\nServer: Vedoo_Server\nContent-Type: text/html; charset: UTF-8\n\n";
String resBody =
"<!DOCTYPE>" +
"<html>" +
" <head>" +
" <title>" + svtitletext.Texts + "</title>" +
" </head>" +
" <body>" +
servercontent.Text +
" </body>" +
"</html>";
String resStr = resHeader + resBody;
byte[] resData = Encoding.ASCII.GetBytes(resStr);
client.SendTo(resData, client.RemoteEndPoint);
client.Close();
}
Where servercontent is a richtextbox that allows the user to input his html code. For example<h4>Hello\<\\h4\>\
I was expecting that on the localhost to show user imput. The custom pagetitle works.

Transfer String via TCP/IP to multiple computers

This code currently takes kinect Body data and writes it in an Excel Worksheet. I have another code that is able to create a TCP/IP connection between two computers. How would I best combine these two ideas?
I require this Joint String Data to be sent over the network and collected by another server computer, in real-time, not in an excel file. Do you have any suggestions ?
In other words, I have some Server code, but i want the server to listen for the Kinect String Data that the client code (Another computer) is generating and currently is writing it to a local excel file.
Client Side
...
_recordBody = !_recordBody;
if (_recordBody == false)
{
recordButton.Content = "Record";
return;
}
recordButton.Content = "Stop Recording";
currentTrackingID = 0;
// create a csv file and write file header
string currPath = System.IO.Directory.GetCurrentDirectory();
string folder = "recordings";
string recordPath = System.IO.Path.Combine(currPath, folder);
if (!Directory.Exists(recordPath))
{
Directory.CreateDirectory(recordPath);
}
timeRecordingStarted = DateTime.Now;
string filename = timeRecordingStarted.ToString("yyyy-MM-dd HH-mm-ss");
filename = filename + ".csv";
filePath = System.IO.Path.Combine(recordPath, filename);
string[] writtentext = {"time," + "headX," +
"headY," +
"headZ," +
"headS," +
"neckX," +
"neckY," +
"neckZ," +
"neckS," +
"spineShoulderX," +
"spineShoulderY," +
"spineShoulderZ," +
...
"handLeftY," +
"handLeftZ," +
"handLeftS," +
"handTipRightX," +
"handTipRightY," +
"handTipRightZ," +
"handTipRightS," +
"handTipLeftX," +
"handTipLeftY," +
"handTipLeftZ," +
"handTipLeftS"
};
File.WriteAllLines(filePath, writtentext);
...
Server Code
static TcpListener tcpListener = new TcpListener(10);
static void Listeners()
{
Socket socketForClient = tcpListener.AcceptSocket();
if (socketForClient.Connected)
{
Console.WriteLine("Client:"+socketForClient.RemoteEndPoint+" now connected to server.");
NetworkStream networkStream = new NetworkStream(socketForClient);
System.IO.StreamWriter streamWriter =
new System.IO.StreamWriter(networkStream);
System.IO.StreamReader streamReader =
new System.IO.StreamReader(networkStream);
{
string theString = streamReader.ReadLine();
Console.WriteLine("Message recieved by client:" + theString);
if (theString == "exit")
break;
}
streamReader.Close();
networkStream.Close();
streamWriter.Close();
//}
}
socketForClient.Close();
Console.WriteLine("Press any key to exit from server program");
Console.ReadKey();
}
public static void Main()
{
//TcpListener tcpListener = new TcpListener(10);
tcpListener.Start();
Console.WriteLine("************This is Server program************");
Console.WriteLine("How many clients are going to connect to this server?:");
int numberOfClientsYouNeedToConnect =int.Parse( Console.ReadLine());
for (int i = 0; i < numberOfClientsYouNeedToConnect; i++)
{
Thread newThread = new Thread(new ThreadStart(Listeners));
newThread.Start();
}
}
}

TcpListener AcceptSocket() accepts two connections for each single GET request

I have this web server program up and running, using TcpListener. The problem is that for each get request made through web browser (or chrome Postman extension), it captures two requests.
namespace Server
{
class WebServer2
{
private TcpListener listener;
private int port = 8080;
public WebServer2()
{
try
{
listener = new TcpListener(IPAddress.Parse("127.0.0.1"), port);
listener.Start();
Console.WriteLine("Listening...");
//start the thread which calls the method 'StartListen'
Thread th = new Thread(new ThreadStart(StartListen));
th.Start();
}
catch (Exception e)
{
Console.WriteLine("An Exception Occurred While Listening: " + e.ToString());
}
}
//Recieve Request
public void StartListen()
{
int iStartPos = 0;
String sRequest;
String sRequestedFile;
String sResponse = "";
while (true)
{
//Accept a new connection
Socket socket = listener.AcceptSocket();
if (socket.Connected)
{
Console.WriteLine("\nClient Connected");
Console.WriteLine("----------------");
//Receive data from the client
Byte[] bReceive = new Byte[1024];
int i = socket.Receive(bReceive, bReceive.Length, 0);
//Convert Byte to String
string sBuffer = Encoding.ASCII.GetString(bReceive);
//Only GET Request is accepted
if (sBuffer.Substring(0, 3) != "GET")
{
Console.WriteLine("Not a Get Request.");
socket.Close();
continue;
}
// Look for HTTP request
iStartPos = sBuffer.IndexOf("HTTP", 1);
// Get the HTTP text and version e.g. it will return "HTTP/1.1"
string sHttpVersion = sBuffer.Substring(iStartPos, 8);
// Extract the Requested Type and Requested file/directory
sRequest = sBuffer.Substring(0, iStartPos - 1);
//If file name not provided
if (sRequest.IndexOf(".") < 1)
{
Console.WriteLine("File name not Provided!");
socket.Close();
continue;
}
//Extract the requested file name
iStartPos = sRequest.LastIndexOf("/") + 1;
sRequestedFile = sRequest.Substring(iStartPos);
Console.WriteLine("Requested File: " + sRequestedFile);
int iTotBytes = 0;
sResponse = "";
FileStream fs = new FileStream(sRequestedFile, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryReader reader = new BinaryReader(fs);
byte[] bytes = new byte[fs.Length];
int read;
while ((read = reader.Read(bytes, 0, bytes.Length)) != 0)
{
// Read from the file and write the data to the network
sResponse = sResponse + Encoding.ASCII.GetString(bytes, 0, read);
iTotBytes = iTotBytes + read;
}
reader.Close();
fs.Close();
SendHeader(sHttpVersion, "text/html", iTotBytes, " 200 OK", ref socket);
SendToBrowser(bytes, ref socket);
socket.Send(bytes, bytes.Length, 0);
socket.Close();
}
}
}
// Overloaded Function, takes string, convert to bytes and calls
// overloaded sendToBrowserFunction.
public void SendToBrowser(String sData, ref Socket socket)
{
SendToBrowser(Encoding.ASCII.GetBytes(sData), ref socket);
}
/// Sends data to the browser (client)
public void SendToBrowser(Byte[] bSendData, ref Socket socket)
{
int numBytes = 0;
try
{
if (socket.Connected)
{
if ((numBytes = socket.Send(bSendData, bSendData.Length, 0)) == -1)
Console.WriteLine("Socket Error");
}
else
Console.WriteLine("Connection Dropped!");
}
catch (Exception e)
{
Console.WriteLine("Error: {0} ", e);
}
}
// This function send the Header Information to the client (Browser)
public void SendHeader(string sHttpVersion, string sMIMEHeader, int iTotBytes, string sStatusCode, ref Socket socket)
{
String sBuffer = "";
Byte[] bSendData;
if (sStatusCode.Equals("404") || sStatusCode.Equals("400"))
{
sBuffer = sBuffer + sHttpVersion + sStatusCode + "\r\n";
sBuffer = sBuffer + "Server: MyServer\r\n";
sBuffer = sBuffer + "Content-Length: " + 0 + "\r\n\r\n";
bSendData = Encoding.ASCII.GetBytes(sBuffer);
SendToBrowser(bSendData, ref socket);
}
else
{
sBuffer = sBuffer + sHttpVersion + sStatusCode + "\r\n";
sBuffer = sBuffer + "Server: MyServer\r\n";
sBuffer = sBuffer + "Content-Type: " + sMIMEHeader + "\r\n";
sBuffer = sBuffer + "Accept-Ranges: bytes\r\n";
sBuffer = sBuffer + "Content-Length: " + iTotBytes + "\r\n\r\n";
bSendData = Encoding.ASCII.GetBytes(sBuffer);
SendToBrowser(bSendData, ref socket);
}
}
}
}
Single request made by chrome against http://localhost:8080/page1.html
Request made by Postman Extension
The funny thing is, everything works find when I send request through my client program (using TcpClient).
I tested your server and got similar results:
Chrome automatically asks for a favicon.ico file for every request. This generates the extra GET request to your server.
Firefox doesn't do this and simply generates one request per refresh.
Then there is a second problem I experienced, which is the one in your Postman screenshot.
Chrome (including the Postman Extension running inside it) reconnects
without sending anything, so the server "hangs" until you get a
response filled with \0 (nul-characters).
This is part of Chrome's prediction service to load subsequent requests faster. You could disable this behavior under Settings (advanced) > Privacy:
In your server implementation, this results in the "Not a Get Request" output if no subsequent GET request follows (instead, Chrome sends \0 to signal its not sending anything anyway).
Note: I didn't experience any of this in the actual Postman application.
While the server waits for chrome to send a request, it cannot service any other requests. To prevent this from happening, consider using an asynchronous approach.

UDP relay implementation do not work as I expected

I am trying to implement the relay of UDP communication.
For example, I have two terminals:
192.168.10.5
192.168.10.6
I would like to monitor between the two by way of 192.168.10.3.
My environment:
Unity 5.1.2-f1 on MacOS X 10.8.5 using C#
Following is my code snippet related to the UDP communication.
void Monitor() {
UdpClient client = new UdpClient (port);
client.Client.ReceiveTimeout = 1000; // msec
client.Client.Blocking = false;
while (ToggleComm.isOn) {
try {
IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
byte[] data = client.Receive(ref anyIP);
string text = Encoding.ASCII.GetString(data);
if (text.Length == 0) {
Thread.Sleep(20);
continue;
}
string fromIP = anyIP.Address.ToString();
// send to the other
if (fromIP.Equals(ipadr1)) {
client.Send(data, data.Length, ipadr2, port);
Debug.Log("from: " + ipadr1 + " to " + ipadr2 + data);
} else {
client.Send(data, data.Length, ipadr1, port);
Debug.Log("from: " + ipadr2 + " to " + ipadr1 + data);
}
}
catch (Exception err) {
}
// without this sleep, on android, the app will freeze at Unity splash screen
Thread.Sleep(200);
}
client.Close ();
}
With the code above,
I can send from 192.168.10.5 to 192.168.10.3
I can send from 192.168.10.3 to 192.168.10.6 (relay)
I can receive at 192.168.10.3 from 192.168.10.6
I cannot receive at 192.168.10.5 from 192.168.10.3
where 192.168.10.6 works as echo server, returning received string back.
My debug print on the relay says
from: 192.168.10.5 to 192.168.10.6
from: 192.168.10.6 to 192.168.10.5
It seems that the relay (192.168.10.3) send to 192.168.10.5, but 192.168.10.5 cannot receive the relayed one.
Following code worked (not elegant yet, though).
I had misunderstanding about port of the sender and receiver.
void Monitor() {
UdpClient client = new UdpClient (port);
client.Client.ReceiveTimeout = 300; // msec
client.Client.Blocking = false;
string fromPort = "6000"; // at first 6000 is set as dummy
while (ToggleComm.isOn) {
try {
IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
byte[] data = client.Receive(ref anyIP);
string text = Encoding.ASCII.GetString(data);
if (text.Length == 0) {
Thread.Sleep(20);
continue;
}
string fromIP = anyIP.Address.ToString();
// send to the other
if (fromIP.Equals(ipadr1)) {
fromPort = anyIP.Port.ToString(); // store the port
client.Send(data, data.Length, ipadr2, port);
Debug.Log("1 from: " + fromIP + "(" + fromPort
+ ") to " + ipadr2 + "(" + port.ToString() + ")");
} else {
client.Send(data, data.Length, ipadr1, Convert.ToInt32(fromPort));
Debug.Log("2 from: " + fromIP + "(" + "..."
+ ") to " + ipadr1 + "(" + fromPort + ")");
}
}
catch (Exception err) {
}
// without this sleep, on android, the app will freeze at Unity splash screen
Thread.Sleep(200);
}
client.Close ();
}
I put the unity project at github (v0.3)

between html5 and C# web socket communication

trying to send string data to windows c# application with this code;
try {
var ws = new WebSocket('ws://192.168.1.77:10048');
ws.onopen = function () {
ws.send("Sunucuya mesaj"); // I WANT TO SEND THIS MESSAGE TO SERVER!
};
ws.onclose = function () {
alert('Bağlantı kapandı.');
};
}
catch (e) {
alert(e);
}
and trying to get data from windows c# application with this code;
static Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
static private string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8181));
serverSocket.Listen(128);
serverSocket.BeginAccept(null, 0, OnAccept, null);
private static void OnAccept(IAsyncResult result)
{
byte[] buffer = new byte[1024];
try
{
Socket client = null;
string headerResponse = "";
if (serverSocket != null && serverSocket.IsBound)
{
client = serverSocket.EndAccept(result);
var i = client.Receive(buffer);
headerResponse = (System.Text.Encoding.UTF8.GetString(buffer)).Substring(0, i);
// write received data to the console
Console.WriteLine(headerResponse);
}
if (client != null)
{
var key = headerResponse.Replace("ey:", "`")
.Split('`')[1] // dGhlIHNhbXBsZSBub25jZQ== \r\n .......
.Replace("\r", "").Split('\n')[0] // dGhlIHNhbXBsZSBub25jZQ==
.Trim();
// key should now equal dGhlIHNhbXBsZSBub25jZQ==
var test1 = AcceptKey(ref key);
var newLine = "\r\n";
var response = "HTTP/1.1 101 Switching Protocols" + newLine
+ "Upgrade: websocket" + newLine
+ "Connection: Upgrade" + newLine
+ "Sec-WebSocket-Accept: " + test1 + newLine + newLine
//+ "Sec-WebSocket-Protocol: chat, superchat" + newLine
//+ "Sec-WebSocket-Version: 13" + newLine
;
// which one should I use? none of them fires the onopen method
client.Send(System.Text.Encoding.UTF8.GetBytes(response));
var i = client.Receive(buffer); // wait for client to send a message
// once the message is received decode it in different formats
Console.WriteLine(Convert.ToBase64String(buffer).Substring(0, i));
Console.WriteLine("\n\nPress enter to send data to client");
Console.Read();
var subA = SubArray<byte>(buffer, 0, i);
client.Send(subA);
Thread.Sleep(10000);//wait for message to be send
}
}
catch (SocketException exception)
{
throw exception;
}
finally
{
if (serverSocket != null && serverSocket.IsBound)
{
serverSocket.BeginAccept(null, 0, OnAccept, null);
}
}
}
with this code i can communicate between client and server but i can't get ws.send("Sunucuya mesaj"); message from server that send from client. headerResponse = (System.Text.Encoding.UTF8.GetString(buffer)).Substring(0, i); in this row you can see the header that is getting from server;
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 192.168.1.77:8181
Origin: http://localhost
Sec-WebSocket-Key: dHI34r7feV/Ar4G0/fONCg==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
How can i get data that is coming from client from server-side?
Thanks...
Messages between client and server are not plain text. See the data framing section of the protocol spec for details on how to encode/decode messages.
There are several liberally licensed open source C# servers you can take examples from. Such as Fleck

Categories

Resources