Click here to Skip to main content
Click here to Skip to main content

WWW (HTTP/HTTPS/FTP) Client using WININET

By , 3 May 2004
 

Introduction

This class is used for HTTP/HTTPS request, and FTP request.

Supported methods are:

  • HTTP/HTTPS
    1. GET
    2. POST
    3. POST multiparts/form-data
  • FTP
    1. GET FILE
    2. PUT FILE

Class Overview

// synchronized www client
 class W3Client {
 public:
  enum w3t { w3ftp, w3http, w3https };
  enum w3m { reqGet, reqPost, reqPostMultipartsFormdata };
 public:
  W3Client(){ _hOpen=NULL; _hConnection=NULL, _hRequest=NULL; }
  virtual ~W3Client(){ InitializePostArguments(); InitializeCookies();}
 public:  
  // connection handling
  bool Connect(const char *szaddress,
         const char *szuser=NULL, const char *szpassword=NULL, 
      const char *szagent=__W3_DEFAULT_AGENT);
  virtual bool Connect(const char *szaddress, long nport,
           const char *szuser=NULL, const char *szpassword=NULL,
           w3t t=w3http, const char *szagent=__W3_DEFAULT_AGENT);
  const char *GetURI(){ return _szuri.c_str(); }
  void Close();

  // post argument handling
  void InitializePostArguments();
  void AddPostArgument(const char *szname, const int nvalue);
  void AddPostArgument(const char *szname, const long nvalue);
  void AddPostArgument(const char *szname, const float nvalue);
  void AddPostArgument(const char *szname, const double nvalue);
  void AddPostArgument(const char *szname, 
                      const char *szvalue, bool bfile=false);
  
  // cookie handling
  void InitializeCookies();
  void AddCookie(const char *szname, const double value);
  void AddCookie(const char *szname, const float value);
  void AddCookie(const char *szname, const long value);
  void AddCookie(const char *szname, const int value);  
  void AddCookie(const char *szname, const char *szvalue);
 
  // http/https request handling
  bool Request(const char *szuri, w3m m=reqGet, const char *szref=NULL);
  unsigned long Response(unsigned char *buf, unsigned long len);
  unsigned int QueryResult();
  const char * QueryContentType();
  unsigned long QueryContentLength();
  unsigned long QueryCookie(unsigned char *buf, 
          unsigned long len, unsigned long idx=0);
  unsigned long QueryRawHeader(unsigned char *buf, unsigned long len);
 
  // ftp handling
  bool PutFile(const char *szuri, const char *szfile, bool ascii=false);
  bool GetFile(const char *szuri, const char *szfile, bool ascii=false);
  unsigned long PutFile(const char *szuri, unsigned char *buf, 
                        unsigned long len, bool ascii=false);
  unsigned long GetFile(const char *szuri, unsigned char *buf, 
                        unsigned long len, bool ascii=false);

 ...
 };

 // Asynchronized www client
 class AsyncW3Client : public W3Client {
 ...
 public:
  bool Connect(const char *szaddress,
            INTERNET_STATUS_CALLBACK lpfn,
            const char *szuser=NULL,
            const char *szpassword=NULL,
            const char *szagent=__W3_DEFAULT_AGENT);
  bool Connect(const char *szaddress, long nport,
          INTERNET_STATUS_CALLBACK lpfn,
          const char *szuser=NULL, const char *szpassword=NULL,
          w3t t=w3http, const char *szagent=__W3_DEFAULT_AGENT);
  bool Request(const char *szuri, w3m m=reqGet, const char *szref=NULL){
       _hCompleteRequestEvent=::CreateEvent(NULL, FALSE, FALSE, NULL);
       return W3Client::Request(szuri, m, szref);
  }
  unsigned long Response(unsigned char *buf, unsigned long len){
   ::CloseHandle(_hCompleteRequestEvent);
   _hCompleteRequestEvent=NULL;
   return W3Client::Response(buf, len);
  }
 public:
  void SetCompleteRequest();
  bool WaitCompleteRequest(unsigned long ntime=INFINITE);
 ...
 };
  1. Synchronized W3Client

    • Connect(...) method connects to HTTP server.
    • Close() method closes connection. These are used with RequestOfURI(...).
    • InitializePostArguments() method initializes POST arguments.
    • AddPostArgument(...) method is supported so that you can add new POST arguments of the following types: string, int, long, float, double, file.
    • Request(...) method is for you to attempt request for HTTP Request (GET, POST, POST-MULTIPARTFORMDATA) with URL. HTTP METHOD indirector has 3 types.
    • InitializeCookies() method initializes cookie values.
    • AddCookie(...) method adds cookie vars.
      • W3Client::reqGet is HTTP GET Request.
      • W3Cient::reqPost is HTTP POST Request.
      • W3Client::reqPostMultiPartsFormData is HTTP POST Request with BINARY FORM DATA.
    • Response(...) method is that you have HTTP Response by bytes.
    • QueryResult() method is you have receive HTTP Request result value.
  2. Asynchronized W3Client

    • SetCompleteRequest() method commits complete Request to AsyncW3Client.
    • WaitCompleteRequest() method waits for Request to be completed.

