title: Node, ws, ssl, nginx giving error 426, upgrade needed
body: <p>I am serving an app using Node.js and NGINX. I am securing NGINX with LetsEncrypt, and running my node app on server with pm2 (using NGINX as a reverse proxy). </p>
  
  <p>My site will not load anything (426 error - upgrade required), but I can connect with the following scratchpad:</p>
  
  <pre><code>var port = 443;
  var ws = new WebSocket("wss://mywebsite.com:" + port);
  
  ws.onopen = function() {
    console.log("Connected");
  }
  
  ws.onmessage = function(comment) {
    console.log(JSON.parse(comment.data));
  }
  </code></pre>
  
  <p>Here is the NGINX setup:</p>
  
  <pre><code>server {
  
          root /var/www/html;
  
          # Add index.php to the list if you are using PHP
          index index.html index.htm index.nginx-debian.html;
  
          server_name mywebsite.com www.mywebsite.com;
  
          location / {
                  proxy_pass http://127.0.0.1:8080/;
                  proxy_http_version 1.1;
                  proxy_set_header Upgrade $http_upgrade;
                  proxy_set_header Connection "upgrade";
      }
  
      listen [::]:443 ssl ipv6only=on; # managed by Certbot
      listen 443 ssl; # managed by Certbot
      ssl_certificate /path/to/cert; # managed by Certbot
      ssl_certificate_key /path/to/key; # managed by Certbot
      include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
      ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
  
  
  }
  server {
      if ($host = www.mywebsite.com) {
          return 301 https://$host$request_uri;
      } # managed by Certbot
  
  
      if ($host = mywebsite.com) {
          return 301 https://$host$request_uri;
      } # managed by Certbot
  
  
          listen 80 default_server;
          listen [::]:80 default_server;
  
          server_name mywebsite.com www.mywebsite.com;
      return 404; # managed by Certbot
  }
  </code></pre>
  
  <p>My client code is basically identical to the scratchpad. This is the relevant server-side code:</p>
  
  <pre><code>var WebSocket = require('ws');
  var serverPort = 8080;
  var wss = new WebSocket.Server({port:serverPort});
  console.log("Server running on port " + serverPort + " started at: " + new Date());
  
  wss.on('connection', function(ws) {
  
          console.log("Connected to websocket: " + ws);
          var introComment = JSON.stringify({
                  user: "Welcome!",
                  data: {
                          body: "Welcome to the realtime feed!",
                          name: "realtime-intro-connection-message",
                  },
  
          });
          ws.send(introComment);
  });
  </code></pre>
  
  <p>These are the response headers the browser receives:</p>
  
  <pre><code>HTTP/1.1 426 Upgrade Required
  Server: nginx/1.10.3 (Ubuntu)
  Date: Wed, 23 May 2018 19:20:36 GMT
  Content-Type: text/plain
  Content-Length: 16
  Connection: keep-alive
  </code></pre>
  
  <p>I read that there should be an "Upgrade" header, is that part of the problem?</p>