From c540e8d102920ce57f8a6d6b24e2752795c28df7 Mon Sep 17 00:00:00 2001 From: Alex Dolski Date: Fri, 25 Mar 2022 14:16:15 -0500 Subject: [PATCH 1/2] Add --build arguments to docker compose invocations --- .github/workflows/ci.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a07fb0d62..24ed4da9a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,24 +13,24 @@ jobs: uses: actions/checkout@v2 - name: Test in Linux JDK 11 if: matrix.os == 'ubuntu-latest' && matrix.java == 'jdk11' - run: docker-compose -f docker/Linux-JDK11/docker-compose.yml up --exit-code-from cantaloupe + run: docker-compose -f docker/Linux-JDK11/docker-compose.yml up --build --exit-code-from cantaloupe - name: Test in Linux JDK 15 if: matrix.os == 'ubuntu-latest' && matrix.java == 'jdk15' - run: docker-compose -f docker/Linux-JDK15/docker-compose.yml up --exit-code-from cantaloupe + run: docker-compose -f docker/Linux-JDK15/docker-compose.yml up --build --exit-code-from cantaloupe - name: Test in Linux JDK 16 if: matrix.os == 'ubuntu-latest' && matrix.java == 'jdk16' - run: docker-compose -f docker/Linux-JDK16/docker-compose.yml up --exit-code-from cantaloupe + run: docker-compose -f docker/Linux-JDK16/docker-compose.yml up --build --exit-code-from cantaloupe - name: Test in Linux GraalVM if: matrix.os == 'ubuntu-latest' && matrix.java == 'graalvm' - run: docker-compose -f docker/Linux-GraalVM20/docker-compose.yml up --exit-code-from cantaloupe + run: docker-compose -f docker/Linux-GraalVM20/docker-compose.yml up --build --exit-code-from cantaloupe - name: Test in Windows JDK 11 if: matrix.os == 'windows-latest' && matrix.java == 'jdk11' - run: docker-compose -f docker/Windows-JDK11/docker-compose.yml up --exit-code-from cantaloupe + run: docker-compose -f docker/Windows-JDK11/docker-compose.yml up --build --exit-code-from cantaloupe - name: Test in Windows JDK 15 if: matrix.os == 'windows-latest' && matrix.java == 'jdk15' - run: docker-compose -f docker/Windows-JDK15/docker-compose.yml up --exit-code-from cantaloupe + run: docker-compose -f docker/Windows-JDK15/docker-compose.yml up --build --exit-code-from cantaloupe - name: Test in Windows JDK 16 if: matrix.os == 'windows-latest' && matrix.java == 'jdk16' - run: docker-compose -f docker/Windows-JDK16/docker-compose.yml up --exit-code-from cantaloupe + run: docker-compose -f docker/Windows-JDK16/docker-compose.yml up --build --exit-code-from cantaloupe # TODO: Windows+GraalVM From 786aa2ed1e5165ecac152f581bbb34524708b760 Mon Sep 17 00:00:00 2001 From: "Mark A. Matney, Jr" Date: Mon, 25 Apr 2022 18:11:05 -0700 Subject: [PATCH 2/2] Fix HTTP 302 redirects via delegate for identifiers with slashes (#581) --- .../cantaloupe/image/MetaIdentifier.java | 28 +++++++++++++++++++ .../cantaloupe/resource/AbstractResource.java | 7 ++--- .../library/cantaloupe/util/StringUtils.java | 16 +++++++++++ .../cantaloupe/image/MetaIdentifierTest.java | 23 +++++++++++++++ .../cantaloupe/util/StringUtilsTest.java | 7 +++++ 5 files changed, 76 insertions(+), 5 deletions(-) diff --git a/src/main/java/edu/illinois/library/cantaloupe/image/MetaIdentifier.java b/src/main/java/edu/illinois/library/cantaloupe/image/MetaIdentifier.java index 35493f3c4..0ceb21880 100644 --- a/src/main/java/edu/illinois/library/cantaloupe/image/MetaIdentifier.java +++ b/src/main/java/edu/illinois/library/cantaloupe/image/MetaIdentifier.java @@ -259,6 +259,34 @@ private void checkFrozen() { } } + /** + *

Translates the meta-identifier into a URI path component.

+ * + *

