Bug 66533 - Wrapping Requests or Responses in Valves is not possible
Summary: Wrapping Requests or Responses in Valves is not possible
Status: RESOLVED DUPLICATE of bug 45014
Alias: None
Product: Tomcat 11
Classification: Unclassified
Component: Catalina (show other bugs)
Version: unspecified
Hardware: PC Linux
: P2 enhancement (vote)
Target Milestone: -------
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-03-17 16:32 UTC by Wolfgang Illmeyer
Modified: 2023-06-02 08:35 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Wolfgang Illmeyer 2023-03-17 16:32:59 UTC
The javadoc of org.apache.catalina.Valve.invoke(Request, Response) states:

> An individual Valve MAY perform the following actions, in the specified order:
> […]
> Examine the properties of the specified Request and Response, wrap either or
> both of these objects to supplement their functionality, and pass them on.

Due to the fact that that said method receives org.apache.catalina.connector.Request and org.apache.catalina.connector.Response, neither of which are interfaces, i don't see how it would be possible to actually wrap either request or response (at least without the developer resorting to ugly black-magic-type measures).

In fact, the argument classes implement HttpServletRequest and HttpServletResponse, respectively, which would be much better suited for creating wrappers (indeed javax.servlet.http.HttpServletRequestWrapper and so on already exist)

I therefore suggest that, with Tomcat 11, the time has finally come to stop mocking developers trying to implement actual functionality in Valves and change the signature of Valve.invoke() to something like:

void invoke(HttpServletRequest, HttpServletResponse)

If I'm missing something from the Request and Response classes, that is currently needed by the included Valves, maybe it could be passed as a third argument of some new type ValveContext or similar. Another possibility would be to extend HttpServletRequest and HttpServletResponse for those purposes, use the resulting interfaces as argument types for the invoke() method and also provide corresponding wrapper base classes.
Comment 1 Mark Thomas 2023-03-17 17:15:29 UTC
See bug 45014

I suspect that this request will get closed for the same reason. Tomcat's internal architecture hasn't changed that much since that bug.
Comment 2 Wolfgang Illmeyer 2023-03-27 11:40:49 UTC
Ok, after playing around with Valves for a little, I would advise against actually using HttpServletRequest & HttpServletResponse and instead opt for extracting an interface from the currently used Request & Response classes.
Comment 3 Christopher Schultz 2023-03-29 18:35:08 UTC
(In reply to Mark Thomas from comment #1)
> Tomcat's internal architecture hasn't changed that much since that bug.

API instability! (I say while smiling and glancing sidelong at Rémy.)

While I am still convinced that RequestWrapper and ResponseWrapper classes would be a good inclusion to Tomcat, I am not convinced that changing the Valve interface to use some other classes or interfaces makes much sense.

Switching to HttServletRequest (and response) is too limiting, and extracting an IRequest interface (and similar with response) is just busy-work. Extending Request (and response) to override capability is just as easy as implementing the dozens of methods from Request (and response) in a custom class. Using my unofficial wrappers cuts-out some of the busy-work, but it's all currently doable.

A Valve is not a Filter. Let's not pretend that it is. Valves exist to do /very specific things/ that cannot be done as Filters, and the power to do that comes directly from explicit access to internal classes such as Request (and response).
Comment 4 Mark Thomas 2023-06-02 08:35:14 UTC

*** This bug has been marked as a duplicate of bug 45014 ***