title: Express.js force HTTPS/SSL redirect error: Too many redirects
body: <p>So the stack is this: Express &amp; Angular deployed to Heroku. I'm trying to serve the app forced over HTTPS by using a simple redirect using the code highlighted below. However when I open up the URL in the browser, I get a 'too many redirects' error. </p>
  
  <p>When I type <a href="http://[myurl].com" rel="noreferrer">http://[myurl].com</a>, I can see the URL in the browser changing to <a href="https://[myurl].com" rel="noreferrer">https://[myurl].com</a> but nothing shows up at that address. It just shows 'Too many redirects'. This proves that it successfully redirects but I feel like Angular is messing it up.</p>
  
  <p>When I remove the redirecting code below and access HTTPS or the HTTP address manually in the browser, it works fine.</p>
  
  <pre><code>//HTTPS redirect middleware
  function ensureSecure(req, res, next) {
      console.log(req.protocol + process.env.PORT + '' + req.hostname + req.url);
      if(req.secure || req.hostname=='localhost'){
          //Secure request, continue to next middleware
          next();
      }else{
          res.redirect('https://' + req.hostname + req.url);
          console.log(req.protocol + process.env.PORT + '' + req.hostname + req.url);
      }
  }
  //Parse the body of the request as a JSON object, part of the middleware stack (https://www.npmjs.com/package/body-parser#bodyparserjsonoptions)
  app.use(bodyParser.json());
  //Serve static Angular JS assets from distribution, part of the middleware stack, but only through HTTPS
  app.all('*', ensureSecure);
  app.use('/', express.static('dist'));
  //Import routes
  app.use('/api', [router_getToken, router_invokeBhApi]);
  //Setup port for access
  app.listen(process.env.PORT || 3000, function () {
      console.log(`The server is running on port ${process.env.PORT || 3000}!`);
  });
  </code></pre>
  
  <p>This is a sample of the heroku logs when you visit <a href="http://[myurl].com" rel="noreferrer">http://[myurl].com</a> (I masked the URL):</p>
  
  <pre><code>2016-11-29T21:50:34.363391+00:00 app[web.1]: 0|app      | http37436[something].com/
  2016-11-29T21:50:34.363468+00:00 app[web.1]: 0|app      | http37436[something].com/
  2016-11-29T21:50:34.402022+00:00 app[web.1]: 0|app      | http37436[something].com/
  2016-11-29T21:50:34.402091+00:00 app[web.1]: 0|app      | http37436[something].com/
  2016-11-29T21:50:34.436006+00:00 app[web.1]: 0|app      | http37436[something].com/
  2016-11-29T21:50:34.437454+00:00 app[web.1]: 0|app      | http37436[something].com/
  2016-11-29T21:50:34.479580+00:00 app[web.1]: 0|app      | http37436[something].com/
  </code></pre>
  
  <p>The browser (Chrome latest) shows these requests in the Network tab over &amp; over &amp; over again:<br>
  'Request URL:<a href="https://[myurl].com/" rel="noreferrer">https://[myurl].com/</a><br>
  Request Method:GET<br>
  Status Code:302 Found'  </p>
  
  <p>Notice how Heroku (the console.log in the express.js code) shows that I'm making HTTP requests but my browser is saying I'm making HTTPS requests. So confused!</p>
  
  <p>EDIT: 
  I tried this as well</p>
  
  <pre><code>//HTTPS redirect middleware
  function ensureSecure(req, res, next) {
      console.log(req.protocol + process.env.PORT + '' + req.hostname + req.url);
      if (req.secure || req.hostname == 'localhost') {
          //Serve Angular App
          express.static('dist');
      } else {
          //res.redirect('https://' + req.hostname + ':' + process.env.PORT + req.url);
          res.redirect('https://[myurl].com/');
      }
  }
  //Parse the body of the request as a JSON object, part of the middleware stack (https://www.npmjs.com/package/body-parser#bodyparserjsonoptions)
  app.use(bodyParser.json());
  //Serve static Angular JS assets from distribution, part of the middleware stack, but only through HTTPS
  app.use('/', ensureSecure);
  //Import routes
  app.use('/api', [router_getToken, router_invokeBhApi]);
  //Setup port for access
  app.listen(process.env.PORT || 3000, function () {
      console.log(`The server is running on port ${process.env.PORT || 3000}!`);
  });
  </code></pre>