1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        msw/urlmsw.cpp 
   3 // Purpose:     MS-Windows native URL support based on WinINet 
   4 // Author:      Hajo Kirchhoff 
   8 // Copyright:   (c) 2003 Hajo Kirchhoff 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  21 #if !wxUSE_PROTOCOL_HTTP 
  22 #include <wx/protocol/protocol.h> 
  24 // empty http protocol replacement (for now) 
  25 // so that wxUSE_URL_NATIVE can be used with 
  26 // wxSOCKETS==0 and wxUSE_PROTOCOL_HTTP==0 
  27 class wxHTTPDummyProto 
: public wxProtocol
 
  30     wxHTTPDummyProto() : wxProtocol() { } 
  32     wxProtocolError 
GetError() { return m_error
; } 
  34     virtual bool Abort() { return TRUE
; } 
  36     wxInputStream 
*GetInputStream(const wxString
& WXUNUSED(path
)) 
  38         return 0;   // input stream is returned by wxURLNativeImp 
  42     wxProtocolError m_error
; 
  44     DECLARE_DYNAMIC_CLASS_NO_COPY(wxHTTPDummyProto
) 
  45     DECLARE_PROTOCOL(wxHTTPDummyProto
) 
  48 // the only "reason for being" for this class is to tell 
  49 // wxURL that there is someone dealing with the http protocol 
  50 IMPLEMENT_DYNAMIC_CLASS(wxHTTPDummyProto
, wxProtocol
) 
  51 IMPLEMENT_PROTOCOL(wxHTTPDummyProto
, wxT("http"), NULL
, FALSE
) 
  52 USE_PROTOCOL(wxHTTPDummyProto
) 
  54 #endif // !wxUSE_PROTOCOL_HTTP 
  57 #ifdef __VISUALC__  // be conservative about this pragma 
  58     // tell the linker to include wininet.lib automatically 
  59     #pragma comment(lib, "wininet.lib") 
  62 #include "wx/string.h" 
  65 #include "wx/module.h" 
  72 // this class needn't be exported 
  73 class wxWinINetURL
:public wxURLNativeImp
 
  76     wxInputStream 
*GetInputStream(wxURL 
*owner
); 
  79     // return the WinINet session handle 
  80     static HINTERNET 
GetSessionHandle(); 
  83 HINTERNET 
wxWinINetURL::GetSessionHandle() 
  85     // this struct ensures that the session is opened when the 
  86     // first call to GetSessionHandle is made 
  87     // it also ensures that the session is closed when the program 
  89     static struct INetSession
 
  93             DWORD rc 
= InternetAttemptConnect(0); 
  95             m_handle 
= InternetOpen
 
  98                         INTERNET_OPEN_TYPE_PRECONFIG
, 
 101                         rc 
== ERROR_SUCCESS 
? 0 : INTERNET_FLAG_OFFLINE
 
 107             InternetCloseHandle(m_handle
); 
 113    return session
.m_handle
; 
 116 // this class needn't be exported 
 117 class /*WXDLLIMPEXP_NET */ wxWinINetInputStream 
: public wxInputStream
 
 120     wxWinINetInputStream(HINTERNET hFile
=0); 
 121     ~wxWinINetInputStream(); 
 123     void Attach(HINTERNET hFile
); 
 125     off_t 
SeekI( off_t 
WXUNUSED(pos
), wxSeekMode 
WXUNUSED(mode
) ) 
 131     void SetError(wxStreamError err
) { m_lasterror
=err
; } 
 133     size_t OnSysRead(void *buffer
, size_t bufsize
); 
 135     DECLARE_NO_COPY_CLASS(wxWinINetInputStream
) 
 138 size_t wxWinINetInputStream::OnSysRead(void *buffer
, size_t bufsize
) 
 141     if ( !InternetReadFile(m_hFile
, buffer
, bufsize
, &bytesread
) ) 
 143         DWORD lError 
= ::GetLastError(); 
 144         if ( lError 
!= ERROR_SUCCESS 
) 
 145             SetError(wxSTREAM_READ_ERROR
); 
 147         DWORD iError
, bLength
; 
 148         InternetGetLastResponseInfo(&iError
, NULL
, &bLength
); 
 151             wxString errorString
; 
 152             InternetGetLastResponseInfo
 
 155                 wxStringBuffer(errorString
, bLength
), 
 159             wxLogError(wxT("Read failed with error %d: %s"), 
 160                        iError
, errorString
); 
 164     if ( bytesread 
== 0 ) 
 166         SetError(wxSTREAM_EOF
); 
 172 wxWinINetInputStream::wxWinINetInputStream(HINTERNET hFile
) 
 177 void wxWinINetInputStream::Attach(HINTERNET newHFile
) 
 179     wxCHECK_RET(m_hFile
==NULL
, 
 180         wxT("cannot attach new stream when stream already exists")); 
 182     SetError(m_hFile
!=NULL 
? wxSTREAM_NO_ERROR 
: wxSTREAM_READ_ERROR
); 
 185 wxWinINetInputStream::~wxWinINetInputStream() 
 189         InternetCloseHandle(m_hFile
); 
 194 wxURLNativeImp 
*wxURL::CreateNativeImpObject() 
 196     return new wxWinINetURL
; 
 199 wxInputStream 
*wxWinINetURL::GetInputStream(wxURL 
*owner
) 
 202     if ( owner
->GetProtocolName() == wxT("http") ) 
 204         service 
= INTERNET_SERVICE_HTTP
; 
 206     else if ( owner
->GetProtocolName() == wxT("ftp") ) 
 208         service 
= INTERNET_SERVICE_FTP
; 
 212         // unknown protocol. Let wxURL try another method. 
 216     wxWinINetInputStream 
*newStream 
= new wxWinINetInputStream
; 
 217     HINTERNET newStreamHandle 
= InternetOpenUrl
 
 223                                     INTERNET_FLAG_KEEP_CONNECTION 
| 
 224                                     INTERNET_FLAG_PASSIVE
, 
 227     newStream
->Attach(newStreamHandle
); 
 232 #endif // wxUSE_URL_NATIVE