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

Protect users from getting stuck with an offline cached app #628

Closed
wants to merge 1 commit into
base: devel
from

Conversation

Projects
None yet
2 participants
@awwx
Contributor

awwx commented Jan 20, 2013

Have standard Meteor also return a 404 for /app.manifest, along with /favicon.ico and /robots.txt.

Rationale:

Suppose a programmer is using some "appcache" smart package (which serves an app cache manifest file) on a domain such as "foo.meteor.com". Later the programmer decides to stop using the "appcache" package and wants to go back to using stock Meteor. A user who previously had been using the app on foo.meteor.com and has it in their browser's app cache will see the following:

  1. On navigating to "foo.meteor.com", the browser will first load the app from the app cache (without accessing the Internet), and so the user will at first be running the old version of the app.
  2. The browser connects to the server and requests the app cache manifest, "/app.manifest". Note that even if the HTML of the new app served by stock Meteor doesn't contain the <html manifest="/app.manifest"> element which specifies using a manifest file, the browser doesn't know that yet because it hasn't requested the app web page ("/") yet.
  3. The stock Meteor server (without this code change) returns the app html for "/app.manifest". The browser believes that the app is still being cached because it didn't get a 404, but since the format is invalid for an app manifest the browser ignores the contents and merely sends an app cache error event.

The user is now stuck. Pressing reload or force reload or restarting their browser does not get the browser off the old cached code. The user will continue to see the old cached app, forever, until they manually clear their browser's app cache.

Of course it would be easy enough to have a "manifest404" smart package that would specifically deliver a 404 for "/app.manifest". A programmer who had previously used an "appcache" smart package could substitute the "manifest404" package and their users would be fine. But it would mean that once any users had used an app cache on a domain such as "foo.meteor.com", that domain would now be "poisoned" in the sense that a stock Meteor without any added packages could never again be used safely on that domain. And that could be a support nightmare, where stock Meteor works everywhere... expect for a few users on a few domains who however long ago happened to use an app cache version of an app on that domain.

So for safety, it seems like not serving app_html for the app manifest is a good idea ^_^

@n1mmy

This comment has been minimized.

Member

n1mmy commented Jan 24, 2013

This is an interesting issue. Thanks for bringing it up, and for the clear explanation!

I don't think this patch is quite the right answer, though. It seems odd to hardcode a particular name for a .manifest file in the framework. What if someone used a different name for their cache file? Maybe what we want is a way for users to specify a 404 for a URL?

Can including a valid but empty manifest file in public/ also un-poison an app, or does it have to be a 404?

@awwx

This comment has been minimized.

Contributor

awwx commented Jan 24, 2013

It does have to be a 404. An empty manifest file is treated as an invalid manifest, but that doesn't cause the browser to stop using the app cache, it merely causes the browser to not update the cache that time.

There's no reason to use different names for the manifest, and good reasons to choose a standard name. Suppose a programmer is using appcache implementation A and decides to switch to appcache implementation B. If both implementations are using the same manifest file name, then the programmer can simply uninstall the appcache-a package and install the appcache-b package. But if the packages are using different names for the manifest, then browsers which have the old manifest from A won't switch over to B.

Maybe what we want is a way for users to specify a 404 for a URL?

Yes, a programmer can work around the problem by configuring Meteor to deliver a 404 for the old manifest. But what this means is that uninstalling the package is no longer enough to get rid of it. Normally if the programmer decides they don't want package-a any more they simply uninstall package-a and it goes away. But the "specify a 404 for the old manifest file" option means that the programmer has to both uninstall the appcache package and configure Meteor to specially deliver a 404 for the old manifest. Forever on that domain, as long as there might be any user who hasn't gotten their app cache cleared yet. And if they ever reinstall Meteor or otherwise lose the special configuration, they get a mysterious bug where the occasional user can't use their app but everyone else can. And what if the domain changes hands? "Yes you can take over example.com but you have to configure Meteor specially to use it".

This is a consequence of Meteor's decision to serve app_html for arbitrary URLs. Most frameworks don't do that. Most frameworks serve content on specific URLs and deliver a 404 on an arbitrary URL. So this issue doesn't arise. If someone stops using an app manifest the framework delivers a 404 and everything is fine.

We should choose a standard name for the manifest file for the same reason that "favicon.ico" and "robots.txt" have standard names: interoperability. Why can't I call my search engine exclusion file "search-engine-exclusions" if I want to? So that when the search engine comes looking for "robots.txt" it finds it. As an appcache package author, why shouldn't I be able to use a arbitrary name for the manifest file? So that when the programmer stops using my appcache package or switches to a different one, the app still works.

@n1mmy

This comment has been minimized.

Member

n1mmy commented Feb 1, 2013

After talking with Geoff, we agree. While this isn't the right long term solution, it is expedient and will solve a real problem. The real solution is server side routing, where the server knows what routes to serve the app html for and which routes to 404. This is on the roadmap already, but will be a while. In the mean time, your patch makes sense. Merged in df93f65.

@n1mmy n1mmy closed this Feb 1, 2013

@awwx

This comment has been minimized.

Contributor

awwx commented Feb 3, 2013

It occurs to me that (until we get server side routing) we might like to make the exclusion to be any URL ending in ".manifest" or ".appcache". This would help developers switching to standard Meteor today (not using the appcache package), when they are publishing on a domain which previously was serving any kind of app cache (not just the one generated by the appcache smart package).

@awwx awwx deleted the awwx:app-manifest-404 branch Mar 31, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment