Skip to content
This repository has been archived by the owner on May 5, 2023. It is now read-only.

Fixing the support of WHATWG URLs #28

Closed
wants to merge 3 commits into from
Closed

Fixing the support of WHATWG URLs #28

wants to merge 3 commits into from

Conversation

sadasant
Copy link
Collaborator

@sadasant sadasant commented Jul 6, 2019

This is an attempt to support WHATWG URLs.
Tests are passing 💚
Feedback is appreciated!

Note: I'm keeping the internal options as a plain object in index.js, but this shouldn't affect the rest of the behavior we're expecting.

Fixes #26

This is an attempt to support WHATWG URLs.
Feedback is appreciated!

Fixes #26
Copy link
Collaborator

@BYK BYK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On top of the review comments, we now need new test cases to make sure the new support actually works and won't break in the future.

function urlInstanceToObject(url) {
var urlObject = {};
// If the opts are genearted with the WHATWG API
if (url && Object.getOwnPropertySymbols && Object.getOwnPropertySymbols(url)[0]) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more comments or pointers explaining this magic would be very useful for the future reader. Even now I don't fully understand what is happening :D

Copy link
Collaborator Author

@sadasant sadasant Jul 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add comments for sure! First here, since it's easier:

This line is about checking whether the url is a WHATWG url or not. I'm doing this by first checking that the url exists (is not falsy), then checking that Object.getOwnPropertySymbols exists (since this feature appeared relatively recently, compared the versions of Node that are expected to work on CI), and finally by combining this Object method with the given URL to confirm that it indeed has symbols.

I currently don't know a better way of doing this! I pushed something fast that seemed to work. I'm interested in learning how to make this better while updating this as fast as I can! 🌻

What do you think of this approach? Any suggestion?

urlObject[key] = urlContext[key];
}
} else {
urlObject = Object.assign({}, url);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TooTallNate - are you okay dropping support for Node < 8 which would allow us to use object spread and maybe some more niceties?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a great question!

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to keep Node 6 support at least.

index.js Outdated
@@ -28,7 +44,7 @@ function Agent(callback, _opts) {
// (i.e. it has a callback function) lazily
this._promisifiedCallback = false;

let opts = _opts;
var opts = _opts;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why var?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let inside blocks breaks some of the environments that are supposed to work on CI (here and in this other PR: TooTallNate/proxy-agents#71 ). I assumed that making all vars would just help us keep consistency! I can change it back for sure, just let me know.

index.js Outdated Show resolved Hide resolved
@@ -91,8 +107,8 @@ Agent.prototype.addRequest = function addRequest(req, _opts) {
req.shouldKeepAlive = false;

// Create the `stream.Duplex` instance
let timeout;
let timedOut = false;
var timeout;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please no vars :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On CI we're testing Node 4 and 5, which doesn't have a proper functional let, I believe. If we drop support of Node < 6 I would agree to stop using vars!

patch-core.js Outdated
_url = undefined;
}
if (!_url && _options) {
_url = url.format(_options);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we do this? Which case are we handling here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https.request has two valid behaviors:

https.request(options[, callback])
https.request(url[, options][, callback])

For that reason, if _url isn't a string and there's no callback, between line 19 and 21 we're assuming the scenario with only two parameters was used, so we're re-assigning the parameters to make sense with their correspondent name. Right at the end of that, I'm assigning undefined to _url, trying to simplify what we're trying to accomplish in that if block.

After that, I'm only checking that if we don't have a _url and we do have _options, we can now try to transform the _options to have a string _url. We do this by using url.format, which returns a string and works for both legacy URLs and WHATWG URLs. This second if block also helps if the user decided to pass a falsy _url, since any form of a falsy _url will break this anyway.

Feedback appreciated! 💚

patch-core.js Outdated
if (typeof _options === 'string') {
options = url.parse(_options);
} else {
options = Object.assign({}, _options);
options = url.parse(_url);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case feels unsafe as we simply discard the original value of _options. What is the assumption we are making here that gives us the ability to discard the old value?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this point we're sure to have a _url. What we're doing next is to grab the options out of the _url and merge them with the received options. In https.get we had this line options = Object.assign({}, url.parse(_url), _options) that had the same intentions of merging both _url and options into one object. What I'm doing is to make it work with the new WHATWG structure, as well as to make sure that both https.get and https.request follow this behavior.

patch-core.js Outdated
options = Object.assign({}, _options);
options = url.parse(_url);
if (_options) {
if (_options && Object.getOwnPropertySymbols && Object.getOwnPropertySymbols(_options)[0]) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code looks repeated, consider abstracting out into a util function?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did abstract this into a re-usable function! Please check the update!

patch-core.js Outdated
} else {
options = url.parse(_url);
if (_options) {
if (_options && Object.getOwnPropertySymbols && Object.getOwnPropertySymbols(_options)[0]) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, this logic now needs more abstraction and explaining :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did abstract this into a re-usable function! Please check the update!

@kamilogorek
Copy link

Ping @TooTallNate

@kunal15595
Copy link

Any progress here?

@TooTallNate
Copy link
Owner

Sorry for letting this one get stale. The project has been refactored to TypeScript and this PR needs to be refactored at this point as well.

@TooTallNate TooTallNate closed this Jan 4, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

HTTPS.Request() does not accept WHATWG URL
5 participants