From b6ba87c76cfc745dab0b98163cdfae4008a2acca Mon Sep 17 00:00:00 2001 From: David Waltermire Date: Sat, 26 Oct 2024 17:49:23 -0400 Subject: [PATCH] Fix a bug caused when an already absolute or opaque URI is attempted to be resolved. Resolves #208. (#214) --- .../function/library/FnDocumentAvailable.java | 44 ++++++++++--------- .../function/library/FnResolveUri.java | 2 + .../library/FnDocumentAvailableTest.java | 23 ++++++++++ 3 files changed, 48 insertions(+), 21 deletions(-) create mode 100644 core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnDocumentAvailableTest.java diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnDocumentAvailable.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnDocumentAvailable.java index 3c2d3bc63..a8ec32a93 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnDocumentAvailable.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnDocumentAvailable.java @@ -13,6 +13,7 @@ import gov.nist.secauto.metaschema.core.metapath.function.FunctionUtils; import gov.nist.secauto.metaschema.core.metapath.function.IArgument; import gov.nist.secauto.metaschema.core.metapath.function.IFunction; +import gov.nist.secauto.metaschema.core.metapath.function.UriFunctionException; import gov.nist.secauto.metaschema.core.metapath.item.IItem; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyUriItem; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IBooleanItem; @@ -105,31 +106,32 @@ public static IBooleanItem fnDocAvailable(@NonNull IStringItem documentUri, @Non * @return if the document is retrievable */ public static IBooleanItem fnDocAvailable(@NonNull IAnyUriItem documentUri, @NonNull DynamicContext context) { - // resolve if possible - IAnyUriItem uri = FnResolveUri.fnResolveUri(documentUri, null, context); - if (!uri.isAbsolute() && !uri.isOpaque()) { - throw new DocumentFunctionException(DocumentFunctionException.ERROR_RETRIEVING_RESOURCE, String - .format("No base-uri is available in the static context to resolve the URI '%s'.", documentUri.toString())); - } - boolean retval; + IAnyUriItem uri; try { - URLConnection connection = uri.asUri().toURL().openConnection(); + uri = documentUri.isAbsolute() || documentUri.isOpaque() + ? documentUri + // if not absolute or opaque, then resolve it to make it absolute + : FnResolveUri.fnResolveUri(documentUri, null, context); + try { + URLConnection connection = uri.asUri().toURL().openConnection(); - if (connection instanceof HttpURLConnection) { - HttpURLConnection httpConnection = (HttpURLConnection) connection; - httpConnection.setRequestMethod("HEAD"); - httpConnection.connect(); - retval = HttpURLConnection.HTTP_OK == httpConnection.getResponseCode(); - httpConnection.disconnect(); - } else { - connection.connect(); - retval = true; + if (connection instanceof HttpURLConnection) { + HttpURLConnection httpConnection = (HttpURLConnection) connection; + httpConnection.setRequestMethod("HEAD"); + httpConnection.connect(); + retval = HttpURLConnection.HTTP_OK == httpConnection.getResponseCode(); + httpConnection.disconnect(); + } else { + connection.connect(); + retval = true; + } + } catch (IOException ex) { + retval = false; } - return IBooleanItem.valueOf(retval); - } catch (IOException ex) { - throw new DocumentFunctionException(DocumentFunctionException.ERROR_RETRIEVING_RESOURCE, String - .format("Unable to retrieve the resource identified by the URI '%s'.", documentUri.toString()), ex); + } catch (UriFunctionException ex) { + retval = false; } + return IBooleanItem.valueOf(retval); } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnResolveUri.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnResolveUri.java index 6a8079355..124e66549 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnResolveUri.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnResolveUri.java @@ -177,6 +177,8 @@ public static IAnyUriItem fnResolveUri( * the evaluation context used to get the static base URI if needed * @return the resolved URI or {@code null} if the {@code relative} URI in * {@code null} + * @throws UriFunctionException + * if the base URI is not configured in the dynamic context */ @NonNull public static IAnyUriItem fnResolveUri( diff --git a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnDocumentAvailableTest.java b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnDocumentAvailableTest.java new file mode 100644 index 000000000..3c03fa371 --- /dev/null +++ b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnDocumentAvailableTest.java @@ -0,0 +1,23 @@ + +package gov.nist.secauto.metaschema.core.metapath.function.library; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import gov.nist.secauto.metaschema.core.metapath.DynamicContext; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyUriItem; + +import org.junit.jupiter.api.Test; + +class FnDocumentAvailableTest { + + /** + * Tests for https://github.com/metaschema-framework/metaschema-java/issues/208. + */ + @Test + void issue208Test() { + IAnyUriItem uri = IAnyUriItem.valueOf( + "https://raw.githubusercontent.com/GSA/fedramp-automation/8301e380c88532ebbb22aca55521701750eb0b83/src/content/awesome-cloud/xml/AwesomeCloudSSP1.xml"); + + assertTrue(FnDocumentAvailable.fnDocAvailable(uri, new DynamicContext()).toBoolean()); + } +}