Virtual Host Proxy Server


Application Security Testing: An Integral Part of DevOps

Environment: VC++ 6, Windows 95/98/NT

From time to time, I pick-up ideas from codeguru.com so I thought that I should contribute as well.

The program I'm submitting today is aimed at solving a problem that sounds simple but appears to be next to impossible: running multiple Web servers on a single Windows 95/98 machine. If you are running NT, you can assign multiple IP addresses to your networks card, edit the hosts file to translate domain names into IP addresses and assign multiple Websites to Internet Information Server...

It's a bit tricky but feasible. If you're running Windows 95 or 98, it's virtually impossible so I had to find a way around that.

What I've done is write a very simple proxy server that translate server names into a sub folder of your local machine so your can host as many Websites as you want with one single HTTP server.

Let's imagine your web root is C:\WebRoot\, you will put the files for http://www.a.com into C:\WebRoot\www.a.com\. The files for www.b.com will go in C:\WebRoot\www.b.com\ and so on.

What the proxy will actually do is replace http://www.a.com/index.htm by on the fly ( is equivalent to localhost and is by definition the IP address of your local machine).

So to test the program, what you really need is a Web server, something as simple as Personal Web Server (PWS) from Microsoft and a browser (Netscape Navigator, Internet Explorer or anything else).

You have to create the directories for the virtual servers as mentioned above and you have to configure your browser to use a proxy.

Here is an example with Internet Explorer 5.0 from Microsoft (Tools>Internet Options>Connections>LAN Settings)

As you can see, by default the proxy is running on port 5060.

Something else you have to be aware of is that the proxy doesn't support HTTP 1.1. The way HTTP 1.1 handles connections is slightly more complicated than HTTP 1.0. To keep the code as simple as possible, I decided to support HTTP 1.0 only. Anyway it's the default behavior of the browser when you go through a proxy as you can see on the following screenshot of IE5.

The code is very basic and there are numerous ways to improve it but a) it solved my problem and b) it's short and easy to read. It also provides a very good example on how to use the CSocket classes which are very high level classes and not very well documented.

