Is there any information that I should add to this to get some help? Or should I just go straight and create a bug report for this (as this might not be a message targeting the users mailing list but Tomcat's developers)?
Thanks, Jimmy On Thu, Jun 5, 2014 at 2:04 PM, Jimmy Royer <jimlero...@gmail.com> wrote: > Hello, > > I am using this combo of components: > > * Apache Tomcat 8.0.8 > * Apache CXF 2.7.11 > * Servlet 3.0 > * JAX-RS 2.0 > * JDK 1.7.0_45 > * Windows 7 > * Chrome browser with the Advanced REST Client plug-in > > I developed some web services using REST that leverages CXF ability to > do asynchronous methods, and under the hood, that uses Apache Tomcat. > > This is working fine overall, the setup and configuration are all > good. There is one exception though. This is when I make a request to > an async web service that uses a space in the URL, encoded to a %20. > > The encoding itself works fine, but internally, when Tomcat resumes > the Servlet 3 continuation, it passes to some class the previously > decoded path and sets it on the request URL. The request is then > passed to the CXF layer, that expects a valid URL with no space and > tries to instantiate a URL object from it, and fails. Here is the > stack trace I got: > > > > """ > 05-Jun-2014 12:33:37.426 SEVERE [http-apr-8080-exec-10] > org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() > for servlet [CXFServlet] in context with path [] threw exception > [java.lang.RuntimeException: java.lang.IllegalArgumentException: > Illegal character in path at index 134: > http://127.0.0.1:8080/qlikview11/bi-service/c4aeb78f-109a-49a3-9716-10d83272a845/folders/13e5f0b4-90e2-4d11-bc5f-4f688e53bed2/Software > Division/documents] with root cause > java.net.URISyntaxException: Illegal character in path at index 134: > http://127.0.0.1:8080/qlikview11/bi-service/c4aeb78f-109a-49a3-9716-10d83272a845/folders/13e5f0b4-90e2-4d11-bc5f-4f688e53bed2/Software > Division/documents > at java.net.URI$Parser.fail(URI.java:2829) > at java.net.URI$Parser.checkChars(URI.java:3002) > at java.net.URI$Parser.parseHierarchical(URI.java:3086) > at java.net.URI$Parser.parse(URI.java:3034) > at java.net.URI.<init>(URI.java:595) > at java.net.URI.create(URI.java:857) > at > org.apache.cxf.transport.servlet.BaseUrlHelper.getBaseURL(BaseUrlHelper.java:49) > at > org.apache.cxf.transport.servlet.ServletController.getBaseURL(ServletController.java:78) > at > org.apache.cxf.transport.servlet.ServletController.updateDestination(ServletController.java:87) > at > org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:200) > at > org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:153) > at > org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:171) > at > org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286) > at > org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:211) > at javax.servlet.http.HttpServlet.service(HttpServlet.java:618) > at > org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:262) > at > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:301) > at > org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) > at > org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:721) > at > org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:639) > at > org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:605) > at org.apache.catalina.core.AsyncContextImpl$1.run(AsyncContextImpl.java:208) > at > org.apache.catalina.core.AsyncContextImpl.doInternalDispatch(AsyncContextImpl.java:363) > at > org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214) > at > org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) > at > org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503) > at > org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:136) > at > org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:78) > at > org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610) > at > org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) > at > org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:405) > at > org.apache.coyote.http11.AbstractHttp11Processor.asyncDispatch(AbstractHttp11Processor.java:1636) > at > org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:646) > at > org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:277) > at > org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2451) > at > org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2440) > at > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) > at > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) > at > org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) > at java.lang.Thread.run(Thread.java:744) > """ > > > > The URL is perfectly encoded when it gets in the Tomcat machinery, but > it gets decoded along the way, and the information is not re-encoded > along the way. It's hard for me to say what should be the proper logic > as I am not familiar with the Tomcat code base, but here is the > workflow of the key classes, methods and URI values that got to this > situation: > >> AsyncContextImpl#dispatch: The request path info used to be dispatched. >> This path was previously decoded during the previous operations. > > --> ApplicationContext#getRequestDispatcher: The decoded path is > eventually sent to this method. The path is normalized and appended to > a variable uriCC meant to represent an URI. The value of this variable > is never re-encoded nor validated to a valid URI. A new > ApplicationDispatcher is returned that contains a non-encoded URI. > > --> ApplicationDispatcher#doDispatch: The previously created > application dispatcher now has to dispatch the request. It overwrites > the request URL from the incoming request (which is properly encoded) > with the previously computed path that is non-encoded. > > --> BaseUrlHelper#getBaseURL: This CXF method eventually gets > called with a request that contains a non-valid URI. The code that > triggers the exception is equivalent to: > URI.create(request.getRequestURL().toString()). > > I came across a somewhat similar bug in the CXF Jira (where the cause > was different). The CXF folks really expect the URL to be properly > encoded. In my case, it seems that this might not be properly handed > by Tomcat to CXF. > > As I said, I'm not familiar with the code base of both Tomcat and CXF, > so please tell me if that could be something wrong with my setup, or > if that is a bug. > > To reproduce this behavior, I guess that these steps would do it: > > 1- Develop an async web method for Tomcat (I'm using Apache CXF JAX-RS > async support for that). > 2- Send a request to this web method that contains an encoded %20 > space, make sure that async support is in and servlet 3 continuations > are used. > > That would be the bare minimum I guess, and not the exact setup I have! > > Best regards, > Jimmy Royer --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org