1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/urlmsw.cpp
3 // Purpose: MS-Windows native URL support based on WinINet
4 // Author: Hajo Kirchhoff
7 // Copyright: (c) 2003 Hajo Kirchhoff
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
22 #include "wx/string.h"
24 #include "wx/module.h"
28 #if !wxUSE_PROTOCOL_HTTP
29 #include "wx/protocol/protocol.h"
31 // empty http protocol replacement (for now)
32 // so that wxUSE_URL_NATIVE can be used with
33 // wxSOCKETS==0 and wxUSE_PROTOCOL_HTTP==0
34 class wxHTTPDummyProto
: public wxProtocol
37 wxHTTPDummyProto() : wxProtocol() { }
39 wxProtocolError
GetError() { return m_error
; }
41 virtual bool Abort() { return true; }
43 wxInputStream
*GetInputStream(const wxString
& WXUNUSED(path
))
45 return 0; // input stream is returned by wxURLNativeImp
49 wxProtocolError m_error
;
51 DECLARE_DYNAMIC_CLASS_NO_COPY(wxHTTPDummyProto
)
52 DECLARE_PROTOCOL(wxHTTPDummyProto
)
55 // the only "reason for being" for this class is to tell
56 // wxURL that there is someone dealing with the http protocol
57 IMPLEMENT_DYNAMIC_CLASS(wxHTTPDummyProto
, wxProtocol
)
58 IMPLEMENT_PROTOCOL(wxHTTPDummyProto
, wxT("http"), NULL
, false)
59 USE_PROTOCOL(wxHTTPDummyProto
)
61 #endif // !wxUSE_PROTOCOL_HTTP
64 #ifdef __VISUALC__ // be conservative about this pragma
65 // tell the linker to include wininet.lib automatically
66 #pragma comment(lib, "wininet.lib")
75 // this class needn't be exported
76 class wxWinINetURL
:public wxURLNativeImp
79 wxInputStream
*GetInputStream(wxURL
*owner
);
82 // return the WinINet session handle
83 static HINTERNET
GetSessionHandle();
86 HINTERNET
wxWinINetURL::GetSessionHandle()
88 // this struct ensures that the session is opened when the
89 // first call to GetSessionHandle is made
90 // it also ensures that the session is closed when the program
92 static struct INetSession
96 DWORD rc
= InternetAttemptConnect(0);
98 m_handle
= InternetOpen
101 INTERNET_OPEN_TYPE_PRECONFIG
,
104 rc
== ERROR_SUCCESS
? 0 : INTERNET_FLAG_OFFLINE
110 InternetCloseHandle(m_handle
);
116 return session
.m_handle
;
119 // this class needn't be exported
120 class /*WXDLLIMPEXP_NET */ wxWinINetInputStream
: public wxInputStream
123 wxWinINetInputStream(HINTERNET hFile
=0);
124 virtual ~wxWinINetInputStream();
126 void Attach(HINTERNET hFile
);
128 wxFileOffset
SeekI( wxFileOffset
WXUNUSED(pos
), wxSeekMode
WXUNUSED(mode
) )
130 wxFileOffset
TellI() const
132 size_t GetSize() const;
135 void SetError(wxStreamError err
) { m_lasterror
=err
; }
137 size_t OnSysRead(void *buffer
, size_t bufsize
);
139 wxDECLARE_NO_COPY_CLASS(wxWinINetInputStream
);
142 size_t wxWinINetInputStream::GetSize() const
144 DWORD contentLength
= 0;
145 DWORD dwSize
= sizeof(contentLength
);
148 if ( HttpQueryInfo( m_hFile
, HTTP_QUERY_CONTENT_LENGTH
| HTTP_QUERY_FLAG_NUMBER
, &contentLength
, &dwSize
, &index
) )
149 return contentLength
;
154 size_t wxWinINetInputStream::OnSysRead(void *buffer
, size_t bufsize
)
157 if ( !InternetReadFile(m_hFile
, buffer
, bufsize
, &bytesread
) )
159 DWORD lError
= ::GetLastError();
160 if ( lError
!= ERROR_SUCCESS
)
161 SetError(wxSTREAM_READ_ERROR
);
163 DWORD iError
, bLength
;
164 InternetGetLastResponseInfo(&iError
, NULL
, &bLength
);
167 wxString errorString
;
168 InternetGetLastResponseInfo
171 wxStringBuffer(errorString
, bLength
),
175 wxLogError(wxT("Read failed with error %d: %s"),
176 iError
, errorString
);
180 if ( bytesread
== 0 )
182 SetError(wxSTREAM_EOF
);
188 wxWinINetInputStream::wxWinINetInputStream(HINTERNET hFile
)
193 void wxWinINetInputStream::Attach(HINTERNET newHFile
)
195 wxCHECK_RET(m_hFile
==NULL
,
196 wxT("cannot attach new stream when stream already exists"));
198 SetError(m_hFile
!=NULL
? wxSTREAM_NO_ERROR
: wxSTREAM_READ_ERROR
);
201 wxWinINetInputStream::~wxWinINetInputStream()
205 InternetCloseHandle(m_hFile
);
210 wxURLNativeImp
*wxURL::CreateNativeImpObject()
212 return new wxWinINetURL
;
215 wxInputStream
*wxWinINetURL::GetInputStream(wxURL
*owner
)
218 if ( owner
->GetScheme() == wxT("http") )
220 service
= INTERNET_SERVICE_HTTP
;
222 else if ( owner
->GetScheme() == wxT("ftp") )
224 service
= INTERNET_SERVICE_FTP
;
228 // unknown protocol. Let wxURL try another method.
232 wxWinINetInputStream
*newStream
= new wxWinINetInputStream
;
233 HINTERNET newStreamHandle
= InternetOpenUrl
239 INTERNET_FLAG_KEEP_CONNECTION
|
240 INTERNET_FLAG_PASSIVE
,
243 newStream
->Attach(newStreamHandle
);
248 #endif // wxUSE_URL_NATIVE