1
/////////////////////////////////////////////////////////////////////////////
4
// Author: Guilhem Lavaux
7
// RCS-ID: $Id: url.cpp,v 1.54 2005/07/28 21:52:50 VZ Exp $
8
// Copyright: (c) 1997, 1998 Guilhem Lavaux
9
// Licence: wxWindows licence
10
/////////////////////////////////////////////////////////////////////////////
12
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13
#pragma implementation "url.h"
16
// For compilers that support precompilation, includes "wx.h".
17
#include "wx/wxprec.h"
25
#include "wx/string.h"
28
#include "wx/module.h"
34
IMPLEMENT_CLASS(wxProtoInfo, wxObject)
35
IMPLEMENT_CLASS(wxURL, wxURI)
38
wxProtoInfo *wxURL::ms_protocols = NULL;
40
// Enforce linking of protocol classes:
41
USE_PROTOCOL(wxFileProto)
43
#if wxUSE_PROTOCOL_HTTP
46
wxHTTP *wxURL::ms_proxyDefault = NULL;
47
bool wxURL::ms_useDefaultProxy = false;
50
#if wxUSE_PROTOCOL_FTP
54
// --------------------------------------------------------------
58
// --------------------------------------------------------------
60
// --------------------------------------------------------------
62
// --------------------------------------------------------------
64
wxURL::wxURL(const wxString& url) : wxURI(url)
70
wxURL::wxURL(const wxURI& url) : wxURI(url)
76
void wxURL::Init(const wxString& url)
79
m_error = wxURL_NOERR;
82
m_nativeImp = CreateNativeImpObject();
85
#if wxUSE_PROTOCOL_HTTP
86
if ( ms_useDefaultProxy && !ms_proxyDefault )
88
SetDefaultProxy( wxGetenv(wxT("HTTP_PROXY")) );
90
if ( !ms_proxyDefault )
93
ms_useDefaultProxy = false;
97
m_useProxy = ms_proxyDefault != NULL;
98
m_proxy = ms_proxyDefault;
99
#endif // wxUSE_PROTOCOL_HTTP
103
// --------------------------------------------------------------
105
// --------------------------------------------------------------
107
wxURL& wxURL::operator = (const wxURI& url)
109
wxURI::operator = (url);
110
Init(url.BuildURI());
114
wxURL& wxURL::operator = (const wxString& url)
116
wxURI::operator = (url);
122
// --------------------------------------------------------------
125
// Builds the URL and takes care of the old protocol stuff
126
// --------------------------------------------------------------
128
bool wxURL::ParseURL()
130
// If the URL was already parsed (m_protocol != NULL), pass this section.
136
// Make sure we have a protocol/scheme
139
m_error = wxURL_SNTXERR;
143
// Find and create the protocol object
144
if (!FetchProtocol())
146
m_error = wxURL_NOPROTO;
150
// Do we need a host name ?
151
if (m_protoinfo->m_needhost)
153
// Make sure we have one, then
156
m_error = wxURL_SNTXERR;
162
#if wxUSE_PROTOCOL_HTTP
165
// Third, we rebuild the URL.
166
m_url = m_scheme + wxT(":");
167
if (m_protoinfo->m_needhost)
168
m_url = m_url + wxT("//") + m_server;
170
// We initialize specific variables.
171
m_protocol = m_proxy; // FIXME: we should clone the protocol
173
#endif // wxUSE_PROTOCOL_HTTP
175
m_error = wxURL_NOERR;
179
// --------------------------------------------------------------
180
// Destruction/Cleanup
181
// --------------------------------------------------------------
183
void wxURL::CleanData()
185
#if wxUSE_PROTOCOL_HTTP
187
#endif // wxUSE_PROTOCOL_HTTP
194
#if wxUSE_PROTOCOL_HTTP
195
if (m_proxy && m_proxy != ms_proxyDefault)
197
#endif // wxUSE_PROTOCOL_HTTP
203
// --------------------------------------------------------------
205
// --------------------------------------------------------------
207
bool wxURL::FetchProtocol()
209
wxProtoInfo *info = ms_protocols;
213
if (m_scheme == info->m_protoname)
216
m_port = info->m_servname;
218
m_protocol = (wxProtocol *)m_protoinfo->m_cinfo->CreateObject();
226
// --------------------------------------------------------------
228
// --------------------------------------------------------------
230
wxInputStream *wxURL::GetInputStream()
234
m_error = wxURL_NOPROTO;
238
m_error = wxURL_NOERR;
241
size_t dwPasswordPos = m_userinfo.find(':');
243
if (dwPasswordPos == wxString::npos)
244
m_protocol->SetUser(m_userinfo);
247
m_protocol->SetUser(m_userinfo(0, dwPasswordPos));
248
m_protocol->SetPassword(m_userinfo(dwPasswordPos+1, m_userinfo.length() + 1));
253
// give the native implementation to return a better stream
254
// such as the native WinINet functionality under MS-Windows
258
rc = m_nativeImp->GetInputStream(this);
262
// else use the standard behaviour
263
#endif // wxUSE_URL_NATIVE
268
// m_protoinfo is NULL when we use a proxy
269
if (!m_useProxy && m_protoinfo->m_needhost)
271
if (!addr.Hostname(m_server))
273
m_error = wxURL_NOHOST;
277
addr.Service(m_port);
279
if (!m_protocol->Connect(addr, true)) // Watcom needs the 2nd arg for some reason
281
m_error = wxURL_CONNERR;
289
// When we use a proxy, we have to pass the whole URL to it.
294
fullPath += wxT("/");
299
fullPath += wxT("?") + m_query;
302
fullPath += wxT("#") + m_fragment;
304
wxInputStream *the_i_stream = m_protocol->GetInputStream(fullPath);
308
m_error = wxURL_PROTOERR;
315
#if wxUSE_PROTOCOL_HTTP
316
void wxURL::SetDefaultProxy(const wxString& url_proxy)
320
if ( ms_proxyDefault )
322
ms_proxyDefault->Close();
323
delete ms_proxyDefault;
324
ms_proxyDefault = NULL;
329
wxString tmp_str = url_proxy;
330
int pos = tmp_str.Find(wxT(':'));
331
if (pos == wxNOT_FOUND)
334
wxString hostname = tmp_str(0, pos),
335
port = tmp_str(pos+1, tmp_str.Length()-pos);
338
if (!addr.Hostname(hostname))
340
if (!addr.Service(port))
344
// Finally, when all is right, we connect the new proxy.
345
ms_proxyDefault->Close();
347
ms_proxyDefault = new wxHTTP();
348
ms_proxyDefault->Connect(addr, true); // Watcom needs the 2nd arg for some reason
352
void wxURL::SetProxy(const wxString& url_proxy)
356
if ( m_proxy && m_proxy != ms_proxyDefault )
367
wxString hostname, port;
372
pos = tmp_str.Find(wxT(':'));
373
// This is an invalid proxy name.
374
if (pos == wxNOT_FOUND)
377
hostname = tmp_str(0, pos);
378
port = tmp_str(pos+1, tmp_str.Length()-pos);
380
addr.Hostname(hostname);
383
// Finally, create the whole stuff.
384
if (m_proxy && m_proxy != ms_proxyDefault)
386
m_proxy = new wxHTTP();
387
m_proxy->Connect(addr, true); // Watcom needs the 2nd arg for some reason
395
#endif // wxUSE_PROTOCOL_HTTP
397
// ----------------------------------------------------------------------
400
// A module which deletes the default proxy if we created it
401
// ----------------------------------------------------------------------
405
class wxURLModule : public wxModule
408
virtual bool OnInit();
409
virtual void OnExit();
412
DECLARE_DYNAMIC_CLASS(wxURLModule)
415
IMPLEMENT_DYNAMIC_CLASS(wxURLModule, wxModule)
417
bool wxURLModule::OnInit()
419
#if wxUSE_PROTOCOL_HTTP
420
// env var HTTP_PROXY contains the address of the default proxy to use if
421
// set, but don't try to create this proxy right now because it will slow
422
// down the program startup (especially if there is no DNS server
423
// available, in which case it may take up to 1 minute)
425
if ( wxGetenv(_T("HTTP_PROXY")) )
427
wxURL::ms_useDefaultProxy = true;
429
#endif // wxUSE_PROTOCOL_HTTP
433
void wxURLModule::OnExit()
435
#if wxUSE_PROTOCOL_HTTP
436
delete wxURL::ms_proxyDefault;
437
wxURL::ms_proxyDefault = NULL;
438
#endif // wxUSE_PROTOCOL_HTTP
441
#endif // wxUSE_SOCKETS
443
// ---------------------------------------------------------------------------
445
// wxURL Compatibility
447
// ---------------------------------------------------------------------------
449
#if WXWIN_COMPATIBILITY_2_4
453
wxString wxURL::GetProtocolName() const
458
wxString wxURL::GetHostName() const
463
wxString wxURL::GetPath() const
468
//Note that this old code really doesn't convert to a URI that well and looks
469
//more like a dirty hack than anything else...
471
wxString wxURL::ConvertToValidURI(const wxString& uri, const wxChar* delims)
477
for (i = 0; i < uri.Len(); i++)
479
wxChar c = uri.GetChar(i);
483
// GRG, Apr/2000: changed to "%20" instead of '+'
485
out_str += wxT("%20");
489
// GRG, Apr/2000: modified according to the URI definition (RFC 2396)
491
// - Alphanumeric characters are never escaped
492
// - Unreserved marks are never escaped
493
// - Delimiters must be escaped if they appear within a component
494
// but not if they are used to separate components. Here we have
495
// no clear way to distinguish between these two cases, so they
496
// are escaped unless they are passed in the 'delims' parameter
497
// (allowed delimiters).
499
static const wxChar marks[] = wxT("-_.!~*()'");
501
if ( !wxIsalnum(c) && !wxStrchr(marks, c) && !wxStrchr(delims, c) )
503
hexa_code.Printf(wxT("%%%02X"), c);
504
out_str += hexa_code;
516
wxString wxURL::ConvertFromURI(const wxString& uri)
518
return wxURI::Unescape(uri);
521
#endif //WXWIN_COMPATIBILITY_2_4