📄 url.cpp
字号:
: m_protocol(protocol), m_host(host), m_port(short_type(port)), 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, const string& query, const string& ref) : m_protocol(protocol), m_host(host), m_port(short_type(port)), m_path(path), m_query(query), m_ref(ref){ m_absolute = (m_protocol != ""); if (s_strict) _checkurl();} net::url::string net::url::get_file() const { std::string file = get_path(); // Workaround: we might have split a local file at the ?. if(!m_query.empty()) { file += '?'; file += m_query; } return urlpath2filepath(file);}void net::url::set_from_spec(const string& spec) { lib::scanner sc(spec, url_delim); sc.tokenize(); std::string sig = sc.get_tokens(); //std::list< std::pair<std::string, HANDLER> >::iterator it; std::list<url_handler_pair*>::iterator it; for(it=s_handlers.begin();it!=s_handlers.end();it++) { url_handler_pair *ph = (*it); if(*(ph->first) == '\0' || lib::starts_with(sig, ph->first)) { //HANDLER h = (*it).second; (this->*(ph->second))(sc, ph->first); m_path = uri2string(m_path); m_query = uri2string(m_query); m_ref = uri2string(m_ref); return; } } lib::logger::get_logger()->error(gettext("%s: Cannot parse URL"), spec.c_str()); }// pat: "n://n:d/"void net::url::set_from_host_port_uri(lib::scanner& sc, const std::string& pat) { m_absolute = true; m_protocol = sc.val_at(0); m_host = sc.val_at(4); m_port = short_type(atoi(sc.val_at(6).c_str())); set_parts(sc, pat);} // pat: "n://dn:d/"void net::url::set_from_numhost_port_uri(lib::scanner& sc, const std::string& pat) { m_absolute = true; m_protocol = sc.val_at(0); m_host = sc.join(4, 6); m_port = short_type(atoi(sc.val_at(7).c_str())); set_parts(sc, pat);} // pat: "n://n/"void net::url::set_from_host_uri(lib::scanner& sc, const std::string& pat) { m_absolute = true; m_protocol = sc.val_at(0); m_host = sc.val_at(4); set_parts(sc, pat); if(m_protocol == "http") m_port = 80; else if(m_protocol == "ftp") m_port = 21;}// pat: "n://dn/"void net::url::set_from_numhost_uri(lib::scanner& sc, const std::string& pat) { m_absolute = true; m_protocol = sc.val_at(0); m_host = sc.join(4, 6); set_parts(sc, pat); if(m_protocol == "http") m_port = 80; else if(m_protocol == "ftp") m_port = 21;}// pat: "n:///" for file:///void net::url::set_from_localhost_file_uri(lib::scanner& sc, const std::string& pat) { m_absolute = true; m_protocol = sc.val_at(0); m_host = "localhost"; m_port = 0; set_parts(sc, pat); // The initial / in the pathname has been eaten}// pat: "/n"void net::url::set_from_absolute_path(lib::scanner& sc, const std::string& pat) { m_absolute = true; m_protocol = "file"; m_host = "localhost"; m_port = 0; m_path = sc.get_src(); if (s_strict) _checkurl();}void net::url::set_from_relative_path(lib::scanner& sc, const std::string& pat) { m_absolute = false; m_protocol = ""; m_host = ""; m_port = 0; set_parts(sc, pat); AM_DBG lib::logger::get_logger()->debug("url::set_from_relative_path: \"%s\" -> \"%s\"", pat.c_str(), m_path.c_str());}// pat: "data:,"void net::url::set_from_data_uri(lib::scanner& sc, const std::string& pat) { m_absolute = true; m_protocol = "data"; m_host = ""; m_port = 0; size_type tok, n_tok = sc.get_values().size(); for (tok = 2; tok < n_tok; tok++) if (sc.val_at(tok) == ",") break; m_path = sc.join(++tok); // Skip data:[mimetype/subtype][;parameter], if (s_strict) _checkurl();}// pat: "scheme:,"void net::url::set_from_scheme(lib::scanner& sc, const std::string& pat) { m_absolute = true; m_protocol = sc.val_at(0); m_host = ""; m_port = 0; m_path = sc.join(2); // Skip scheme: // Unsure: should we do #fragment processing for unknown URLs? // initially I thought not, but the ambulantpdbt: scheme needs it... int hpos = m_path.find('#'); if (hpos != std::string::npos) { m_ref = m_path.substr(hpos+1); m_path = m_path.substr(0, hpos); } if (s_strict) _checkurl();}void net::url::set_parts(lib::scanner& sc, const std::string& pat) { const std::string& toks = sc.get_tokens(); size_type n = toks.length(); size_type i1 = pat.length(); // Most patterns include the initial / of the pathname, but we want it in // the pathname. if (i1 > 0 && pat[i1-1] == '/') i1--; size_type i2 = toks.find_last_of('?'); size_type i3 = toks.find_last_of('#'); i2 = (i2 == std::string::npos)?n:i2; i3 = (i3 == std::string::npos)?n:i3; size_type i4 = i2<i3?i2:i3; m_path = sc.join(i1, i4); m_query = sc.join(i2+1, i3); m_ref = sc.join(i3+1); if (s_strict) _checkurl();}bool net::url::is_local_file() const{ if (m_protocol == "file" && (m_host == "localhost" || m_host == "")) return true; if (!m_absolute && m_protocol == "") { // We're not sure. AM_DBG lib::logger::get_logger()->trace("url::is_local_file: assume True for relative url: \"%s\"", repr(*this).c_str()); return true; } return false;} std::string net::url::get_url() const{ std::string rv = repr(*this); if (!m_absolute) lib::logger::get_logger()->trace("url::get_url(): URL not absolute: \"%s\"", rv.c_str()); rv = string2uri(rv); return rv;}net::url net::url::get_base() const{ std::string path = get_path(); std::string basepath = lib::filesys::get_base(path); net::url rv = net::url( get_protocol(), get_host(), get_port(), basepath); if (m_absolute) rv.m_absolute = true; return rv;}net::url net::url::join_to_base(const net::url &base) const{ // Note: this hasn't been checked against RFCxxxx. We pick up protocol, host, port // and initial pathname from base. Alll other items from base are ignored. if (m_absolute) return *this; std::string basepath = base.get_path(); std::string newpath = get_path(); if (newpath == "") { // New path is, for instance, only #anchor. newpath = basepath; } else if (newpath[0] != '/') { // New_path is not absolute. Prepend base of basepath basepath = lib::filesys::get_base(basepath); // Convert basepath from Windows to URL, if needed. // XXXX Incomplete?// if (base.m_absolute && basepath[0] != '/')// basepath = "/" + basepath; std::string::iterator cp; for (cp=basepath.begin(); cp != basepath.end(); cp++) { char c = *cp; if (c == '\\') *cp = '/'; } newpath = lib::filesys::join(basepath, newpath); // Now ad //newpath = lib::filesys::join(basepath, newpath, "/"); } AM_DBG lib::logger::get_logger()->debug("url::join_to_base: old \"%s\" base \"%s\" newpath \"%s\"", repr(*this).c_str(), repr(base).c_str(), newpath.c_str()); net::url rv = net::url( base.get_protocol(), base.get_host(), base.get_port(), newpath, m_query, m_ref); if (base.m_absolute) rv.m_absolute = true; return rv;}net::url net::url::get_document() const{ net::url rv = net::url(m_protocol, m_host, m_port, m_path, m_query, ""); rv.m_absolute = m_absolute; return rv;}net::url net::url::add_fragment(string fragment) const{ net::url rv = net::url(m_protocol, m_host, m_port, m_path, m_query, uri2string(fragment)); rv.m_absolute = m_absolute; return rv;}bool net::url::same_document(const net::url &base) const{ return (m_protocol == base.m_protocol && m_host == base.m_host && m_port == base.m_port && m_path == base.m_path && m_query == base.m_query);}// Very limited guesstype (for now), only guesses some HTML documents.std::stringnet::url::guesstype() const{ size_t dotpos = m_path.find_last_of("."); if (dotpos == std::string::npos) return ""; std::string ext = m_path.substr(dotpos); if (ext == ".htm" || ext == ".HTM" || ext == ".html" || ext == ".HTML") return "text/html"; if (ext == ".smi" || ext == ".SMI" || ext == ".smil" || ext == ".SMIL") return "application/smil"; if (ext == ".xml" || ext == ".XML") return "application/xml"; if (ext == ".mp3" || ext == ".MP3") return "audio/mpeg"; if (ext == ".wav" || ext == ".WAV") return "audio/wav"; return "";}#if defined(AMBULANT_PLATFORM_UNIX)// Places where to look for (cached) datafilesconst char *datafile_locations[] = { ".", // Placeholder, to be replaced by set_datafile_directory() ".", "..", "Extras", "../Extras",#ifdef AMBULANT_DATADIR AMBULANT_DATADIR ,#else "/usr/local/share/ambulant",#endif NULL};std::string datafile_directory;voidnet::url::set_datafile_directory(std::string pathname){ datafile_directory = pathname; datafile_locations[0] = datafile_directory.c_str();}std::pair<bool, net::url>net::url::get_local_datafile() const{ const char* result = NULL; if (!is_local_file()) return std::pair<bool, net::url>(false, net::url(*this)); if (! is_absolute()) { string rel_path = get_path(); const char **dir; for(dir = datafile_locations; *dir; dir++) { string abs_path(*dir); abs_path += "/" + rel_path; if (access(abs_path.c_str(), 0) >= 0) { if (abs_path[0] != '/') { char buf[1024]; if (getcwd(buf, sizeof buf)) { std::string curdir(buf); abs_path = curdir + "/" + abs_path; } } result = abs_path.c_str(); break; } } } else if (is_local_file() && access (get_file().c_str(), 0) >= 0) { result = get_file().c_str(); } if (!result) return std::pair<bool, net::url>(false, net::url(*this)); return std::pair<bool, net::url>(true, net::url("file", "", result));}#else // AMBULANT_PLATFORM_UNIX// Hack: if it is not Unix it must be windows:-)// Places where to look for (cached) datafilesstatic const char *datafile_locations[] = { "Extras\\", "..\\..\\Extras\\", "", "..\\", "..\\Extras\\", NULL};static std::string datafile_directory;voidnet::url::set_datafile_directory(std::string pathname){ datafile_directory = pathname;}std::pair<bool, net::url>net::url::get_local_datafile() const{ // XXXX Needs work!#ifdef AMBULANT_PLATFORM_WIN32_WCE // Too lazy to convert char to wide char right now return std::pair<bool, net::url>(false, net::url(*this));#else if (datafile_directory == "") { set_datafile_directory(lib::win32::get_module_dir()); } const char* result = NULL; string path; if (!is_local_file()) return std::pair<bool, net::url>(false, net::url(*this)); if (! is_absolute()) { string rel_path = get_path(); const char **dir; for(dir = datafile_locations; *dir; dir++) { path = datafile_directory + *dir; path += rel_path; if (lib::win32::file_exists(path)) { result = path.c_str(); break; } } } else if (is_local_file()) { path = get_file(); if (lib::win32::file_exists(path)) result = path.c_str(); } if (!result) return std::pair<bool, net::url>(false, net::url(*this)); std::string *pathname = new std::string(result); return std::pair<bool, net::url>(true, net::url("file", "", *pathname));#endif}#endif //AMBULANT_PLATFORM_UNIX///////////////// module private static initializerclass url_static_init { public: url_static_init() { net::url::init_statics(); }};static url_static_init url_static_init_inst;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -