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

Further clarify ordering of request parameters when accessed through getParameterNames and getParameterMap #393

Open
ChristopherSchultz opened this issue Feb 17, 2021 · 2 comments

Comments

@ChristopherSchultz
Copy link
Contributor

For background, please see this thread on the Apache Tomcat users mailing list.

The Servlet Specification specifies in section 3.1 that request parameters coming from the URL query string should be "presented before post body data" to web applications. It does not further specify ordering within the URL-parameter or POST form-data parameters which are parsed by the container.

It seems reasonable for application developers to expect that parameters would be presented in left-to-right order from the URL and top-to-bottom order in POST form-data, but nowhere is that explicitly stated in the Servlet or related specifications.

Apache Tomcat's implementation is such that parameter names will be enumerated in this left-to-right/top-to-bottom fashion and likewise the ordering of map entries coming from HttpServletRequest.getParameterMap will also be in this order. It's likely that other implementations are the same or at least similar.

Clarifying this order explicitly in the Servlet specification would be helpful to application programmers who would like to rely on this behavior.

As justification for codifying this behavior, I would like to refer to HTML 5 section on "Forms" which consistently refers to "tree order" (aka document-order) as the proper way to order form elements in many situations, specifically when assembling the form-data to submit to the server. Further, RFC 7578 specifies that "Form processors given forms with a well-defined ordering SHOULD send back results in order" and specifically forbids intermediaries (e.g. proxies, etc.) from re-ordering form-data.

Given:

  1. HTTP and HTML specifications agree that form-element ordering is (always) important
  2. HTML form-data can be sent in either URL parameters (i.e. GET) or via a request entity (i.e. POST)
  3. The Servlet Specification requires that parameters from the URL should come before those in the request body

Therefore, the Servlet Specification should explicitly define the ordering of request parameters:

  1. First, by source (URL parameter vs request body)
  2. Second, by ordering within the set of parameters in each source; that is, from left-to-right for URL parameters and top-to-bottom for request bodies

This will ensure that web applications can reliably predict the ordering of form-data if it is necessary to do so.

@ChristopherSchultz
Copy link
Contributor Author

As a further clarification, parameter name ordering should be such that the first appearance of the name dictates its position in the enumeration returned by HttpServletRequest.getParameterNames.

I happen to think that the total-ordering of request parameter name/value pairs is less important than the total-ordering of the request parameter names. For example, it's certainly possible to have repeated request parameter names with distinct values. In this case:

http://example.com/resource?a=foo&b=bar&a=baz

When calling HttpServletRequest.getParameterNames, it should be explicitly required that a comes before b in the list, and when calling HttpServletRequest.getParameterMap, the result of .getKeys() on that Map should also exhibit that order. But when calling HttpServletRequest.getParameterMap().entrySet(), I think reasonable people can disagree over whether the elements should be in this order:

  1. a=foo
  2. b=bar
  3. a=baz

Or this order:

  1. a=foo
  2. a=baz
  3. b=bar

@bvfalcon
Copy link

bvfalcon commented Sep 6, 2023

Therefore, the Servlet Specification should explicitly define the ordering of request parameters:

  1. First, by source (URL parameter vs request body)
  2. Second, by ordering within the set of parameters in each source; that is, from left-to-right for URL parameters and top-to bottom for request bodies

Seems to me, this requirement (in part of URL parameters) contradicts with RFC 3986, Section 3.4. Query (definition of "hierarchical data" see in Section 1.2.3. Hierarchical Identifiers). Parameters in URL (Query component) cannot be considered as ordered from left to right. If URL parameters must be considered as hierarchical data, they must be set in the Path component.
For example: http://example.com/resource/foo/bar/baz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants