Click here to Skip to main content
15,881,172 members
Articles / Desktop Programming / MFC

Negotiating proxies in the form of a Whois client

Rate me:
Please Sign up or sign in to vote.
4.82/5 (6 votes)
19 May 20063 min read 43.9K   903   17  
An article on dealing with proxies.
#include "StdAfx.h"
#include ".\httpproxyclient.h"
#include "Base64Coder.h"
#include <vector>
using namespace std;

CHttpProxyClient::CHttpProxyClient(void)
{
	m_proxySocket = -1;
	m_httpVersion = HTTP_10;
	strcpy(m_szErrorMsg,"Success");
	memset(&proxy_address,0,sizeof(proxy_address));
	strcpy(m_szUserName,"");
	strcpy(m_szPassword,"");
}

CHttpProxyClient::~CHttpProxyClient(void)
{
}

// sets the username to use for authorization
void CHttpProxyClient::SetUserName(char* szUserName)
{
	strcpy(m_szUserName,szUserName);
}

// sets the password to use for proxy Authorization
void CHttpProxyClient::SetPassword(char* szPassword)
{
	strcpy(m_szPassword,szPassword);
}

void CHttpProxyClient::SetHttpVersion(HTTP_VER ver)
{
	m_httpVersion = ver;
}

// Requests a given resource from the proxy, sending the specified proxy authentication info if required
// proxy authentication requires use of Base64Coder to encode the authentication
// Header should terminate in a CRLF pair
bool CHttpProxyClient::Request(HTTP_METHOD method, char* szURI, char* szHeader,
							   bool bUseProxyAuthentication/*=false*/,
							   char* szMessageBody/*=NULL*/)
{
	if (m_proxySocket == -1)
	{
		strcpy(m_szErrorMsg,"Socket not valid, please call SetProxy and then Connect first");
		return false;
	}
	char *szMethod = new char[8];
	switch(method) {
	case HTTP_OPTIONS:
		strcpy(szMethod,"OPTIONS");
		break;
	case HTTP_GET:
		strcpy(szMethod,"GET");
		break;
	case HTTP_HEAD:
		strcpy(szMethod,"HEAD");
		break;
	case HTTP_POST:
		strcpy(szMethod,"POST");
		break;
	case HTTP_PUT:
		strcpy(szMethod,"PUT");
		break;
	case HTTP_DELETE:
		strcpy(szMethod,"DELETE");
		break;
	case HTTP_TRACE:
		strcpy(szMethod,"TRACE");
		break;
	case HTTP_CONNECT:
		strcpy(szMethod,"CONNECT");
		break;
	default:
		strcpy(szMethod,"GET");
	}
	char msg[2048];
	char ver[9];
	if (m_httpVersion == HTTP_10)
	{
		strcpy(ver,"HTTP/1.0");
	}
	else if (m_httpVersion == HTTP_11)
	{
		strcpy(ver,"HTTP/1.1");
	}
	else
	{
		strcpy(m_szErrorMsg,"Invalid HTTP Version");
		return false;
	}
	sprintf(msg,"%s %s %s\r\n",szMethod,szURI,ver);
	if (send(m_proxySocket,msg,(int)strlen(msg),0) == SOCKET_ERROR)
	{
		strcpy(m_szErrorMsg,"Error sending message");
		return false;
	}
	if (szHeader != NULL)
	{
		sprintf(msg,"%s",szHeader);
		if (send(m_proxySocket,msg,(int)strlen(msg),0) == SOCKET_ERROR)
		{
			strcpy(m_szErrorMsg,"Error sending message");
			return false;
		}
	}
	if (bUseProxyAuthentication)
	{
		Base64Coder coder;
		if ((strcmp(m_szUserName,"") != 0) && (strcmp(m_szPassword,"") != 0))
		{
			sprintf(msg,"%s:%s",m_szUserName,m_szPassword);
			coder.Encode(msg);
		}
		else if (strcmp(m_szUserName,"") != 0)
		{
			sprintf(msg,"%s:",m_szUserName);
			coder.Encode(msg);
		}
		else if (strcmp(m_szPassword,"") != 0)
		{
			sprintf(msg,":%s",m_szPassword);
			coder.Encode(msg);
		}
		sprintf(msg,"Proxy-Authorization: Basic %s\r\n",coder.EncodedMessage());
		if (send(m_proxySocket,msg,(int)strlen(msg),0) == SOCKET_ERROR)
		{
			strcpy(m_szErrorMsg,"Error sending message");
			return false;
		}
	}
	sprintf(msg,"\r\n");
	if (send(m_proxySocket,msg,(int)strlen(msg),0) == SOCKET_ERROR)
	{
		strcpy(m_szErrorMsg,"Error sending message");
		return false;
	}
	if (szMessageBody != NULL)
	{
		if (send(m_proxySocket,szMessageBody,(int)strlen(szMessageBody),0) == SOCKET_ERROR)
		{
			strcpy(m_szErrorMsg,"Error sending message");
			return false;
		}
	}
	strcpy(m_szErrorMsg,"Success");
	return true;
}

// Initiates a connection to the specified proxy
bool CHttpProxyClient::Connect()
{
	if (proxy_address.sin_port == 0)
	{
		strcpy(m_szErrorMsg,"Please call SetProxy first");
		return false;
	}
	if( ( m_proxySocket = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ){
		strcpy(m_szErrorMsg, "Could not establish socket connection." );
		return false;
	}

	// Code for proxy authentication if allowed by proxy server:
	if( connect( m_proxySocket, (struct sockaddr *)&proxy_address, sizeof( struct sockaddr ) ) == -1 ){
		strcpy(m_szErrorMsg, "Could not connect to proxy." );
		return false;
	}
	strcpy(m_szErrorMsg,"Success");
	return true;
}

//Sets the proxy to use
bool CHttpProxyClient::SetProxy(char* szProxy, int nProxyPort)
{
	struct hostent *he;

	if( !( he = gethostbyname( szProxy ) ) ){
		strcpy(m_szErrorMsg, "Could not resolve host" );
		return false;
	}

	proxy_address.sin_family = AF_INET;
	proxy_address.sin_port   = htons( nProxyPort );
	proxy_address.sin_addr   = *( (struct in_addr *)he->h_addr );
	memset(& (proxy_address.sin_zero ), '\0', 8 );  //clear the struct
	strcpy(m_szErrorMsg,"Success");
	return true;
}

// Reads a line of text from the servers response
char *CHttpProxyClient::ReadLine()
{
	vector<char> vText;
	char         buffer[1];
	int          bytesReceived;

	while (true) {

		bytesReceived = recv(m_proxySocket, buffer, 1, 0);

		if(bytesReceived <= 0)
			return NULL;

		if(buffer[0] == '\n') {

			char *pChar = new char[vText.size() + 1];
			memset(pChar, 0, vText.size() + 1);

			for (int f = 0; f < (int)vText.size(); f++)
				pChar[f] = vText[f];

			return pChar;

		} 
		else 
		{
			vText.push_back(buffer[0]);
		}
	}
	return NULL;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
Programming using MFC and ATL for almost 12 years now. Currently studying Operating System implementation as well as Image processing. Previously worked on DSP and the use of FFT for audio application. Programmed using ADO, ODBC, ATL, COM, MFC for shell interfacing, databasing tasks, Internet items, and customization programs.

Comments and Discussions