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

Reply via email to