mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Allow static resources to be configured as online only.
Add a route policy type "static-online" for files in public/ that shouldn't be cached offline. Put "static-online" files in the manifest NETWORK section instead of in the CACHE section.
This commit is contained in:
committed by
Nick Martin
parent
1be9a4989c
commit
2500312cd5
@@ -157,9 +157,9 @@ var appUrl = function (url) {
|
||||
if (url === '/app.manifest')
|
||||
return false;
|
||||
|
||||
// Avoid serving app HTML for declared network routes such as /sockjs/.
|
||||
// Avoid serving app HTML for declared routes such as /sockjs/.
|
||||
if (__meteor_bootstrap__._routePolicy &&
|
||||
__meteor_bootstrap__._routePolicy.classify(url) === 'network')
|
||||
__meteor_bootstrap__._routePolicy.classify(url))
|
||||
return false;
|
||||
|
||||
// we currently return app HTML on all URLs by default
|
||||
|
||||
@@ -27,6 +27,11 @@
|
||||
else if (_.contains(knownBrowsers, option)) {
|
||||
enabledBrowsers[option] = value;
|
||||
}
|
||||
else if (option === 'onlineOnly') {
|
||||
_.each(value, function (urlPrefix) {
|
||||
Meteor._routePolicy.declare(urlPrefix, 'static-online');
|
||||
});
|
||||
}
|
||||
else {
|
||||
throw new Error('Invalid AppCache config option: ' + option)
|
||||
}
|
||||
@@ -93,7 +98,8 @@
|
||||
manifest += "CACHE:" + "\n";
|
||||
manifest += "/" + "\n";
|
||||
_.each(bundle.manifest, function (resource) {
|
||||
if (resource.where === 'client') {
|
||||
if (resource.where === 'client' &&
|
||||
! Meteor._routePolicy.classify(resource.url)) {
|
||||
manifest += resource.url + "\n";
|
||||
}
|
||||
});
|
||||
@@ -107,9 +113,15 @@
|
||||
// TODO adding the manifest file to NETWORK should be unnecessary?
|
||||
// Want more testing to be sure.
|
||||
manifest += "/app.manifest" + "\n";
|
||||
_.each(Meteor._routePolicy.urlPrefixesFor('network'), function (urlPrefix) {
|
||||
manifest += urlPrefix + "\n";
|
||||
});
|
||||
_.each(
|
||||
[].concat(
|
||||
Meteor._routePolicy.urlPrefixesFor('network'),
|
||||
Meteor._routePolicy.urlPrefixesFor('static-online')
|
||||
),
|
||||
function (urlPrefix) {
|
||||
manifest += urlPrefix + "\n";
|
||||
}
|
||||
);
|
||||
manifest += "*" + "\n";
|
||||
|
||||
// content length needs to be based on bytes
|
||||
@@ -139,7 +151,10 @@
|
||||
"** online as well as making it not cacheable for offline use).\n" +
|
||||
"**\n" +
|
||||
"** To avoid this problem we recommend keeping the size of your static\n" +
|
||||
"** application assets under 5MB."
|
||||
"** application assets under 5MB.\n" +
|
||||
"**\n" +
|
||||
"** If you have some larger assets that you'd like to make online only,\n" +
|
||||
"** you can do that with the AppCache "onlineOnly" config option."
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
// In addition to listing specific files to be cached, the browser
|
||||
// application cache manifest allows URLs to be designated as NETWORK
|
||||
// (always fetched from the Internet) and FALLBACK (which we use to
|
||||
// serve app HTML on arbitrary URLs).
|
||||
//
|
||||
// The limitation of the manifest file format is that the designations
|
||||
// are by prefix only: if "/foo" is declared NETWORK then "/foobar"
|
||||
// will also be treated as a network route.
|
||||
//
|
||||
// Meteor._routePolicy is a low-level API for declaring the route type
|
||||
// of URL prefixes:
|
||||
//
|
||||
// "network": for network routes that should not conflict with static
|
||||
// resources. (For example, if "/sockjs/" is a network route, we
|
||||
// shouldn't have "/sockjs/red-sock.jpg" as a static resource).
|
||||
//
|
||||
// "static-online": for static resources which should not be cached in
|
||||
// the app cache. This is implemented by also adding them to the
|
||||
// NETWORK section (as otherwise the browser would receive app HTML
|
||||
// for them because of the FALLBACK section), but static-online routes
|
||||
// don't need to be checked for conflict with static resources.
|
||||
|
||||
(function () {
|
||||
|
||||
// The route policy is a singleton in a running application, but we
|
||||
@@ -17,8 +39,8 @@
|
||||
},
|
||||
|
||||
checkType: function (type) {
|
||||
if (! _.contains(['network'], type))
|
||||
return 'the route type must be "network"';
|
||||
if (! _.contains(['network', 'static-online'], type))
|
||||
return 'the route type must be "network" or "static-online"';
|
||||
return null;
|
||||
},
|
||||
|
||||
@@ -35,6 +57,8 @@
|
||||
|
||||
checkForConflictWithStatic: function (urlPrefix, type, _testManifest) {
|
||||
var self = this;
|
||||
if (type === 'static-online')
|
||||
return null;
|
||||
var manifest = _testManifest || __meteor_bootstrap__.bundle.manifest;
|
||||
var conflict = _.find(manifest, function (resource) {
|
||||
return (resource.type === 'static' &&
|
||||
|
||||
@@ -2,9 +2,8 @@ Tinytest.add("routepolicy", function (test) {
|
||||
var policy = new Meteor.__RoutePolicyConstructor();
|
||||
|
||||
policy.declare('/sockjs/', 'network');
|
||||
// App routes might look like this...
|
||||
// policy.declare('/posts/', 'app');
|
||||
// policy.declare('/about', 'app');
|
||||
policy.declare('/bigphoto.jpg', 'static-online');
|
||||
policy.declare('/anotherphoto.png', 'static-online');
|
||||
|
||||
test.equal(policy.classify('/'), null);
|
||||
test.equal(policy.classify('/foo'), null);
|
||||
@@ -13,11 +12,14 @@ Tinytest.add("routepolicy", function (test) {
|
||||
test.equal(policy.classify('/sockjs/'), 'network');
|
||||
test.equal(policy.classify('/sockjs/foo'), 'network');
|
||||
|
||||
// test.equal(policy.classify('/posts/'), 'app');
|
||||
// test.equal(policy.classify('/posts/1234'), 'app');
|
||||
test.equal(policy.classify('/bigphoto.jpg'), 'static-online');
|
||||
test.equal(policy.classify('/bigphoto.jpg.orig'), 'static-online');
|
||||
|
||||
test.equal(policy.urlPrefixesFor('network'), ['/sockjs/']);
|
||||
// test.equal(policy.urlPrefixesFor('app'), ['/about', '/posts/']);
|
||||
test.equal(
|
||||
policy.urlPrefixesFor('static-online'),
|
||||
['/anotherphoto.png', '/bigphoto.jpg']
|
||||
);
|
||||
});
|
||||
|
||||
Tinytest.add("routepolicy - static conflicts", function (test) {
|
||||
@@ -26,9 +28,14 @@ Tinytest.add("routepolicy - static conflicts", function (test) {
|
||||
"path": "static/sockjs/socks-are-comfy.jpg",
|
||||
"type": "static",
|
||||
"where": "client",
|
||||
"cacheable": false,
|
||||
"url": "/sockjs/socks-are-comfy.jpg"
|
||||
},
|
||||
{
|
||||
"path": "static/bigphoto.jpg",
|
||||
"type": "static",
|
||||
"where": "client",
|
||||
"url": "/bigphoto.jpg"
|
||||
}
|
||||
];
|
||||
var policy = new Meteor.__RoutePolicyConstructor();
|
||||
|
||||
@@ -36,4 +43,9 @@ Tinytest.add("routepolicy - static conflicts", function (test) {
|
||||
policy.checkForConflictWithStatic('/sockjs/', 'network', manifest),
|
||||
"static resource /sockjs/socks-are-comfy.jpg conflicts with network route /sockjs/"
|
||||
);
|
||||
|
||||
test.equal(
|
||||
policy.checkForConflictWithStatic('/bigphoto.jpg', 'static-online', manifest),
|
||||
null
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user