/* * This file is part of vospace-rest * Copyright (C) 2021 Istituto Nazionale di Astrofisica * SPDX-License-Identifier: GPL-3.0-or-later */ package it.inaf.oats.vospace; import it.inaf.oats.vospace.exception.InternalFaultException; import it.inaf.oats.vospace.exception.InvalidURIException; import java.net.URI; import java.net.URISyntaxException; import java.util.regex.Pattern; import net.ivoa.xml.vospace.v2.Node; public class URIUtils { // It's different from the one in NodeUtils! // Slashes are treated separately private static final Pattern FORBIDDEN_CHARS = Pattern.compile("[\\x00\\x08\\x0B\\x0C\\x0E-\\x1F" + Pattern.quote("<>?\":\\|'`*") + "]"); private static final String SCHEME = "vos"; public static boolean isURIInternal(String URI) { if(URI == null) throw new IllegalArgumentException("URI can't be null"); return URI.toLowerCase().startsWith(SCHEME); } public static String returnURIFromVosPath(String vosPath, String authority) { String result = null; try { URI uri = new URI( SCHEME, authority, vosPath, null, null ); result = uri.toASCIIString(); } catch (URISyntaxException e) { throw new InternalFaultException("unable to percent encode URI from authority and path: " + authority + " , " + vosPath); } return result; } public static String returnVosPathFromNodeURI(Node myNode, String authority) { return returnVosPathFromNodeURI(myNode.getUri(), authority); } // This method validates the URI too public static String returnVosPathFromNodeURI(String nodeURI, String authority) { String resultPath = null; try { if(nodeURI == null) throw new IllegalArgumentException("URI string is null"); URI uri = new URI(nodeURI); // Check scheme if (!uri.isAbsolute() || uri.isOpaque() || !uri.getRawSchemeSpecificPart().startsWith("//") || !uri.getScheme().equalsIgnoreCase(SCHEME)) { throw new InvalidURIException(nodeURI); } // Check authority if (!uri.getAuthority().replace("~", "!").equals(authority)) { throw new InvalidURIException(nodeURI); } // Check path String rawPath = uri.getRawPath(); // Check if raw Path is null or contains percent encoded slashes or multiple // separators if (rawPath == null || rawPath.contains("//") || rawPath.contains("%2F") || rawPath.contains("%2f")) { throw new InvalidURIException(nodeURI); } resultPath = uri.getPath(); if (resultPath.isBlank() || FORBIDDEN_CHARS.matcher(resultPath).find() || (!resultPath.equals("/") && resultPath.endsWith("/"))) { throw new InvalidURIException(nodeURI); } } catch (URISyntaxException e) { throw new InvalidURIException(nodeURI); } return resultPath; } }