daisy/pipeline

dp2.exe does not accept UNC paths

Opened this issue · 1 comments

Expected Behavior

I'm trying to run the Daisy Pipeline CLI with an UNC path and I expect that the DTBook is processed.

Actual Behavior

The job is not processed with error Job request is not valid.

Steps to Reproduce

  1. Construct a share such that you have read and write permission. For instance, if the machine name is DEV, create a share Temp so that new files can be created in \\DEV\Temp and so that they can be read too.
  2. Put an arbitrary DTBook file in that share, for instance \\DEV\Temp\dtbook.xml
  3. Execute in a CMD, dp2.exe dtbook-to-pef --source \\DEV\Temp\dtbook.xml --output \\DEV\Temp\output-folder

Details

Changing the backward slashes to forward slashes gives the same issue.

Environment

  • Windows 11 64-bit
  • DAISY Pipeline 2 version: 1.14.14
  • Interface: Command Line

Logs

2023-08-14 15:41:03,958 [ERROR] o.d.p.webservice.impl.JobsResource - bad request:
java.io.FileNotFoundException: Input not found: not a valid file URI: file://dev-10/Tekstproductie/pip-job-handler/in/soft-hyphen-test-1.xml
	at org.daisy.pipeline.script.ScriptInput$Builder.checkInputURI(ScriptInput.java:200) ~[org.daisy.pipeline.framework-core-7.0.1.jar:na]
	at org.daisy.pipeline.script.ScriptInput$Builder.withInput(ScriptInput.java:103) ~[org.daisy.pipeline.framework-core-7.0.1.jar:na]
	at org.daisy.pipeline.script.BoundScript$Builder.withInput(BoundScript.java:44) ~[org.daisy.pipeline.framework-core-7.0.1.jar:na]
	at org.daisy.pipeline.webservice.impl.JobsResource.addInputsToJob(JobsResource.java:458) ~[org.daisy.pipeline.webservice-3.1.0.jar:na]
	at org.daisy.pipeline.webservice.impl.JobsResource.createJob(JobsResource.java:387) ~[org.daisy.pipeline.webservice-3.1.0.jar:na]
	at org.daisy.pipeline.webservice.impl.JobsResource.createResource(JobsResource.java:178) ~[org.daisy.pipeline.webservice-3.1.0.jar:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
	at org.restlet.resource.ServerResource.doHandle(ServerResource.java:503) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.resource.ServerResource.post(ServerResource.java:1215) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.resource.ServerResource.doHandle(ServerResource.java:592) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.resource.ServerResource.doNegotiatedHandle(ServerResource.java:649) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.resource.ServerResource.doConditionalHandle(ServerResource.java:348) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.resource.ServerResource.handle(ServerResource.java:951) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.resource.Finder.handle(Finder.java:246) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.doHandle(Filter.java:159) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.handle(Filter.java:206) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Router.doHandle(Router.java:431) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Router.handle(Router.java:648) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.doHandle(Filter.java:159) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.handle(Filter.java:206) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.doHandle(Filter.java:159) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.handle(Filter.java:206) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.doHandle(Filter.java:159) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:155) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.handle(Filter.java:206) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.doHandle(Filter.java:159) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.handle(Filter.java:206) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:211) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.engine.application.ApplicationHelper.handle(ApplicationHelper.java:84) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.Application.handle(Application.java:381) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.doHandle(Filter.java:159) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.handle(Filter.java:206) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Router.doHandle(Router.java:431) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Router.handle(Router.java:648) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.doHandle(Filter.java:159) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.handle(Filter.java:206) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Router.doHandle(Router.java:431) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Router.handle(Router.java:648) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.doHandle(Filter.java:159) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:155) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.handle(Filter.java:206) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.doHandle(Filter.java:159) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.routing.Filter.handle(Filter.java:206) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:211) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.Component.handle(Component.java:392) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.Server.handle(Server.java:516) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.engine.ServerHelper.handle(ServerHelper.java:72) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:152) ~[org.restlet.osgi.org.restlet-2.1-RC6.jar:na]
	at org.restlet.ext.jetty.JettyServerHelper$WrappedServer.handle(JettyServerHelper.java:170) ~[org.restlet.osgi.org.restlet.ext.jetty-2.1-RC6.jar:na]
	at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:452) ~[org.eclipse.jetty.jetty-server-7.6.5.v20120716.jar:7.6.5.v20120716]
	at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:894) ~[org.eclipse.jetty.jetty-server-7.6.5.v20120716.jar:7.6.5.v20120716]
	at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:948) ~[org.eclipse.jetty.jetty-server-7.6.5.v20120716.jar:7.6.5.v20120716]
	at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:851) ~[org.eclipse.jetty.jetty-http-7.6.5.v20120716.jar:7.6.5.v20120716]
	at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235) ~[org.eclipse.jetty.jetty-http-7.6.5.v20120716.jar:7.6.5.v20120716]
	at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77) ~[org.eclipse.jetty.jetty-server-7.6.5.v20120716.jar:7.6.5.v20120716]
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:622) ~[org.eclipse.jetty.jetty-io-7.6.5.v20120716.jar:7.6.5.v20120716]
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:46) ~[org.eclipse.jetty.jetty-io-7.6.5.v20120716.jar:7.6.5.v20120716]
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:603) ~[org.eclipse.jetty.jetty-util-7.6.5.v20120716.jar:7.6.5.v20120716]
	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:538) ~[org.eclipse.jetty.jetty-util-7.6.5.v20120716.jar:7.6.5.v20120716]
	at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
