]> git.saurik.com Git - wxWidgets.git/blame - src/msw/urlmsw.cpp
applying patch, fixes #10523
[wxWidgets.git] / src / msw / urlmsw.cpp
CommitLineData
25959b95 1/////////////////////////////////////////////////////////////////////////////
7ec69821 2// Name: src/msw/urlmsw.cpp
25959b95
VZ
3// Purpose: MS-Windows native URL support based on WinINet
4// Author: Hajo Kirchhoff
5// Modified by:
6// Created: 06/11/2003
7// RCS-ID: $Id$
8// Copyright: (c) 2003 Hajo Kirchhoff
65571936 9// Licence: wxWindows licence
25959b95
VZ
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16 #pragma hdrstop
17#endif
18
19#if wxUSE_URL_NATIVE
20
8ecff181
WS
21#ifndef WX_PRECOMP
22 #include "wx/list.h"
df91131c 23 #include "wx/string.h"
de6185e2 24 #include "wx/utils.h"
02761f6c 25 #include "wx/module.h"
f0d9be8a 26 #include "wx/log.h"
8ecff181
WS
27#endif
28
25959b95 29#if !wxUSE_PROTOCOL_HTTP
7ec69821 30#include "wx/protocol/protocol.h"
25959b95
VZ
31
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
35class wxHTTPDummyProto : public wxProtocol
36{
37public:
38 wxHTTPDummyProto() : wxProtocol() { }
39
40 wxProtocolError GetError() { return m_error; }
41
27d2dbbc 42 virtual bool Abort() { return true; }
25959b95
VZ
43
44 wxInputStream *GetInputStream(const wxString& WXUNUSED(path))
45 {
46 return 0; // input stream is returned by wxURLNativeImp
47 }
48
49protected:
50 wxProtocolError m_error;
51
52 DECLARE_DYNAMIC_CLASS_NO_COPY(wxHTTPDummyProto)
53 DECLARE_PROTOCOL(wxHTTPDummyProto)
54};
55
56// the only "reason for being" for this class is to tell
57// wxURL that there is someone dealing with the http protocol
58IMPLEMENT_DYNAMIC_CLASS(wxHTTPDummyProto, wxProtocol)
7ec69821 59IMPLEMENT_PROTOCOL(wxHTTPDummyProto, wxT("http"), NULL, false)
25959b95
VZ
60USE_PROTOCOL(wxHTTPDummyProto)
61
62#endif // !wxUSE_PROTOCOL_HTTP
63
64
65#ifdef __VISUALC__ // be conservative about this pragma
66 // tell the linker to include wininet.lib automatically
67 #pragma comment(lib, "wininet.lib")
68#endif
69
25959b95
VZ
70#include "wx/url.h"
71
72#include <string.h>
73#include <ctype.h>
74#include <wininet.h>
75
76// this class needn't be exported
77class wxWinINetURL:public wxURLNativeImp
78{
79public:
80 wxInputStream *GetInputStream(wxURL *owner);
81
82protected:
83 // return the WinINet session handle
84 static HINTERNET GetSessionHandle();
85};
86
87HINTERNET wxWinINetURL::GetSessionHandle()
88{
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
92 // terminates
93 static struct INetSession
94 {
95 INetSession()
96 {
97 DWORD rc = InternetAttemptConnect(0);
98
99 m_handle = InternetOpen
100 (
101 wxVERSION_STRING,
102 INTERNET_OPEN_TYPE_PRECONFIG,
103 NULL,
104 NULL,
105 rc == ERROR_SUCCESS ? 0 : INTERNET_FLAG_OFFLINE
106 );
107 }
108
109 ~INetSession()
110 {
111 InternetCloseHandle(m_handle);
112 }
113
114 HINTERNET m_handle;
115 } session;
116
117 return session.m_handle;
118}
119
120// this class needn't be exported
121class /*WXDLLIMPEXP_NET */ wxWinINetInputStream : public wxInputStream
122{
123public:
124 wxWinINetInputStream(HINTERNET hFile=0);
d3c7fc99 125 virtual ~wxWinINetInputStream();
25959b95
VZ
126
127 void Attach(HINTERNET hFile);
128
30984dea 129 wxFileOffset SeekI( wxFileOffset WXUNUSED(pos), wxSeekMode WXUNUSED(mode) )
25959b95 130 { return -1; }
30984dea 131 wxFileOffset TellI() const
25959b95 132 { return -1; }
624f82cc 133 size_t GetSize() const;
25959b95
VZ
134
135protected:
136 void SetError(wxStreamError err) { m_lasterror=err; }
137 HINTERNET m_hFile;
138 size_t OnSysRead(void *buffer, size_t bufsize);
139
c0c133e1 140 wxDECLARE_NO_COPY_CLASS(wxWinINetInputStream);
25959b95
VZ
141};
142
624f82cc
VZ
143size_t wxWinINetInputStream::GetSize() const
144{
145 DWORD contentLength = 0;
146 DWORD dwSize = sizeof(contentLength);
147 DWORD index = 0;
148
149 if ( HttpQueryInfo( m_hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &contentLength, &dwSize, &index) )
150 return contentLength;
151 else
152 return 0;
153}
154
25959b95
VZ
155size_t wxWinINetInputStream::OnSysRead(void *buffer, size_t bufsize)
156{
157 DWORD bytesread = 0;
158 if ( !InternetReadFile(m_hFile, buffer, bufsize, &bytesread) )
159 {
160 DWORD lError = ::GetLastError();
161 if ( lError != ERROR_SUCCESS )
162 SetError(wxSTREAM_READ_ERROR);
163
164 DWORD iError, bLength;
165 InternetGetLastResponseInfo(&iError, NULL, &bLength);
166 if ( bLength > 0 )
167 {
168 wxString errorString;
169 InternetGetLastResponseInfo
170 (
171 &iError,
172 wxStringBuffer(errorString, bLength),
173 &bLength
174 );
175
176 wxLogError(wxT("Read failed with error %d: %s"),
177 iError, errorString);
178 }
179 }
180
181 if ( bytesread == 0 )
182 {
183 SetError(wxSTREAM_EOF);
184 }
185
186 return bytesread;
187}
188
189wxWinINetInputStream::wxWinINetInputStream(HINTERNET hFile)
190 : m_hFile(hFile)
191{
192}
193
194void wxWinINetInputStream::Attach(HINTERNET newHFile)
195{
196 wxCHECK_RET(m_hFile==NULL,
197 wxT("cannot attach new stream when stream already exists"));
198 m_hFile=newHFile;
199 SetError(m_hFile!=NULL ? wxSTREAM_NO_ERROR : wxSTREAM_READ_ERROR);
200}
201
202wxWinINetInputStream::~wxWinINetInputStream()
203{
204 if ( m_hFile )
205 {
206 InternetCloseHandle(m_hFile);
207 m_hFile=0;
208 }
209}
210
211wxURLNativeImp *wxURL::CreateNativeImpObject()
212{
213 return new wxWinINetURL;
214}
215
216wxInputStream *wxWinINetURL::GetInputStream(wxURL *owner)
217{
218 DWORD service;
c66d0fc3 219 if ( owner->GetScheme() == wxT("http") )
25959b95
VZ
220 {
221 service = INTERNET_SERVICE_HTTP;
222 }
c66d0fc3 223 else if ( owner->GetScheme() == wxT("ftp") )
25959b95
VZ
224 {
225 service = INTERNET_SERVICE_FTP;
226 }
227 else
228 {
229 // unknown protocol. Let wxURL try another method.
230 return 0;
231 }
232
233 wxWinINetInputStream *newStream = new wxWinINetInputStream;
234 HINTERNET newStreamHandle = InternetOpenUrl
235 (
236 GetSessionHandle(),
237 owner->GetURL(),
238 NULL,
239 0,
240 INTERNET_FLAG_KEEP_CONNECTION |
241 INTERNET_FLAG_PASSIVE,
242 (DWORD_PTR)newStream
243 );
244 newStream->Attach(newStreamHandle);
245
246 return newStream;
247}
248
249#endif // wxUSE_URL_NATIVE