Skip to content

Commit

Permalink
Extended Url scheme
Browse files Browse the repository at this point in the history
  • Loading branch information
iagaponenko committed Sep 17, 2024
1 parent a7d1bbc commit 58fcc91
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 9 deletions.
33 changes: 28 additions & 5 deletions src/http/Url.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,27 @@ namespace lsst::qserv::http {
Url::Url(string const& url) : _url(url) { _translate(); }

string const& Url::fileHost() const {
if ((_scheme == DATA_JSON) || (_scheme == FILE)) return _fileHost;
if ((_scheme == DATA_JSON) || (_scheme == DATA_CSV) || (_scheme == FILE)) return _fileHost;
throw logic_error(_error(__func__, "not a file resource."));
}

string const& Url::filePath() const {
if ((_scheme == DATA_JSON) || (_scheme == FILE)) return _filePath;
if ((_scheme == DATA_JSON) || (_scheme == DATA_CSV) || (_scheme == FILE)) return _filePath;
throw logic_error(_error(__func__, "not a file resource."));
}

string const& Url::host() const {
if ((_scheme != DATA_JSON) && (_scheme != FILE)) return _host;
if ((_scheme == HTTP) || (_scheme == HTTPS)) return _host;
throw logic_error(_error(__func__, "not an HTTP/HTTPS resource."));
}

uint16_t Url::port() const {
if ((_scheme != DATA_JSON) && (_scheme != FILE)) return _port;
if ((_scheme == HTTP) || (_scheme == HTTPS)) return _port;
throw logic_error(_error(__func__, "not an HTTP/HTTPS resource."));
}

string const& Url::target() const {
if ((_scheme != DATA_JSON) && (_scheme != FILE)) return _target;
if ((_scheme == HTTP) || (_scheme == HTTPS)) return _target;
throw logic_error(_error(__func__, "not an HTTP/HTTPS resource."));
}

Expand All @@ -66,6 +66,7 @@ void Url::_translate() {
if (_url.empty()) throw invalid_argument(_error(__func__, "url is empty."));

static map<string, Scheme> const schemes = {{"data-json://", Scheme::DATA_JSON},
{"data-csv://", Scheme::DATA_CSV},
{"file://", Scheme::FILE},
{"http://", Scheme::HTTP},
{"https://", Scheme::HTTPS}};
Expand All @@ -84,6 +85,28 @@ void Url::_translate() {
return;
}
}
} else if (Scheme::DATA_CSV == scheme) {
// This scheme assumes the following format: "data-csv://<host>/[<file>]"
string const hostFilePath = _url.substr(prefix.length());
string::size_type const pos = hostFilePath.find_first_of('/');
if (pos != string::npos) {
if (pos == 0) {
// This URL doesn't have the host name: data-csv:///<path>
if (hostFilePath.length() > 1) {
_scheme = scheme;
_filePath = hostFilePath;
return;
}
} else {
// This URL has the host name: file://<host>/<path>
if (hostFilePath.length() > pos + 1) {
_scheme = scheme;
_fileHost = hostFilePath.substr(0, pos);
_filePath = hostFilePath.substr(pos);
return;
}
}
}
} else if (Scheme::FILE == scheme) {
// Note that the file path should be always absolute in the URL. It's impossible to
// pass a relative location of a file in this scheme. The file path is required to
Expand Down
2 changes: 1 addition & 1 deletion src/http/Url.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace lsst::qserv::http {
class Url {
public:
/// Types of resources
enum Scheme { DATA_JSON, FILE, HTTP, HTTPS };
enum Scheme { DATA_JSON, DATA_CSV, FILE, HTTP, HTTPS };

// Default construction is prohibited to avoid extra complexity in managing
// a "valid" state of the resource object.
Expand Down
14 changes: 11 additions & 3 deletions src/http/testUrl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,21 @@ BOOST_AUTO_TEST_CASE(UrlTest) {
BOOST_CHECK_THROW({ ptr.reset(new Url("data-json://h/f")); }, invalid_argument);

// The well-formed URL
string dataUrl = "data-json://h/";
BOOST_REQUIRE_NO_THROW({ ptr.reset(new Url(dataUrl)); });
BOOST_REQUIRE_NO_THROW({ BOOST_CHECK_EQUAL(ptr->url(), dataUrl); });
string dataJsonUrl = "data-json://h/";
BOOST_REQUIRE_NO_THROW({ ptr.reset(new Url(dataJsonUrl)); });
BOOST_REQUIRE_NO_THROW({ BOOST_CHECK_EQUAL(ptr->url(), dataJsonUrl); });
BOOST_REQUIRE_NO_THROW({ BOOST_CHECK_EQUAL(ptr->scheme(), Url::Scheme::DATA_JSON); });
BOOST_REQUIRE_NO_THROW({ BOOST_CHECK_EQUAL(ptr->fileHost(), "h"); });
BOOST_REQUIRE_NO_THROW({ BOOST_CHECK_EQUAL(ptr->filePath(), string()); });

// The well-formed URL
string dataCsvUrl = "data-csv://h/f";
BOOST_REQUIRE_NO_THROW({ ptr.reset(new Url(dataCsvUrl)); });
BOOST_REQUIRE_NO_THROW({ BOOST_CHECK_EQUAL(ptr->url(), dataCsvUrl); });
BOOST_REQUIRE_NO_THROW({ BOOST_CHECK_EQUAL(ptr->scheme(), Url::Scheme::DATA_CSV); });
BOOST_REQUIRE_NO_THROW({ BOOST_CHECK_EQUAL(ptr->fileHost(), "h"); });
BOOST_REQUIRE_NO_THROW({ BOOST_CHECK_EQUAL(ptr->filePath(), "/f"); });

// Resources which are too short to include anyting by the name of a scheme
// aren't allowed.
BOOST_CHECK_THROW({ ptr.reset(new Url("file:///")); }, invalid_argument);
Expand Down

0 comments on commit 58fcc91

Please sign in to comment.