Fix URI parsing for URLs with ambiguous protocols

This commit is contained in:
Ashley Rogers 2024-04-19 13:47:32 -04:00
parent e868c5c85b
commit ce2b693bae
2 changed files with 34 additions and 3 deletions

View File

@ -6,20 +6,35 @@
#include <stdexcept>
namespace CesiumUtility {
const char* HTTPS_PREFIX = "https";
const char* HTTPS_PREFIX_COLON = "https:";
std::string cesiumConformUrl(const std::string& url) {
if (url.rfind("//", 0) == 0) {
return std::string(HTTPS_PREFIX_COLON).append(url);
} else if (url.find("://", 0) == 0) {
return std::string(HTTPS_PREFIX).append(url);
}
return url;
}
std::string Uri::resolve(
const std::string& base,
const std::string& relative,
bool useBaseQuery) {
const std::string conformedBase = cesiumConformUrl(base);
const std::string conformedRelative = cesiumConformUrl(relative);
UriUriA baseUri;
if (uriParseSingleUriA(&baseUri, base.c_str(), nullptr) != URI_SUCCESS) {
if (uriParseSingleUriA(&baseUri, conformedBase.c_str(), nullptr) !=
URI_SUCCESS) {
// Could not parse the base, so just use the relative directly and hope for
// the best.
return relative;
}
UriUriA relativeUri;
if (uriParseSingleUriA(&relativeUri, relative.c_str(), nullptr) !=
if (uriParseSingleUriA(&relativeUri, conformedRelative.c_str(), nullptr) !=
URI_SUCCESS) {
// Could not parse one of the URLs, so just use the relative directly and
// hope for the best.
@ -102,8 +117,9 @@ std::string Uri::addQuery(
}
std::string Uri::getQueryValue(const std::string& url, const std::string& key) {
const std::string conformedUrl = cesiumConformUrl(url);
UriUriA uri;
if (uriParseSingleUriA(&uri, url.c_str(), nullptr) != URI_SUCCESS) {
if (uriParseSingleUriA(&uri, conformedUrl.c_str(), nullptr) != URI_SUCCESS) {
return "";
}
UriQueryListA* queryList;

View File

@ -0,0 +1,15 @@
#include "CesiumUtility/Uri.h"
#include <catch2/catch.hpp>
TEST_CASE("Uri::resolve") {
CHECK(
CesiumUtility::Uri::resolve("https://www.example.com/", "/page/test") ==
"https://www.example.com/page/test");
CHECK(
CesiumUtility::Uri::resolve("//www.example.com", "/page/test") ==
"https://www.example.com/page/test");
CHECK(
CesiumUtility::Uri::resolve("://www.example.com", "/page/test") ==
"https://www.example.com/page/test");
}