Usage

  1. Synchronized HTTP GET

    #include <iostream>
    #include "w3c.h"
    
    using namespace std;
    
    int main(int argc, char *argv[]){
      
      W3Client w3;
     
      if(w3.Connect("http://google.com/")){
       if(w3.Request("/")){
        char buf[1024]="\0";
        while(w3.Response(reinterpret_cast<unsigned char *>(buf), 1024))
         cout << buf ;
      }
       w3.Close();
      }
      return 0;
    }
  2. Synchronized HTTP POST multiparts/form-data

    int main(int argc, char *argv[]){
     
     W3Client client;
    
     if(client.Connect("http://gooshin.zzem.net/")){
      client.AddPostArgument("f[]", "d:\\log1.txt", true);
      client.AddPostArgument("f[]", "d:\\log2.txt", true);
      client.AddPostArgument("f[]", "d:\\log3.txt", true);
      if(client.Request("/test.php", W3Client::reqPostMultipartsFormdata)){
       char buf[1024]="\0";
       while(client.Response(reinterpret_cast<unsigned char*>(buf), 1024)>0){
        cout << buf << endl;
        memset(buf, 0x00, 1024);
       }
      }
      client.Close();
     }
    
     return 0;
    }
  3. Asynchronized HTTP client

    #include <iostream>
    #include <net/w3c.h>
    #include <wt.h>
    #include <windows.h>
    
    using namespace std;
    
    CRITICAL_SECTION __cs;
    
    class AsDown : public AsyncW3Client, public IWORKERTHREAD {
    public:
     AsDown(unsigned int idx):AsyncW3Client(), IWORKERTHREAD(idx){}
     virtual ~AsDown(){}
    private:
     virtual void OnWork(){
      while(true){
       WaitCompleteRequest();
       unsigned char buf[1024]="\0";
       while(Response(buf, 1024)){
         ::EnterCriticalSection(&__cs);
         cout << reinterpret_cast<char*>(buf);
         ::LeaveCriticalSection(&__cs);
         memset(buf, 0x00, 1024);
       }
       ::Sleep(500);
      }
     }
    };
    void CALLBACK __getstatus(  HINTERNET hInternet,
                   DWORD_PTR dwContext,
                   DWORD dwInternetStatus,
                   LPVOID lpvStatusInformation,
                   DWORD dwStatusInformationLength
                   ){
     AsyncW3Client *pcontext=reinterpret_cast<AsyncW3Client*>(dwContext);
     
     unsigned long nbytes=0;
      ::EnterCriticalSection(&__cs);
      switch(dwInternetStatus){
     case INTERNET_STATUS_SENDING_REQUEST:
      cout << "request sending..." << endl;
      break;
     case INTERNET_STATUS_REQUEST_SENT:
      {
       unsigned long *pnsent=(unsigned long*)lpvStatusInformation;
       cout << "bytes sent: " << *pnsent << endl;
       nbytes+=*pnsent;
       cout << "request sent..." << endl;
      }
      break;
     case INTERNET_STATUS_REQUEST_COMPLETE:
      {
       INTERNET_ASYNC_RESULT *pAsyncRes = 
              (INTERNET_ASYNC_RESULT *)lpvStatusInformation;
       cout << "Function call finished" << endl;
       cout << "dwResult: " << pAsyncRes->dwResult << endl;
       cout << "dwError:  " << pAsyncRes->dwError << endl;
       cout.flush();
       pcontext->SetCompleteRequest();
        cout << "request complete..." << endl;  
      }
      break;
      }
      ::LeaveCriticalSection(&__cs);
     
      return;
    }
    int main(int argc, char *argv[]){ 
     ::InitializeCriticalSection(&__cs);
     AsDown client(3);
     if(client.Connect("http://gooshin.zzem.net/", __getstatus)){
      __wtstart(client);
      client.Request("/test.php");
      Sleep(5000);
      client.InitializePostArguments();
      client.AddPostArgument("f[]", "d:\\log1.txt", true);
      client.AddPostArgument("f[]", "d:\\log2.txt", true);
      client.AddPostArgument("f[]", "d:\\log3.txt", true);
      client.Request("/test.php", AsDown::reqPostMultipartsFormdata);
      Sleep(5000);
      client.InitializePostArguments();
      client.AddPostArgument("f", "sss");
      client.Request("/test2.php", AsDown::reqPost);  
      Sleep(5000);
      
      __wtwait(client);
      client.Close();
     }
     ::DeleteCriticalSection(&__cs);
     return 0;
    }

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Yongseon Heo
Software Developer
Korea (Republic Of) Korea (Republic Of)
Member
Poke tongue | ;-P

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralHTTPS Not Workingsussneverneverland15 Jun '05 - 6:26 
Hello everyone,
I like this application and I would love to use it. I type into the window https://myclient.php and the application does not get through to the server. I don't know if I am doing something wrong or if there is something in the code that I need to change. Please let me know because I would love to use this application for HTTPS. Thanks. Zeljko
GeneralRe: HTTPS Not Working PinmemberTomazZ5 Dec '05 - 2:08 
I am using SSL library from platform SDK:
..\Microsoft Platform SDK\Samples\WinBase\Security\SSL
 
