skleeschulte / basic-to-passport-auth-http-proxy

HTTP proxy server that can access resources which use the Passport SSI Version 1.4 Protocol for authorization with credentials supplied by Basic HTTP authentication.
MIT License
60 stars 20 forks source link

'ERR_HTTP_HEADERS_SENT' terminate the script #10

Open Sonsbecker opened 3 years ago

Sonsbecker commented 3 years ago

Hello, I use the script (as "root") with Node.js (v12) to establish a HyperBackup connection to OneDrive on a Synology server (DS214 + DSM6.2.3-25426 Update 3). I proceeded exactly according to "README". It works.

But after a while the following error messages appear and the script is terminated completely. Can no longer connect to OneDrive. Only when I restart the script.

  proxy:error [29502539/7982] Sending error response: 500 read ECONNRESET +1h                                              <<-- always other times
  proxy:error [29502539/7982] Sending error response: 500 Cannot call write after a stream was destroyed +37ms             <<-- always other times
_http_outgoing.js:526
    throw new ERR_HTTP_HEADERS_SENT('set');
    ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:526:11)
    at sendResponse (/usr/basic-to-passport-auth-http-proxy-master/lib/server.js:48:17)
    at ProxyServer.<anonymous> (/usr/basic-to-passport-auth-http-proxy-master/lib/server.js:264:5)
    at ProxyServer.emit (/usr/basic-to-passport-auth-http-proxy-master/node_modules/eventemitter3/index.js:210:27)
    at ClientRequest.proxyError (/usr/basic-to-passport-auth-http-proxy-master/node_modules/http-proxy/lib/http-proxy/passes/web-incoming.js:163:18)
    at ClientRequest.emit (events.js:310:20)
    at TLSSocket.socketErrorListener (_http_client.js:426:9)
    at TLSSocket.emit (events.js:310:20)
    at errorOrDestroy (internal/streams/destroy.js:108:12)
    at onwriteError (_stream_writable.js:418:5) {
  code: 'ERR_HTTP_HEADERS_SENT'
}

What's wrong? Or to put it better: What can I do to ensure that the connection is automatically re-established?

many greetings

Benjamin

skleeschulte commented 3 years ago

If I understand correctly, you run the proxy server directly with Node.js, not with Docker? Then you could modify the file lib/server.js to help pin down the error. At the end of the file, you find the following code:

/**
 * Handle proxy errors
 */
proxy.on('error', (err, req, res) => {
    sendResponse(null, req, res, 500, err.message || '' + err);
});

Change it to:

/**
 * Handle proxy errors
 */
proxy.on('error', (err, req, res) => {
    const errorMessage = err.message || '' + err;
    log.e(`[${req.__requestId}] Proxy error: ${errorMessage}`);
    sendResponse(null, req, res, 500, errorMessage);
});

Then restart the server, wait for the error to reappear and post the log output here. Thank you!

Sonsbecker commented 3 years ago

I made the change. However, I don't see any change in the output. Here is the full output after starting the script.

` added 17 packages, and audited 18 packages in 6s

2 high severity vulnerabilities

To address all issues (including breaking changes), run: npm audit fix --force

Run npm audit for details. proxy:info Proxy server listening: { address: '::', family: 'IPv6', port: 3000 } +0ms proxy:error socket hang up +0ms proxy:error [8820/9154] Sending error response: 500 socket hang up +2ms proxy:error read ECONNRESET +31m proxy:error [1859697/1246] Sending error response: 500 read ECONNRESET +111ms proxy:error write ETIMEDOUT +3h proxy:error [12533928/9443] Sending error response: 500 write ETIMEDOUT +4ms _http_outgoing.js:526 throw new ERR_HTTP_HEADERS_SENT('set'); ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client at ServerResponse.setHeader (_http_outgoing.js:526:11) at sendResponse (/usr/basic-to-passport-auth-http-proxy-master/lib/server.js:48:17) at ProxyServer. (/usr/basic-to-passport-auth-http-proxy-master/lib/server.js:271:5) at ProxyServer.emit (/usr/basic-to-passport-auth-http-proxy-master/node_modules/eventemitter3/index.js:210:27) at ClientRequest.proxyError (/usr/basic-to-passport-auth-http-proxy-master/node_modules/http-proxy/lib/http-proxy/passes/web-incoming.js:163:18) at ClientRequest.emit (events.js:310:20) at TLSSocket.socketErrorListener (_http_client.js:426:9) at TLSSocket.emit (events.js:310:20) at errorOrDestroy (internal/streams/destroy.js:108:12) at onwriteError (_stream_writable.js:424:5) { code: 'ERR_HTTP_HEADERS_SENT' } `

Or is there a log file somewhere where the errors are recorded?

skleeschulte commented 2 years ago

I suggest to run the script with forever or to use the provided Docker image, which uses forever internally. The forever command in the Docker image is forever --minUptime 1000 --spinSleepTime 1000 lib/server.js. This is a hacky workaround which restarts the script whenever it crashes, but might be a solution depending on the root cause for the ECONNRESET error.