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"
23 #include "wx/string.h"
25 #include "wx/module.h"
29 #if !wxUSE_PROTOCOL_HTTP
30 #include "wx/protocol/protocol.h"
32 // empty http protocol replacement (for now)
33 // so that wxUSE_URL_NATIVE can be used with
34 // wxSOCKETS==0 and wxUSE_PROTOCOL_HTTP==0
35 class wxHTTPDummyProto
: public wxProtocol
38 wxHTTPDummyProto() : wxProtocol() { }
40 wxProtocolError
GetError() { return m_error
; }
42 virtual bool Abort() { return true; }
44 wxInputStream
*GetInputStream(const wxString
& WXUNUSED(path
))
46 return 0; // input stream is returned by wxURLNativeImp
50 wxProtocolError m_error
;
52 DECLARE_DYNAMIC_CLASS_NO_COPY(wxHTTPDummyProto
)
53 DECLARE_PROTOCOL(wxHTTPDummyProto
)
56 // the only "reason for being" for this class is to tell
57 // wxURL that there is someone dealing with the http protocol
58 IMPLEMENT_DYNAMIC_CLASS(wxHTTPDummyProto
, wxProtocol
)
59 IMPLEMENT_PROTOCOL(wxHTTPDummyProto
, wxT("http"), NULL
, false)
60 USE_PROTOCOL(wxHTTPDummyProto
)
62 #endif // !wxUSE_PROTOCOL_HTTP
65 #ifdef __VISUALC__ // be conservative about this pragma
66 // tell the linker to include wininet.lib automatically
67 #pragma comment(lib, "wininet.lib")
76 // this class needn't be exported
77 class wxWinINetURL
:public wxURLNativeImp
80 wxInputStream
*GetInputStream(wxURL
*owner
);
83 // return the WinINet session handle
84 static HINTERNET
GetSessionHandle();
87 HINTERNET
wxWinINetURL::GetSessionHandle()
89 // this struct ensures that the session is opened when the
90 // first call to GetSessionHandle is made
91 // it also ensures that the session is closed when the program
93 static struct INetSession
97 DWORD rc
= InternetAttemptConnect(0);
99 m_handle
= InternetOpen
102 INTERNET_OPEN_TYPE_PRECONFIG
,
105 rc
== ERROR_SUCCESS
? 0 : INTERNET_FLAG_OFFLINE
111 InternetCloseHandle(m_handle
);
117 return session
.m_handle
;
120 // this class needn't be exported
121 class /*WXDLLIMPEXP_NET */ wxWinINetInputStream
: public wxInputStream
124 wxWinINetInputStream(HINTERNET hFile
=0);
125 virtual ~wxWinINetInputStream();
127 void Attach(HINTERNET hFile
);
129 wxFileOffset
SeekI( wxFileOffset
WXUNUSED(pos
), wxSeekMode
WXUNUSED(mode
) )
131 wxFileOffset
TellI() const
133 size_t GetSize() const;
136 void SetError(wxStreamError err
) { m_lasterror
=err
; }
138 size_t OnSysRead(void *buffer
, size_t bufsize
);
140 DECLARE_NO_COPY_CLASS(wxWinINetInputStream
)
143 size_t wxWinINetInputStream::GetSize() const
145 DWORD contentLength
= 0;
146 DWORD dwSize
= sizeof(contentLength
);
149 if ( HttpQueryInfo( m_hFile
, HTTP_QUERY_CONTENT_LENGTH
| HTTP_QUERY_FLAG_NUMBER
, &contentLength
, &dwSize
, &index
) )
150 return contentLength
;
155 size_t wxWinINetInputStream::OnSysRead(void *buffer
, size_t bufsize
)
158 if ( !InternetReadFile(m_hFile
, buffer
, bufsize
, &bytesread
) )
160 DWORD lError
= ::GetLastError();
161 if ( lError
!= ERROR_SUCCESS
)
162 SetError(wxSTREAM_READ_ERROR
);
164 DWORD iError
, bLength
;
165 InternetGetLastResponseInfo(&iError
, NULL
, &bLength
);
168 wxString errorString
;
169 InternetGetLastResponseInfo
172 wxStringBuffer(errorString
, bLength
),
176 wxLogError(wxT("Read failed with error %d: %s"),
177 iError
, errorString
);
181 if ( bytesread
== 0 )
183 SetError(wxSTREAM_EOF
);
189 wxWinINetInputStream::wxWinINetInputStream(HINTERNET hFile
)
194 void wxWinINetInputStream::Attach(HINTERNET newHFile
)
196 wxCHECK_RET(m_hFile
==NULL
,
197 wxT("cannot attach new stream when stream already exists"));
199 SetError(m_hFile
!=NULL
? wxSTREAM_NO_ERROR
: wxSTREAM_READ_ERROR
);
202 wxWinINetInputStream::~wxWinINetInputStream()
206 InternetCloseHandle(m_hFile
);
211 wxURLNativeImp
*wxURL::CreateNativeImpObject()
213 return new wxWinINetURL
;
216 wxInputStream
*wxWinINetURL::GetInputStream(wxURL
*owner
)
219 if ( owner
->GetScheme() == wxT("http") )
221 service
= INTERNET_SERVICE_HTTP
;
223 else if ( owner
->GetScheme() == wxT("ftp") )
225 service
= INTERNET_SERVICE_FTP
;
229 // unknown protocol. Let wxURL try another method.
233 wxWinINetInputStream
*newStream
= new wxWinINetInputStream
;
234 HINTERNET newStreamHandle
= InternetOpenUrl
240 INTERNET_FLAG_KEEP_CONNECTION
|
241 INTERNET_FLAG_PASSIVE
,
244 newStream
->Attach(newStreamHandle
);
249 #endif // wxUSE_URL_NATIVE