On 2014/06/19 05:35 PM, Christopher Schultz wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Michael,

On 6/19/14, 10:54 AM, Michael van Rooyen wrote:
On 2014/06/19 04:48 PM, Michael van Rooyen wrote:
On 2014/06/19 04:20 PM, Christopher Schultz wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256

Michael,

On 6/19/14, 9:43 AM, Michael van Rooyen wrote:
We've been running Tomcat 6.0.36 without issues for many
months. Our pages have many components and are constructed
using getRequestDispacher("...").include(request, response)
to pull the components in.

For the past few weeks, we've had a few instances where, in
constructing a page, the parameters in the query string
passed to getRequestDispatcher(), are not being passed
through to the components included.

For example, if a browser submits the request
/main.jsp?id=foo, then from that page, we include
/product.jsp?id=bar, the product.jsp page should see the
following parameters:

id = [ bar, foo ]

This happens almost all the time, but sporadically, we're
getting just:

id = [ foo ] instead.

If the entry page was /main.jsp?cat=foobar, for example, then
on including /product.jsp?id=bar, we should get:

id = [ bar ], cat = [ foobar ]

But instead, we sometimes get just:

cat = [ foobar ]

Here is an extract from our logs.  The first is just before
the call the getRequestDispatcher().include(), and shows the
URI.

19 Jun 2014 2:58:04 PM
org.apache.catalina.core.ApplicationContext log INFO: Trace @
2014-06-19 14:58:04.808 [system: TP-Processor7]
/full/include/view/generic/smallfeature.jsp?id=25951215082928&cached=true



web.Session$Site.include(Session.java:58)
And then the smallfeature.jsp logs the contents of the
parameterMap directly thereafter:

19 Jun 2014 2:58:04 PM
org.apache.catalina.core.ApplicationContext log INFO: Trace @
2014-06-19 14:58:04.81
[993BE7ADFD65B94F2A62E85B64B3B8A2/null: TP-Processor7]
Parameters: cat = lcu; page = browse;
web.tags.Log.doStartTag(Log.java:48)


You can see the id and cached parameters are missing, and
the parameters that are available are actually those from the
main page.  Has anyone experienced this before, or know what
may cause it?
I think there is a hole in the spec, here, because Servlet Spec
3.0, section 9.1.1 states:

" Parameters specified in the query string used to create the
RequestDispatcher take precedence over other parameters of the
same name passed to the included servlet. The parameters
associated with a RequestDispatcher are scoped to apply only
for the duration of the include or forward call. "

The term "take precedence" could be interpreted as "overriding
completely" (Tomcat's implementation) or "appending" (your
expectation), and I think I would agree with the current
implementation Tomcat appears to have: the "id" parameter in
your included query string completely replaces the "id"
parameter that came from the original request.

Short of a clarification of the Servlet spec, you are going to
have to do something else in order to fix this problem. Might I
recommend the use of a request /attribute/ instead of a query
string parameter to pass information from one resource to
another for inclusion?
Thanks for the info Chris.  The problem is that tomcat is not
behaving consistently - from what I see, Tomcat doesn't "override
completely", rather, it "appends".  But sometimes, sporadically,
it "ignores", and when it does ignore, it breaks our site.

If you compare the two logs I listed earlier (the "ignore"
scenario), to two below (normal scenario), you see the parameters
being appended.  I'm not sure if there is something weird about
our code that causes the "append" behaviour, but for now I'm
assuming that this is Tomcat's normal behaviour.

Normal behaviour: just before the call to
getRequestDispatcher().include(), we log the URI:

19 Jun 2014 4:30:16 PM
org.apache.catalina.core.ApplicationContext log INFO: Trace @
2014-06-19 16:30:16.96 [system: TP-Processor24]
/full/include/view/book/detail.jsp?id=2691420082928&cached=false
web.Session$Site.include(Session.java:58)

Right thereafter, detail.jsp logs the actual parameters
received:

19 Jun 2014 4:30:16 PM
org.apache.catalina.core.ApplicationContext log INFO: Trace @
2014-06-19 16:30:16.961 [97A547EA5879F643AA717483B7165A39/null:
TP-Processor24] Parameters: id = [ 2691420082928, bdgc-269-g050
]; cached = false; page = detail;
web.tags.Log.doStartTag(Log.java:48)

Here, you see that the parameters from the include
(id=2691420082928 and cached=false) are being prepended to the
parameters on the original request (id=bdgc-269-g050 and page =
detail).  Both ids are in the array, with the included one as
element 0.  This is when things are working normally.  In the
"ignore" scenario, the second log would be:

Parameters: id = [ bdgc-269-g050 ]; cached = false;

In other words, the parameters from the URL passed to include(),
are ignored completely...

Thanks, Michael.

Sorry, a typo in the "ignore" parameters above, the line should
read:

Parameters: id = [ bdgc-269-g050 ]; page = detail;

And not

Parameters: id = [ bdgc-269-g050 ]; cached = false;

Since the cached parameter is part of the included query string,
which is ignored.
Can you provide the URI of the original page (details.jsp) as well as
the URI that is being used to include the sub-request? You aren't
providing both in your examples. Also, I have no idea how you are
logging, so I can't be sure you haven't broken the logging code somehow.

Can you provide the code you are using for logging the parameters
received by the JSP in the sub-request?

- -chris

Chris, we log from the JSP using custom tags:

<x:dump value="Parameters: %[params]" var="dump"/><x:log level="trace" message="${dump}"/>

Inside the custom tag, the variable "dump" is set to its value using this code:

                StringBuffer buf = new StringBuffer();
Map<String,String[]> params = pageContext.getRequest().getParameterMap(); for (Map.Entry<String,String[]> param : params.entrySet()) {
                    buf.append(param.getKey()).append(" = ");
                    if (param.getValue().length == 1)
                        buf.append(param.getValue()[0]);
                    else
                    {
                        buf.append("[ ");
                        for (String val : param.getValue())
                            buf.append(val).append(", ");
                        buf.delete(buf.length()-2,  buf.length());
                        buf.append(" ]");
                    }
                    buf.append("; ");
                }
                pageContext.setAttribute(var_, buf.toString());

We use our own logging framework, but it's very simple and just outputs what we ask it to.

The original URI in the *correct* behaviour case above, is:

/shop/main.jsp?page=detail&id=bdgc-269-g050

Then getRequestDispatcher("/full/include/view/book/detail.jsp?id=2691420082928&cached=false").include(req,res);

Gives parameters: { id = [ 2691420082928, bdgc-269-g050 ]; cached = false; page = detail; } in detail.jsp.

In the *broken* case, the same original URI and included URI gives parameters:

{ id = [ bdgc-269-g050 ]; page = detail; } in detail.jsp.

Almost all the time, Tomcat does the right thing, but every few thousand requests, it doesn't pass the query string parameters to the included page.

Thanks,
Michael.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to