Uh oh!
There was an error while loading. Please reload this page.
Make http.request correctly parse {host: "hostname:port"} - #2271
Conversation
There was a problem hiding this comment.
Doesn't need this license.
Also, 'use strict'; here please! :)
nfriedly
commented
Jul 29, 2015
Oh, and two things I forgot to mention:
|
nfriedly
commented
Jul 29, 2015
@Fishrock123 thanks, I just pushed a new commit that I believe addresses everything you pointed out. If you want, I'll rebase it into one. |
There was a problem hiding this comment.
This will fail on IPv6 address and port, e.g. [::]:80. Could use url here like url.parse('fake://' + str).
There was a problem hiding this comment.
Good point. I'll add a test for that.
sam-github
commented
Jul 29, 2015
-1
|
silverwind
commented
Jul 29, 2015
I'm also feeling this is probably too magical, so I have to -1 as well here. |
nfriedly
commented
Jul 29, 2015
@sam-github just before you posted, I switched to using |
nfriedly
commented
Jul 29, 2015
There is a bug here, but I agree that this is starting to get a little silly and definitely don't want to make things worse. What would you guys say to a proper |
nfriedly
commented
Jul 29, 2015
Actually, there's already an (undocumented) Although using it directly on the options object would change the behavior of ...It also leaves the brackets around ipv6 addresses, which also breaks dns lookups, so probably not a good option. |
sam-github
commented
Jul 29, 2015
Even with url parsing, I'm personally still -1, I just don't think this is reasonable for the HTTP library, which should focus on getting HTTP right, and let npm add API/use-case sugar. And its trivial to add this on top of |
sam-github
commented
Jul 29, 2015
And doesn't the change to test-http-dns-error.js mean this is a little bit backwards incompatible? |
nfriedly
commented
Jul 29, 2015
To give a real-world example of where this bug makes node.js/io.js behave unexpectedly, I have a library that connects to a remote server. When testing, I mock the remote server with one running on localhost:8080, I then change the Yes, I can work around it easily enough, but that doesn't change the fact that it's a bug, or at the very least, doesn't work as expected. In the As for the test-http-dns-error.js, that test is expecting an error. With this patch, it would get a different error, but I think that's an acceptable change. That said, I'd be willing to rework it further to avoid that if it's important to you. |
The issue: http.request() treats host as an alternate form of hostname, which it sort of is, except that host is (normally) allowed to contain a port number. Before this change, if host contains a port number and there isn't a hostname field to override it, http.request() attempts a DNS lookup on the entire host field, including the port number. This always fails. The fix: If a host field is present, use the url lib to parse it and use the parsed hostname nad port values as fallbacks if options.hostname and options.port are unset. Includes tests for localhost:12346 and [::1]:12346.
nfriedly
commented
Jul 30, 2015
Here we go, I gave it one more shot. This one uses I added two lines to unwrap bracketed ipv6 addresses, based on the equivalent lines in I also rebased everything into a single commit to clean up the history. What do you guys say? If it's still a stack of -1's then I'll give up... |
jasnell
commented
Nov 16, 2015
@sam-github@silverwind .. looks like the conversation on this one stalled out. There was an updated commit that was never reviewed. Mind taking a look? |
jasnell
commented
Nov 16, 2015
@nodejs/http |
mscdex
commented
Nov 16, 2015
I think this doesn't play nice with IPv6 functionparse(s){varparsedHost={host: s};if(s){url.Url.prototype.parseHost.call(parsedHost);// unwrap brackets from ipv6 ip addressesconsthostname=parsedHost.hostname;if(hostname[0]==='['&&hostname[hostname.length-1]===']'){parsedHost.hostname=hostname.substr(1,hostname.length-2);}}}console.dir(parse('::1'));// displays:// { host: '::1', port: '1', hostname: ':' } |
jasnell
commented
Nov 16, 2015
:-) @mscdex .. you read my mind. I had that same kind of test queued up on my todo list. I'm leaning towards a -1 on this particular change |
dougwilson
commented
Nov 16, 2015
I agree with the concept, but not sure about the particular implementation. Of course, the string |
silverwind
commented
Nov 16, 2015
For some reason, I can't get this particular example to work at all here, any ideas? >url.Url.prototype.parseHost.call({host: '::1'})undefinedAs for this issue: It has some value I'd say. |
mscdex
commented
Nov 16, 2015
@dougwilson I'd bet that most people just use
So I could easily see people using values like |
mscdex
commented
Nov 16, 2015
@silverwind The reason is that |
dougwilson
commented
Nov 16, 2015
Hi @mscdex , it's a good thing I noted that it would be too confusing to actually enforce that in my post already :) |
jasnell
commented
Mar 22, 2016
Closing given the discussion. |
The issue:
http.request()treatshostas an alternate form ofhostname, which it sort of is, except thathostis (normally) allowed to contain a port number.Before this change, if
hostcontains a port number and there isn't ahostnamefield to override it,http.request()attempts a DNS lookup on the entire host field, including the port number. This always fails.The fix:
If a host field is present, split it around
':'and use the first portion as a fallbackhostnameand the second (if present) as a fallbackport. ("Fallback" meaning that the values from thehostfield are only used when thehostnameandportfields aren't set.)Includes a test to verify the correct behavior.
I originally filed an issue on joyent/node and submitted a patch there, but @jasnell said that this might be a better fit for nodejs/io.js or nodejs/node, so I'm sending the same patch to each. (The node patch is at #72) Please merge into whichever repo is appropriate and close the other one.