diff --git a/build.gradle b/build.gradle index 24a48e7e1d9421db9fd412656420abc807302a5e..2a9a41cb1c856f5607f489eed11c44b3a1e79abf 100644 --- a/build.gradle +++ b/build.gradle @@ -1,13 +1,6 @@ apply plugin: 'java' apply plugin: 'war' -compileJava.options.encoding = 'UTF-8' - -test{ - forkEvery = 1 - include '**/Test*' -} - repositories { jcenter() mavenCentral() @@ -32,5 +25,10 @@ compileJava { options.encoding = "UTF-8" } +test{ + forkEvery = 1 + include '**/Test*' +} + sourceSets.main.java.srcDirs = ["src"] sourceSets.test.java.srcDirs = ["test"] diff --git a/src/tap/config/ConfigurableServiceConnection.java b/src/tap/config/ConfigurableServiceConnection.java index c92d01f2a681723d428023d68b4fe695b5850b84..48d3db434f856494ae11cf45b2432fa69789249d 100644 --- a/src/tap/config/ConfigurableServiceConnection.java +++ b/src/tap/config/ConfigurableServiceConnection.java @@ -1,5 +1,74 @@ package tap.config; +import static tap.config.TAPConfiguration.DEFAULT_ASYNC_FETCH_SIZE; +import static tap.config.TAPConfiguration.DEFAULT_DIRECTORY_PER_USER; +import static tap.config.TAPConfiguration.DEFAULT_EXECUTION_DURATION; +import static tap.config.TAPConfiguration.DEFAULT_GROUP_USER_DIRECTORIES; +import static tap.config.TAPConfiguration.DEFAULT_MAX_ASYNC_JOBS; +import static tap.config.TAPConfiguration.DEFAULT_RETENTION_PERIOD; +import static tap.config.TAPConfiguration.DEFAULT_SYNC_FETCH_SIZE; +import static tap.config.TAPConfiguration.DEFAULT_UPLOAD_MAX_FILE_SIZE; +import static tap.config.TAPConfiguration.KEY_ASYNC_FETCH_SIZE; +import static tap.config.TAPConfiguration.KEY_COORD_SYS; +import static tap.config.TAPConfiguration.KEY_DEFAULT_EXECUTION_DURATION; +import static tap.config.TAPConfiguration.KEY_DEFAULT_OUTPUT_LIMIT; +import static tap.config.TAPConfiguration.KEY_DEFAULT_RETENTION_PERIOD; +import static tap.config.TAPConfiguration.KEY_DEFAULT_UPLOAD_LIMIT; +import static tap.config.TAPConfiguration.KEY_DIRECTORY_PER_USER; +import static tap.config.TAPConfiguration.KEY_FILE_MANAGER; +import static tap.config.TAPConfiguration.KEY_FILE_ROOT_PATH; +import static tap.config.TAPConfiguration.KEY_GEOMETRIES; +import static tap.config.TAPConfiguration.KEY_GROUP_USER_DIRECTORIES; +import static tap.config.TAPConfiguration.KEY_LOG_ROTATION; +import static tap.config.TAPConfiguration.KEY_MAX_ASYNC_JOBS; +import static tap.config.TAPConfiguration.KEY_MAX_EXECUTION_DURATION; +import static tap.config.TAPConfiguration.KEY_MAX_OUTPUT_LIMIT; +import static tap.config.TAPConfiguration.KEY_MAX_RETENTION_PERIOD; +import static tap.config.TAPConfiguration.KEY_MAX_UPLOAD_LIMIT; +import static tap.config.TAPConfiguration.KEY_METADATA; +import static tap.config.TAPConfiguration.KEY_METADATA_FILE; +import static tap.config.TAPConfiguration.KEY_MIN_LOG_LEVEL; +import static tap.config.TAPConfiguration.KEY_OUTPUT_FORMATS; +import static tap.config.TAPConfiguration.KEY_PROVIDER_NAME; +import static tap.config.TAPConfiguration.KEY_SERVICE_DESCRIPTION; +import static tap.config.TAPConfiguration.KEY_SYNC_FETCH_SIZE; +import static tap.config.TAPConfiguration.KEY_TAP_FACTORY; +import static tap.config.TAPConfiguration.KEY_UDFS; +import static tap.config.TAPConfiguration.KEY_UPLOAD_ENABLED; +import static tap.config.TAPConfiguration.KEY_UPLOAD_MAX_FILE_SIZE; +import static tap.config.TAPConfiguration.KEY_USER_IDENTIFIER; +import static tap.config.TAPConfiguration.VALUE_ALL; +import static tap.config.TAPConfiguration.VALUE_ANY; +import static tap.config.TAPConfiguration.VALUE_CSV; +import static tap.config.TAPConfiguration.VALUE_DB; +import static tap.config.TAPConfiguration.VALUE_FITS; +import static tap.config.TAPConfiguration.VALUE_HTML; +import static tap.config.TAPConfiguration.VALUE_JSON; +import static tap.config.TAPConfiguration.VALUE_LOCAL; +import static tap.config.TAPConfiguration.VALUE_NONE; +import static tap.config.TAPConfiguration.VALUE_SV; +import static tap.config.TAPConfiguration.VALUE_TEXT; +import static tap.config.TAPConfiguration.VALUE_TSV; +import static tap.config.TAPConfiguration.VALUE_VOT; +import static tap.config.TAPConfiguration.VALUE_VOTABLE; +import static tap.config.TAPConfiguration.VALUE_XML; +import static tap.config.TAPConfiguration.fetchClass; +import static tap.config.TAPConfiguration.getProperty; +import static tap.config.TAPConfiguration.hasConstructor; +import static tap.config.TAPConfiguration.isClassName; +import static tap.config.TAPConfiguration.newInstance; +import static tap.config.TAPConfiguration.parseLimit; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Properties; + /* * This file is part of TAPLibrary. * @@ -28,7 +97,13 @@ import tap.TAPException; import tap.TAPFactory; import tap.db.DBConnection; import tap.db.JDBCConnection; -import tap.formatter.*; +import tap.formatter.FITSFormat; +import tap.formatter.HTMLFormat; +import tap.formatter.JSONFormat; +import tap.formatter.OutputFormat; +import tap.formatter.SVFormat; +import tap.formatter.TextFormat; +import tap.formatter.VOTableFormat; import tap.log.DefaultTAPLog; import tap.log.TAPLog; import tap.metadata.TAPMetadata; @@ -41,14 +116,6 @@ import uws.service.file.LocalUWSFileManager; import uws.service.file.UWSFileManager; import uws.service.log.UWSLog.LogLevel; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.*; - -import static tap.config.TAPConfiguration.*; - /** * <p>Concrete implementation of {@link ServiceConnection}, fully parameterized with a TAP configuration file.</p> * @@ -267,11 +334,14 @@ public final class ConfigurableServiceConnection implements ServiceConnection { * @param propertyName Name of the property which gives the given file path. * * @return The specified File instance. - * + * + * @throws ParseException If the given file path is a URI/URL. */ - protected static final File getFile(final String filePath, final String webAppRootPath, final String propertyName) { + protected static final File getFile(final String filePath, final String webAppRootPath, final String propertyName) throws TAPException{ if (filePath == null) return null; + else if (filePath.matches(".*:.*")) + throw new TAPException("Incorrect file path for the property \"" + propertyName + "\": \"" + filePath + "\"! URI/URLs are not expected here."); File f = new File(filePath); if (f.isAbsolute()) diff --git a/src/tap/resource/ForwardResource.java b/src/tap/resource/ForwardResource.java index c5a1b80ccb5a63e96b83ba80d0c410a168fc696f..3e3f9a6e5c71166cdd49b29da43829c7a31d14fa 100644 --- a/src/tap/resource/ForwardResource.java +++ b/src/tap/resource/ForwardResource.java @@ -16,7 +16,7 @@ package tap.resource; * You should have received a copy of the GNU Lesser General Public License * along with TAPLibrary. If not, see <http://www.gnu.org/licenses/>. * - * Copyright 2015 - Astronomisches Rechen Institut (ARI) + * Copyright 2015-2017 - Astronomisches Rechen Institut (ARI) */ import java.io.BufferedReader; @@ -48,14 +48,14 @@ import uws.service.log.UWSLog.LogLevel; * the given URL will be performed. * </p> * - * <p><i>See {@link #forward(String, String, HttpServletRequest, HttpServletResponse)} for more details</i></p> + * <p><i>See {@link #forward(String, String, HttpServletRequest, HttpServletResponse)} for more details</i></p> * * @author Grégory Mantelet (ARI) - * @version 2.1 (11/2015) + * @version 2.1 (03/2017) * @since 2.1 */ public abstract class ForwardResource implements TAPResource { - + /** Logger that {@link #forward(String, String, HttpServletRequest, HttpServletResponse)} must use * in case of not grave error (e.g. the specified Web Application file can not be found). */ protected final TAPLog logger; @@ -65,7 +65,7 @@ public abstract class ForwardResource implements TAPResource { * * @param logger A TAP logger. */ - protected ForwardResource(final TAPLog logger) { + protected ForwardResource(final TAPLog logger){ this.logger = logger; } @@ -79,7 +79,7 @@ public abstract class ForwardResource implements TAPResource { * In this case the request is forwarded to this file. It is neither a redirection nor a copy, * but a kind of inclusion of the interpreted file into the response. * <i>This method MUST be used if your page/content is a JSP.</i></li> - * <li><b>a local file</b> if a URI starts with "file:". In this case, the content of the local file is copied in the HTTP response. There is no interpretation. So this method should not be used for JSP.</li> + * <li><b>a local file</b> if a URI starts with "file:". In this case, the content of the local file is copied in the HTTP response. There is no interpretation. So this method should not be used for JSP.</li> * <li><b>a distance document</b> in all other cases. Indeed, if there is a scheme different from "file:" the given URI will be considered as a URL. * In this case, any request to the TAP home page is redirected to this URL.</li> * </ol> @@ -87,7 +87,7 @@ public abstract class ForwardResource implements TAPResource { * <p><b>Important note:</b> * The 1st option is applied ONLY IF the path of the TAP servlet is NOT the root path of the web application: * that's to say <code>/*</code>. In the case where a URI without scheme is provided though the servlet path - * is <code>/*</code>, this function will resolve the full path on the local file system and apply the + * is <code>/*</code>, this function will resolve the full path on the local file system and apply the * 2nd option: write the file content directly in the response. Note that will work only in cases where the * specified file is not a JSP or does not need any kind of interpretation by the function * {@link RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse)}. @@ -106,7 +106,7 @@ public abstract class ForwardResource implements TAPResource { * or when the HTTP connection has been aborted. * @throws IllegalStateException If an attempt of resetting the buffer fails. */ - public final boolean forward(final String file, final String mimeType, final HttpServletRequest request, final HttpServletResponse response) throws IOException { + public final boolean forward(final String file, final String mimeType, final HttpServletRequest request, final HttpServletResponse response) throws IOException{ boolean written = false; // Display the specified file, if any is specified: @@ -114,17 +114,17 @@ public abstract class ForwardResource implements TAPResource { URI uri = null; try{ - uri = new URI(file); - + uri = new URI(file.replaceAll(" ", "%20")); + /* Note: the space replacement is just a convenient way to fix badly encoding URIs. + * A proper way would be to encode all such incorrect URI characters (e.g. accents), but + * the idea here is to focus on the most common mistake while writing manually 'file:' URIs. */ + /* If the servlet is set on the root Web Application path, a forward toward a WebContent resource won't work. * The file then need to be copied "manually" in the HTTPServletResponse. For that, the trick consists to rewrite * the given file path to a URI with the scheme "file://". */ - String tmpFile = null; - if (request.getServletPath().length() == 0 && uri.getScheme() == null){ - tmpFile = "file://"+request.getServletContext().getRealPath(file); - uri = new URI(tmpFile); - } - + if (request.getServletPath().length() == 0 && uri.getScheme() == null) + uri = new URI("file", null, request.getServletContext().getRealPath(file), null); + /* CASE: FILE IN WebContent */ if (uri.getScheme() == null){ try{ @@ -206,7 +206,7 @@ public abstract class ForwardResource implements TAPResource { }catch(IOException ioe){ /* This IOException can be caught here only if caused by a HTTP client abortion or by a closing of the HTTPrequest. - * So, it must be propagated until the TAP instance, where it will be merely logged as INFO. No response/error can be + * So, it must be propagated until the TAP instance, where it will be merely logged as INFO. No response/error can be * returned in the HTTP response. */ throw ioe; diff --git a/test/tap/config/TestConfigurableServiceConnection.java b/test/tap/config/TestConfigurableServiceConnection.java index ea69a6668bd7f196f19e9a4d3b4efe0757df84d6..38ddbd5d575a1643e45834619064a4e9b24ca7ad 100644 --- a/test/tap/config/TestConfigurableServiceConnection.java +++ b/test/tap/config/TestConfigurableServiceConnection.java @@ -1124,11 +1124,8 @@ public class TestConfigurableServiceConnection { // NULL test => NULL must be returned. assertNull(ConfigurableServiceConnection.getFile(null, rootPath, propertyName)); - // Valid file URI: - path = "/custom/user/dir"; - assertEquals(path, ConfigurableServiceConnection.getFile("file://" + path, rootPath, propertyName).getAbsolutePath()); - // Valid absolute file path: + path = "/custom/user/dir"; assertEquals(path, ConfigurableServiceConnection.getFile(path, rootPath, propertyName).getAbsolutePath()); // File name relative to the given rootPath: @@ -1144,14 +1141,14 @@ public class TestConfigurableServiceConnection { fail("None of these tests should have failed!"); } - // Test with a file URI having a bad syntax: - path = "file:#toto^foo"; + // Test with a file URI: + path = "file:/custom/user/dir"; try{ ConfigurableServiceConnection.getFile(path, rootPath, propertyName); - fail("This test should have failed, because the given file URI has a bad syntax!"); + fail("This test should have failed, because URIs are no longer supported!"); }catch(Exception ex){ assertEquals(TAPException.class, ex.getClass()); - assertEquals("Incorrect file URI for the property \"" + propertyName + "\": \"" + path + "\"! Bad syntax for the given file URI.", ex.getMessage()); + assertEquals("Incorrect file path for the property \"" + propertyName + "\": \"" + path + "\"! URI/URLs are not expected here.", ex.getMessage()); } // Test with an URL: @@ -1161,7 +1158,7 @@ public class TestConfigurableServiceConnection { fail("This test should have failed, because the given URI uses the HTTP protocol (actually, it uses a protocol different from \"file\"!"); }catch(Exception ex){ assertEquals(TAPException.class, ex.getClass()); - assertEquals("Incorrect file URI for the property \"" + propertyName + "\": \"" + path + "\"! Only URI with the protocol \"file:\" are allowed.", ex.getMessage()); + assertEquals("Incorrect file path for the property \"" + propertyName + "\": \"" + path + "\"! URI/URLs are not expected here.", ex.getMessage()); } }