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