]>
git.saurik.com Git - wxWidgets.git/blob - src/common/url.cpp
1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Guilhem Lavaux
8 // Copyright: (c) 1997, 1998 Guilhem Lavaux
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
21 #include "wx/string.h"
24 #include "wx/module.h"
30 IMPLEMENT_CLASS(wxProtoInfo
, wxObject
)
31 IMPLEMENT_CLASS(wxURL
, wxURI
)
34 wxProtoInfo
*wxURL::ms_protocols
= NULL
;
36 // Enforce linking of protocol classes:
37 USE_PROTOCOL(wxFileProto
)
39 #if wxUSE_PROTOCOL_HTTP
42 wxHTTP
*wxURL::ms_proxyDefault
= NULL
;
43 bool wxURL::ms_useDefaultProxy
= false;
46 #if wxUSE_PROTOCOL_FTP
50 // --------------------------------------------------------------
54 // --------------------------------------------------------------
56 // --------------------------------------------------------------
58 // --------------------------------------------------------------
60 wxURL::wxURL(const wxString
& url
) : wxURI(url
)
66 wxURL::wxURL(const wxURI
& url
) : wxURI(url
)
72 void wxURL::Init(const wxString
& url
)
75 m_error
= wxURL_NOERR
;
78 m_nativeImp
= CreateNativeImpObject();
81 #if wxUSE_PROTOCOL_HTTP
82 if ( ms_useDefaultProxy
&& !ms_proxyDefault
)
84 SetDefaultProxy( wxGetenv(wxT("HTTP_PROXY")) );
86 if ( !ms_proxyDefault
)
89 ms_useDefaultProxy
= false;
93 m_useProxy
= ms_proxyDefault
!= NULL
;
94 m_proxy
= ms_proxyDefault
;
95 #endif // wxUSE_PROTOCOL_HTTP
99 // --------------------------------------------------------------
101 // --------------------------------------------------------------
103 wxURL
& wxURL::operator = (const wxURI
& url
)
105 wxURI::operator = (url
);
106 Init(url
.BuildURI());
110 wxURL
& wxURL::operator = (const wxString
& url
)
112 wxURI::operator = (url
);
118 // --------------------------------------------------------------
121 // Builds the URL and takes care of the old protocol stuff
122 // --------------------------------------------------------------
124 bool wxURL::ParseURL()
126 // If the URL was already parsed (m_protocol != NULL), pass this section.
132 // Make sure we have a protocol/scheme
135 m_error
= wxURL_SNTXERR
;
139 // Find and create the protocol object
140 if (!FetchProtocol())
142 m_error
= wxURL_NOPROTO
;
146 // Do we need a host name ?
147 if (m_protoinfo
->m_needhost
)
149 // Make sure we have one, then
152 m_error
= wxURL_SNTXERR
;
158 #if wxUSE_PROTOCOL_HTTP
161 // Third, we rebuild the URL.
162 m_url
= m_scheme
+ wxT(":");
163 if (m_protoinfo
->m_needhost
)
164 m_url
= m_url
+ wxT("//") + m_server
;
166 // We initialize specific variables.
167 m_protocol
= m_proxy
; // FIXME: we should clone the protocol
169 #endif // wxUSE_PROTOCOL_HTTP
171 m_error
= wxURL_NOERR
;
175 // --------------------------------------------------------------
176 // Destruction/Cleanup
177 // --------------------------------------------------------------
179 void wxURL::CleanData()
181 #if wxUSE_PROTOCOL_HTTP
183 #endif // wxUSE_PROTOCOL_HTTP
190 #if wxUSE_PROTOCOL_HTTP
191 if (m_proxy
&& m_proxy
!= ms_proxyDefault
)
193 #endif // wxUSE_PROTOCOL_HTTP
199 // --------------------------------------------------------------
201 // --------------------------------------------------------------
203 bool wxURL::FetchProtocol()
205 wxProtoInfo
*info
= ms_protocols
;
209 if (m_scheme
== info
->m_protoname
)
212 m_port
= info
->m_servname
;
214 m_protocol
= (wxProtocol
*)m_protoinfo
->m_cinfo
->CreateObject();
222 // --------------------------------------------------------------
224 // --------------------------------------------------------------
226 wxInputStream
*wxURL::GetInputStream()
230 m_error
= wxURL_NOPROTO
;
234 m_error
= wxURL_NOERR
;
237 size_t dwPasswordPos
= m_userinfo
.find(':');
239 if (dwPasswordPos
== wxString::npos
)
240 m_protocol
->SetUser(m_userinfo
);
243 m_protocol
->SetUser(m_userinfo(0, dwPasswordPos
));
244 m_protocol
->SetPassword(m_userinfo(dwPasswordPos
+1, m_userinfo
.length() + 1));
249 // give the native implementation to return a better stream
250 // such as the native WinINet functionality under MS-Windows
254 rc
= m_nativeImp
->GetInputStream(this);
258 // else use the standard behaviour
259 #endif // wxUSE_URL_NATIVE
264 // m_protoinfo is NULL when we use a proxy
265 if (!m_useProxy
&& m_protoinfo
->m_needhost
)
267 if (!addr
.Hostname(m_server
))
269 m_error
= wxURL_NOHOST
;
273 addr
.Service(m_port
);
275 if (!m_protocol
->Connect(addr
, true)) // Watcom needs the 2nd arg for some reason
277 m_error
= wxURL_CONNERR
;
285 // When we use a proxy, we have to pass the whole URL to it.
290 fullPath
+= wxT("/");
295 fullPath
+= wxT("?") + m_query
;
298 fullPath
+= wxT("#") + m_fragment
;
300 wxInputStream
*the_i_stream
= m_protocol
->GetInputStream(fullPath
);
304 m_error
= wxURL_PROTOERR
;
311 #if wxUSE_PROTOCOL_HTTP
312 void wxURL::SetDefaultProxy(const wxString
& url_proxy
)
316 if ( ms_proxyDefault
)
318 ms_proxyDefault
->Close();
319 delete ms_proxyDefault
;
320 ms_proxyDefault
= NULL
;
325 wxString tmp_str
= url_proxy
;
326 int pos
= tmp_str
.Find(wxT(':'));
327 if (pos
== wxNOT_FOUND
)
330 wxString hostname
= tmp_str(0, pos
),
331 port
= tmp_str(pos
+1, tmp_str
.Length()-pos
);
334 if (!addr
.Hostname(hostname
))
336 if (!addr
.Service(port
))
340 // Finally, when all is right, we connect the new proxy.
341 ms_proxyDefault
->Close();
343 ms_proxyDefault
= new wxHTTP();
344 ms_proxyDefault
->Connect(addr
, true); // Watcom needs the 2nd arg for some reason
348 void wxURL::SetProxy(const wxString
& url_proxy
)
352 if ( m_proxy
&& m_proxy
!= ms_proxyDefault
)
363 wxString hostname
, port
;
368 pos
= tmp_str
.Find(wxT(':'));
369 // This is an invalid proxy name.
370 if (pos
== wxNOT_FOUND
)
373 hostname
= tmp_str(0, pos
);
374 port
= tmp_str(pos
+1, tmp_str
.Length()-pos
);
376 addr
.Hostname(hostname
);
379 // Finally, create the whole stuff.
380 if (m_proxy
&& m_proxy
!= ms_proxyDefault
)
382 m_proxy
= new wxHTTP();
383 m_proxy
->Connect(addr
, true); // Watcom needs the 2nd arg for some reason
391 #endif // wxUSE_PROTOCOL_HTTP
393 // ----------------------------------------------------------------------
396 // A module which deletes the default proxy if we created it
397 // ----------------------------------------------------------------------
401 class wxURLModule
: public wxModule
404 virtual bool OnInit();
405 virtual void OnExit();
408 DECLARE_DYNAMIC_CLASS(wxURLModule
)
411 IMPLEMENT_DYNAMIC_CLASS(wxURLModule
, wxModule
)
413 bool wxURLModule::OnInit()
415 #if wxUSE_PROTOCOL_HTTP
416 // env var HTTP_PROXY contains the address of the default proxy to use if
417 // set, but don't try to create this proxy right now because it will slow
418 // down the program startup (especially if there is no DNS server
419 // available, in which case it may take up to 1 minute)
421 if ( wxGetenv(_T("HTTP_PROXY")) )
423 wxURL::ms_useDefaultProxy
= true;
425 #endif // wxUSE_PROTOCOL_HTTP
429 void wxURLModule::OnExit()
431 #if wxUSE_PROTOCOL_HTTP
432 delete wxURL::ms_proxyDefault
;
433 wxURL::ms_proxyDefault
= NULL
;
434 #endif // wxUSE_PROTOCOL_HTTP
437 #endif // wxUSE_SOCKETS
439 // ---------------------------------------------------------------------------
441 // wxURL Compatibility
443 // ---------------------------------------------------------------------------
445 #if WXWIN_COMPATIBILITY_2_4
449 wxString
wxURL::GetProtocolName() const
454 wxString
wxURL::GetHostName() const
459 wxString
wxURL::GetPath() const
464 //Note that this old code really doesn't convert to a URI that well and looks
465 //more like a dirty hack than anything else...
467 wxString
wxURL::ConvertToValidURI(const wxString
& uri
, const wxChar
* delims
)
473 for (i
= 0; i
< uri
.Len(); i
++)
475 wxChar c
= uri
.GetChar(i
);
479 // GRG, Apr/2000: changed to "%20" instead of '+'
481 out_str
+= wxT("%20");
485 // GRG, Apr/2000: modified according to the URI definition (RFC 2396)
487 // - Alphanumeric characters are never escaped
488 // - Unreserved marks are never escaped
489 // - Delimiters must be escaped if they appear within a component
490 // but not if they are used to separate components. Here we have
491 // no clear way to distinguish between these two cases, so they
492 // are escaped unless they are passed in the 'delims' parameter
493 // (allowed delimiters).
495 static const wxChar marks
[] = wxT("-_.!~*()'");
497 if ( !wxIsalnum(c
) && !wxStrchr(marks
, c
) && !wxStrchr(delims
, c
) )
499 hexa_code
.Printf(wxT("%%%02X"), c
);
500 out_str
+= hexa_code
;
512 wxString
wxURL::ConvertFromURI(const wxString
& uri
)
514 return wxURI::Unescape(uri
);
517 #endif //WXWIN_COMPATIBILITY_2_4