// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2009 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see .
#include
#include
#include
#include
#include "str_util.h"
#include "str_replace.h"
#include "url.h"
using std::string;
// Break a URL down into its protocol, server, port and file components
// URL format:
// [{http|https|socks}://][user[:passwd]@]host.dom.dom[:port][/dir/file]
//
void parse_url(const char* url, PARSED_URL& purl) {
char* p, *q, *buf;
char _buf[256];
// strip off the protocol if present
//
if (strncmp(url, "http://", 7) == 0) {
safe_strcpy(_buf, url+7);
purl.protocol = URL_PROTOCOL_HTTP;
} else if (strncmp(url, "https://", 8) == 0) {
safe_strcpy(_buf, url+8);
purl.protocol = URL_PROTOCOL_HTTPS;
} else if (strncmp(url, "socks://", 8) == 0) {
safe_strcpy(_buf, url+8);
purl.protocol = URL_PROTOCOL_SOCKS;
} else {
safe_strcpy(_buf, url);
purl.protocol = URL_PROTOCOL_UNKNOWN;
}
buf = _buf;
// parse user name and password
//
strcpy(purl.user, "");
strcpy(purl.passwd, "");
p = strchr(buf, '@');
if (p) {
*p = 0;
q = strchr(buf, ':');
if (q) {
*q = 0;
strcpy(purl.user, buf);
strcpy(purl.passwd, q+1);
} else {
strcpy(purl.user, buf);
}
buf = p+1;
}
// parse and strip off file part if present
//
p = strchr(buf, '/');
if (p) {
strcpy(purl.file, p+1);
*p = 0;
} else {
strcpy(purl.file, "");
}
// parse and strip off port if present
//
p = strchr(buf,':');
if (p) {
purl.port = atol(p+1);
*p = 0;
} else {
// CMC note: if they didn't pass in a port #,
// but the url starts with https://, assume they
// want a secure port (HTTPS, port 443)
purl.port = (purl.protocol == URL_PROTOCOL_HTTPS) ? 443 : 80;
}
// what remains is the host
//
strcpy(purl.host, buf);
}
static char x2c(char *what) {
register char digit;
digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
digit *= 16;
digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
return(digit);
}
void c2x(char *what) {
char buf[3];
char num = atoi(what);
char d1 = num / 16;
char d2 = num % 16;
int abase1, abase2;
if (d1 < 10) abase1 = 48;
else abase1 = 55;
if (d2 < 10) abase2 = 48;
else abase2 = 55;
buf[0] = d1+abase1;
buf[1] = d2+abase2;
buf[2] = 0;
strcpy(what, buf);
}
void unescape_url(char *url) {
int x,y;
for (x=0,y=0;url[y];++x,++y) {
if ((url[x] = url[y]) == '%') {
url[x] = x2c(&url[y+1]);
y+=2;
}
}
url[x] = '\0';
}
void unescape_url_safe(char *url, int url_size) {
int x,y;
for (x=0,y=0; url[y] && (x