Skip to content

Commit

Permalink
Improve leading slash handling in index URI manipulation (#60)
Browse files Browse the repository at this point in the history
Signed-off-by: Juan Cruz Viotti <[email protected]>
  • Loading branch information
jviotti authored Jan 3, 2025
1 parent 034e4ce commit 854aea6
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 19 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ lint:
.PHONY: test
test:
./test/cli/common/index/invalid-configuration.sh $(PREFIX)/bin/sourcemeta-registry-index
./test/cli/common/index/url-base-trailing-slash.sh $(PREFIX)/bin/sourcemeta-registry-index
ifeq ($(ENTERPRISE), ON)
./test/cli/ee/index/no-options.sh $(PREFIX)/bin/sourcemeta-registry-index
./test/cli/ee/index/no-output.sh $(PREFIX)/bin/sourcemeta-registry-index
Expand Down
58 changes: 39 additions & 19 deletions src/index/index.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

#include "configure.h"

#include <algorithm> // std::transform
#include <cassert> // assert
#include <cctype> // std::tolower
#include <cstdlib> // EXIT_FAILURE, EXIT_SUCCESS
Expand All @@ -17,6 +16,7 @@
#include <functional> // std::ref
#include <iostream> // std::cerr, std::cout
#include <span> // std::span
#include <sstream> // std::ostringstream
#include <string> // std::string
#include <string_view> // std::string_view
#include <vector> // std::vector
Expand All @@ -25,6 +25,35 @@
#include "enterprise_index.h"
#endif

template <typename T>
static auto write_lower_except_trailing(T &stream, const std::string &input,
const char trailing) -> void {
for (auto iterator = input.cbegin(); iterator != input.cend(); ++iterator) {
if (std::next(iterator) == input.cend() && *iterator == trailing) {
continue;
}

stream << static_cast<char>(std::tolower(*iterator));
}
}

static auto url_join(const std::string &first, const std::string &second,
const std::string &third, const std::string &extension)
-> std::string {
std::ostringstream result;
write_lower_except_trailing(result, first, '/');
result << '/';
write_lower_except_trailing(result, second, '/');
result << '/';
write_lower_except_trailing(result, third, '.');
if (!result.str().ends_with(extension)) {
result << '.';
result << extension;
}

return result.str();
}

static auto index(const sourcemeta::jsontoolkit::JSON &configuration,
const std::filesystem::path &base,
const std::filesystem::path &output) -> int {
Expand Down Expand Up @@ -68,24 +97,15 @@ static auto index(const sourcemeta::jsontoolkit::JSON &configuration,
return EXIT_FAILURE;
}

std::ostringstream new_identifier;
new_identifier << server_url.recompose();
new_identifier << '/';
new_identifier << schema_entry.first;
new_identifier << '/';
for (const auto character : identifier_uri.recompose()) {
new_identifier << static_cast<char>(std::tolower(character));
}

// We want to guarantee identifiers end with a JSON extension,
// as we want to use the non-extension URI to potentially metadata
// about schemas, etc
if (!new_identifier.str().ends_with(".json")) {
new_identifier << ".json";
}

std::cerr << "Rebased identifier: " << new_identifier.str() << "\n";
resolver.reidentify(current_identifier, new_identifier.str());
const auto new_identifier{
url_join(server_url.recompose(), schema_entry.first,
identifier_uri.recompose(),
// We want to guarantee identifiers end with a JSON
// extension, as we want to use the non-extension URI to
// potentially metadata about schemas, etc
"json")};
std::cerr << "Rebased identifier: " << new_identifier << "\n";
resolver.reidentify(current_identifier, new_identifier);
}
}

Expand Down
41 changes: 41 additions & 0 deletions test/cli/common/index/url-base-trailing-slash.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/sh

set -o errexit
set -o nounset

TMP="$(mktemp -d)"
clean() { rm -rf "$TMP"; }
trap clean EXIT

cat << EOF > "$TMP/configuration.json"
{
"url": "https://sourcemeta.com/",
"port": 8000,
"schemas": {
"example/schemas": {
"base": "https://example.com/",
"path": "./schemas"
}
}
}
EOF

mkdir "$TMP/schemas"

cat << 'EOF' > "$TMP/schemas/test.json"
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.com/test.json"
}
EOF

"$1" "$TMP/configuration.json" "$TMP/output"

cat << 'EOF' > "$TMP/expected.json"
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://sourcemeta.com/example/schemas/test.json"
}
EOF

diff "$TMP/output/schemas/example/schemas/test.json" "$TMP/expected.json"

0 comments on commit 854aea6

Please sign in to comment.