]> git.saurik.com Git - wxWidgets.git/blame - src/common/url.cpp
MIME support
[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
GL
47
48/////////////////////////////////////////////////////////////////
49// wxURL ////////////////////////////////////////////////////////
50/////////////////////////////////////////////////////////////////
51
52/*
53 * --------------------------------------------------------------
54 * --------- wxURL CONSTRUCTOR DESTRUCTOR -----------------------
55 * --------------------------------------------------------------
56 */
57
58wxURL::wxURL(const wxString& url)
59{
60 m_protocol = NULL;
3b4183d8
GL
61 if (g_proxy->IsConnected()) {
62 m_protocol = g_proxy;
f4ada568
GL
63 m_protoname = "proxy";
64 m_path = url;
65 return;
66 }
67 m_url = url;
68 m_error = wxURL_NOERR;
41895a05 69 ParseURL();
f4ada568
GL
70}
71
72bool wxURL::ParseURL()
73{
74 wxString last_url = m_url;
75
76 // Clean up
77 CleanData();
78
79 // Extract protocol name
80 if (!PrepProto(last_url)) {
81 m_error = wxURL_SNTXERR;
82 return FALSE;
83 }
84
85 // Find and create the protocol object
86 if (!FetchProtocol()) {
87 m_error = wxURL_NOPROTO;
88 return FALSE;
89 }
90
91 // Do we need a host name ?
92 if (m_protoinfo->m_needhost) {
93 // Extract it
94 if (!PrepHost(last_url)) {
95 m_error = wxURL_SNTXERR;
96 return FALSE;
97 }
98 }
99
100 // Extract full path
101 if (!PrepPath(last_url)) {
102 m_error = wxURL_NOPATH;
103 return FALSE;
104 }
105
106 m_error = wxURL_NOERR;
107 return TRUE;
108}
109
110void wxURL::CleanData()
111{
112 if (m_protoname != "proxy")
113 delete m_protocol;
114}
115
116wxURL::~wxURL()
117{
118 CleanData();
119}
120
121/*
122 * --------------------------------------------------------------
123 * --------- wxURL urls decoders --------------------------------
124 * --------------------------------------------------------------
125 */
126bool wxURL::PrepProto(wxString& url)
127{
128 int pos;
129
130 // Find end
131 pos = url.Find(':');
132 if (pos == -1)
133 return FALSE;
134
135 m_protoname = url(0, pos);
136
137 url = url(pos+1, url.Length());
138
139 return TRUE;
140}
141
142bool wxURL::PrepHost(wxString& url)
143{
856d2e52 144 wxString temp_url;
f4ada568
GL
145 int pos, pos2;
146
fcc6dddd 147 if ((url.GetChar(0) != '/') || (url.GetChar(1) != '/'))
f4ada568
GL
148 return FALSE;
149
150 url = url(2, url.Length());
151
152 pos = url.Find('/');
153 if (pos == -1)
b7db6f0b 154 pos = url.Length();
f4ada568 155
856d2e52
GL
156 if (pos == 0)
157 return FALSE;
158
159 temp_url = url(0, pos);
160 url = url(url.Find('/'), url.Length());
161
162 // Retrieve service number
163 pos2 = temp_url.Find(':', TRUE);
f4ada568 164 if (pos2 != -1 && pos2 < pos) {
375abe3d 165 m_servname = temp_url(pos2+1, pos);
f4ada568
GL
166 if (!m_servname.IsNumber())
167 return FALSE;
856d2e52 168 temp_url = temp_url(0, pos2);
f4ada568
GL
169 }
170
856d2e52
GL
171 // Retrieve user and password.
172 pos2 = temp_url.Find('@');
173 // Even if pos2 equals -1, this code is right.
174 m_hostname = temp_url(pos2+1, temp_url.Length());
f4ada568 175
856d2e52
GL
176 m_user = "";
177 m_password = "";
178
179 if (pos2 == -1)
180 return TRUE;
181
182 temp_url = temp_url(0, pos2);
183 pos2 = temp_url.Find(':');
184
185 if (pos2 == -1)
186 return FALSE;
187
188 m_user = temp_url(0, pos2);
189 m_password = temp_url(pos2+1, url.Length());
f4ada568
GL
190
191 return TRUE;
192}
193
194bool wxURL::PrepPath(wxString& url)
195{
196 if (url.Length() != 0)
197 m_path = url;
198 else
199 m_path = "/";
200 return TRUE;
201}
202
203bool wxURL::FetchProtocol()
204{
205 wxProtoInfo *info = g_protocols;
206
207 while (info) {
208 if (m_protoname == info->m_protoname) {
209 if (m_servname.IsNull())
210 m_servname = info->m_servname;
211
212 m_protoinfo = info;
213 m_protocol = (wxProtocol *)m_protoinfo->m_cinfo->CreateObject();
214 wxSocketHandler::Master().Register(m_protocol);
215 return TRUE;
216 }
217 info = info->next;
218 }
219 return FALSE;
220}
221
222/*
223 * --------------------------------------------------------------
224 * --------- wxURL get ------------------------------------------
225 * --------------------------------------------------------------
226 */
227wxInputStream *wxURL::GetInputStream(void)
228{
229 wxIPV4address addr;
230 wxInputStream *the_i_stream = NULL;
231
232 if (!m_protocol)
233 if (!ParseURL())
234 return NULL;
235
236 if (!m_protocol) {
237 m_error = wxURL_NOPROTO;
238 return NULL;
239 }
240
241 m_error = wxURL_NOERR;
856d2e52
GL
242 if (m_user != "") {
243 m_protocol->SetUser(m_user);
244 m_protocol->SetPassword(m_password);
245 }
246
f4ada568
GL
247 if (m_protoinfo->m_needhost) {
248 if (!addr.Hostname(m_hostname)) {
249 m_error = wxURL_NOHOST;
250 return NULL;
251 }
252
253 addr.Service(m_servname);
254
8a2c6ef8
JS
255 if (!m_protocol->Connect(addr, TRUE)) // Watcom needs the 2nd arg for some reason
256 {
f4ada568
GL
257 m_error = wxURL_CONNERR;
258 return NULL;
259 }
260 }
261
262 the_i_stream = m_protocol->GetInputStream(m_path);
263 if (!the_i_stream) {
264 m_error = wxURL_PROTOERR;
265 return NULL;
266 }
267
268 return the_i_stream;
269}
270
271void wxURL::SetDefaultProxy(const wxString& url_proxy)
272{
3b4183d8 273 g_proxy->Close();
f4ada568
GL
274
275 if (url_proxy.IsNull())
276 return;
277
278 wxString tmp_str = url_proxy;
279 int pos = tmp_str.Find(':');
280 wxString hostname = tmp_str(0, pos),
281 port = tmp_str(pos, tmp_str.Length()-pos);
282 wxIPV4address addr;
283
284 addr.Hostname(hostname);
285 addr.Service(port);
286
8a2c6ef8 287 g_proxy->Connect(addr, TRUE); // Watcom needs the 2nd arg for some reason
f4ada568
GL
288}
289
290void wxURL::SetProxy(const wxString& url_proxy)
291{
292 if (url_proxy.IsNull()) {
293 m_proxy.Close();
294 return;
295 }
296
297 CleanData();
298
299 wxString tmp_str;
300 wxString hostname, port;
301 int pos;
302 wxIPV4address addr;
303
304 tmp_str = url_proxy;
305 pos = tmp_str.Find(':');
306 hostname = tmp_str(0, pos);
307 port = tmp_str(pos, tmp_str.Length()-pos);
308
309 addr.Hostname(hostname);
310 addr.Service(port);
311
8a2c6ef8 312 m_proxy.Connect(addr, TRUE); // Watcom needs the 2nd arg for some reason
f4ada568
GL
313
314 m_protocol = &m_proxy;
315 m_protoname = "proxy";
316 m_path = url_proxy;
317}
35a4dab7
GL
318
319#endif
320 // wxUSE_SOCKETS