// 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 "url.h" #if defined(_WIN32) && !defined(__STDWX_H__) #include "boinc_win.h" #elif defined(_WIN32) && defined(__STDWX_H__) #include "stdwx.h" #else #include "config.h" #include #include #include #include #include #endif #include "str_util.h" #include "str_replace.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