1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/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 wxFileOffset
SeekI( wxFileOffset
WXUNUSED(pos
), wxSeekMode
WXUNUSED(mode
) )
127 wxFileOffset
TellI() const
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
->GetScheme() == wxT("http") )
204 service
= INTERNET_SERVICE_HTTP
;
206 else if ( owner
->GetScheme() == 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