Node (Koa) not serving static files on HTTPS connection

928 Views Asked by At

Trying to request a static css stylesheet on the node (koa) server over a https connection, fails. Works fine on http.

HTTP works fine:

- http://www.example.com/assets/css/style.913142291ae94ed177988e5dfc67c66e.css serves the file, works fine, stylesheet is loaded to the application. mime-type is 'text/css'

HTTPS fails

- https://www.example.com/assets/css/style.913142291ae94ed177988e5dfc67c66e.css downloads the file, css not serving right. mime-type is 'application/octet-stream'

Issue only happens with Safari browsers, older versions of Chrome browsers. But does not happen on the latest Chrome browser.

How is this happening?


Here is the log for the Context object showing response 404 on https protocol:

koa: ctx at staticMiddlewareHandler { request: 
   { method: 'GET',
     url: '/assets/css/style.913142291ae94ed177988e5dfc67c66e.css',
     header: 
      { connection: 'upgrade',
        host: 'www.mydomain.com',
        'x-real-ip': '172.XX.XX.XXX',
        'x-forwarded-for': '116.XX.X.XXX, 172.XX.XX.XXX',
        'x-nginx-proxy': 'true',
        accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'accept-encoding': 'gzip, deflate',
        'accept-language': 'en-us',
        dnt: '1',
        'upgrade-insecure-requests': '1',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Safari/604.1.38',
        'x-forwarded-port': '443',
        'x-forwarded-proto': 'https' } },
  response: 
   { status: 404,
     message: 'Not Found',
     header: 
      { 'x-dns-prefetch-control': 'off',
        'x-frame-options': 'SAMEORIGIN',
        'x-download-options': 'noopen',
        'x-xss-protection': '1; mode=block' } },
  app: { subdomainOffset: 2, proxy: false, env: 'development' },
  originalUrl: '/assets/css/style.913142291ae94ed177988e5dfc67c66e.css',
  req: '<original node req>',
  res: '<original node res>',
  socket: '<original node socket>' }

Update

Node js application code via the ReactQL boilerplate. Full code here: https://github.com/reactql/kit/blob/master/kit/entry/server.js#L131

// Static file middleware
export function staticMiddleware() {
  return async function staticMiddlewareHandler(ctx, next) {
    try {
      if (ctx.path !== '/') {
        return await koaSend(
          ctx,
          ctx.path,
          process.env.NODE_ENV === 'production' ? {
            root: PATHS.public,
            immutable: true,
          } : {
            root: PATHS.distDev,
          },
        );
      }
    } catch (e) { /* Errors will fall through */ }
    return next();
  };
}

Nginx config

server {
    listen 80;
    server_name domain.com;
    return 301 $scheme://www.$host$request_uri;
}

server {
    listen 80;
    server_name www.domain.com;
    client_max_body_size 20M;
    charset utf-8;

    # ELB stores the protocol used between the client
    # and the load balancer in the X-Forwarded-Proto request header.
    # Check for 'https' and redirect if not
    if ($http_x_forwarded_proto != 'https') {
        return 301 https://$host$request_uri;
    }

    location / {
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-NginX-Proxy true;

        # Bound to Docker my `react` container, exposed on port 4000.
        # Set name from docker-compose.yml `volumes_from`
        proxy_pass http://react:4000;
    }
}

Update 2 I have a AWS load balancer sitting on top of the nginx proxy, redirect all 443 traffic to 80.

0

There are 0 best solutions below