WinSock/HTTP trouble

Started by
2 comments, last by hplus0603 18 years, 10 months ago
I have the following function (request) that GETs a webpage and returns the result through message:

#include <cstdlib>
#include <iostream>

using namespace std;

/* 
 * 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>
#include <string>
#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

    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("GET ");
 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
 //string Auth        = "username:password";
 //Figureout a way to encode test into base64 !
 //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;
}

It works fine if I call a webpage like http://www.unitedmedia.com/comics/dilbert/index.html this way:
request ("www.unitedmedia.com", "/comics/dilbert/index.html", "",  message);
But say I want to call http://i.domaindlx.com/psychoscore/test.asp (which works fine on firefox) with the command:
request ("i.domaindlx.com", "/psychoscore/test.asp", "",  message);
it comes back with:
<html><head><title>Site Not Found</title></head>
<body>No web site is configured at this address.</body></html>
I've tried changing it to POST, using www.domaindlx.com instead (this comes back with invalid hostname) and www.i.domaindlx.com with no luck. I'm guessing it is confused by the fact it has a subdomain "i" in the "http://i.domaindlx.com...". Is there any way round this? If not does anyone know where that Site not found error is coming from (DNS, server, client?) Thanks!
Advertisement
Hmm, works fine with my own minibrowser experiment.
Did you try to remove some of the html parameters?
(like accept-language etc.)

Try to restrict to the smallest possible request. No parameters, no content-type, no content. Just the basic http request.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Quote:Original post by Endurion
Hmm, works fine with my own minibrowser experiment.
Did you try to remove some of the html parameters?
(like accept-language etc.)

Try to restrict to the smallest possible request. No parameters, no content-type, no content. Just the basic http request.


Still no luck. It seems to work on other server scripts (eg BBC weather), just not mine. very strange.
Try this alternate code and see if it works or not. Might give you some insights.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement