On Mon, Jun 9, 2014 at 9:00 AM, Daniel Mikusa <dmik...@gopivotal.com> wrote: > On Mon, Jun 9, 2014 at 8:46 AM, Jimmy Royer <jimlero...@gmail.com> wrote: > >> Is there any information that I should add to this to get some help? >> > > Any chance you could put together a sample app or unit test to replicate > the problem? Ideally without third party components like CXF. It would > make it easier someone on the list to recreate the problem and thus easier > for someone to help.
I've setup a project and I can reproduce something where we see that the URL is non-encoded when I make use of the AsyncContext#dispatch method, but the overall workflow of my sample does not make sense because I don't know when this method should used or why. >> 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)? >> > > The users list is always a good first place to start. As an FYI, don't top > post. Reply inline like this, or just at the bottom. It's the convention > followed on the list. Okay got it, I'll follow the standard, thanks for the reply! > Dan > > >> 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