]> git.saurik.com Git - wxWidgets.git/blame - src/common/url.cpp
Added another missing file (wxBufferedStreams doc)
[wxWidgets.git] / src / common / url.cpp
CommitLineData
f4ada568
GL
1/////////////////////////////////////////////////////////////////////////////
2// Name: url.cpp
3// Purpose: URL parser
4// Author: Guilhem Lavaux
5// Modified by:
6// Created: 20/07/1997
7// RCS-ID: $Id$
8// Copyright: (c) 1997, 1998 Guilhem Lavaux
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "url.h"
14#endif
fcc6dddd
JS
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
35a4dab7
GL
23#if wxUSE_SOCKETS
24
fcc6dddd
JS
25#ifndef WX_PRECOMP
26#endif
27
f4ada568
GL
28#include <string.h>
29#include <ctype.h>
30
31// wxWindows headers
32#include <wx/string.h>
33#include <wx/list.h>
34#include <wx/utils.h>
35
36// wxSocket header
37#include "wx/url.h"
38
f4ada568
GL
39#if !USE_SHARED_LIBRARY
40IMPLEMENT_CLASS(wxProtoInfo, wxObject)
41IMPLEMENT_CLASS(wxURL, wxObject)
42#endif
43
44// Protocols list
45wxProtoInfo *wxURL::g_protocols = NULL;
3b4183d8 46wxHTTP *wxURL::g_proxy;
f4ada568 47
fae05df5
GL
48// --------------------------------------------------------------
49// wxURL
50// --------------------------------------------------------------
f4ada568 51
fae05df5
GL
52// --------------------------------------------------------------
53// --------- wxURL CONSTRUCTOR DESTRUCTOR -----------------------
54// --------------------------------------------------------------
f4ada568
GL
55
56wxURL::wxURL(const wxString& url)
57{
58 m_protocol = NULL;
3b4183d8
GL
59 if (g_proxy->IsConnected()) {
60 m_protocol = g_proxy;
f4ada568
GL
61 m_protoname = "proxy";
62 m_path = url;
63 return;
64 }
65 m_url = url;
66 m_error = wxURL_NOERR;
41895a05 67 ParseURL();
f4ada568
GL
68}
69
70bool wxURL::ParseURL()
71{
72 wxString last_url = m_url;
73
74 // Clean up
75 CleanData();
76
77 // Extract protocol name
78 if (!PrepProto(last_url)) {
79 m_error = wxURL_SNTXERR;
80 return FALSE;
81 }
82
83 // Find and create the protocol object
84 if (!FetchProtocol()) {
85 m_error = wxURL_NOPROTO;
86 return FALSE;
87 }
88
89 // Do we need a host name ?
90 if (m_protoinfo->m_needhost) {
91 // Extract it
92 if (!PrepHost(last_url)) {
93 m_error = wxURL_SNTXERR;
94 return FALSE;
95 }
96 }
97
98 // Extract full path
99 if (!PrepPath(last_url)) {
100 m_error = wxURL_NOPATH;
101 return FALSE;
102 }
103
104 m_error = wxURL_NOERR;
105 return TRUE;
106}
107
108void wxURL::CleanData()
109{
00421206 110 if (m_protoname != _T("proxy"))
f4ada568
GL
111 delete m_protocol;
112}
113
114wxURL::~wxURL()
115{
116 CleanData();
117}
118
fae05df5
GL
119// --------------------------------------------------------------
120// --------- wxURL urls decoders --------------------------------
121// --------------------------------------------------------------
122
f4ada568
GL
123bool wxURL::PrepProto(wxString& url)
124{
125 int pos;
126
127 // Find end
128 pos = url.Find(':');
129 if (pos == -1)
130 return FALSE;
131
132 m_protoname = url(0, pos);
133
134 url = url(pos+1, url.Length());
135
136 return TRUE;
137}
138
139bool wxURL::PrepHost(wxString& url)
140{
856d2e52 141 wxString temp_url;
f4ada568
GL
142 int pos, pos2;
143
fcc6dddd 144 if ((url.GetChar(0) != '/') || (url.GetChar(1) != '/'))
f4ada568
GL
145 return FALSE;
146
147 url = url(2, url.Length());
148
149 pos = url.Find('/');
150 if (pos == -1)
b7db6f0b 151 pos = url.Length();
f4ada568 152
856d2e52
GL
153 if (pos == 0)
154 return FALSE;
155
156 temp_url = url(0, pos);
157 url = url(url.Find('/'), url.Length());
158
159 // Retrieve service number
160 pos2 = temp_url.Find(':', TRUE);
f4ada568 161 if (pos2 != -1 && pos2 < pos) {
375abe3d 162 m_servname = temp_url(pos2+1, pos);
f4ada568
GL
163 if (!m_servname.IsNumber())
164 return FALSE;
856d2e52 165 temp_url = temp_url(0, pos2);
f4ada568
GL
166 }
167
856d2e52
GL
168 // Retrieve user and password.
169 pos2 = temp_url.Find('@');
170 // Even if pos2 equals -1, this code is right.
171 m_hostname = temp_url(pos2+1, temp_url.Length());
f4ada568 172
856d2e52
GL
173 m_user = "";
174 m_password = "";
175
176 if (pos2 == -1)
177 return TRUE;
178
179 temp_url = temp_url(0, pos2);
180 pos2 = temp_url.Find(':');
181
182 if (pos2 == -1)
183 return FALSE;
184
185 m_user = temp_url(0, pos2);
186 m_password = temp_url(pos2+1, url.Length());
f4ada568
GL
187
188 return TRUE;
189}
190
191bool wxURL::PrepPath(wxString& url)
192{
193 if (url.Length() != 0)
194 m_path = url;
195 else
196 m_path = "/";
197 return TRUE;
198}
199
200bool wxURL::FetchProtocol()
201{
202 wxProtoInfo *info = g_protocols;
203
204 while (info) {
205 if (m_protoname == info->m_protoname) {
206 if (m_servname.IsNull())
207 m_servname = info->m_servname;
208
209 m_protoinfo = info;
210 m_protocol = (wxProtocol *)m_protoinfo->m_cinfo->CreateObject();
f4ada568
GL
211 return TRUE;
212 }
213 info = info->next;
214 }
215 return FALSE;
216}
217
fae05df5
GL
218// --------------------------------------------------------------
219// --------- wxURL get ------------------------------------------
220// --------------------------------------------------------------
221
f4ada568
GL
222wxInputStream *wxURL::GetInputStream(void)
223{
224 wxIPV4address addr;
225 wxInputStream *the_i_stream = NULL;
226
227 if (!m_protocol)
228 if (!ParseURL())
229 return NULL;
230
231 if (!m_protocol) {
232 m_error = wxURL_NOPROTO;
233 return NULL;
234 }
235
236 m_error = wxURL_NOERR;
00421206 237 if (m_user != _T("")) {
856d2e52
GL
238 m_protocol->SetUser(m_user);
239 m_protocol->SetPassword(m_password);
240 }
241
f4ada568
GL
242 if (m_protoinfo->m_needhost) {
243 if (!addr.Hostname(m_hostname)) {
244 m_error = wxURL_NOHOST;
245 return NULL;
246 }
247
248 addr.Service(m_servname);
249
8a2c6ef8
JS
250 if (!m_protocol->Connect(addr, TRUE)) // Watcom needs the 2nd arg for some reason
251 {
f4ada568
GL
252 m_error = wxURL_CONNERR;
253 return NULL;
254 }
255 }
256
257 the_i_stream = m_protocol->GetInputStream(m_path);
258 if (!the_i_stream) {
259 m_error = wxURL_PROTOERR;
260 return NULL;
261 }
262
263 return the_i_stream;
264}
265
266void wxURL::SetDefaultProxy(const wxString& url_proxy)
267{
3b4183d8 268 g_proxy->Close();
f4ada568
GL
269
270 if (url_proxy.IsNull())
271 return;
272
273 wxString tmp_str = url_proxy;
274 int pos = tmp_str.Find(':');
275 wxString hostname = tmp_str(0, pos),
276 port = tmp_str(pos, tmp_str.Length()-pos);
277 wxIPV4address addr;
278
279 addr.Hostname(hostname);
280 addr.Service(port);
281
8a2c6ef8 282 g_proxy->Connect(addr, TRUE); // Watcom needs the 2nd arg for some reason
f4ada568
GL
283}
284
285void wxURL::SetProxy(const wxString& url_proxy)
286{
287 if (url_proxy.IsNull()) {
288 m_proxy.Close();
289 return;
290 }
291
292 CleanData();
293
294 wxString tmp_str;
295 wxString hostname, port;
296 int pos;
297 wxIPV4address addr;
298
299 tmp_str = url_proxy;
300 pos = tmp_str.Find(':');
301 hostname = tmp_str(0, pos);
302 port = tmp_str(pos, tmp_str.Length()-pos);
303
304 addr.Hostname(hostname);
305 addr.Service(port);
306
8a2c6ef8 307 m_proxy.Connect(addr, TRUE); // Watcom needs the 2nd arg for some reason
f4ada568
GL
308
309 m_protocol = &m_proxy;
310 m_protoname = "proxy";
311 m_path = url_proxy;
312}
35a4dab7 313
14906731
GL
314wxString wxURL::ConvertToValidURI(const wxString& uri)
315{
fae05df5
GL
316 wxString out_str;
317 wxString hexa_code;
318 size_t i;
319
320 for (i=0;i<uri.Len();i++) {
321 wxChar c = uri.GetChar(i);
322
5a96d2f4
GL
323 if (c == _T(' '))
324 out_str += _T('+');
325 else {
326 if (!isalpha(c) && c != _T('.') && c != _T('+') && c != _T('.') &&
327 c != _T('/')) {
328 hexa_code.Printf(_T("%%%02X"), c);
329 out_str += hexa_code;
330 } else
331 out_str += c;
332 }
fae05df5
GL
333 }
334
335 return out_str;
14906731
GL
336}
337
35a4dab7
GL
338#endif
339 // wxUSE_SOCKETS