Hi Christopher.

I believe that yours is a really good explanation of why Tomcat collapses consecutive slashes in URLs.
It's certainly worth a FAQ article, in case the question ever pops up again.

It maybe even be worth a note somewhere in the main documentation, such as where it explains how Tomcat actually maps URLs to webapps. Except that I can't locate the documentation which specifically explains this..
Maybe this is because Tomcat normally refers to the Servlet Spec for this ?

The closest I find is here : http://tomcat.apache.org/tomcat-9.0-doc/config/context.html#Naming Maybe inserting a note to the effect of 'Note: before any of the mapping below takes place, Tomcat collapses any consecutive "/" characters in the path portion of the URL to a single "/". The complete explanation is here : --> FAQ article" '


On 05.12.2019 17:13, Christopher Schultz wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

André,

On 12/5/19 04:55, André Warnier (tomcat/perl) wrote:
Christopher,

I believe that the problem of the OP is that either this filter or
the application, *relies* on the fact that Tomcat would NOT
collapse multiple consecutive slashes in the URL, to a single
slash. That (the non-collapsing) seems to have been the case in
some previous versions of Tomcat, and has apparently been changed
in more recent versions of Tomcat (and probably rightly so, to
adhere more strictly to the specs).

Actually, it's somewhat in *violation* of the specs. But it's a
generally-accepted violation because it allows security rules to
actually remain sane.

If you want to protect "/foo/bar.html" which maps to a file on the
disk, you'll find that the filesystem collapses slashes and will load
that same file regardless of how many extra slashes you put in there.
"/foo////bar.html" is going to give you the same result.

The same is true for multiple levels like "/foo/bar/bar.html". If you
want to protect all files in "/foo/bar" it's not practical to add
protections for "/foo/bar/" and "/foo//bar/" and "/foo///bar/" and ...
you see where I'm going with this.

So the server decides that slash-collapsing will allow security
constraints to be more practically applied.

