Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify behaviour when the same filter is matched by several filter-mapping elements #52

Open
glassfishrobot opened this issue Jan 7, 2013 · 6 comments
Labels
Candidate4NextRelease This issues should be consider for inclusion in the next release project. Question Further information is requested

Comments

@glassfishrobot
Copy link

The chapter 6.2.4 Configuration of Filters in a Web Application defines how a container builds the chain of filters to be applied to a particular request URI.

My question is what should happen if there are several matching filter-mappings for the same filter (either by different s, or by an and a ):
whether
a) the filter has to be called several times, as many as how many matching s are there.
or
b) the filter has to be called only once, honoring the first filter-mapping that matches,

An example:

filterA /view/* *.do

If the requested URI is "/view/bar.do", does the filter have to be called twice?

My own reading is that "a)" (multiple calls) is what is implied by that chapter, but I would like this to be mentioned explicitly.

If actually the requirement is "b)" (single call), then I would like someone to clarify what mapping takes priority when there is both an url-pattern and a servlet-name match. As the servlet-name mappings are processed first, it seems that the servlet-name mapping wins, but it is confusing as those filters are positioned later in the resulting filter chain than the ones mapped by url-patterns.

In Tomcat 7 the "b)" behaviour was implemented but with url-patterns having the priority, stemming from the following issue:
https://issues.apache.org/bugzilla/show_bug.cgi?id=49922

@glassfishrobot
Copy link
Author

@glassfishrobot Commented
Reported by kkolinko

@glassfishrobot
Copy link
Author

@glassfishrobot Commented
janbartel said:
Interestingly jetty shows two different behaviours. If you define a single filter mapping with multiple url-patterns as the example above, we will only apply the filter once. If, however, you defined different filter mappings for each url-pattern, we would apply the filter once for each mapping. Obviously consistent behaviour would be desirable.

Section 6.2.4 does mention breaking a single filter mapping with multiple url-patterns into multiple filter-mappings - which would lend some support to calling the filter multiple times - however the wording mentions breaking a single filter-mapping into multiple filter-mappings only in the context of there being at least one servlet-name present:

"If a filter mapping contains both and , the container must expand the filter mapping into multiple filter mappings (one for each and , preserving the order of the <servlet-name< and elements".

So the current wording does not make clear if filter mappings with multiple url-patterns should be broken out into separate mappings. Furthermore, it does not make clear whether multiple mappings to the same filter, whether originating from multiple matching url-patterns and/or a servlet-name, result in multiple invocations of the same Filter in the filter chain.

In considering a wording fix and clarification of multiple vs single invocation, we need to bear in mind the resultant filter chain ordering. Consider the following:

AFilter /foo/* *.jsp BFilter *.jsp AFilter /foo/bar/*

The possible filter chain outcomes for a request path of "/foo/bar/x.jsp" are:

  1. With multiple applications of the same filter (and multiple url-patterns within a single mapping are treated as multiple mappings):
    AFilter (/foo/)
    AFilter(
    .jsp)
    BFilter (.jsp)
    AFilter (/foo/bar/
    )

  2. Single application of matching filter, first wins:
    AFilter (/foo/)
    BFilter (
    .jsp)

  3. Single application of matching filter, last wins:
    BFilter (.jsp)
    AFilter(/foo/bar/
    )

Option 1) has the advantage of being strictly consistent. Whilst with 2) and 3) it's simply an arbitrary choice, and moreover leaves users with parts of their web.xml that are effectively being ignored.

Incidentally, I think the wording of Section 8.2.3 point 2.a. is wrong. It says "Filters that match a request are chained in the order in which they are declared in the web.xml". In fact it is not the order of the declaration of the , but the .

@glassfishrobot
Copy link
Author

@glassfishrobot Commented
This issue was imported from java.net JIRA SERVLET_SPEC-52

@glassfishrobot
Copy link
Author

@gregw gregw added Enhancement New feature or request and removed Component: Filter/Servlet labels Jan 18, 2020
@gregw gregw added Question Further information is requested and removed Enhancement New feature or request labels May 21, 2020
@gregw
Copy link
Contributor

gregw commented May 21, 2020

Here is another example that illustrates this question:

  <servlet>
    <servlet-name>Servlet0</servlet-name>
    <servlet-class>org.example.ZeroServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>Servlet0</servlet-name>
    <url-pattern>/foo/*</url-pattern>
  </servlet-mapping>
  
  <filter>
    <filter-name>X</filter-name>
    <filter-class>org.example.XFilter</filter-class>
  </filter>
  
  <filter-mapping>
    <filter-name>X</filter-name>
    <servlet-name>Servlet0</servlet-name>
    <url-pattern>*.txt</url-pattern>
    <url-pattern>/foo/*</url-pattern>
  </filter-mapping>

Should a request to /foo/bar.txt invoke filter X once, twice or three times?

Section 6.2.4 of of the 4.0 spec says that combined filter mapping is equivalent to:

  <filter-mapping>
    <filter-name>X</filter-name>
    <servlet-name>Servlet0</servlet-name>
  </filter-mapping>
  <filter-mapping>
    <filter-name>X</filter-name>
    <url-pattern>*.txt</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>X</filter-name>
    <url-pattern>/foo/*</url-pattern>
  </filter-mapping>

It then tells us that the order is by the url-patterns in the order they are declared and then the filtername, but it is silent of what to do if a mapping has mutliple matches that apply.

@gregw
Copy link
Contributor

gregw commented May 21, 2020

See also #318 for a related clarification

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Candidate4NextRelease This issues should be consider for inclusion in the next release project. Question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants