Tester2 0 Newbie Poster

I am one of the many people trying to grasp something new in this forum. I come here, because it seems to frequented by C++ experts, who actually try to respond.

I am trying to learn how to program an HTTP protocol based text file download. I have searched far and wide on the internet, and find both commercial and non-commercial code to provide internet functionality. I have not found a single, Borland Builder based, windows socket and http tutorial.

I did download one of the free, non-commercial files, and it did compile and run on Borland Builder 6.0 with just a few changes. I believe it has a socket, because the RichText box control I am using fills with various obscure facts about my internet service provider (including its usual $9.95 per month advertisement), all in text, when I activate the code that was said to perform an HTTP based POST. I think that means that the code was able to access a socket. I'm not as sure that it was able to create the socket, as I already had internet explorer opened to a web site and was connected.

IF YOU'VE READ THIS FAR, then perhaps I should note that what I ultimately need to do is to access a password protected directory, and download a text file using http protocol. I was told this was both possible and none too difficult. (I was at my limits getting the file I downloaded to compile under Borland Builder.) I did search for and purchase multiple texts on internet programming, but all via mail. The local bookstores and college library have nothing in them describing C++ programming of HTTP commands, I've spent days looking before I came here. I am attaching some code. It is supposed to accomplish an internet POST. I understand that is useful for chat rooms and a few other things, but not for my needs at present. To be perfectly straightforward, much of what this code does is Greek to me. I downloaded it to see if it could be made to work, as a roadmap to a means by which to get a socket connection. Step two is trying to figure out how to convert the POST function to a GET function that will download a text file from a password protected directory. (I honestly don't know, in the context of this code, what it is supposed to return, or why I received the info I did from an internet service provider whose url I wasn't trying to use.)

I'll post the code I downloaded. If anyone can get me to the point where this code will enable me to access a password protected directory, we'll call it:

"http://mysite.hostserver.com/secret"

with user name: myname

and password: mypassword,

and download file: mytextfile.txt using http,

that would be, as the waitress on the television commercial says, "great".

The code I was using is based upon Windows sockets and winsock2.h. I don't want to change this. I just want it to work. Any help would be much appreciated.

BORLAND BUILDER 6.0 CODE FOLLOWS:

/*
 *                                 http_post.cpp
 *
 * by Uday Chitragar - 2004/Dec/01
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any
 * damages arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any
 * purpose, including commercial applications, and to alter it and
 * redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must
 * not claim that you wrote the original software. If you use this
 * software in a product, an acknowledgment in the product documentation
 * would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and
 * must not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 * distribution.
 *
 * */

/* 
 * Notes:
 * This source demonstrates sending HTTP POST request to webserver from C++
 * This uses sockets hence can be compiled on Linux, UNIX, Win
 */

//#define LINUX_OS
#define WIN_OS
#define _DEBUG_PRINT(X)   /* X */

//For commn
#include <iostream.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

//#ifdef LINUX_OS
// #include <netdb.h>
//#endif

//#ifdef WIN_OS
// #include <Winsock2.h>
//#endif


#define SEND_RQ(MSG) \
                /*cout<<send_str;*/ \
  send(sock,MSG,strlen(MSG),0);