TomazZ
GeneralRe: HTTPS Not Working Pinmemberszuzso14 Dec '05 - 2:40 
Use this link to solve https problem:
http://support.microsoft.com/kb/q182888/
 
BR
Zsolt
GeneralRe: HTTPS Not Working Pinmembermeouvn8 Mar '06 - 20:13 
When i go to above link, i did follow code in that link, but it get error with error code = 10035
 
--------------------------
ERP VN: www.erpvn.net
GeneralRe: HTTPS Not Working Pinmembermeouvn9 Mar '06 - 16:08 
I modified that code below:
 
int times = 0;
DWORD dwError = 0;
Again:
// SEND REQUEST
if(!::HttpSendRequest( _hRequest, // handle by returned HttpOpenRequest
NULL, // additional HTTP header
0, // additional HTTP header length
NULL, // additional data in HTTP Post or HTTP Put
0) // additional data length
)
{
// James modified
dwError = ::GetLastError();
times++;
if (times < 10)// && dwError == ERROR_INTERNET_INVALID_CA)
{
if (_bAskInstallCert) // Show Dlg
{
DWORD dwNetErr = 0;
// Make sure to check return code from InternetErrorDlg
// user may click either OK or Cancel. In case of Cancel
// request should not be resumbitted.
dwNetErr = InternetErrorDlg (GetDesktopWindow(),
_hRequest,
//ERROR_INTERNET_INVALID_CA,
dwError,
FLAGS_ERROR_UI_FILTER_FOR_ERRORS |
FLAGS_ERROR_UI_FLAGS_GENERATE_DATA |
FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS,
NULL);
 
switch(dwNetErr){
case ERROR_INTERNET_FORCE_RETRY:
printf("Interne force retry\n");
break;
case ERROR_CANCELLED:
printf("Cancelled\n");
times = 10; // Stop
break;
case ERROR_SUCCESS:
printf("Success\n");
break;
}
 
goto Again;
}
else // without Dlg
{
DWORD dwNetErr = 0;
DWORD dwFlags;
DWORD dwBuffLen = sizeof(dwFlags);
 
InternetQueryOption (_hRequest, INTERNET_OPTION_SECURITY_FLAGS,
(LPVOID)&dwFlags, &dwBuffLen);
 
dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_CN_INVALID ;
if ( !InternetSetOption (_hRequest, INTERNET_OPTION_SECURITY_FLAGS,
&dwFlags, sizeof (dwFlags) ) )
printf("Set Option failed errcode: %ld\n", GetLastError());
 

goto Again;
}
}

 
--------------------------
ERP VN: www.erpvn.net
GeneralRe: HTTPS Not Working Pinmemberzhirenze9 Dec '06 - 3:47 
:-OSet the W3Client::w3https W3Client::reqPost in your code as follow:
client.Connect("ServerName",Port,NULL,NULL,W3Client::w3https);
client.Request("ObjFile", W3Client::reqPost)

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 4 May 2004
Article Copyright 2004 by Yongseon Heo
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid