On Mon, Jun 9, 2014 at 9:07 AM, Mark Thomas <ma...@apache.org> wrote: > On 09/06/2014 13:46, Jimmy Royer wrote: >> Is there any information that I should add to this to get some help? > > Right now, no. There may be further questions as folks dig into this. > >> 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)? > > No. That is likely to get closed as INVALID since - at the moment - > there is not a clearly identified bug in Tomcat. > > There are lots of moving parts here and while there is obviously a bug > somewhere, it isn't yet clear where that bug is. > > I suspect that most folks took a look at this and decided it was just > too big / complicated to get into. Given the complexity of the > situation, the effort you have taken to make the issue as clear as it > is, is very much appreciated. To be honest, I doubt anyone could have > written a better question given the problem. > > Give me a little time to dig into it and I'll get back to you with > either an answer or - more likely - some specific questions or things to > test. > > Mark
I understand. I can submit what I started as a sample project to target this bug which includes a minimum of dependencies along with a Maven configuration. I can push it to github and that would be very easy for you to get it. What do you prefer? My sample project does not exactly shows the problem, as a call to AsyncContext#dispatch is necessary and I'm not sure how and why it's used. But that could save you the project setup time at least. Jimmy >> >> 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 >> > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org > For additional commands, e-mail: users-h...@tomcat.apache.org > --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org