using namespace std;
//<exe> hostname api parameters
int request (char* hostname, char* api, char* parameters, string& message)
{

	#ifdef WIN_OS
	{
		WSADATA	WsaData;
		WSAStartup (0x0101, &WsaData);
	}
	#endif
    struct sockaddr_in {
        short   sin_family;
        u_short sin_port;
        struct  in_addr sin_addr;
        char    sin_zero[8];
};
    sockaddr_in sin;
    int sock = socket (AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
		return -100;
	}
    sin.sin_family = AF_INET;
    sin.sin_port = htons( (unsigned short)80);

    struct hostent * host_addr = gethostbyname(hostname);
    if(host_addr==NULL) {
      _DEBUG_PRINT( cout<<"Unable to locate host"<<endl );
      return -103;
    }
    sin.sin_addr.s_addr = *((int*)*host_addr->h_addr_list) ;
    _DEBUG_PRINT( cout<<"Port :"<<sin.sin_port<<", Address : "<< sin.sin_addr.s_addr<<endl);

    if( connect (sock,(const struct sockaddr *)&sin, sizeof(sockaddr_in) ) == -1 ) {
     _DEBUG_PRINT( cout<<"connect failed"<<endl ) ;
     return -101;
    }

 string send_str;

 SEND_RQ("POST ");
 SEND_RQ(api);
 SEND_RQ(" HTTP/1.0\r\n");
 SEND_RQ("Accept: */*\r\n");
 SEND_RQ("User-Agent: Mozilla/4.0\r\n");

 char content_header[100];
 sprintf(content_header,"Content-Length: %d\r\n",strlen(parameters));
 SEND_RQ(content_header);
 SEND_RQ("Accept-Language: en-us\r\n");
 SEND_RQ("Accept-Encoding: gzip, deflate\r\n");
 SEND_RQ("Host: ");
 SEND_RQ("hostname");
 SEND_RQ("\r\n");
 SEND_RQ("Content-Type: application/x-www-form-urlencoded\r\n");

//If you need to send a basic authorization  
//NOTE:  IS THIS TO GET
// PAST YOUR OWN SITE'S ADMINISTRATOR PASSWORD, OR THE
// DIRECTORY PASSWORD?  I NEED TO GET PAST MY DIRECTORY
// PROTECTING PASSWORD.  
//(USING NON-PASSWORD PROTECTED DIRECTORY
// ISN'T AN OPTION).
//string Auth        = "mysite:mypassword";
//string AuthInfo = Auth;
 //Figureout a way to encode test into base64 !  WHAT????
//string AuthInfo    = base64_encode(reinterpret_cast<const unsigned char*>(Auth.c_str()),Auth.length());
//string sPassReq    = "Authorization: Basic " + AuthInfo;
//SEND_RQ(sPassReq.c_str());

 SEND_RQ("\r\n");
 SEND_RQ("\r\n");
 SEND_RQ(parameters);
 SEND_RQ("\r\n");

 _DEBUG_PRINT(cout<<"####HEADER####"<<endl);
 char c1[1];
 int l,line_length;
 bool loop = true;
 bool bHeader = false;

 while(loop) {
   l = recv(sock, c1, 1, 0);
   if(l<0) loop = false;
   if(c1[0]=='\n') {
       if(line_length == 0) loop = false;

       line_length = 0;
       if(message.find("200") != string::npos)
	       bHeader = true;

   }
   else if(c1[0]!='\r') line_length++;
   _DEBUG_PRINT( cout<<c1[0]);
   message += c1[0];
 }

 message="";
 if(bHeader) {

     _DEBUG_PRINT( cout<<"####BODY####"<<endl) ;
     char p[1024];
     while((l = recv(sock,p,1023,0)) > 0)  {
         _DEBUG_PRINT( cout.write(p,l)) ;
	     p[l] = '\0';
	     message += p;
     }

     _DEBUG_PRINT( cout << message.c_str());
 } else {
	 return -102;
 }


#ifdef WIN_OS
   WSACleanup( );
#endif

 return 0;
}


void __fastcall TForm1::Button1Click(TObject *Sender)
{
  string message;
  char* mysite = "www.netzero.com";
  char* postapi =  "/post_url.pl";
  char* myparams = "search=hello&date=todat";
//Following line originally used "string& message".  I don't know what
//that was supposed to accomplish, but what follows
//was what I was able to get to compile, with "string message" instead.
  int errornumberreturned = request(mysite, postapi, myparams, message);
  const char* mymessage = message.c_str();
  RichEdit1->Text= mymessage;
  RichEdit2->Text = errornumberreturned;
//errornumberreturned was 0  -> never got to functions to return error code??
  // message contains response!  WELL, it contained a response.  
}
//---------------------------------------------------------------------------