Solved

using CinternetSession

Posted on 2001-07-21
24
357 Views
Last Modified: 2012-08-13
here's what I got:

#include "stdafx.h"
#include <afxinet.h>
#include "http.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

using namespace std;

void connectTo(char* site, char* page){

     CInternetSession* pNet;
     CHttpConnection* pConn;
     CHttpFile* pFile;
     
     DWORD dwRet;
     UINT nRead;
     
     char* szBuff[4096];
     CString source;
     pNet = new CInternetSession(NULL, 1, PRE_CONFIG_INTERNET_ACCESS, NULL, NULL, INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD);


     try{
          pConn = pNet->GetHttpConnection(site);
          cout<<"connection made to: "<<site<<endl;
     }
     catch(...){
          cout<<"connection failed to: "<<site<<endl;
     }
     
     pFile = pConn->OpenRequest(NULL, page); // Open an HTTP request.
         
     try{
          pFile->SendRequest( ); // Try sending the request.
          pFile->QueryInfoStatusCode(dwRet);

          cout<<"request made to: "<<page<<endl;
     }
     catch(CInternetException *e){
          cout<<"request failed to "<<page<<" error code:"<<e->m_dwError<<endl;
     }


     if(dwRet == HTTP_STATUS_OK){
         
          while (nRead = pFile->Read(szBuff, 4096) > 0){
         
            source.Insert(source.GetLength()+1,(char*)szBuff);
          }
          cout<<(LPCTSTR) source<<endl;//i think the bug is here
     }

     delete pConn;
     delete pFile;
     pNet->Close();
     delete pNet;

}



int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){
     int nRetCode = 0;

     // initialize MFC and print and error on failure
     if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)){
          // TODO: change error code to suit your needs
          cerr << _T("Fatal Error: MFC initialization failed") << endl;
          nRetCode = 1;
     }
     else{
          //connectTo("matts-laptop/testsite/","default.asp" );//no "http://"
          connectTo("www.yahoo.com","index.html" );//no "http://"
     }
         
     return nRetCode;
}

when it runs it should print the returned html from the page, which it does....plus a whole heap of extra characters, any ideas????
0
Comment
Question by:MattC
  • 11
  • 7
  • 6
24 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 100 total points
ID: 6305177
I'd rewrite

    if(dwRet == HTTP_STATUS_OK){
         
         while (nRead = pFile->Read(szBuff, 4096) > 0){
         
           source.Insert(source.GetLength()+1,(char*)szBuff);
         }
         cout<<(LPCTSTR) source<<endl;//i think the bug is here
    }

to read




    if(dwRet == HTTP_STATUS_OK){
         ZeroMemory ( szBuff, sizeof ( szBuff));

         while (nRead = pFile->Read(szBuff, 4096) > 0){
         
           source.Insert(source.GetLength(),(char*)szBuff);
           ZeroMemory ( szBuff, sizeof ( szBuff));// 'Read()' does not zero-terminate the buffer!!!

         }
         cout<<(LPCTSTR) source<<endl;
    }
0
 
LVL 86

Expert Comment

by:jkr
ID: 6305182
Or, not to be such a performance hog:

   if(dwRet == HTTP_STATUS_OK){

        while (nRead = pFile->Read(szBuff, 4096) > 0){
          szBuff [ nRead + 1] = '/0'; ));// 'Read()' does not zero-terminate the buffer!!!

          source.Insert(source.GetLength(),(char*)szBuff);
        }
        cout<<(LPCTSTR) source<<endl;
   }
0
 
LVL 1

Author Comment

by:MattC
ID: 6305183
could you explain what this line means, i just started on this stuff today =(


  ZeroMemory ( szBuff, sizeof ( szBuff));

 
0
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 
LVL 86

Expert Comment

by:jkr
ID: 6305184
As we're just optimizing :o)



  if(dwRet == HTTP_STATUS_OK){

       while (nRead = pFile->Read(szBuff, 4096) > 0){
         szBuff [ nRead + 1] = '/0'; ));// 'Read()' does not zero-terminate the buffer!!!

         source += CString ( szBuff);
       }
       cout<<(LPCTSTR) source<<endl;
  }
0
 
LVL 86

Expert Comment

by:jkr
ID: 6305188
>>could you explain what this line means, i just started
>>on this stuff today =(
>> ZeroMemory ( szBuff, sizeof ( szBuff));

It zeroes out a memory area. A 'C'-style string is characterized by a terminating binary '0', and as the 'Read()' operation does not terminate the buffer with it, the strings you're adding are 'longer' - that's the 'extra characters' you noticed.

0
 
LVL 1

Author Comment

by:MattC
ID: 6305190

 >>>szBuff [ nRead + 1] = '/0'; ));
should be
 szBuff [ nRead + 1] = "/0";

=)
0
 
LVL 1

Author Comment

by:MattC
ID: 6305191
if(dwRet == HTTP_STATUS_OK){

       while (nRead = pFile->Read(szBuff, 4096) > 0){
         szBuff [ nRead + 1] = "/0";
          source += CString ( szBuff);


       }
       cout<<(LPCTSTR) source<<endl;

     }


compiler complain that:

C:\Documents\Programming\http\http.cpp(63) : error C2440: 'type cast' : cannot convert from 'char *[4096]' to 'class CString'
0
 
LVL 86

Expert Comment

by:jkr
ID: 6305194
>>>>>szBuff [ nRead + 1] = '/0'; ));
>>should be
>>szBuff [ nRead + 1] = "/0";

No, it should read

szBuff [ nRead + 1] = '\0'; // backslash!