2023-08-14 15:41:03,958 [DEBUG] o.d.p.w.impl.GenericResource - Bad Request (400) - The request could not be understood by the server due to malformed syntax
2023-08-14 15:41:03,958 [DEBUG] o.d.p.w.impl.GenericResource - Input not found: not a valid file URI: file://dev-10/Tekstproductie/pip-job-handler/in/soft-hyphen-test-1.xml
2023-08-14 15:41:03,960 [DEBUG] o.d.p.w.impl.GenericResource - <?xml version="1.0" encoding="UTF-8"?><error xmlns="http://www.daisy.org/ns/pipeline/data" query="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1"><description>Input not found: not a valid file URI: file://dev-10/Tekstproductie/pip-job-handler/in/soft-hyphen-test-1.xml</description><trace>java.lang.Throwable: Input not found: not a valid file URI: file://dev-10/Tekstproductie/pip-job-handler/in/soft-hyphen-test-1.xml&#xD;
	at org.daisy.pipeline.webservice.impl.GenericResource.getErrorRepresentation(GenericResource.java:40)&#xD;
	at org.daisy.pipeline.webservice.impl.JobsResource.badRequest(JobsResource.java:220)&#xD;
	at org.daisy.pipeline.webservice.impl.JobsResource.createResource(JobsResource.java:182)&#xD;
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)&#xD;
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)&#xD;
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)&#xD;
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)&#xD;
	at org.restlet.resource.ServerResource.doHandle(ServerResource.java:503)&#xD;
	at org.restlet.resource.ServerResource.post(ServerResource.java:1215)&#xD;
	at org.restlet.resource.ServerResource.doHandle(ServerResource.java:592)&#xD;
	at org.restlet.resource.ServerResource.doNegotiatedHandle(ServerResource.java:649)&#xD;
	at org.restlet.resource.ServerResource.doConditionalHandle(ServerResource.java:348)&#xD;
	at org.restlet.resource.ServerResource.handle(ServerResource.java:951)&#xD;
	at org.restlet.resource.Finder.handle(Finder.java:246)&#xD;
	at org.restlet.routing.Filter.doHandle(Filter.java:159)&#xD;
	at org.restlet.routing.Filter.handle(Filter.java:206)&#xD;
	at org.restlet.routing.Router.doHandle(Router.java:431)&#xD;
	at org.restlet.routing.Router.handle(Router.java:648)&#xD;
	at org.restlet.routing.Filter.doHandle(Filter.java:159)&#xD;
	at org.restlet.routing.Filter.handle(Filter.java:206)&#xD;
	at org.restlet.routing.Filter.doHandle(Filter.java:159)&#xD;
	at org.restlet.routing.Filter.handle(Filter.java:206)&#xD;
	at org.restlet.routing.Filter.doHandle(Filter.java:159)&#xD;
	at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:155)&#xD;
	at org.restlet.routing.Filter.handle(Filter.java:206)&#xD;
	at org.restlet.routing.Filter.doHandle(Filter.java:159)&#xD;
	at org.restlet.routing.Filter.handle(Filter.java:206)&#xD;
	at org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:211)&#xD;
	at org.restlet.engine.application.ApplicationHelper.handle(ApplicationHelper.java:84)&#xD;
	at org.restlet.Application.handle(Application.java:381)&#xD;
	at org.restlet.routing.Filter.doHandle(Filter.java:159)&#xD;
	at org.restlet.routing.Filter.handle(Filter.java:206)&#xD;
	at org.restlet.routing.Router.doHandle(Router.java:431)&#xD;
	at org.restlet.routing.Router.handle(Router.java:648)&#xD;
	at org.restlet.routing.Filter.doHandle(Filter.java:159)&#xD;
	at org.restlet.routing.Filter.handle(Filter.java:206)&#xD;
	at org.restlet.routing.Router.doHandle(Router.java:431)&#xD;
	at org.restlet.routing.Router.handle(Router.java:648)&#xD;
	at org.restlet.routing.Filter.doHandle(Filter.java:159)&#xD;
	at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:155)&#xD;
	at org.restlet.routing.Filter.handle(Filter.java:206)&#xD;
	at org.restlet.routing.Filter.doHandle(Filter.java:159)&#xD;
	at org.restlet.routing.Filter.handle(Filter.java:206)&#xD;
	at org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:211)&#xD;
	at org.restlet.Component.handle(Component.java:392)&#xD;
	at org.restlet.Server.handle(Server.java:516)&#xD;
	at org.restlet.engine.ServerHelper.handle(ServerHelper.java:72)&#xD;
	at org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:152)&#xD;
	at org.restlet.ext.jetty.JettyServerHelper$WrappedServer.handle(JettyServerHelper.java:170)&#xD;
	at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:452)&#xD;
	at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:894)&#xD;
	at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:948)&#xD;
	at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:851)&#xD;
	at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)&#xD;
	at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77)&#xD;
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:622)&#xD;
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:46)&#xD;
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:603)&#xD;
	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:538)&#xD;
	at java.base/java.lang.Thread.run(Thread.java:833)&#xD;
</trace></error>

@PaulRambags Thanks for the report. This seems to be a Java issue with the 2-slash form of UNC URIs.

Here is a possible solution:

--- a/framework/framework-core/src/main/java/org/daisy/pipeline/script/ScriptInput.java
+++ b/framework/framework-core/src/main/java/org/daisy/pipeline/script/ScriptInput.java
@@ -195,6 +195,12 @@ public class ScriptInput {
                                        throw new FileNotFoundException(
                                                "Input not found: expected an absolute file or a relative path, but got: " + uri);
                                try {
+                                       // Windows: try to convert 2-slash UNC form to 4-slash form
+                                       if (uri.getAuthority() != null && !"".equals(uri.getAuthority()))
+                                               try {
+                                                       uri = new URI("file", "", "//" + uri.getAuthority() + uri.getPath(), uri.getQuery(), uri.getFragment());
+                                               } catch (URISyntaxException e) {
+                                               }
                                        absoluteFile = new File(uri);
                                } catch (IllegalArgumentException e) {
                                        throw new FileNotFoundException(

Someone would need to test it on Windows. There might be similar issues in different places in the code.