00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "wvurl.h"
00011 #include "strutils.h"
00012
00013
00014 struct DefaultPort
00015 {
00016 const char *proto;
00017 int port;
00018 bool uses_slashes;
00019 };
00020
00021
00022
00023 static DefaultPort portmap[] = {
00024 { "exchangeits", 7070, false },
00025 { "exchangeit", 6969, false },
00026 { "https", 443, true },
00027 { "http", 80, true },
00028 { "file", 0, true },
00029 { "sip", 5060, false },
00030 { "ftp", 21, true },
00031 { NULL, 0 }
00032 };
00033
00034
00035 static int get_default_port(WvString proto)
00036 {
00037 DefaultPort *p = portmap;
00038 for (p = portmap; p->proto != NULL; p++)
00039 {
00040 if (strncmp(p->proto, proto, strlen(p->proto)) == 0)
00041 return p->port;
00042 }
00043 return -1;
00044 }
00045
00046
00047
00048
00049 static bool protocol_uses_slashes(WvString proto)
00050 {
00051 DefaultPort *p = portmap;
00052 for (p = portmap; p->proto != NULL; p++)
00053 {
00054 if (strncmp(p->proto, proto, strlen(p->proto)) == 0)
00055 return p->uses_slashes;
00056 }
00057 return false;
00058 }
00059
00060
00061 WvUrl::WvUrl(WvStringParm url) : err("No error")
00062 {
00063 WvString work(url);
00064 char *cptr, *wptr = work.edit();
00065
00066 port = 0;
00067 addr = NULL;
00068 resolving = true;
00069
00070
00071 wptr = trim_string(wptr);
00072 cptr = wptr + strcspn(wptr, " \t\r\n");
00073 *cptr = 0;
00074
00075
00076
00077 if (get_default_port(wptr) < 0)
00078 {
00079 err = "WvUrl cannot handle the given protocol.";
00080 return;
00081 }
00082
00083 cptr = strchr(wptr, ':');
00084 if (!cptr)
00085 {
00086 err = "No colon after the protocol.";
00087 return;
00088 }
00089 *cptr = 0;
00090 proto = wptr;
00091
00092 bool use_slashes = protocol_uses_slashes(proto);
00093 wptr = cptr + (use_slashes ? 3 : 1);
00094
00095 cptr = strchr(wptr, '@');
00096 if (!cptr)
00097 {
00098 user = "";
00099 password = "";
00100 }
00101 else
00102 {
00103 *cptr = 0;
00104 char *cptr2 = strchr(wptr, ':');
00105 if (cptr2 && (*(cptr2+1) != 0))
00106 {
00107 *cptr2 = 0;
00108 password = cptr2 + 1;
00109 }
00110 else
00111 password = "";
00112 user = wptr;
00113 wptr = cptr + 1;
00114 }
00115
00116 cptr = strchr(wptr, '/');
00117 if (!cptr)
00118 file = use_slashes ? "/" : "";
00119 else
00120 {
00121 file = cptr;
00122 *cptr = 0;
00123 }
00124
00125 cptr = strchr(wptr, ':');
00126 if (!cptr)
00127 port = get_default_port(proto);
00128 else
00129 {
00130 port = atoi(cptr+1);
00131 *cptr = 0;
00132 }
00133
00134 hostname = wptr;
00135
00136 resolve();
00137 }
00138
00139
00140 WvUrl::WvUrl(const WvUrl &url) : err("No error")
00141 {
00142 addr = NULL;
00143 resolving = true;
00144
00145 proto = url.proto;
00146 user = url.user;
00147 password = url.password;
00148 hostname = url.hostname;
00149 file = url.file;
00150 port = url.port;
00151
00152 resolve();
00153 }
00154
00155
00156 WvUrl::~WvUrl()
00157 {
00158 if (addr) delete addr;
00159 }
00160
00161
00162 bool WvUrl::resolve()
00163 {
00164 const WvIPAddr *ip;
00165 int numaddrs;
00166
00167 numaddrs = dns.findaddr(0, hostname, &ip);
00168 if (!numaddrs)
00169 {
00170 err = WvString("Host '%s' could not be found.", hostname);
00171 resolving = false;
00172 return false;
00173 }
00174 else if (numaddrs < 0)
00175 {
00176 resolving = true;
00177 return false;
00178 }
00179 else
00180 {
00181 resolving = false;
00182 if (addr) delete addr;
00183 addr = new WvIPPortAddr(*ip, port);
00184 return true;
00185 }
00186 }
00187
00188
00189
00190
00191 WvUrl::operator WvString () const
00192 {
00193 if (!isok())
00194 return WvString("(Invalid URL: %s)", err);
00195
00196 WvString protostr;
00197 if (protocol_uses_slashes(proto))
00198 protostr = WvString("%s://", proto);
00199 else
00200 protostr = WvString("%s:", proto);
00201 WvString userstr("");
00202 if (user && user.len() != 0)
00203 {
00204 userstr = WvString("%s", user);
00205 if (password && password.len() != 0)
00206 userstr.append(WvString(":%s@", password));
00207 else
00208 userstr.append("@");
00209 }
00210 WvString portstr("");
00211 if (port && port != get_default_port(proto))
00212 portstr = WvString(":%s", port);
00213 if (hostname)
00214 return WvString("%s%s%s%s%s", protostr, userstr, hostname, portstr, file);
00215 else if (addr)
00216 return WvString("%s%s%s%s%s", protostr, userstr, *addr, portstr, file);
00217 else
00218 {
00219 assert(0);
00220 return WvString("(Invalid URL)");
00221 }
00222 }
00223
00224