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(
"@");
00208 }
00209 WvString portstr(
"");
00210
if (
port &&
port !=
get_default_port(
proto))
00211 portstr = WvString(
":%s",
port);
00212
if (
hostname)
00213
return WvString(
"%s%s%s%s%s", protostr, userstr,
hostname, portstr,
file);
00214
else if (
addr)
00215
return WvString(
"%s%s%s%s%s", protostr, userstr, *
addr, portstr,
file);
00216
else
00217 {
00218 assert(0);
00219
return WvString(
"(Invalid URL)");
00220 }
00221 }
00222
00223