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

clientId on ForeignFetchEvents #1017

Closed
jridgewell opened this issue Dec 2, 2016 · 7 comments
Closed

clientId on ForeignFetchEvents #1017

jridgewell opened this issue Dec 2, 2016 · 7 comments
Milestone

Comments

@jridgewell
Copy link

jridgewell commented Dec 2, 2016

I'd like to request that ForeignFetchEvents provide a clientId property like FetchEvents do.

Background

Our "App" breaks code into several javascript files, a "core" script and a series of extensions. Each script has a long-cached, fingerprinted URL that allows us to identify. Every week, we publish new scripts (keeping the old) at the new fingerprint URL. All pages are then updated to use the new script URLs.

To speed up the first request after we publish, we've implemented a Service Worker that follows a "stale-while-revalidate" model. When we request script /[this weeks fingerprint]/extension.js, we'll check to see if we have a previous release's extension.js cached. If so, we'll take two steps:

  1. Version lock this client to the previous release
    • This ensures the next request by the client will serve the exact same version
  2. Request the new JS in the background, updating cache

This works extremely well for the normal Fetch case. All requests start by requesting the latest version, SW determines the version to serve and gives cached responses using a uniform version, and the SW requests all the new scripts in the background.

Now, our "app" works both on our own domain, and on an arbitrary publisher's domain. To give the same speed boost after publish, we'd like to implement the same stale-while-revalidate behavior. Foreign Fetch, however, has does not provide a clientId, so we're unable to uniquely identify which client is issuing a request. And if we can't identify the client, we can't determine if the client is version locked by a previous week's cached script.

Temporary Solution

In the meantime, we've taken to using a combination of the request's referrer and a 60 second "batch" timer. All requests made by the referrer within those 60 seconds get the same "clientId". Once those 60 seconds have expired, a new id is generated.

While this'll work for now, it's far from perfect. If the publisher's page uses a <meta name="referrer" content="none"> tag, our fallback is useless for uniquely identifying. Or, if something happens and the next script request comes after the 60 second batch, we run the risk of serving a nonuniform version.

Real Solution

Providing a unique clientId like the one on FetchEvents would solve this problem completely. As the string is supposed to be opaque and transient, it shouldn't have any privacy issues.

@mkruisselbrink mkruisselbrink added this to the Version 2 milestone Dec 2, 2016
@mkruisselbrink
Copy link
Collaborator

I agree that it sounds reasonable to add some kind of clientId to ForeignFetchEvent. Easiest would of course be to just return "the" clientId of the client. I wonder if that would cause any concerns around cross-origin correlating clients though, so maybe we'd have to make sure to return a different (but consistent) clientId for the same client to different origins?

@jakearchibald
Copy link
Contributor

Yeah, we have to think very hard about this in terms of security. I like @mkruisselbrink's idea around double-keying, but even then it feels like something that the originating origin should opt into.

@cramforce
Copy link

I think we should try to avoid any kind of opt-in. The magic of foreign-fetch on CDN origins is that large portions of the web get better transparently.

Of course, security/privacy has to be thought through. It being the same clientId as exposed to another worker for a given origin would definitely not be required IMO.

@isonmad
Copy link
Contributor

isonmad commented Jan 16, 2017

Would it not be possible to generate the javascript source URLs dynamically, and instead fetch /[this weeks fingerprint]/extension.js?clientID=ABCXYZ..., then key the version-locking on that string (the same random string appended to every extension URL in a given client) and strip the ?... part off before sending it on to the network?

@cramforce
Copy link

@isonmad In our case there doesn't run any JS to generate the JS URLs. It is crucially important that the request is started by the preload scanner.

@jridgewell
Copy link
Author

Further, the foreign domains where our javascript is being linked from are owned by the publishers, not us. We can't force them to generate unique cliendIds for every page request (and it would break other aspects of our caching CDN).

@jakearchibald
Copy link
Contributor

Closing, as we're removing foreign fetch.

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

No branches or pull requests

5 participants