C++/CLI HTTP Proxy problems...
- by darkantimatter
Hi, I'm trying(very hard) to make a small HTTP Proxy server which I can use to save all communications to a file. Seeing as I dont really have any experience in the area, I used a class from codeproject.com and some associated code to get started (It was made in the old CLI syntax, so I converted it). I couldn't get it working, so I added lots more code to make it work (threads etc), and now it sort of works. Basically, it recieves something from a client (I just configured Mozilla Firefox to route its connections through this proxy) and then routes it to google.com. After it sends Mozilla's data to google, recieves a responce, and sends that to Mozilla. This works fine, but then the proxy fails to recieve any data from Mozilla. It just loops in the Sleep(50) section. Anyway, heres the code:
ProxyTest.cpp:
#include "stdafx.h"
#include "windows.h"
#include "CHTTPProxy.h"
public ref class ClientThread {
public:
System::Net::Sockets::TcpClient ^ pClient;
CHttpProxy ^ pProxy;
System::Int32 ^ pRecieveBufferSize;
System::Threading::Thread ^ Thread;
ClientThread(System::Net::Sockets::TcpClient ^ sClient,
CHttpProxy ^ sProxy,
System::Int32 ^ sRecieveBufferSize) {
pClient = sClient;
pProxy = sProxy;
pRecieveBufferSize = sRecieveBufferSize;
};
void StartReading() {
Thread = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this,&ClientThread::ThreadEntryPoint));
Thread->Start();
};
void ThreadEntryPoint() {
char * bytess;
bytess = new char[(int)pRecieveBufferSize];
memset(bytess, 0, (int)pRecieveBufferSize);
array<unsigned char> ^ bytes = gcnew array<unsigned char>((int)pRecieveBufferSize);
array<unsigned char> ^ sendbytes;
do {
if (pClient->GetStream()->DataAvailable) {
try {
do {
Sleep(100); //Lets wait for whole packet to get cached (If it even does...)
unsigned int k = pClient->GetStream()->Read(bytes, 0, (int)pRecieveBufferSize); //Read it
for(unsigned int i=0; i<(int)pRecieveBufferSize; i++) bytess[i] = bytes[i];
Console::WriteLine("Packet Received:\n"+gcnew System::String(bytess));
pProxy->SendToServer(bytes,pClient->GetStream()); //Now send it to google!
pClient->GetStream()->Flush();
} while(pClient->GetStream()->DataAvailable);
} catch (Exception ^ e) {
break;
}
} else {
Sleep(50); //It just loops here because it thinks mozilla isnt sending anything
if (!(pClient->Connected)) break;
};
} while (pClient->GetStream()->CanRead);
delete [] bytess;
pClient->Close();
};
};
int main(array<System::String ^> ^args)
{
System::Collections::Generic::Stack<ClientThread ^> ^ Clients =
gcnew System::Collections::Generic::Stack<ClientThread ^>();
System::Net::Sockets::TcpListener ^ pTcpListener = gcnew System::Net::Sockets::TcpListener(8080);
pTcpListener->Start();
System::Net::Sockets::TcpClient ^ pTcpClient;
while (1) {
pTcpClient = pTcpListener->AcceptTcpClient(); //Wait for client
ClientThread ^ Client = gcnew ClientThread(pTcpClient,
gcnew CHttpProxy("www.google.com.au", 80),
pTcpClient->ReceiveBufferSize); //Make a new object for this client
Client->StartReading(); //Start the thread
Clients->Push(Client); //Add it to the list
};
pTcpListener->Stop();
return 0;
}
CHTTPProxy.h, from http://www.codeproject.com/KB/IP/howtoproxy.aspx with a lot of modifications:
//THIS FILE IS FROM http://www.codeproject.com/KB/IP/howtoproxy.aspx. I DID NOT MAKE THIS! BUT I HAVE MADE SEVERAL MODIFICATIONS!
#using <mscorlib.dll>
#using <SYSTEM.DLL>
using namespace System;
using System::Net::Sockets::TcpClient;
using System::String;
using System::Exception;
using System::Net::Sockets::NetworkStream;
#include <stdio.h>
ref class CHttpProxy
{
public:
CHttpProxy(System::String ^ szHost, int port);
System::String ^ m_host;
int m_port;
void SendToServer(array<unsigned char> ^ Packet, System::Net::Sockets::NetworkStream ^ sendstr);
};
CHttpProxy::CHttpProxy(System::String ^ szHost, int port)
{
m_host = gcnew System::String(szHost);
m_port = port;
}
void CHttpProxy::SendToServer(array<unsigned char> ^ Packet, System::Net::Sockets::NetworkStream ^ sendstr)
{
TcpClient ^ tcpclnt = gcnew TcpClient();
try
{
tcpclnt->Connect(m_host,m_port);
}
catch (Exception ^ e )
{
Console::WriteLine(e->ToString());
return;
}
// Send it
if ( tcpclnt )
{
NetworkStream ^ networkStream;
networkStream = tcpclnt->GetStream();
int size = Packet->Length;
networkStream->Write(Packet, 0, size);
array<unsigned char> ^ bytes = gcnew array<unsigned char>(tcpclnt->ReceiveBufferSize);
char * bytess = new char[tcpclnt->ReceiveBufferSize];
Sleep(500); //Wait for responce
do {
unsigned int k = networkStream->Read(bytes, 0, (int)tcpclnt->ReceiveBufferSize); //Read from google
for(unsigned int i=0; i<k; i++) {
bytess[i] = bytes[i];
if (bytess[i] == 0) bytess[i] = ' '; //Dont terminate the string
if (bytess[i] < 8) bytess[i] = ' '; //Somethings making the computer beep, and its not 7?!?!
};
Console::WriteLine("\n\nAbove packet sent to google. Google Packet Received:\n"+gcnew System::String(bytess));
sendstr->Write(bytes,0,k); //Send it to mozilla
Console::WriteLine("\n\nAbove packet sent to client...");
//Sleep(1000);
} while(networkStream->DataAvailable);
delete [] bytess;
}
return;
}
Any help would be much appreciated, I've tried for hours.