What if we get super-spec-compliant and allow those extra slashes?
Well, you'd have to get really (and, IMHO, /overly/) strict about how
those slashes are treated. In Java, you'd have to do something like this
:

    String path = ... // file-path from request
    String docRoot = ... // docroot base, absolute
    File file = new File(docRoot, path);
    if(!file.exists())
      // return 404
    if(!path.equals(file.getAbsolutePath().substring(docRoot.length()))
      // return 404

That last check will check to make sure that the path requested by the
client *exactly equals* that of the path on the disk. That means that
multiple-slashes are essentially forbidden when requesting disk-files.

(It gets more fun when you are requesting a directory which has an
"index file" like index.html and you have to decide whether or not
it's okay to load that file automatically, even though the client
didn't specifically request it.)

So now we are spec-compliant. Yay! Except that all those sloppy
webmasters links no longer work because they do all kinds of weird URL
manipulations that don't always result in a perfectly-clean URL. So
we've achieved spec-compliance and inconvenienced users. Did we really
achieve anything? Those multi-slash URLs were never going to work. It
is really a big deal to just ... let them work? So we collapse slashes
and everything is fine. Nobody is really going to complain if
/foo//bar.html and /foo/bar.html both work instead of one of them
returning 404.

What about resource that are *not* on a disk? Like servlets and stuff
like that? Well, the servlet spec allows us to map to URL patterns of
various types. Some are exact, others prefixes, etc. We can also
define security constraints with the same kind of url-pattern basis.
Generally, those things should agree. What happens when you introduce
multiple-slashes in there?

Well, nobody is ever going to map a bunch of additional slashes to
make their servlets work properly. So we are back to the same problem
as the on-disk-file: the multiple-slashes are essentially forbidden if
we want to be super-spec-compliant. So we relax a little and take the
practical approach: collapse slashes and move on with our lives. This
has the added benefit of making security constraints more consistent,
and fewer mistakes. And encouraging fewer security mistakes is a Good
Thing.

And the collapsing of multiple consecutive slashes in the URL, is
probably done at such an early stage in the request processing,
that it is not easy to do something to turn it off (which may or
may not be spec-compliant anyway).

Turning it off would be a giant mess. And yes, it needs to be doe
quite early because Tomcat has to figure out which web application
will be responding to the request. So it's one of the first things
that Tomcat has to do with  an incoming request.

I did not look up the HTTP specs to find where this collapsing of
slashes is specified, but I found this in the Apache httpd
documentation, which would seem to suggest that consecutive slashes
are not necessarily invalid, and may even *mean* something :
http://httpd.apache.org/docs/2.4/mod/core.html#location (see : Note
about "/")

Ok, then I got curious and did have a quick look at RFCs 7230 and
7231, and they are mute about consecutive slashes.  RFC2396 on the
other hand does not seem to forbid consecutive slashes, and as I
understand it, they are even "significant", as they seem to delimit
a path element (which just happens to be empty).
https://tools.ietf.org/html/rfc3986#section-3.3 does not seem to
forbid consecutive slashes either.

But I would suppose that if the Tomcat developers decided to
collapse multiple consecutive slashes, they must have had a
reason.

Yep: see above. It's a deliberate violation of the spec designed to
make the world work the way everyone expects it to work, and also make
security configuration sensible, too.

- -chris

On 04.12.2019 15:18, Christopher Schultz wrote: Kushagra,

On 12/4/19 06:32, Kushagra Bindal wrote:
I am not saying that this is a tomcat issue, I am just asking
if there is a way by which we can handle this. As maybe in
later version of 8.5.24 Tomcat has take some action to handle
such conditions.

I still don't really see the problem. Your responses have included
tiny bits of information separately and not everything all at once.
If you have a <filter> defined and mapped to a URL pattern, it
should work and not give you a 404.

Try this with the examples application:

http://localhost:8080/examples/servlets/servlet/HelloWorldExample

It will respond no matter how any slashes you put in various
places:

http://localhost:8080/examples/servlets/servlet//HelloWorldExample
http://localhost:8080/examples/servlets//servlet//HelloWorldExample


http://localhost:8080/examples/servlets/servlet//////HelloWorldExample

There are no 404 errors.

Are you sure your application has deployed correctly?

-chris

On Wed, Dec 4, 2019 at 4:53 PM Mark Thomas
<ma...@apache.org> wrote:

On 04/12/2019 05:16, Kushagra Bindal wrote:
Hi Mark/Manna/Chris,

Do we have any way out to handle this type of behavior?

All the evidence so far points to an application issue, not
a Tomcat issue.

If you are able to create a simple test case that
demonstrates a Tomcat issue we can take a look.

Mark



On Tue, Dec 3, 2019 at 5:46 AM Kushagra Bindal <
bindal.kusha...@gmail.com>
wrote:

Chris,

If you will check in my early email then you will find
that with // it
is
throwing 404. But as soon as I removed it manually then
it starts
working
properly and all these url were working fine in 8.5.24
version.

On Tue, Dec 3, 2019, 1:21 AM Christopher Schultz <
ch...@christopherschultz.net> wrote:

Kushagra,

On 12/2/19 11:29, Kushagra Bindal wrote:
I think it should be.

<filter>
<description>DanglingSessionInvalidateFilter</description>




<filter-name>DanglingSessionInvalidateFilter</filter-name>
<filter-class>com.SessionInvalidateFilter</filter-class>


</filter> <filter-mapping>
<filter-name>DanglingSessionInvalidateFilter</filter-name>




<url-pattern>/restcall/*</url-pattern> </filter-mapping>

Here in below URL:

"http://backend_tomcat:8080/sdm/restcall/v1/platform//healthC
hec


k"



sdm will be the context path.

But in another example that I shared in my last
email, one use case
http://backend_tomcat:8080//sdm/restcall)(.*)/file_uploads


my context path itself contains //.

So, please suggest a viable solution which we can
try to solve this problem. :)

Thanks in advance for your help & support in
resolving this issue.

All of these slashes really should be collapsed into a
single slash before processing. I don't see an issue. If
the client requests:

http://backend_tomcat:8080/sdm/restcall/v1/platform//healthCheck





then the filter/servlet at /sdm/restcall/* will respond.

If the client requests:

http://backend_tomcat:8080//sdm/restcall/foo/file_uploads



Then the filter/servlet at /sdm/restcall/* will respond.

It doesn't really matter how many extra slashes the
client adds... they should all be collapsed by the server
and your application should not have to make arrangements
to handle them, add them back, or worry about whether
they are there or not.

-chris

On Mon, Dec 2, 2019 at 9:00 PM Mark Thomas
<ma...@apache.org> wrote:

On 02/12/2019 10:59, Kushagra Bindal wrote:
Hi Mark,

These are Rest Endpoints, and so will be
processed through Filter.

That is unusual.

Do, you think Servlet mapping will play any
role here?

If the filter is handling them, no.

So I'll change the question. Which URL pattern
from the filter mapping do you expect:

"http://backend_tomcat:8080/sdm/restcall/v1/platform//health
Che


ck"





to match?

The Context Path question still needs an
answer.

Mark



On Mon, Dec 2, 2019 at 2:33 PM Mark Thomas
<ma...@apache.org> wrote:

On 02/12/2019 04:53, Kushagra Bindal
wrote:
Hi Mark,

Please find the snippet from web.xml

Which URL pattern do you expect:

"http://backend_tomcat:8080/sdm/restcall/v1/platform//heal
thC


heck


"



to match?

And what is the Context Path at which the
application is deployed?

Mark



<servlet>
<servlet-name>default</servlet-name>




<servlet-class>org.apache.catalina.servlets.DefaultServlet</servle
t-c




lass>


<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param> <init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet> <servlet>
<servlet-name>jsp</servlet-name>


<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class







<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param> <init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet> <!-- The mapping for the
default servlet --> <servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> <!-- The mappings for
the JSP servlet --> <servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping> <servlet>
<servlet-name>PatternTemplateLaunchServlet</servlet-name>




<servlet-class>PatternTemplateLaunchServlet</servlet-class>


</servlet>
<servlet>
<servlet-name>MyReportsLaunchServlet</servlet-name>




<servlet-class>MyReportsLaunchServlet</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>PatternTemplateLaunchServlet</servlet-name>




<url-pattern>/patterntemplatelaunch</url-pattern>
</servlet-mapping> <servlet-mapping>
<servlet-name>MyReportsLaunchServlet</servlet-name>




<url-pattern>/MyReportsLaunchServlet</url-pattern>
</servlet-mapping>

Please let me know if you need anyother
details from our side.

On Mon, Dec 2, 2019 at 3:07 AM Mark
Thomas <ma...@apache.org> wrote:

On 01/12/2019 07:11, Kushagra Bindal
wrote:
Hi Manna/Mark,

Below are the sample URL which we
are passing to Tomcat.

http://backend_tomcat:8080//sdm/restcall)(.*)/file_uplo
ads






http://backend_tomcat:8080/sdm/restcall/v1/platform//healthCheck

As from the above example you can see
that // location may vary case
by
case.

So, you guys have a probable solution
to handle such situation, then
please
do let me know.

Tomcat is simply going to normalize
those to single '/'. The
application
should be fine with that.

To repeat my previous request: Can you
provide more details such as: - an
example request URI *and* - the
<url-pattern> for the servlet you
expect it to match to

Mark


-----------------------------------------------------------------




- ----


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




---------------------------------------------------------------------


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

-----BEGIN PGP SIGNATURE-----
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl3pLLwACgkQHPApP6U8
pFhJBA//XZXoK7Yd01UBtUBSrji4l2lwCiT8pxh9YGvWd6FOs3SVpTyoNg1EVxqZ
JCeBzFeYIjOouA8FyXbOZO6olSi/B6SP/yNPtchgYQnCTloGKrH3Og1t46ZdfpgZ
408ay/UpIZJAOZTPjtnXYLmgwNgm79xR82+sOb/LK6tSk0ujzDryEuMG/QECvulM
NsGl/PXVo5WBlvHoj3L7WgcMAx7hnmBWBr1SLdnGi0a/ZlgzGYriH9LLaSfOjIyc
y2lmij9uAzwiiCe46+bQJ3YHxm4m+/39jFizJj+WhE/f8ecj3vxLcBoAwaruQRXW
b65/fzPRfpGA+mUapFTh5S2+KS8YWhbABdfLL1Du6RDIhmEFTa2SkMs/Qpo9bAlY
fYuVeuwudIQrXingp+uRFhMMbbyzFd6U89pktf3k3wBLfazOnB5csMOwPcE1jlq2
TGcjiLq6PwnfSeAKhCEQHzgLOyXIM0izsd0nkRvAC5YuuhVN6vqetma8wvMsvoVD
kaPQwKdRXHjoydLF9z4GaKRO97yeC9EP+vHQhXjrQqWe1HO4q06xL8EwpxTU46T+
qqXRLtvEJrdKfOaiVK0E+it9Rh5uSSKjzW79qVzuQ5H59Lb4fJm0BsKc0nI2bgfu
wkTazYm8SJ0ziZs/ElCpUKgLG5WChRiSDFowUEnM35U7+1T6H4U=
=Fh+F
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
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