[SOLVED] After 1.8 Upgrade setBundledJsCssUrlRewriteHook CDN Infinite Loop

I’ve been working on updating my production app from Meteor 1.5.x to 1.8.1 and everything has been going pretty smoothly - way to go Meteor!

I have run into one strange issue when deploying to my staging server. The WebAppInternals setBundledJsCssUrlRewriteHook is firing non-stop. It’s logging that it’s sending the js and css over and over again.

sswee - 2019-10-07 21:58:52-07:00CDN Setup: setBundledJsCssUrlRewriteHook: Setting a URL to: https://d24q3ld97k5pkl.cloudfront.net/2b5db0a7729e9aa6e5d6c3b4d84e66d5adb05b83.js?meteor_js_resource=true&_g_app_v_=266
sswee - 2019-10-07 21:58:53-07:00CDN Setup: setBundledJsCssUrlRewriteHook: Setting a URL to: https://d24q3ld97k5pkl.cloudfront.net/0f1571de65f821f27069dfadda7cc0720242cd53.css?meteor_css_resource=true&_g_app_v_=266
11z08 - 2019-10-07 21:58:53-07:00CDN Setup: setBundledJsCssUrlRewriteHook: Setting a URL to: https://d24q3ld97k5pkl.cloudfront.net/2b5db0a7729e9aa6e5d6c3b4d84e66d5adb05b83.js?meteor_js_resource=true&_g_app_v_=266
11z08 - 2019-10-07 21:58:54-07:00CDN Setup: setBundledJsCssUrlRewriteHook: Setting a URL to: https://d24q3ld97k5pkl.cloudfront.net/0f1571de65f821f27069dfadda7cc0720242cd53.css?meteor_css_resource=true&_g_app_v_=266
...

I run my app behind a CloudFront CDN and have the following code in /server:

Meteor.startup(function() {

  //  Set Meteor to use CDN for all static assets if in production mode
  if(Meteor.isProduction) {

    if(process.env.CDN_URL && process.env.GALAXY_APP_VERSION_ID) {

      //  Configure CDN URL to call the latest version of the app
      WebAppInternals.setBundledJsCssUrlRewriteHook(function(url) {
        console.log("CDN Setup: setBundledJsCssUrlRewriteHook: Setting a URL to: " + "https://" + process.env.CDN_URL + url + "&_g_app_v_=" + process.env.GALAXY_APP_VERSION_ID);
        return 'https://' + process.env.CDN_URL + url + '&_g_app_v_=' + process.env.GALAXY_APP_VERSION_ID;
      });
    }
  }

When using Meteor 1.5.x the above log would fire a few times upon deploying my app. Even with 50+ users it would only log a few times. I assumed the above doesn’t run on every request - but it just runs as Meteor configures this? Or does it run on every single user request? If so, it didn’t seem to exhibit that behavior before upgrading. On my test server with even a single user, the logging happens non-stop forever.

Now it’s running repeatedly forever. My first thought was maybe there was some reactive trigger or Meteor.startup() was repeatedly running but they’re not.

Does this have anything to do with how Meteor handles assets now? Past version 1.5?

I’ve tried searching everywhere. I’m at a loss.

1 Like

I did some retroactive testing on Meteor versions:

1.6.0.1 - Doesn’t loop infinitely. Logs a few times and then stops. Similar to 1.5.x
1.6.1.4 - Couldn’t get this version to production-minify properly without some error about Your current PostCSS version is 5.2.18, but postcss-modules-scope uses 6.0.21. Perhaps this is the source of the error below. So couldn’t test this on Galaxy.
1.7.0.5 - Has the same infinite-loop behavior as 1.8.1

There’s a lot of results on Google about CloudFront “infinite loops” but they’re all related to redirecting. I can’t help but this this is Meteor related if it’s working correctly in 1.5.x and 1.6.0.1 with no changes to the code or the CDN settings.

This is a bummer - this was the last holdout of going into production with 1.8.1

The only thing I may note is my app does use the old Meteor 1.0 app structure. Will be updating soon. But the app builds and runs as expected even with the old structure. And it’s not like the entire Meteor.startup() block is running repeatedly. It’s just the hook to WebAppInternals.setBundledJsCssUrlRewriteHook.

I cloned the Meteor todos example app, updated it to Meteor 1.8.1, added the same WebAppInternals setBundledJsCssUrlRewriteHook hook in the appropriate imports/startup/server folder and wired up a CloudFront CDN and it is doing the same thing - infinitely looping the hook.

So, same thing is happening in a test app. I did have to remove the app-prod-security package which is an umbrella package for browser-policy and force-ssl in order to get the app to load the JS bundle served from CloudFront without complaining about the Content-Security-Policy. I currently run my app with no CSP (which I should update).

Will investigate that further as maybe the issue lies in there somewhere.

I was able to stop the infinite loop by (strangely) adding force-ssl to both my app and the todos example app. Not sure why this makes any difference as I host on Galaxy and all the docs say to remove force-ssl and just turn on the “Force HTTPS” checkbox in the Galaxy Domain settings - which I have always done.

This stops the loop but still calls setBundledJsCssUrlRewriteHook upon every client visit or refresh. So it’s still over-running and using resources and polluting the log.

Does anyone else out there have a Meteor 1.7.x or 1.8.x app with a CloudFront CDN that’s working correctly? Have you tried logging this hook to make sure it’s running how you think it is?

Again, in the past, I have always logged this hook and it only runs each time the app starts after a deploy. Never with each client or looping like this. I may file a Meteor bug on this as it seems something in Meteor has changed.

Maybe scanning the changelog of 1.7 (or 1.6) can give a clue

I read it word-for-word before upgrading. I’ve been pouring over every release for details. Not finding much anywhere related to this.

We are using cloudfront. Will discuss with our guys what they did once I’m at the office. If anything related, I’ll report back here

we are only using WebAppInternals.setBundledJsCssPrefix()

I narrowed it down to a change made between Meteor version 1.6 and 1.6.1. There’s some changes made to the webapp package.

Created an official issue - https://github.com/meteor/meteor/issues/10731

1 Like

Nice catch. Seems like removing the memoize function a likely culprit. Although depending on the function, it’s possible that the running unmemoized function is not that expensive e.g. replacing url prefix

If that is the case, the rewrite will be called for every first access to the server to serve the assets

No, it’s getting called every time any resource is accessed, which like you said, may not be that expensive. Before, it would only fire once when the server started. But it’s still strangely infinitely looping on Galaxy.

The loop seems like https -> http and vice versa issue since you mentioned forced-ssl removed the loop. Definitely a bug

I figured it out. The infinite loop is just the Galaxybot checking your app. The updates to webapp in 1.6 now send a fresh response on every request. They removed memoization which is what was only causing my setBundledJsCssPrefix() to log once before.

The Galaxybot’s request is always http so adding force-ssl intercepts this and responds with a 302 redirect to the same URL that is already https which in affect does nothing in your app. But it does bypass your web server hence the logging not occurring.

It has nothing to do with CDNs or setBundledJsCssPrefix(). Full explanation - https://github.com/meteor/meteor/issues/10731

2 Likes