medialize / URI.js

Javascript URL mutation library
http://medialize.github.io/URI.js/
MIT License
6.26k stars 475 forks source link

Slash automatically added to URI with fragment and no path #273

Open jamesamcl opened 8 years ago

jamesamcl commented 8 years ago
> URI('http://example.com#foo').toString()
'http://example.com/#foo'

As far as I know, http://example.com#foo is a valid URI. This is quite a big issue for me because if the URI changes after loading/serialization, it completely invalidates my RDF.

jamesamcl commented 8 years ago

Related to #221.

jamesamcl commented 8 years ago

Seems you're right as far as normalisation guidelines go for HTTP - RFC 3986 says:

In general, a URI that uses the generic syntax for authority with an
empty path should be normalized to a path of "/".  Likewise, an
explicit ":port", for which the port is empty or the default for the
scheme, is equivalent to one where the port and its ":" delimiter are
elided and thus should be removed by scheme-based normalization.  For
example, the second URI above is the normal form for the "http"
scheme.

However, this is HTTP specific and shouldn't happen for URIs with other protocols.

rodneyrehm commented 8 years ago

You are correct, http://example.com#foo is a valid URI, as path-abempty may indeed be the empty string (per RFC 3986 Collected ABNF).

toString() runs URI.build() behind the scene, which adds the path if required:

var u = URI('http://example.com#foo');
u.toString()
// "http://example.com/#foo"

u._parts.path = null;
u.toString()
// "http://example.com#foo"

The slash is added by URI.parseAuthority() in case there is no path. Replacing "/" with "" (empty string) would not help, as URI.build() would interpret the empty string to mean /. However, returning null instead of the empty string would solve your problem - and make 13 tests fail, thus has to be considered a breaking change.

However, this is HTTP specific and shouldn't happen for URIs with other protocols.

I agree, but your example showed an http url?

jamesamcl commented 8 years ago

Thanks,

I agree, but your example showed an http url?

Yes - I only found out about the difference with HTTP afterwards.

Maybe permitting empty paths could be an option to avoid breaking tests?

rodneyrehm commented 8 years ago

Maybe permitting empty paths could be an option to avoid breaking tests?

how do you suggest we do that?