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

Reply via email to