]> git.saurik.com Git - wxWidgets.git/blame - src/msw/urlmsw.cpp
catch unhandled exceptions in POSIX threads implementation the same way wxMSW does
[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"
8ecff181
WS
26#endif
27
25959b95 28#if !wxUSE_PROTOCOL_HTTP
7ec69821 29#include "wx/protocol/protocol.h"
25959b95
VZ
30
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
34class wxHTTPDummyProto : public wxProtocol
35{
36public:
37 wxHTTPDummyProto() : wxProtocol() { }
38
39 wxProtocolError GetError() { return m_error; }
40
27d2dbbc 41 virtual bool Abort() { return true; }
25959b95
VZ
42
43 wxInputStream *GetInputStream(const wxString& WXUNUSED(path))
44 {
45 return 0; // input stream is returned by wxURLNativeImp
46 }
47
48protected:
49 wxProtocolError m_error;
50
51 DECLARE_DYNAMIC_CLASS_NO_COPY(wxHTTPDummyProto)
52 DECLARE_PROTOCOL(wxHTTPDummyProto)
53};
54
55// the only "reason for being" for this class is to tell
56// wxURL that there is someone dealing with the http protocol
57IMPLEMENT_DYNAMIC_CLASS(wxHTTPDummyProto, wxProtocol)
7ec69821 58IMPLEMENT_PROTOCOL(wxHTTPDummyProto, wxT("http"), NULL, false)
25959b95
VZ
59USE_PROTOCOL(wxHTTPDummyProto)
60
61#endif // !wxUSE_PROTOCOL_HTTP
62
63
64#ifdef __VISUALC__ // be conservative about this pragma
65 // tell the linker to include wininet.lib automatically
66 #pragma comment(lib, "wininet.lib")
67#endif
68
25959b95
VZ
69#include "wx/url.h"
70
71#include <string.h>
72#include <ctype.h>
73#include <wininet.h>
74
75// this class needn't be exported
76class wxWinINetURL:public wxURLNativeImp
77{
78public:
79 wxInputStream *GetInputStream(wxURL *owner);
80
81protected:
82 // return the WinINet session handle
83 static HINTERNET GetSessionHandle();
84};
85
86HINTERNET wxWinINetURL::GetSessionHandle()
87{
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
91 // terminates
92 static struct INetSession
93 {
94 INetSession()
95 {
96 DWORD rc = InternetAttemptConnect(0);
97
98 m_handle = InternetOpen
99 (
100 wxVERSION_STRING,
101 INTERNET_OPEN_TYPE_PRECONFIG,
102 NULL,
103 NULL,
104 rc == ERROR_SUCCESS ? 0 : INTERNET_FLAG_OFFLINE
105 );
106 }
107
108 ~INetSession()
109 {
110 InternetCloseHandle(m_handle);
111 }
112
113 HINTERNET m_handle;
114 } session;
115
116 return session.m_handle;
117}
118
119// this class needn't be exported
120class /*WXDLLIMPEXP_NET */ wxWinINetInputStream : public wxInputStream
121{
122public:
123 wxWinINetInputStream(HINTERNET hFile=0);
d3c7fc99 124 virtual ~wxWinINetInputStream();
25959b95
VZ
125
126 void Attach(HINTERNET hFile);
127
30984dea 128 wxFileOffset SeekI( wxFileOffset WXUNUSED(pos), wxSeekMode WXUNUSED(mode) )
25959b95 129 { return -1; }
30984dea 130 wxFileOffset TellI() const
25959b95
VZ
131 { return -1; }
132
133protected:
134 void SetError(wxStreamError err) { m_lasterror=err; }
135 HINTERNET m_hFile;
136 size_t OnSysRead(void *buffer, size_t bufsize);
137
138 DECLARE_NO_COPY_CLASS(wxWinINetInputStream)
139};
140
141size_t wxWinINetInputStream::OnSysRead(void *buffer, size_t bufsize)
142{
143 DWORD bytesread = 0;
144 if ( !InternetReadFile(m_hFile, buffer, bufsize, &bytesread) )
145 {
146 DWORD lError = ::GetLastError();
147 if ( lError != ERROR_SUCCESS )
148 SetError(wxSTREAM_READ_ERROR);
149
150 DWORD iError, bLength;
151 InternetGetLastResponseInfo(&iError, NULL, &bLength);
152 if ( bLength > 0 )
153 {
154 wxString errorString;
155 InternetGetLastResponseInfo
156 (
157 &iError,
158 wxStringBuffer(errorString, bLength),
159 &bLength
160 );
161
162 wxLogError(wxT("Read failed with error %d: %s"),
163 iError, errorString);
164 }
165 }
166
167 if ( bytesread == 0 )
168 {
169 SetError(wxSTREAM_EOF);
170 }
171
172 return bytesread;
173}
174
175wxWinINetInputStream::wxWinINetInputStream(HINTERNET hFile)
176 : m_hFile(hFile)
177{
178}
179
180void wxWinINetInputStream::Attach(HINTERNET newHFile)
181{
182 wxCHECK_RET(m_hFile==NULL,
183 wxT("cannot attach new stream when stream already exists"));
184 m_hFile=newHFile;
185 SetError(m_hFile!=NULL ? wxSTREAM_NO_ERROR : wxSTREAM_READ_ERROR);
186}
187
188wxWinINetInputStream::~wxWinINetInputStream()
189{
190 if ( m_hFile )
191 {
192 InternetCloseHandle(m_hFile);
193 m_hFile=0;
194 }
195}
196
197wxURLNativeImp *wxURL::CreateNativeImpObject()
198{
199 return new wxWinINetURL;
200}
201
202wxInputStream *wxWinINetURL::GetInputStream(wxURL *owner)
203{
204 DWORD service;
c66d0fc3 205 if ( owner->GetScheme() == wxT("http") )
25959b95
VZ
206 {
207 service = INTERNET_SERVICE_HTTP;
208 }
c66d0fc3 209 else if ( owner->GetScheme() == wxT("ftp") )
25959b95
VZ
210 {
211 service = INTERNET_SERVICE_FTP;
212 }
213 else
214 {
215 // unknown protocol. Let wxURL try another method.
216 return 0;
217 }
218
219 wxWinINetInputStream *newStream = new wxWinINetInputStream;
220 HINTERNET newStreamHandle = InternetOpenUrl
221 (
222 GetSessionHandle(),
223 owner->GetURL(),
224 NULL,
225 0,
226 INTERNET_FLAG_KEEP_CONNECTION |
227 INTERNET_FLAG_PASSIVE,
228 (DWORD_PTR)newStream
229 );
230 newStream->Attach(newStreamHandle);
231
232 return newStream;
233}
234
235#endif // wxUSE_URL_NATIVE