'\0' is a character, "\0" is a pointer to a zero-terminated string. What we want to do is inserting a null byte at the end of the stream...

BTW:

char* szBuff[4096];

is wrong, that declares an array of pointers - you probably wanted to use

char szBuff[4096];

As we need to write the terminating null byte, take that into consideration:

char szBuff[4096 + 1];
0
 
LVL 86

Expert Comment

by:jkr
ID: 6305198
>>C:\Documents\Programming\http\http.cpp(63) : error
>>C2440: 'type cast' : cannot convert from 'char *[4096]'
>>to 'class CString'

That's related to my last comment - it should read

char szBuff[4096 + 1];
0
 
LVL 1

Author Comment

by:MattC
ID: 6305201
but it doesn't print any of the html now. it did with the Zeromemory thing, but I do want to learn memory efficient coding

also it only works if I request an .asp page.  as soon as i try and get an html page it dwRet give me: 405

HTTP_STATUS_BAD_METHOD  405 The method used is not allowed.

what the heck does that mean
0
 
LVL 86

Expert Comment

by:jkr
ID: 6305206
You might want to check the sample at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcsample98/html/_sample_mfc_tear.asp ('TEAR: "Tearing" HTML Pages Off the Internet'):

"The TEAR sample shows how to write an MFC console application that uses WININET.DLL to communicate with the Internet. The sample shows how to form an HTTP request using CHttpFile against CHttpConnection and CInternetSession objects."

This sample should also be available on your VC++ CD.
0
 
LVL 1

Author Comment

by:MattC
ID: 6305208
unfortunately I'm not at home.  

I'm thinking it's either how I'm setting up:

pNet = new CInternetSession(NULL, 1, PRE_CONFIG_INTERNET_ACCESS, NULL, NULL, INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD);

or:

pNet->GetHttpConnection(site);



??
0
 
LVL 1

Author Comment

by:MattC
ID: 6305212
s'ok it was

pFile = pConn->OpenRequest("GET", page); // Open an HTTP request.

instead of

pFile = pConn->OpenRequest(NULL, page); // Open an HTTP request.
0
 
LVL 1

Author Comment

by:MattC
ID: 6305216
so currently it will only work like:

if(dwRet == HTTP_STATUS_OK){

       ZeroMemory ( szBuff, sizeof ( szBuff));

        while (nRead = pFile->Read(szBuff, 4096) > 0){

              //szBuff [ nRead + 1] = '\0';
               //source += CString ( szBuff);
       
          source.Insert(source.GetLength(),(char*)szBuff);
         ZeroMemory ( szBuff, sizeof ( szBuff));// 'Read()' does not zero-terminate the buffer!!!

        }
        cout<<"HTML RECEIVED: "<<(LPCTSTR) source<<endl;


     }else{
             cout<<dwRet<<endl;
     }

and not

if(dwRet == HTTP_STATUS_OK){

      while (nRead = pFile->Read(szBuff, 4096) > 0){
        szBuff [ nRead + 1] = '\0';
         source += CString ( szBuff);


      }
      cout<<(LPCTSTR) source<<endl;

    }

0
 
LVL 10

Expert Comment

by:makerp
ID: 6305946
this is from an active x i wrote, it may help

void CActiveXChatCtrl::OnButton()
{
     /* the session must be created with a name or it asserts,
     the documentation says otherwise!, typical */
     CInternetSession session("session");
     /* we can use the base class as we dont need the extra
     functionality that CHttpFile offers (whats being returned in
     our case here is a CHttpFile) but we will use the base class */
     CStdioFile *file = session.OpenURL(m_url);

     /* read in 100 bytes, this will call CHttpFile's Read member */
     char buffer[100];
     int l = file->Read(buffer,sizeof(buffer));
     /* tak on a NULL */
     buffer[l] = '\0';

     /* set the window text of the edit control */
     m_pEdit->SetWindowText(buffer);

     /* delete the file object */
     delete file;
     /* the session will drop out of scope now and close */
}
0
 
LVL 10

Expert Comment

by:makerp
ID: 6305947
m_url, is the url, its an object member, populated already
0
 
LVL 1

Author Comment

by:MattC
ID: 6306584
well I wanted to use CString becuase it has lots of useful methods
0
 
LVL 10

Expert Comment

by:makerp
ID: 6307900
m_url is a CString
0
 
LVL 1

Author Comment

by:MattC
ID: 6311937
will a CStdioFile object let me query the pages,header info as well as the pages source?
0
 
LVL 10

Expert Comment

by:makerp
ID: 6311954
no,
    CHttpFile *file = session.OpenURL(m_url);

should work
0
 
LVL 1

Author Comment

by:MattC
ID: 6312354
what is the advantage of:

pNet = new CInternetSession(NULL, 1, PRE_CONFIG_INTERNET_ACCESS, NULL, NULL, INTERNET_FLAG_DONT_CACHE
| INTERNET_FLAG_RELOAD);

pConn = pNet->GetHttpConnection(site);
pFile = pConn->OpenRequest(NULL, page);
pFile->SendRequest( );

Over


CHttpFile *file = session.OpenURL(m_url);
0
 
LVL 10

Expert Comment

by:makerp
ID: 6312374
its alot easier to code but less powerfull, if horses for courses, use what suits
0
 
LVL 1

Author Comment

by:MattC
ID: 6316792
in what way less powerful, is there a bigger performance hit or just less flexible
0
 
LVL 10

Expert Comment

by:makerp
ID: 6316801
well you dont have the flexability
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

813 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now