Empty URI query string parameters: "a=&b=" versus "a&b" - http

Should the following URLs be considered functionally equivalent?
http://example.com/foo?a=&b=
http://example.com/foo?a&b
This came about when a user of a Drupal module I wrote which parses apart and then rewrites URIs noticed that the code sometimes causes the query string parts to change in unexpected ways due to how some of the underlying PHP functions behave. For example:
parse_str("a&b", $values); print http_build_query($values);
a=&b=
Is this something I should bother worrying about?
Edit so SO stops complaining that this question is similar to another one: The question is whether it's safe to assume that "no value for X" and "empty value for X" are equivalent, not whether the "no value" style is syntactically correct (which it is).

RFC 3986 Uniform Resource Identifier (URI): Generic Syntax doesn't have anything to say about the structure of the query string aside from how characters like ? should be dealt with. So strictly speaking, your two example URLs are different. Of course, the application which receives those query strings may treat them as functionally equivalent, but this isn't something you can determine from the URL alone.

As per RFC6570 empty query parameters are allowed. Please refer to section 3.2.9
Example Template Expansion
{&x,y,empty} &x=1024&y=768&empty=

Related

jsonapi.org correct way to use pagination using the page query string

In the documentation for jsonapi for pagination is says the following:
For example, a page-based strategy might use query parameters such as
page[number] and page[size]
How would I represent this in the query string? http://localhost:4200/people?page[number]=1&page[size]=25, I don't think using a map link structure is a valid query string. Only the page parameter is reserved according to the documentation.
I don't think using a map link structure is a valid query string.
You're right technically, and that's why the spec has the note that says:
Note: The example query parameters above use unencoded [ and ] characters simply for readability. In practice, these characters must be percent-encoded, per the requirements in RFC 3986.
So, page[size] is really page%5Bsize%5D which is a valid query parameter name.
Only the page parameter is reserved according to the documentation.
When the spec text says that only page is reserved, it actually means that any page[......] style query parameter is reserved. (I can tell you that for sure as one of the spec's editors.) But it should say so more explicitly, so I'll open an issue for it.

Use of typed URI in sesame sail openrdf

My question is simple but maybe non-sense. (in that case , sorry to people who gonna spend time to explain me why )
I'd like to create a resource like (i dont show all the resource declaration here ) :
<owl:DatatypeProperty rdf:about="relation:isPartOf">
<rdfs:domain rdf:resource="http://www.w3.org/2004/02/skos/core#note"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#anyURI"/>
</owl:DatatypeProperty>
<rdf:Description rdf:about="resource:context:sc#c1">
<skos:note rdf:datatype="relation:isPartOf" rdf:resource="resource:context:sc#c2">
</skos:note>
</rdf:Description>
Important to see is the triple about a skos:note relation
Subject : c1 a uri. Predicate : a skos:note , Object : a typed URI
My URI is not a direct URI but a "relation;isPartOf" uri.
I create a custom typedUri class to do that / i used a home made triple store so i can use my own class.
I change a little bit the RDFXMWritter to output these example. so "it works".
My question is more : Can a URI be typed like this ? why sesame openrdf do not provide a TypedURI class ? I'm sure there is a good reason ? any help, ideas or answers would be nice.
i'm quite sure , my idea to create a TypedURi class is wrong somewhere . but where ? :-)
thank you
EDIT : the TypedURI is not really a new kind of resource. The URI in my context is still a URI. i just declare that inside my skos:note statement , that for c1 , the object of the statement is a data of type "relation:isPartOf" and the range of the data is a anyURI.
... The typedURI helps to implements the datatype with such a range.
First of all: no, a URI can not be typed like this in RDF. Which also answers your second question: OpenRDF Sesame does not provide this functionality because it is not part of the RDF model.
Typing of URIs (or more accurately, resources, which are identified using URIs) is done by using an rdf:type relation, linking the resource URI to a class URI. For example, to make the resource ex:p1 of type foaf:Person, we would say (using Turtle syntax for RDF):
ex:p1 rdf:type foaf:Person .
There's another kind of typing in RDF, namely datatyping. This only applies to literal values so it can not be used on a URI. It is used to make a literal value a string, an integer number, a date, etc.
Update a confusion may arise because xsd:anyURI is a valid datatype in RDF, and it is (in XML Schema) defined to be a type for URIs. However, when using a datatype in RDF, its lexical space is always a literal (simply because the spec only allows for literals to actually have a datatype). So you could indeed do something like this (using Turtle syntax for literal notation):
"http://www.example.org/some/uri"^^xsd:anyURI
But from the point of view of the RDF model, this is not a URI, but a literal string (with datatype xsd:anyURI). So in a sense, yes, you can add types to URIs in RDF, but you can only do this by "converting" them to literals first.

Is it valid to combine a form POST with a query string?

I know that in most MVC frameworks, for example, both query string params and form params will be made available to the processing code, and usually merged into one set of params (often with POST taking precedence). However, is it a valid thing to do according to the HTTP specification? Say you were to POST to:
http://1.2.3.4/MyApplication/Books?bookCode=1234
... and submit some update like a change to the book name whose book code is 1234, you'd be wanting the processing code to take both the bookCode query string param into account, and the POSTed form params with the updated book information. Is this valid, and is it a good idea?
Is it valid according HTTP specifications ?
Yes.
Here is the general syntax of URL as defined in those specs
http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
There is no additional constraints on the form of the http_URL. In particular, the http method (i.e. POST,GET,PUT,HEAD,...) used don't add any restriction on the http URL format.
When using the GET method : the server can consider that the request body is empty.
When using the POST method : the server must handle the request body.
Is it a good idea ?
It depends what you need to do. I suggest you this link explaining the ideas behind GET and POST.
I can think that in some situation it can be handy to always have some parameters like the user language in the query part of the url.
I know that in most MVC frameworks, for example, both query string params and form params will be made available to the processing code, and usually merged into one set of params (often with POST taking precedence).
Any competent framework should support this.
Is this valid
Yes. The POST method in HTTP does not impose any restrictions on the URI used.
is it a good idea?
Obviously not, if the framework you are going to use is still clue-challenged. Otherwise, it depends on what you want to accomplish. The major use case (redirection of a data subset to a new POST target) has been irretrievably broken by browser implementations (all mechanically following the broken lead of Mosaic/Netscape), so the considerations here are mostly theoretical.

http url input parameters

Is this a valid http url
http://www.example.com?x&y
or
we must always have = sign for parameters.
http://www.example.com?x1=x&x2=y
Well, it works, and the W3C recommendations are extremely general -- only the use of ? and + are defined. So I think from the perspective of HTTP/HTML the = is optional. It's use is obviously a common convention and many client & server libraries use it, but there doesn't seem to be any reason you couldn't define a service to work on some other scheme.
Anecdotally, I like to leave out the =blah part when I'm using the query string as a flag as in http://www.example.com?logout
Reference: http://www.w3.org/Addressing/URL/4_URI_Recommentations.html
According to the ABNF in Appendix A of RFC 3986, both examples above are valid URL.
Note that if you read only the Wikipedia article on Query string, you might get the false impression that the second ne is the only valid one.

Authoritative position of duplicate HTTP GET query keys

I am having trouble on finding authoritative information about the behavior with HTTP GET query string duplicate fields, like
http://example.com/page?field=foo&field=bar
and in particular if the order is kept or not. Most web-oriented languages produce an array containing both foo and bar associated to a key "field", but I would like to know if authoritative statement exist (e.g. on a RFC) about this point. RFC 3986 has a section 3.4. Query, which refers to key=value pairs, but nothing is said on how to interpret order and duplicate fields and so on. This makes sense, since it's backend dependent, and not in the scope of that RFC...
Although a de-facto standard exists, I'd like to see an authoritative source for it, just out of curiosity.
There is no spec on this. You may do what you like.
Typical approaches include: first-given, last-given, array-of-all, string-join-with-comma-of-all.
Suppose the raw request is:
GET /blog/posts?tag=ruby&tag=rails HTTP/1.1
Host: example.com
Then there are various options for what request.query['tag'] should yield, depending on the language or the framework:
request.query['tag'] => 'ruby'
request.query['tag'] => 'rails'
request.query['tag'] => ['ruby', 'rails']
request.query['tag'] => 'ruby,rails'
The situation seems to have changed since this question was asked and the accepted answer was written 12 years ago. I believe we now have an authoritative source: The WHATWG URL Standard describes the process of extracting and parsing a query string in detail in section 6.2 (https://url.spec.whatwg.org/#interface-urlsearchparams) and section 5.1 on x-www-form-urlencoded parsing (https://url.spec.whatwg.org/#urlencoded-parsing). The parsing output is "an initially empty list of name-value tuples where both name and value hold a string", where a list is defined as a finite ordered sequence, and the key-value pairs are added to this list in the order they appear in the URL. At first there is no mention of repeated keys, but some methods on the URLSearchParams class in section 6.2 (https://url.spec.whatwg.org/#interface-urlsearchparams) set clear expectations on ordering: "The getAll(name) method steps are to return the values of all name-value pairs whose name is name... in list order"; The sort() method specifies that "The relative order between name-value pairs with equal names must be preserved." (Emphasis mine). Examining the Github issue referenced in the commit where the sort method was added, we see that the original proposal was to sort on values where keys were identical, but this was changed: "The reason for the default sort not affecting the value order is that ordering of the values can be significant. We should not assume that it's ok to move the order of the values around." (https://github.com/whatwg/url/issues/26#issuecomment-271600764)
I can confirm that for PHP (at least in version 4.4.4 and newer) it works like this:
GET /blog/posts?tag=ruby&tag=rails HTTP/1.1
Host: example.com
results in:
request.query['tag'] => 'rails'
But
GET /blog/posts?tag[]=ruby&tag[]=rails HTTP/1.1
Host: example.com
results in:
request.query['tag'] => ['ruby', 'rails']
This behavior is the same for GET and POST data.
yfeldblum's answer is perfect.
Just a note about a fifth behavior I noticed recently: on Windows Phone, opening an application with an uri with a duplicate query key will result in NavigationFailed with:
System.ArgumentException: An item with the same key had already been added.
The culprit is System.Windows.Navigation.UriParsingHelper.InternalUriParseQueryStringToDictionary(Uri uri, Boolean decodeResults).
So the system won't even let you handle it the way you want, it will forbid it. You are left with the only solution to choose your own format (CSV, JSON, XML, ...) and uri-escape-it.
Most (all?) of the frameworks offer no guarantees, so assume they will be returned in random order.
Always take the safest approach.
For example, java HttpServlet interface:
ServletRequest.html#getParameterValues
Even the getParameterMap method leaves out any mention about parameter order (the order of a java.util.Map iterator cannot be relied on either.)
Typically, duplicate parameter values like
http://example.com/page?field=foo&field=bar
result in a single queryString parameter that is an array:
field[0]=='foo'
field[1]=='bar'
I've seen this behavior in ASP, ASP.NET and PHP4.
The ?array[]=value1&array[]=value2 approach is certainly a very popular one.
supported by most Javascript frameworks
supported by Java Spring
supported by PHP

Resources