cloudhead / node-static

rfc 2616 compliant HTTP static-file server module, with built-in caching.
MIT License
2.18k stars 245 forks source link

[ERR_HTTP_HEADERS_SENT] after successfully requesting a file with "Range: bytes=0-" #241

Open EdricCantu opened 1 year ago

EdricCantu commented 1 year ago

The [ERR_HTTP_HEADERS_SENT] error happens no matter how much or how little I add or remove to my code.

even just the basic server,

var ns = new (require('node-static')).Server('./pub');
httpserver = require('http').createServer((req, res)=>{
     req.addListener('end',()=>{
      ns.serve(req, res);
    }).resume();
});
httpserver.listen(1111);

as given from the documentation. For some reason, it only affects a specific file; And by specific file, I mean a file which happens to, for some reason, be requested with a Range: bytes=0- header.

node:_http_server:342
    throw new ERR_HTTP_HEADERS_SENT('write');
    ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot write headers after they are sent to the client
    at new NodeError (node:internal/errors:405:5)
    at ServerResponse.writeHead (node:_http_server:342:11)
    at Server.finish (/home/user/project/node_modules/node-static/lib/node-static.js:125:17)
    at finish (/home/user/project/node_modules/node-static/lib/node-static.js:170:14)
    at /home/user/project/node_modules/node-static/lib/node-static.js:337:13
    at streamFile (/home/user/project/node_modules/node-static/lib/node-static.js:382:13)
    at ReadStream.<anonymous> (/home/user/project/node_modules/node-static/lib/node-static.js:375:17)
    at ReadStream.emit (node:events:511:28)
    at emitCloseNT (node:internal/streams/destroy:132:10)
    at process.processTicksAndRejections (node:internal/process/task_queues:81:21) {
  code: 'ERR_HTTP_HEADERS_SENT'
  }

This has always worked up until a few days ago, which I guess is more likely my browsers fault.

and after some minor research, it appears that on that specific file, my browser is sending a Range: bytes=0- header. When I make a request to that same file, without the header present, it does not cause node-static to error out on me.

According to an official chromium contributor, and I suppose RFC 7233 §2.1, this is a normal, valid, and considerably probable request, despite the redundant header, that an HTTP server should be able to withstand. It is simply sent to verify that the server supports Range headers.

Node.js: v20.3.0 NPM: v9.7.1 node-static: 0.7.11 running OS: Debian 11 (Crostini Linux VM on Chrome OS) Host OS (and browser): Chrome 115.0.5790.30 Beta

zkrige commented 1 year ago

I'm getting the same issue. its definitely related to byte range

if (status !== 200 || req.method !== 'GET') {
    res.writeHead(status, headers);
    res.end();
}

status is 206 for a range request, so it falls into this if block, and tries to write headers again

zkrige commented 1 year ago

I've submitted PR to fix this