* Added wxsocket lib and sample (I hope I don't forget some file)
[wxWidgets.git] / src / common / url.cpp
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
15 #include <string.h>
16 #include <ctype.h>
17
18 // wxWindows headers
19 #include <wx/string.h>
20 #include <wx/list.h>
21 #include <wx/utils.h>
22
23 // wxSocket header
24 #include "wx/url.h"
25
26 #ifdef __BORLANDC__
27 #pragma hdrstop
28 #endif
29
30 #if !USE_SHARED_LIBRARY
31 IMPLEMENT_CLASS(wxProtoInfo, wxObject)
32 IMPLEMENT_CLASS(wxURL, wxObject)
33 #endif
34
35 // Protocols list
36 wxProtoInfo *wxURL::g_protocols = NULL;
37 wxHTTP wxURL::g_proxy;
38
39 /////////////////////////////////////////////////////////////////
40 // wxURL ////////////////////////////////////////////////////////
41 /////////////////////////////////////////////////////////////////
42
43 /*
44 * --------------------------------------------------------------
45 * --------- wxURL CONSTRUCTOR DESTRUCTOR -----------------------
46 * --------------------------------------------------------------
47 */
48
49 wxURL::wxURL(const wxString& url)
50 {
51 m_protocol = NULL;
52 if (g_proxy.IsConnected()) {
53 m_protocol = &g_proxy;
54 m_protoname = "proxy";
55 m_path = url;
56 return;
57 }
58 m_url = url;
59 m_error = wxURL_NOERR;
60 }
61
62 bool wxURL::ParseURL()
63 {
64 wxString last_url = m_url;
65
66 // Clean up
67 CleanData();
68
69 // Extract protocol name
70 if (!PrepProto(last_url)) {
71 m_error = wxURL_SNTXERR;
72 return FALSE;
73 }
74
75 // Find and create the protocol object
76 if (!FetchProtocol()) {
77 m_error = wxURL_NOPROTO;
78 return FALSE;
79 }
80
81 // Do we need a host name ?
82 if (m_protoinfo->m_needhost) {
83 // Extract it
84 if (!PrepHost(last_url)) {
85 m_error = wxURL_SNTXERR;
86 return FALSE;
87 }
88 }
89
90 // Extract full path
91 if (!PrepPath(last_url)) {
92 m_error = wxURL_NOPATH;
93 return FALSE;
94 }
95
96 m_error = wxURL_NOERR;
97 return TRUE;
98 }
99
100 void wxURL::CleanData()
101 {
102 if (m_protoname != "proxy")
103 delete m_protocol;
104 }
105
106 wxURL::~wxURL()
107 {
108 CleanData();
109 }
110
111 /*
112 * --------------------------------------------------------------
113 * --------- wxURL urls decoders --------------------------------
114 * --------------------------------------------------------------
115 */
116 bool wxURL::PrepProto(wxString& url)
117 {
118 int pos;
119
120 // Find end
121 pos = url.Find(':');
122 if (pos == -1)
123 return FALSE;
124
125 m_protoname = url(0, pos);
126
127 url = url(pos+1, url.Length());
128
129 return TRUE;
130 }
131
132 bool wxURL::PrepHost(wxString& url)
133 {
134 int pos, pos2;
135
136 if ((url[0UL] != '/') || (url[1UL] != '/'))
137 return FALSE;
138
139 url = url(2, url.Length());
140
141 pos = url.Find('/');
142 if (pos == -1)
143 return FALSE;
144
145 pos2 = url.Find(':');
146 if (pos2 != -1 && pos2 < pos) {
147 m_servname = url(pos2, pos);
148 if (!m_servname.IsNumber())
149 return FALSE;
150 pos2 = pos;
151 }
152
153 m_hostname = url(0, pos);
154
155 url = url(url.Find('/'), url.Length());
156
157 return TRUE;
158 }
159
160 bool wxURL::PrepPath(wxString& url)
161 {
162 if (url.Length() != 0)
163 m_path = url;
164 else
165 m_path = "/";
166 return TRUE;
167 }
168
169 bool wxURL::FetchProtocol()
170 {
171 wxProtoInfo *info = g_protocols;
172
173 while (info) {
174 if (m_protoname == info->m_protoname) {
175 if (m_servname.IsNull())
176 m_servname = info->m_servname;
177
178 m_protoinfo = info;
179 m_protocol = (wxProtocol *)m_protoinfo->m_cinfo->CreateObject();
180 wxSocketHandler::Master().Register(m_protocol);
181 return TRUE;
182 }
183 info = info->next;
184 }
185 return FALSE;
186 }
187
188 /*
189 * --------------------------------------------------------------
190 * --------- wxURL get ------------------------------------------
191 * --------------------------------------------------------------
192 */
193 wxInputStream *wxURL::GetInputStream(void)
194 {
195 wxIPV4address addr;
196 wxInputStream *the_i_stream = NULL;
197
198 if (!m_protocol)
199 if (!ParseURL())
200 return NULL;
201
202 if (!m_protocol) {
203 m_error = wxURL_NOPROTO;
204 return NULL;
205 }
206
207 m_error = wxURL_NOERR;
208 if (m_protoinfo->m_needhost) {
209 if (!addr.Hostname(m_hostname)) {
210 m_error = wxURL_NOHOST;
211 return NULL;
212 }
213
214 addr.Service(m_servname);
215
216 if (!m_protocol->Connect(addr)) {
217 m_error = wxURL_CONNERR;
218 return NULL;
219 }
220 }
221
222 the_i_stream = m_protocol->GetInputStream(m_path);
223 if (!the_i_stream) {
224 m_error = wxURL_PROTOERR;
225 return NULL;
226 }
227
228 return the_i_stream;
229 }
230
231 void wxURL::SetDefaultProxy(const wxString& url_proxy)
232 {
233 g_proxy.Close();
234
235 if (url_proxy.IsNull())
236 return;
237
238 wxString tmp_str = url_proxy;
239 int pos = tmp_str.Find(':');
240 wxString hostname = tmp_str(0, pos),
241 port = tmp_str(pos, tmp_str.Length()-pos);
242 wxIPV4address addr;
243
244 addr.Hostname(hostname);
245 addr.Service(port);
246
247 g_proxy.Connect(addr);
248 }
249
250 void wxURL::SetProxy(const wxString& url_proxy)
251 {
252 if (url_proxy.IsNull()) {
253 m_proxy.Close();
254 return;
255 }
256
257 CleanData();
258
259 wxString tmp_str;
260 wxString hostname, port;
261 int pos;
262 wxIPV4address addr;
263
264 tmp_str = url_proxy;
265 pos = tmp_str.Find(':');
266 hostname = tmp_str(0, pos);
267 port = tmp_str(pos, tmp_str.Length()-pos);
268
269 addr.Hostname(hostname);
270 addr.Service(port);
271
272 m_proxy.Connect(addr);
273
274 m_protocol = &m_proxy;
275 m_protoname = "proxy";
276 m_path = url_proxy;
277 }