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

url.format does not postfix slashes to protocol but doc pretend it should by default #3361

Closed
sdumetz opened this issue Oct 14, 2015 · 6 comments
Labels
semver-major PRs that contain breaking changes and should be released in the next major version. url Issues and PRs related to the legacy built-in url module.

Comments

@sdumetz
Copy link

sdumetz commented Oct 14, 2015

Quoting the doc :

protocol is treated the same with or without the trailing : (colon).
The protocols http, https, ftp, gopher, file will be postfixed with :// (colon-slash-slash).
All other protocols mailto, xmpp, aim, sftp, foo, etc will be postfixed with : (colon).
slashes set to true if the protocol requires :// (colon-slash-slash)
Only needs to be set for protocols not previously listed as requiring slashes, such as mongodb://localhost:8000/.

But a quick test (using nodejs V4.1) show the problem:

url = require("url");
uri = url.parse("/home/user");
uri.protocol = "file";
console.log(url.format(uri));

Output : file:/home/user. While the expected output is : file:///home/user

Setting uri.slashes = true make it format the correct URL.

I think it's not worth it to modify the module itself as it's stable. However the doc should be updated to reflect this behaviour.

Should I submit a PR reflecting this?

@silverwind silverwind added the url Issues and PRs related to the legacy built-in url module. label Oct 14, 2015
@claudiorodriguez
Copy link
Contributor

Just pasting what I had found here, as I had created a duplicate issue.

If you look at https://github.com/nodejs/node/blob/master/lib/url.js you see:

  // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.
  // unless they had them to begin with.
  if (this.slashes ||
      (!protocol || slashedProtocol[protocol]) && host !== false) {
    host = '//' + (host || '');
    if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
  } else if (!host) {
    host = '';
  }

So the documented behaviour only happens when host/hostname are set.
You can check this with the following snippet:

var url = require('url');

var unslashedUri = url.parse('/no-slashes');
var slashedUriByHost = url.parse('/slashes-host');
var slashedUriForced = url.parse('/slashes-forced');

unslashedUri.protocol = 'file';
console.log(url.format(unslashedUri)); // file:/no-slashes

slashedUriByHost.protocol = 'file';
slashedUriByHost.host = 'localhost';
console.log(url.format(slashedUriByHost)); // file://localhost/slashes-host

slashedUriForced.protocol = 'file';
slashedUriForced.slashes = true
console.log(url.format(slashedUriForced)); // file:///slashes-forced

claudiorodriguez pushed a commit to claudiorodriguez/node that referenced this issue Dec 2, 2015
Change url.format's references to slash postfixing to reflect
true behaviour (it only automatically postfixes slashes to the
slashedProtocols when host is present).

Fixes: nodejs#3361
@silverwind
Copy link
Contributor

Hmm, I'd say this is worth a breaking change as a file uri without :// is invalid in all cases. Output should adhere to file://host/path, host being '' when not defined.

@silverwind silverwind added the semver-major PRs that contain breaking changes and should be released in the next major version. label Dec 3, 2015
@sdumetz
Copy link
Author

sdumetz commented Dec 4, 2015

To be sure we're ok on the desired end result, this test would currently fail :

  '/some/path' : {
    'href': '/some/path',
    'pathname': '/some/path',
    'path': '/some/path',
    'host':'',
    'hostname':''
  }

(in test/parallel/test-url.js)
as host and hostname would be null.
It probably won't be acceptable to have host always be defined to ''instead of null when protocol is null. That would make the fix easy (init host and hostname to ''?) but would have side effects probably well above possible benefits.for example it would cause some trouble for major use cases where we want host to be null, but protocol is context dependant (/index.html in is http: while in browser nav it's file:).

More sensible solution would be to have something specific to protocols that don't have a hostname but still want slashes. A bit like the way javascript: is handled.

Or did I miss something?

@silverwind
Copy link
Contributor

Hmm, that's an unexpected failure. Unfortunately, I'm not really familiar with that code. I agree that a failure like this is unacceptable. By the way, we have #2303 which is pretty much a rewrite of the module for perf reasons, which also contains a few breaking changes. If a fix for this turns out to be too complicated, maybe it's better to incorporate it there.

@silverwind silverwind reopened this Dec 6, 2015
@silverwind
Copy link
Contributor

Reopened because 2a29b70 does not take care of the issue, it just documents the current behaviour.

rvagg pushed a commit that referenced this issue Dec 8, 2015
Change url.format's references to slash postfixing to reflect
true behaviour (it only automatically postfixes slashes to the
slashedProtocols when host is present).

Fixes: #3361

PR-URL: #4119
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Roman Reiss <[email protected]>
Reviewed-By: Minwoo Jung <[email protected]>
MylesBorins pushed a commit that referenced this issue Dec 29, 2015
Change url.format's references to slash postfixing to reflect
true behaviour (it only automatically postfixes slashes to the
slashedProtocols when host is present).

Fixes: #3361

PR-URL: #4119
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Roman Reiss <[email protected]>
Reviewed-By: Minwoo Jung <[email protected]>
MylesBorins pushed a commit that referenced this issue Jan 19, 2016
Change url.format's references to slash postfixing to reflect
true behaviour (it only automatically postfixes slashes to the
slashedProtocols when host is present).

Fixes: #3361

PR-URL: #4119
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Roman Reiss <[email protected]>
Reviewed-By: Minwoo Jung <[email protected]>
scovetta pushed a commit to scovetta/node that referenced this issue Apr 2, 2016
Change url.format's references to slash postfixing to reflect
true behaviour (it only automatically postfixes slashes to the
slashedProtocols when host is present).

Fixes: nodejs#3361

PR-URL: nodejs#4119
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Roman Reiss <[email protected]>
Reviewed-By: Minwoo Jung <[email protected]>
@Trott
Copy link
Member

Trott commented Jun 8, 2016

https://url.spec.whatwg.org/#url-syntax indicates that all special schemes (ftp, file, gopher, http, https, ws, wss) must be followed by a : and scheme-relative URL, which starts with //.

So it seems that any URL generated with those schemes specified should include //. PR coming shortly, but I don't know how receptive people are going to be to it.

Trott added a commit to Trott/io.js that referenced this issue Jun 9, 2016
`file:` URLs that do not start with `file://` are invalid. Browsers
convert `file:/etc/passwd` to `file:///etc/passwd`. This is also what
the docs indicate we are doing, but we're not.

Fixes: nodejs#3361
@Trott Trott closed this as completed in 336b027 Jun 16, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver-major PRs that contain breaking changes and should be released in the next major version. url Issues and PRs related to the legacy built-in url module.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants