⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 url.cpp

📁 彩信浏览器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// This file is part of Ambulant Player, www.ambulantplayer.org.//// Copyright (C) 2003-2007 Stichting CWI, // Kruislaan 413, 1098 SJ Amsterdam, The Netherlands.//// Ambulant Player 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 2.1 of the License, or// (at your option) any later version.//// Ambulant Player 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 Ambulant Player; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA/*  * @$Id: url.cpp,v 1.72.2.1 2007/02/20 16:25:35 jackjansen Exp $  */#ifndef AM_DBG#define AM_DBG if(0)#endif#include "ambulant/net/url.h"#include "ambulant/lib/logger.h"#include "ambulant/lib/string_util.h"#include "ambulant/lib/filesys.h"#include "ambulant/lib/textptr.h"#include <string>#if !defined(AMBULANT_NO_IOSTREAMS) && !defined(AMBULANT_NO_STRINGSTREAM)#include <sstream>#endifusing namespace ambulant;bool ambulant::net::url::s_strict = false;const std::string url_delim = ":/?#,";// Characters to be escaped in pathnames. Note that ~ and ? have special meanings in// http: urls, but not specifically in file: urls.const std::string file_url_escape_reqd = " <>{}|\\^[]`";const std::string file_url_escape = file_url_escape_reqd + "%";const std::string file_url_escape_frag = file_url_escape + "#";//// Helper routines to convert local file pathnames to url-style paths// and vice-versa//#ifdef AMBULANT_PLATFORM_WIN32#include "ambulant/lib/win32/win32_error.h"#include <wininet.h>static std::stringfilepath2urlpath(const std::string& fparg, bool handle_frag=false){	std::string filepath = fparg;	size_t urlbufsize = filepath.size()*3+7; // Worst case: all characters escaped	LPTSTR urlbuf = (LPTSTR)malloc(urlbufsize*sizeof(TCHAR));	DWORD urlbufsizearg = (DWORD)urlbufsize;	assert(urlbuf);	urlbuf[0] = 0;	std::string fragment;	if (handle_frag) {		// Unfortunately passing ICU_BROWSER_MODE to ICU doesn't work:-(		// Remove the fragment by hand, re-apply it later.		size_t fragpos = filepath.find('#');		if (fragpos != std::string::npos) {			fragment = filepath.substr(fragpos);			filepath = filepath.substr(0, fragpos);		}	}	if (!InternetCanonicalizeUrl(lib::textptr(filepath.c_str()), urlbuf, &urlbufsizearg, 0)) {		DWORD dw = GetLastError();		lib::win32::win_report_error(filepath.c_str(), dw);		urlbuf[0] = 0;	}	std::string rv = lib::textptr(urlbuf);	// Work around stupid bug in InternetCanonicalizeURL: it forgets a slash.	if (rv.substr(0, 7) == "file://" && rv[7] != '/')		rv = "file:///" + rv.substr(7);	// Now replace backslashes and turn everything into lower case	std::string::iterator i;	for(i=rv.begin(); i!=rv.end(); i++) {		char c = *i;		if (c == '\\') 			*i = '/';		else			*i = tolower(c);	}	free(urlbuf);	// Finally re-apply the fragment id, if there is one	if (fragment != "") {		rv = rv + fragment;	}	return rv;}static std::stringurlpath2filepath(const std::string& urlpath){	size_t filebufsize = urlpath.size()+1;	LPTSTR filebuf = (LPTSTR)malloc(filebufsize*sizeof(TCHAR));	DWORD filebufsizearg = (DWORD)filebufsize;	assert(filebuf);	filebuf[0] = 0;	lib::textptr tp(urlpath.c_str());	if (!InternetCanonicalizeUrl(tp, filebuf, 			&filebufsizearg, ICU_DECODE | ICU_NO_ENCODE)) {		DWORD dw = GetLastError();		lib::win32::win_report_error(urlpath.c_str(), dw);		filebuf[0] = 0;	}	std::string rv = lib::textptr(filebuf);	// Work around stupid bug in InternetCanonicalizeURL: it forgets a slash.	if (rv.substr(0, 8) == "file:///")		rv = rv.substr(8);	else if (rv[0] == '/' && rv[2] == ':')		rv = rv.substr(1);	// Finally replace slashes by backslashes	std::string::iterator i;	for(i=rv.begin(); i!=rv.end(); i++) {		char c = *i;		if (c == '/') 			*i = '\\';	}	free(filebuf);	return rv;}#else// Unix implementationstatic std::stringfilepath2urlpath(const std::string& filepath, bool handle_frag=false){	std::string::const_iterator i;	std::string rv;	const std::string *esc = &file_url_escape;	if (handle_frag) esc = &file_url_escape_frag;	for(i=filepath.begin(); i!=filepath.end(); i++) {		char c = *i;		if ( esc->find(c) != std::string::npos ) {			char buf[4];			sprintf(buf, "%%%02.2x", (unsigned)c);			rv += buf;		} else {			rv += c;		}	}	return rv;}static std::stringurlpath2filepath(const std::string& urlpath){	std::string::const_iterator i;	std::string rv;	for(i=urlpath.begin(); i!=urlpath.end(); i++) {		char c = *i;		if ( c == '%' ) {			char buf[3];			unsigned utfval;			buf[0] = *++i;			buf[1] = *++i;			buf[2] = '\0';			if (sscanf(buf, "%x", &utfval) == 1) {				rv += (char)utfval;			} else {				// Put the original string back. What else can we do...				rv += '%';				rv += buf;			}		} else {			rv += c;		}	}	return rv;}#endif // AMBULANT_PLATFORM_WIN32/* static data and helper functions for URI %-en/decoding( RFC3986) */std::string hex_digits("0123456789ABCDEFabcdef");std::string gen_delims(":/?#[]@");std::string sub_delims("!$&'()*+,;=");std::string reserved(gen_delims+sub_delims);std::string unreserved(hex_digits+"GHIJKLMNOPQRSTUVWXYZghijklmnopqrstuvwxyz-._~");static boolis_hex (std::string& s) {	for (size_t i = 0; i < s.size(); i++) {		if (hex_digits.find(s[i]) == std::string::npos)			return false;	}	return true;}static std::stringuint2hex (unsigned int val) {	std::string rv = "";	unsigned int v = val;	if (v == 0) rv += '0';	do {		unsigned int pos = v&0xf; // get rightmost 4 bits		rv.insert(0, hex_digits,pos,1);		v >>= 4;	} while (v != 0);	if (rv.size() < 2) // ensure at least 2 chars		rv.insert(0, "0");	return (rv);}static unsigned inthex2uint (std::string& s) {	unsigned int rv = 0;		for (size_t i = 0; i < s.size(); i++) {		char c = s[i];		rv *= 16;		unsigned int pos = (unsigned int) hex_digits.find(c);		if (pos == std::string::npos) // not found, terminate			break;		if (pos >= 16) // lowercase a-f			pos -= 6;		rv += pos; // position in hex_digits is value of char	}	return (rv);}static boolis_reserved (unsigned int c) {	const char cc = c;	std::string s(1,cc);	if (s.find_first_of(reserved) == std::string::npos)		return false;	return true;}static boolis_unreserved (unsigned int c) {	const char cc = c;	std::string s(1,cc);		if (s.find_first_of(unreserved) == std::string::npos)		return false;	return true;}static std::stringuri2string(const std::string uri) {	std::string rv = "";	std::string s  = uri;	size_t pos;	while ((pos = s.substr().find("%")) != std::string::npos 	       && (pos < s.size()-2)) {		// pick next 2 characters		std::string hex_chars = s.substr(pos+1,2);		rv += s.substr(0,pos);		if (is_hex(hex_chars))			rv += hex2uint(hex_chars);		else  {			rv += "%"; // '%' not followed by 2 hex digits;			pos -= 2;  // continue next char after '%'		}		s = s.substr(pos+3); // skip "%xx"	}	rv += s; // concat tail	return rv;}static std::stringstring2uri(const std::string str) {	std::string rv = "";		for (size_t i = 0; i < str.size(); i++) {		unsigned char c = str[i];		if (is_reserved(c) || is_unreserved(c)) {			rv += c;		} else if (c == '%') {			if (i < str.size()-2) {				// pick next 2 characters				std::string ss = str.substr(i+1,2);				if (is_hex(ss)) {					unsigned int hc = hex2uint(ss);					if (is_unreserved(hc)) {					// convert unreserved %xx to char				 	        rv += hc;						i +=2 ;						continue;					}				}			}			rv += c;		} else { // convert to '%' followed by 2 hex digits			rv += '%';			rv += uint2hex(c);		}	}	return rv;}// static //std::list< std::pair<std::string, net::url::HANDLER> > net::url::s_handlers;// workaround for g++ 2.95std::list< net::url_handler_pair* > s_handlers;// staticvoid net::url::init_statics() {	// workaround for g++ 2.95	static url_handler_pair h1 = {"n://n:d/", &url::set_from_host_port_uri};	s_handlers.push_back(&h1);		static url_handler_pair h1a = {"n://n:d", &url::set_from_host_port_uri};	s_handlers.push_back(&h1a);		static url_handler_pair h1b = {"n://dn:d/", &url::set_from_numhost_port_uri};	s_handlers.push_back(&h1b);		static url_handler_pair h1c = {"n://dn:d", &url::set_from_numhost_port_uri};	s_handlers.push_back(&h1c);		static url_handler_pair h2 = {"n://n/", &url::set_from_host_uri};	s_handlers.push_back(&h2);		static url_handler_pair h2a = {"n://n", &url::set_from_host_uri};	s_handlers.push_back(&h2a);		static url_handler_pair h2b= {"n://dn/", &url::set_from_numhost_uri};	s_handlers.push_back(&h2b);		static url_handler_pair h2c = {"n://dn", &url::set_from_numhost_uri};	s_handlers.push_back(&h2c);		static url_handler_pair h3 = { "n:///", &url::set_from_localhost_file_uri};	s_handlers.push_back(&h3);	static url_handler_pair h4a = { "n:,", &url::set_from_data_uri};	s_handlers.push_back(&h4a);	static url_handler_pair h4b = { "n:n,", &url::set_from_data_uri};	s_handlers.push_back(&h4b);	static url_handler_pair h4c = { "n:n/n,", &url::set_from_data_uri};	s_handlers.push_back(&h4c);	static url_handler_pair h5 = {"/n", &url::set_from_absolute_path};	s_handlers.push_back(&h5);		static url_handler_pair h6 = {"n:", &url::set_from_scheme};	s_handlers.push_back(&h6);		static url_handler_pair h9 = {"", &url::set_from_relative_path};	s_handlers.push_back(&h9);		/*	typedef std::pair<std::string, HANDLER> pair;	s_handlers.push_back(pair("n://n:n/",&url::set_from_host_port_uri));	s_handlers.push_back(pair("n://n/",&url::set_from_host_uri));	s_handlers.push_back(pair("n:///",&url::set_from_localhost_file_uri));	s_handlers.push_back(pair("/n",&url::set_from_unix_path));	s_handlers.push_back(pair("n:n",&url::set_from_windows_path));	s_handlers.push_back(pair("n:/n",&url::set_from_windows_path));	*/ } // staticAMBULANTAPI net::url net::url::from_filename(const std::string& spec, bool handle_frag){	return net::url(filepath2urlpath(spec, handle_frag));}// staticAMBULANTAPI net::urlnet::url::from_filename(const char *spec, bool handle_frag){	return net::url(filepath2urlpath(spec, handle_frag));}// Private: check URL for character escapingvoid net::url::_checkurl() const{#if 0	// This is no longer valid, because escape-processing has been done on m_path	if (m_path.find_first_of(file_url_escape_reqd) != std::string::npos)		lib::logger::get_logger()->warn("%s: URL contains illegal characters", get_url().c_str());#endif}net::url::url() :	m_absolute(true),	m_port(0){} net::url::url(const string& spec) :	m_port(0){	set_from_spec(spec);}	 net::url::url(const string& protocol, const string& host, 	const string& path) :	m_protocol(protocol),	m_host(host),	m_port(0),	m_path(path){	m_absolute = (m_protocol != "");	if (s_strict) _checkurl();}net::url::url(const string& protocol, const string& host, int port, 	const string& path) 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -