void URI::parse(const std::string& uri) { std::string::const_iterator it = uri.begin(); std::string::const_iterator end = uri.end(); if (it == end) return; if (*it != '/' && *it != '.' && *it != '?' && *it != '#') { std::string scheme; while (it != end && *it != ':' && *it != '?' && *it != '#' && *it != '/') scheme += *it++; if (it != end && *it == ':') { ++it; if (it == end) throw SyntaxException("URI scheme must be followed by authority or path", uri); setScheme(scheme); if (*it == '/') { ++it; if (it != end && *it == '/') { ++it; parseAuthority(it, end); } else --it; } parsePathEtc(it, end); } else { it = uri.begin(); parsePathEtc(it, end); } } else parsePathEtc(it, end); }
bool Uri::Private::parseRelativePart() { if (expectChar('/')) { if (expectChar('/')) { parseAuthority(); parsePathAbempty(); return true; } else { --m_parserPos; } } const size_t parserOldPos = m_parserPos; if (parsePathAbsolute()) { return true; } m_parserPos = parserOldPos; if (parsePathNoScheme()) { return true; } m_parserPos = parserOldPos; if (parsePathEmpty()) { return true; } return false; }
void URI::setAuthority(const std::string& authority) { _userInfo.clear(); _host.clear(); _port = 0; std::string::const_iterator beg = authority.begin(); std::string::const_iterator end = authority.end(); parseAuthority(beg, end); }
URI::URI(const std::string& scheme, const std::string& authority, const std::string& path, const std::string& query): _scheme(scheme), _path(path), _query(query) { toLowerInPlace(_scheme); std::string::const_iterator beg = authority.begin(); std::string::const_iterator end = authority.end(); parseAuthority(beg, end); }
URI::URI(const std::string& scheme, const std::string& authority, const std::string& pathEtc): _scheme(scheme) { toLowerInPlace(_scheme); std::string::const_iterator beg = authority.begin(); std::string::const_iterator end = authority.end(); parseAuthority(beg, end); beg = pathEtc.begin(); end = pathEtc.end(); parsePathEtc(beg, end); }
static Uri parseUri(char const* str) { Uri uri; auto scheme = parseScheme(str); auto authority = parseAuthority(scheme.ch); auto path = parsePath(authority.ch); uri.schemeIs(scheme.value); uri.authorityIs(authority.value); uri.pathIs(path.value); return uri; }
void ParseURL::parseNonFully() noexcept { if (url_.empty()) { valid_ = false; return; } // Check if the URL has only printable characters and no control character. if (!validateURL(url_)) { valid_ = false; return; } auto pathStart = url_.find('/'); auto queryStart = url_.find('?'); auto hashStart = url_.find('#'); auto queryEnd = std::min(hashStart, std::string::npos); auto pathEnd = std::min(queryStart, hashStart); auto authorityEnd = std::min(pathStart, pathEnd); authority_ = url_.subpiece(0, authorityEnd).str(); if (pathStart < pathEnd) { path_ = url_.subpiece(pathStart, pathEnd - pathStart); } else { // missing the '/', e.g. '?query=3' path_ = ""; } if (queryStart < queryEnd) { query_ = url_.subpiece(queryStart + 1, queryEnd - queryStart - 1); } else if (queryStart != std::string::npos && hashStart < queryStart) { valid_ = false; return; } if (hashStart != std::string::npos) { fragment_ = url_.subpiece(hashStart + 1, std::string::npos); } if (!parseAuthority()) { valid_ = false; return; } valid_ = true; }