103

Suppose I have a url like this:

http://www.example.com?key=123&KEY=198

Then what will be result of

request.querystring("key")

and 

request.querystring("KEY")

I am a bit confused.

Clint Eastwood
  • 4,995
  • 3
  • 31
  • 27
  • What programming language is this related to? You tagged this as [tag:request.querystring] but neglected a language tag. There appear to be methods like this in several languages and frameworks: NodeJS, C#, asp.net, Laravel, and maybe others. – Stephen Ostermiller Feb 24 '22 at 20:32

4 Answers4

107

The RFC for URIs says:

6.2.2.1. Case Normalization

When a URI uses components of the generic syntax, the component syntax equivalence rules always apply; namely, that the scheme and host are case-insensitive and therefore should be normalized to lowercase. For example, the URI HTTP://www.EXAMPLE.com/ is equivalent to http://www.example.com/.

The other generic syntax components are assumed to be case-sensitive unless specifically defined otherwise by the scheme (see Section 6.2.3).

Note that scheme ("http" here), host (server name) are case-insensitive but should be in lowercase anyway. The rest is case-sensitive unless you're using a different scheme that explicitly says it should be insensitive.

So key and KEY are different things in all http-based URIs according to the spec.

Edit: @Nicholas is partly wrong in assuming that the authority defines what it accepts, that's true for custom schemes and authorities that define their own URIs, but http is a well-defined spec that everyone conforms to (or you could have http queries that have, say, the pipe character as a delimiter. Imagine the chaos there!)

the RFC spec for HTTP says:

The scheme and host are case-insensitive and normally provided in lowercase; all other components are compared in a case-sensitive manner. Characters other than those in the "reserved" set are equivalent to their percent-encoded octets: the normal form is to not encode them (see Sections 2.1 and 2.2 of [RFC3986]).

So the query part of the URI as defined by the spec for the HTTP scheme is case-sensitive. If Microsoft has a case-insensitive parser for query strings, its not conforming to the spec. Not that I guess this level of pickiness really matters much.

Community
  • 1
  • 1
gbjbaanb
  • 51,617
  • 12
  • 104
  • 148
  • Note that those parts being case-sensitive is about the HTTP and HTML behavior meaning that user agents (that is, browsers) must repeat the same case they received. The server can **interpret** the submitted paths plus all query parameter names and values as it seems fit and this is not limited by any specs. – Mikko Rantalainen Jan 27 '21 at 12:00
  • @MikkoRantalainen not so, the spec for HTTP refers to the whole query string. That includes such specifications as which character to use as a delimiter, and what encoding system to use. A server that interprets this differently is no longer using the http spec but its own, custom one, and may as well use a different delimiter (such as a pipe) – gbjbaanb Jan 27 '21 at 18:37
  • For example, https://tools.ietf.org/html/rfc7231#section-4.3.1 says "It is tempting to think of resource identifiers [...] However, there are no such limitations in practice [...] only the origin server needs to know how each of its resource identifiers corresponds to an implementation [...] A payload within a GET request message has no defined semantics". HTML defines three encodings and following those will make it *easier* to work with user agents: https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fs-enctype – Mikko Rantalainen Jan 28 '21 at 07:23
  • Nowadays one can create almost custom implementations over HTTP with XHR and fully custom implementations using WebSocket. Only if you want to use *relative URLs* you need to pay any attention to using slashes or pipes or whatever character you want to use as resource identifier. With absolute URLs, the browser doesn't need to understand any part of the HTTP or HTTPS URL after the host. Except that everything is case sensitive. – Mikko Rantalainen Jan 28 '21 at 07:26
55

@gbjbaanb's answer is incorrect: The RFCs only specify the allowed character set for the query string. Like the path and fragment components of the URI, the query URI component only has meaning only to the authority providing the resource.

It is entirely up to that authority on whether this stuff is case-sensitive or not.

In the case of C# and IIS, the backing store for the parsed query string in the HttpRequest object is a System.Collections.Specialized.NameValueCollection which happens to be case-insensitive (by default).

Since that class offers other constructors allow different equality comparers to be provided, there is absolutely nothing to prevent an implementation from making it case-sensitive.

Further, since the page itself (and the client-side javascript) have access to the raw URI, they are free to do whatever they want with it.

If the query string is built as a result of an HTML form submission, the keys (names) come from the value of the form controls name attribute, which the HTML specs say is case-sensitive. But as near as I know, nobody really does that.

So, at the end of the day, you have to know what the request handler is expecting in your query string. It might (or it might not) be case-sensitive.

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • 2
    I was looking at legacy C# code, trying to understand why the keys were treated as case-insensitive, and your answer explained it well. +1 – Marcel Lamothe Oct 13 '15 at 14:32
13

In short, they are considered equal in many programming languages.

Different parts of the URL are different in terms of case sensitivity:

  • Protocol (http) -- case insensitive
  • Host name (example.com) -- case insensitive
  • Path (/folder/document.html) -- case sensitive
  • Query string Key(?fuzz=bar OR ?FUZZ=bar) -- case insensitive
  • Query string Value (?fuzz=bar&buzz=BAR) -- case sensitive
Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
samtax01
  • 834
  • 9
  • 11
  • 1
    In many, but not in all. And the most important, that the behaviour differs not only between languages, but between different web frameworks. – checkraise Apr 15 '21 at 14:31
  • the above ignores mixed case FuZz? – StevenWernerCS Dec 16 '21 at 23:04
  • Note that the string value is not really case sensitive, that one is really much more dependent on the application consuming that data. Another example would be `?fuzz=bar&FuZz=BAR` of which the result is two values "bar" and "BAR" (in that order) attached to one variable named "fuzz". – Alexis Wilke Feb 24 '22 at 19:22
  • 1
    It lacks of references.. – deFreitas Mar 11 '23 at 21:20
10

According to hurl.it, key will be equal to 123 and KEY, 198. They will be accessible as two different querystrings.

Rémi Delhaye
  • 794
  • 3
  • 16
  • 1
    What if the language is changed to classic ASP. – choudhury smrutiranjan parida Jul 11 '14 at 14:16
  • 5
    @ch.smrutiranjanparida, the language choice is independent to how a query parameter is supposed to be handled. Whether you use COBOL, Perl, Erlang, Classic ASP, R, Java, Lisp doesn't matter. Of course, libraries that interpret querystrings may have bugs, and programmers may diligently lower-case querystrings (and *shouldn't*), but from a URI point of view _they are different if the case is different_. See the [RFC](http://tools.ietf.org/html/rfc3986#page-11) in the [accepted answer](http://stackoverflow.com/a/24700171/111575) for more details. – Abel Nov 18 '15 at 08:49
  • @Abel got it. Thanks for the input. :) – choudhury smrutiranjan parida Nov 19 '15 at 07:16