// VirtualHostProxy.cpp 
// // Virtual Host Proxy Server
// (c) Franck JEANNIN 1999 - fjeannin@linkguard.com
// // Simulate multiple Web servers on one single Windows 95/98 machine 
// // Does not support HTTP 1.1 (HTTP 1.0 only)
// Use high level MFC socket classes: CSocket
// #include "stdafx.h"
#include <afxsock.h> // MFC socket extensions
#include <conio.h>
#define BUFFERSIZE 10000
#define PROXYPORT 5060
#define SERVERPORT 80
int main(int argc, char* argv[])
{ CSocket Proxy;
CSocket Client;
CSocket Server;
// initialize MFC
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { printf("Fatal Error: MFC initialization failed\nPress any key\n"); getch(); return -1; } // initialize Socket support if (!AfxSocketInit()) { printf("Fatal Error: Socket initialization failed\nPress any key\n"); getch(); return -1; } // create Proxy socket if (!Proxy.Create(PROXYPORT)) { printf("Fatal Error: Proxy socket creation failed\nError %d\n\nPress any key\n",GetLastError()); getch(); return -1; } if (!Proxy.Listen(1)) { printf("Fatal Error: Proxy socket activation failed\nError %d\n\nPress any key\n",GetLastError()); getch(); return -1; } else { printf("Virtual Host Proxy Server started on port %d\n(c) Franck JEANNIN 1999\n\n",PROXYPORT); } while(1) { if (!Proxy.Accept(Client)) { printf("Fatal Error: Client connection to Proxy failed\nError %d\n\nPress any key\n",GetLastError()); getch(); return -1; } int n = Client.Receive(Buffer,BUFFERSIZE); if (n == -1) { printf("Fatal Error: Client transmission to Proxy failed\nError %d\n\nPress any key\n",GetLastError()); getch(); return -1; } Buffer[n] = 0; printf("Received from client: %s\n",Buffer); // calls to http://www.a.com/mypage.htm are transformed to calls to char* p = strstr(Buffer,"//"); if (p) { p += 2; memmove(p+sizeof(SERVERADDRESS),p,n); memcpy(p,SERVERADDRESS,sizeof(SERVERADDRESS)-1); *(p+sizeof(SERVERADDRESS)-1) = '/'; n += sizeof(SERVERADDRESS); } if (!Server.Create()) { printf("Fatal Error: Server socket creation failed\nError %d\n\nPress any key\n",GetLastError()); getch(); return -1; } if (!Server.Connect(SERVERADDRESS,SERVERPORT)) { printf("Fatal Error: Server socket connection to HTTP server failed\nError %d\n\nPress any key\n",GetLastError()); getch(); return -1; } n = Server.Send(Buffer,n); if (n == -1) { printf("Fatal Error: Proxy transmission to Server failed\nError %d\n\nPress any key\n",GetLastError()); getch(); return -1; } Buffer[n] = 0; printf("Sent to server: %s\n",Buffer); while ( (n = Server.Receive(Buffer,BUFFERSIZE)) != 0) { if (n == -1) { printf("Fatal Error: Server transmission to Proxy failed\nError %d\n\nPress any key\n",GetLastError()); getch(); return -1; } Buffer[n] = 0; printf("Received from server: %s\n",Buffer); n = Client.Send(Buffer,n); if (n == -1) { printf("Fatal Error: Proxy transmission to Server failed\nError %d\n\nPress any key\n",GetLastError()); getch(); return -1; } Buffer[n] = 0; printf("Sent to Client: %s\n",Buffer); }  printf("Closing Client & Server sockets\n"); Client.Close(); Server.Close(); } return 0; }

Download demo project - 47KB



  • Very good starting point

    Posted by Legacy on 01/22/2004 12:00am

    Originally posted by: Edgar Leon

    Great and simple, I've succesfully modify it to meet my needs.

    I'm very thankfull

  • "www.163.com" cann't be logged on, use the proxy

    Posted by Legacy on 10/25/2001 12:00am

    Originally posted by: wisber

    Your proxy don't work properly,
    the website "www.163.com" cann't be logged on.

  • Virtual Host Proxy Server

    Posted by Legacy on 06/28/2001 12:00am

    Originally posted by: George

    Any ideas on how HTTP/1.1 persistant connections work?
    I have done some experimentation and I am still mystified.
    If I recv twice before sending something to the HTTP server I get a broken pipe, or error.

  • Anyway you have to add .

    Posted by Legacy on 05/18/2001 12:00am

    Originally posted by: michel

    Very usefull for my first step in CSocket; Merci.

    Insert a CWinApp instance at the beginning of your main().
    for exemple CWinApp MyApp;
    Have a look to the "help" for AfxWinInit and AfxSocketInit.

  • no response from client

    Posted by Legacy on 04/20/2001 12:00am

    Originally posted by: Adrian Austin

    Please Help. I found your code on the net. Good stuff. I'm currently trying to write a simple proxy server to sit in between our windows clients and the real proxy server. We're doing this so that we can do some clever authentication on client ip addresses.

    Anyway, I found your code and thought this was the answer. I'd already tried a very similar thing in visual basic.

    I still have a problem however,
    in the command prompt window it all seems to work great. The http request comes in, is sent to the proxy server and the correct response comes back BUT, when I step throught the code I can see that it thinks it has successfully sent the response back to the client but Internet Explorer just sits there and eventually times out. I can't work out why this is happening.

    Any ideas very much appretiated?

    Also, will this work for ftp and all other protocols?

  • For me either

    Posted by Legacy on 03/13/2001 12:00am

    Originally posted by: Chris

    If I had a webpage with a graphic in it. The page would load the html page fine but would not continue loading graphics embedded in the page. It would stick on the while( n = server.receive(Buffer.BUFFERSIZE) ) != 0 ) line.

    If I change the logic to check to see if the last receive was less then BUFFERSIZE it works under DEBUG mode only. I am not an expert at this so my debugging that error was futile.

  • Your proxy not work propery

    Posted by Legacy on 01/16/2000 12:00am

    Originally posted by: JP

    Your proxy not work propery

  • You must have javascript enabled in order to post comments.

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date
We have made updates to our Privacy Policy to reflect the implementation of the General Data Protection Regulation.