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

Removes hash fragments from url in offline audit #1319

Merged
merged 3 commits into from
Jan 28, 2017

Conversation

wardpeet
Copy link
Collaborator

Reviewers: ALL
We store the url inside options.url without a fragment so we should do this check without fragment as well.
Make sure that I don't break anything crucial :p

Fixes PR #1296

@@ -34,4 +36,8 @@ class Offline extends Gatherer {
}
}

function cleanHash(url) {
return url.href.removeURLFragment();
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not familiar withremoveURLFragment. Where does it come from?

If it's not part of a spec, url.origin + url.pathname + url.search would be clear.

Copy link
Collaborator Author

@wardpeet wardpeet Dec 27, 2016

Choose a reason for hiding this comment

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

To be honest autocomplete let me to it :p. (https://cs.chromium.org/chromium/src/third_party/WebKit/Source/devtools/front_end/platform/utilities.js?q=removeURLFragment&sq=package:chromium&l=215)

I can just copy that function instead so we are sure it never disappears. Reason I didn't want to build the url myself is that I keep the href as pure as it can be but maybe it's not necessary at all 😄

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh wow. Yea, let's go with our own implementation instead of a function added to String's prototoype.

How about url.origin + url.pathname + url.search? It's obvious and pure 👍

Copy link
Member

Choose a reason for hiding this comment

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

maybe do the new URL() part inside here too? Can also do url.hash = ''; return url.href;

Copy link
Member

Choose a reason for hiding this comment

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

okay the subclass of URL is now in place, so we can move it there. :)

@@ -25,7 +26,8 @@ class Offline extends Gatherer {

afterPass(options, tracingData) {
const navigationRecord = tracingData.networkRecords.filter(record => {
return record._url === options.url && record._fetchedViaServiceWorker;
return cleanHash(new URL(record._url)) === cleanHash(new URL(options.url)) &&
Copy link
Member

@brendankenny brendankenny Jan 3, 2017

Choose a reason for hiding this comment

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

This seems a little worrying at first (how do we account for all the crazy things SPAs do with URL fragments?), but this is in line with how service worker caching of the page works (the SW Cache explicitly ignores the URL fragment on requests), so seems like it may be the right thing to do.

@jeffposnick for his opinion and for any cases where this may go awry

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure I understand the full context, but in general, yeah, I think ignoring the hash would make sense from the point of view of both the Cache Storage API and navigation requests.

@@ -34,4 +36,8 @@ class Offline extends Gatherer {
}
}

function cleanHash(url) {
return url.href.removeURLFragment();
Copy link
Member

Choose a reason for hiding this comment

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

maybe do the new URL() part inside here too? Can also do url.hash = ''; return url.href;

assert.strictEqual(artifact, 200);
}),
offlineGather.afterPass(optionsWithQueryString, tracingData).then(artifact => {
assert.strictEqual(artifact, -1);
Copy link
Member

Choose a reason for hiding this comment

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

this is a failure test, so maybe move to the other it()?

@brendankenny
Copy link
Member

brendankenny commented Jan 3, 2017

We store the url inside options.url without a fragment so we should do this check without fragment as well.

To clarify what's happening here:

  • In the CLI (based on the example in "URL responds with a 200 when offline" fails incorrectly #1296), if you test https://unindented.github.io/little-yam/, the offline test will also load https://unindented.github.io/little-yam/ which matches the response URL that comes back from the SW.

  • In the extension, if you load https://unindented.github.io/little-yam/ it gets redirected to https://unindented.github.io/little-yam/#/login?_k=oaybjy before testing by LH even starts, which we then compare against the offline response URL https://unindented.github.io/little-yam/ from the SW and fail the test.

    In this example, it's actually sw-precache that's stripping the fragment and requesting https://unindented.github.io/little-yam/, but that's what would be done anyway if you weren't using sw-precache and requested a match for https://unindented.github.io/little-yam/#/login?_k=oaybjy from the cache directly.

This is kind of the opposite problem of #715, where a real redirect (not just adding a fragment to the URL) makes the CLI fail the offline test because it tests the original URL but the extension passes since it always tests the redirected URL.

@paulirish
Copy link
Member

I think this could sit on top of the subclassed URL proposal I made over here:
#1390 (comment)

so it could be new URL(record._url)).stripHash() === new URL(options._url)).stripHash() && ...

@wardpeet
Copy link
Collaborator Author

wardpeet commented Jan 4, 2017

@paulirish that make sense :)
I could change this to @ebidel suggestion and @patrickhulce could fix the url abstraction inside #1390 or i can just close this PR :p

@brendankenny maybe update the audit to check url with fragment and without?

@brendankenny
Copy link
Member

#1390 landed, so good to go on adding method to the url shim

@wardpeet
Copy link
Collaborator Author

wardpeet commented Jan 8, 2017

I've 2 options. I went for option 1

Option 1:

/**
 * Removes hash from URL
 * @return {URL} Url object chaining
 */
URL.prototype.stripHash = function stripHash() {
  this.hash = '';

  return this;
};

Option 2:

/**
 * Removes hash from an url and returns it
 * @return {string} Url without the hash
 */
URL.prototype.stripHash = function stripHash() {
  const currentHash = this.hash;
  this.hash = '';

  const urlWithoutHash = this.href;
  this.hash = currentHash;

  return urlWithoutHash;
};

@brendankenny
Copy link
Member

a third option would mirror the URL spec's equality with the exclude fragments flag set. We could name it something awkward like

/**
 * Determine if url1 equals url2, ignoring URL fragments.
 * @param {string} url1
 * @param {string} url2
 * @return {boolean}
 */
URL.equalWithExcludedFragments = function(url1, url2) {
  url1 = new URL(url1);
  url1.hash = '';

  url2 = new URL(url2);
  url2.hash = '';

  return url1.href === url2.href;
};

(or pick a much better name :)

@wardpeet
Copy link
Collaborator Author

wardpeet commented Jan 9, 2017

@brendankenny do you rather have option 3?

@brendankenny
Copy link
Member

I would, but don't know what others think

* Removes hash from URL
* @return {URL} Url object chaining
*/
URL.prototype.stripHash = function stripHash() {
Copy link
Member

Choose a reason for hiding this comment

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

need test(s) in url-shim-test for whatever we end up putting in here

@patrickhulce
Copy link
Collaborator

+1 to a static method over a prototype extension, but I'm not terribly invested in it and fine with this too.

@wardpeet
Copy link
Collaborator Author

equalWithExcludedFragments it will be :)

@brendankenny
Copy link
Member

yay awkward naming :)

@brendankenny
Copy link
Member

@wardpeet :):) what do you think?

@wardpeet
Copy link
Collaborator Author

i'll try to update today :)

@ebidel
Copy link
Contributor

ebidel commented Jan 21, 2017

@wardpeet can you rebase?

…ne check.

We store the url inside options.url without a fragment so we should do this check without fragment as well.
Fixes PR GoogleChrome#1296
@wardpeet
Copy link
Collaborator Author

Updated finally, sorry for the wait!

@ebidel
Copy link
Contributor

ebidel commented Jan 23, 2017

Can you add a test for equalWithExcludedFragments in url-shim-test.js?

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

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

@wardpeet I'm going to add the tests for you :P

@wardpeet
Copy link
Collaborator Author

@brendankenny thanks

@wardpeet wardpeet deleted the offline-queryfragment branch May 11, 2017 18:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants