Search code examples
node.jshttphttp-proxyhttp-options-method

Proxy server is not handling OPTIONS request correctly


I have this simple node.js proxy server implementation:

const s = http.createServer((req, res) => {

  console.log('req method:', req.method);

  if(String(req.method || '').toUpperCase() === 'OPTIONS'){
    res.setHeader('Access-Control-Expose-Headers', '*');
    res.setHeader('Access-Control-Allow-Credentials', 'true');
    res.setHeader('Access-Control-Max-Age', '3600');
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Headers', '*');
    res.setHeader('Access-Control-Allow-Methods', '*');
    res.setHeader('Connection', 'keep-alive');
    res.setHeader('Access-Control-Request-Method', 'POST');
    res.setHeader('Allow', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
    res.setHeader('Allowed', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
    return res.writeHead(200);
  }

  // ...
});

the problem is that it's not receiving any requests except OPTIONS requests and I suspect that's because it's not handling the OPTIONS requests correctly. I want to allow everything because this is all running locally on localhost - is there something I am doing wrong with my OPTIONS request handling for this proxy server?

When I use the http-proxy lib, everything seems to work fine:

const httpProxy = require('http-proxy');
const proxy = httpProxy.createProxyServer({target:'http://localhost:2020'});
const s = http.createServer((req,res) => proxy.web(req,res));

..so there is something wrong with my implementation...I guess the most basic question - as a proxy server should I be forwarding the OPTIONS requests to the proxied server or just be responding early? that's definitely the first decision point..


Solution

  • One thing I noticed, is that you are missing the Content-Length header.

    According to RFC7231 section 4.3.7 you must send

    Content-Length: 0
    

    if you do not have a response body.

    And regarding the 2nd part of your question: OPTIONS requests shall be forwarded to the destination server. They are not cacheable.