Reverses {@link #fromURIPathComponent(String, DelegateProxy)}.

+ * + * @param delegateProxy Delegate proxy. + */ + public String toURIPathComponent(DelegateProxy delegateProxy) { + // Encode just the identifier part. + final Identifier originalIdentifier = getIdentifier(); + final String slashedIdentifier = originalIdentifier.toString(); + final String deSlashedIdentifier = StringUtils.encodeSlashes(slashedIdentifier); + final String encodedIdentifier = Reference.encode(deSlashedIdentifier); + final MetaIdentifierTransformer xformer = + new MetaIdentifierTransformerFactory().newInstance(delegateProxy); + final String serializedMetaIdentifier; + + setIdentifier(new Identifier(encodedIdentifier)); + serializedMetaIdentifier = xformer.serialize(this); + // Now that we've serialized the encoded meta-identifier, put it back to how it was before + setIdentifier(originalIdentifier); + + LOGGER.debug("[Slash-substituted identifier: {}] -> [de-slashed identifier: {}] -> " + + "[percent-encoded identifier: {}] -> [raw path component: {}]", + slashedIdentifier, deSlashedIdentifier, encodedIdentifier, serializedMetaIdentifier); + return serializedMetaIdentifier; + } + @Override public String toString() { return new StandardMetaIdentifierTransformer().serialize(this); diff --git a/src/main/java/edu/illinois/library/cantaloupe/resource/AbstractResource.java b/src/main/java/edu/illinois/library/cantaloupe/resource/AbstractResource.java index 20181b298..ecc8484b1 100644 --- a/src/main/java/edu/illinois/library/cantaloupe/resource/AbstractResource.java +++ b/src/main/java/edu/illinois/library/cantaloupe/resource/AbstractResource.java @@ -13,8 +13,6 @@ import edu.illinois.library.cantaloupe.image.Format; import edu.illinois.library.cantaloupe.image.Identifier; import edu.illinois.library.cantaloupe.image.MetaIdentifier; -import edu.illinois.library.cantaloupe.image.MetaIdentifierTransformer; -import edu.illinois.library.cantaloupe.image.MetaIdentifierTransformerFactory; import edu.illinois.library.cantaloupe.delegate.DelegateProxy; import edu.illinois.library.cantaloupe.delegate.DelegateProxyService; import edu.illinois.library.cantaloupe.delegate.UnavailableException; @@ -594,9 +592,8 @@ protected Reference getPublicReference(MetaIdentifier newMetaIdentifier) { final int identifierIndex = pathComponents.indexOf( getIdentifierPathComponent()); - final MetaIdentifierTransformer xformer = - new MetaIdentifierTransformerFactory().newInstance(getDelegateProxy()); - final String newMetaIdentifierString = xformer.serialize(newMetaIdentifier); + final String newMetaIdentifierString = + newMetaIdentifier.toURIPathComponent(getDelegateProxy()); publicRef.setPathComponent(identifierIndex, newMetaIdentifierString); return publicRef; } diff --git a/src/main/java/edu/illinois/library/cantaloupe/util/StringUtils.java b/src/main/java/edu/illinois/library/cantaloupe/util/StringUtils.java index c8e4c38c5..4a20f05a8 100644 --- a/src/main/java/edu/illinois/library/cantaloupe/util/StringUtils.java +++ b/src/main/java/edu/illinois/library/cantaloupe/util/StringUtils.java @@ -41,6 +41,22 @@ public static String decodeSlashes(final String uriPathComponent) { return uriPathComponent; } + /** + * Reverses {@link #decodeSlashes(String)}. + * + * @param slashedIdentifier Identifier with slashes to be substituted. + * @return Identifier with slashes substituted. + */ + public static String encodeSlashes(final String slashedIdentifier) { + final String substitute = Configuration.getInstance(). + getString(Key.SLASH_SUBSTITUTE, ""); + if (!substitute.isEmpty()) { + return org.apache.commons.lang3.StringUtils.replace( + slashedIdentifier, "/", substitute); + } + return slashedIdentifier; + } + public static String escapeHTML(String html) { StringBuilder out = new StringBuilder(Math.max(16, html.length())); for (int i = 0, length = html.length(); i < length; i++) { diff --git a/src/test/java/edu/illinois/library/cantaloupe/image/MetaIdentifierTest.java b/src/test/java/edu/illinois/library/cantaloupe/image/MetaIdentifierTest.java index 13b519d46..b9a318de3 100644 --- a/src/test/java/edu/illinois/library/cantaloupe/image/MetaIdentifierTest.java +++ b/src/test/java/edu/illinois/library/cantaloupe/image/MetaIdentifierTest.java @@ -264,6 +264,29 @@ void testSetScaleConstraintWithFrozenInstance() { () -> instance.setScaleConstraint(scaleConstraint)); } + /* toURIPathComponent() */ + + @Test + void testToURIPathComponent() { + final Configuration config = Configuration.getInstance(); + config.setProperty(Key.SLASH_SUBSTITUTE, "BUG"); + config.setProperty(Key.META_IDENTIFIER_TRANSFORMER, + StandardMetaIdentifierTransformer.class.getSimpleName()); + + DelegateProxy delegateProxy = TestUtil.newDelegateProxy(); + MetaIdentifier metaIdentifier = MetaIdentifier.builder() + .withIdentifier("cats/:dogs") + .withPageNumber(2) + .withScaleConstraint(2, 3) + .build(); + MetaIdentifier beforeMethodCall = new MetaIdentifier(metaIdentifier); + String actual = metaIdentifier.toURIPathComponent(delegateProxy); + String expected = "catsBUG%3Adogs;2;2:3"; + assertEquals(expected, actual); + // Make sure the call to toURIPathComponent didn't change the meta-identifier. + assertEquals(beforeMethodCall, metaIdentifier); + } + /* toString() */ @Test diff --git a/src/test/java/edu/illinois/library/cantaloupe/util/StringUtilsTest.java b/src/test/java/edu/illinois/library/cantaloupe/util/StringUtilsTest.java index e6b5f00b1..704966bf9 100644 --- a/src/test/java/edu/illinois/library/cantaloupe/util/StringUtilsTest.java +++ b/src/test/java/edu/illinois/library/cantaloupe/util/StringUtilsTest.java @@ -25,6 +25,13 @@ void testDecodeSlashes() { assertEquals("ca/ts", StringUtils.decodeSlashes("ca$$ts")); } + @Test + void testEncodeSlashes() { + Configuration.getInstance().setProperty(Key.SLASH_SUBSTITUTE, "$$"); + assertEquals("cats", StringUtils.encodeSlashes("cats")); + assertEquals("ca$$ts", StringUtils.encodeSlashes("ca/ts")); + } + @Test void testEscapeHTML() { String html = "the quick brown fox";