3
votes

[context] tomcat 7 - java 1.7

Hey everyone; I'm facing with stranges working. In my web.xml file, I mapped request like this :

web.xml

<web-app>
    <filter>
        <filter-name>filter</filter-name>
        <filter-class>demo.DemoFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>Servlet</servlet-name>
        <servlet-class>demo.DemoServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>Servlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

DemoFilter.java (implements Filter)

@Override
public void doFilter( ServletRequest req, ServletResponse res, FilterChain chain )
        throws IOException, ServletException
{
    try
    {
        chain.doFilter(req, res);
    }
    catch ( Exception e )
    {
        System.err.println("error");
        ((HttpServletResponse) res).setContentType("text/html");
        ((HttpServletResponse) res).setStatus(HttpServletResponse.SC_NOT_FOUND);
        res.getWriter().write("foo");
    }
}

DemoServlet.java (extends HttpServlet)

@Override
protected void doGet( HttpServletRequest req, HttpServletResponse resp )
        throws ServletException, IOException
{
    System.err.println(req.getRequestURI());
    throw new RuntimeException("ERROR");
}

[1 = Expected result] First, when I tried to request "/foo/bar", the filter and the servlet were called (and the page display the word 'foo'). Console result :

/foo/bar    
error

[2 = Unexpected result] Then, when I tried to request "/WEB-INF/foo/bar", nothing was called (my filter and my servlet were not hit) and I get a Tomcat error report :

HTTP Status 404 -

type Status report

message

description The requested resource is not available.
Apache Tomcat/7.0.30

EDIT : Here, I expected to get the following result :

/WEB-INF/foo/bar    
error

I aim to use my Filter to handle Exception ("/WEB-INF" calls included).

  • Why request which start with "/WEB-INF/" never hit filter/servlet mapped on "/*" pattern ?
  • How can we solve this problem?

Thanks in advance!

PS : I would like to keep my current web.xml configuration ("url-pattern" = "/*" ; without using "error-page")


EDIT : My question was misunderstood. I don't want to serve file access under my "WEB-INF" directory. I want to serve every request with my Filter and Servlet (url-pattern='/*') even if the request URI start with "/WEB-INF/". Thanks !

5
Because that's what it says in the Servlet Specification.user207421
why do you want ot request /WEB-INF/foo/bar? what do you plan to put there that will need such access?TheZuck
@TheZuck To create a filter which log user action for example. Or in my case, to centralize exception handling in a filter.Passage One
I get what you're trying to do now, this is an interesting question, however, since WEB-INF is so special the answer will be very specific and not so interesting IMO. Serve everything else using your regular filter, and catch hack attempts on the other 1000 ways people can try to penetrate your site. Accessing WEB-INF (and its companion META-INF) is something which can only come from a hack attempt, so I wouldn't feel obligated to respond in a graceful way.TheZuck
tomcat 7 - java 1.7 - this is criminal. No one should be running JDK 7 anymore. Upgrade, please.duffymo

5 Answers

6
votes

There's a major conceptual misunderstanding here. Resources in /WEB-INF aren't publicly accessible at all. The way how you put the question indicates otherwise. This is not right. I believe that you just asked about the concrete problem the wrong way.

Based on a comment, I understood that you wanted to log accessed files in /WEB-INF as well as 404 errors. I guess that you actually meant that you want to log forwarded, included and error'ed resources as well next to directly requested resources. Normally, the forwarded and included resources are indeed hidden in /WEB-INF to prevent direct access.

A filter is by default invoked on directly requested resources only, not on forwarded and included resources nor on error'ed resources like in your 404 attempt. For that you need to add the appropriate <dispatcher> entries to the mapping:

<filter-mapping>
    <filter-name>filter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

(each of them are optional; the REQUEST is the default one when totally absent)

This way the filter will not only intercept on directly requested resources, but also on forwarded, included and error'ed resources. The ERROR dispatcher will make it to kick in on the 404 error as well.

2
votes

WEB-INF directory is a private area of the web application, any files under WEB-INF directory cannot be accessed directly from browser by specifying the URL like the way you've specified.

The web container will not serve the content of this directory. However the content of the this directory is accessible by the classes, like the servlets that you've mapped in your web.xml within the application.

2
votes

If you want to restrict direct URL access to some files, put them under WEB-INF directory.

Quote from here: http://www.servletworld.com/servlet-tutorials/web-application-directory-structure.html

WEB-INF directory is a private area of the web application, any files under WEB-INF directory cannot be accessed directly from browser by specifying the URL like http://somesite/WEB-INF/someresource.html. Web container will not serve the content of this directory. However the content of the WEB-INF directory is accessible by the classes within the application. So if there are any resources like JSPs or HTML document that you don’t wish to be accessible directly from web browser, you should place it under WEB-INF directory.

0
votes

Both answers posted are correct and this is the same for any application server you use and JDK. Although from servlet specification 3.0 web.xml is optional or you could use web-framgment.xml to break web.xml.

0
votes

According to the servlet specification, any requests from the client to access the resources in WEB-INF/ directory must be returned with a SC_NOT_FOUND(404) response. See section 10.5 Directory Structure.

https://download.oracle.com/otn-pub/jcp/servlet-3_1-fr-eval-spec/servlet-3_1-final.pdf https://download.oracle.com/otn-pub/jcp/servlet-3.0-fr-eval-oth-JSpec/servlet-3_0-final-spec.pdf