no more streaming
This commit is contained in:
@@ -15,14 +15,16 @@ app.use(express.json({
|
||||
// Request timeout middleware
|
||||
app.use((req, res, next) => {
|
||||
// Set request timeout
|
||||
req.setTimeout(config.requestTimeout, () => {
|
||||
const timeoutHandle = setTimeout(() => {
|
||||
logger.error({
|
||||
method: req.method,
|
||||
url: req.url,
|
||||
timeout: config.requestTimeout,
|
||||
headersSent: res.headersSent,
|
||||
finished: res.finished,
|
||||
}, 'Request timeout');
|
||||
|
||||
if (!res.headersSent) {
|
||||
if (!res.headersSent && !res.finished) {
|
||||
res.status(504).json({
|
||||
jsonrpc: '2.0',
|
||||
error: {
|
||||
@@ -32,6 +34,15 @@ app.use((req, res, next) => {
|
||||
id: req.body?.id,
|
||||
});
|
||||
}
|
||||
}, config.requestTimeout);
|
||||
|
||||
// Clear timeout when response finishes
|
||||
res.on('finish', () => {
|
||||
clearTimeout(timeoutHandle);
|
||||
});
|
||||
|
||||
res.on('close', () => {
|
||||
clearTimeout(timeoutHandle);
|
||||
});
|
||||
|
||||
next();
|
||||
|
||||
@@ -172,15 +172,14 @@ class RPCProxy {
|
||||
let clientCloseReason = null;
|
||||
let responseCompleted = false;
|
||||
|
||||
req.on('close', () => {
|
||||
// Use 'aborted' event which is more reliable for detecting client disconnects
|
||||
req.on('aborted', () => {
|
||||
if (!clientClosed) {
|
||||
clientClosed = true;
|
||||
clientCloseReason = 'connection_closed';
|
||||
clientCloseReason = 'request_aborted';
|
||||
const elapsedMs = Date.now() - startTime;
|
||||
|
||||
// Immediate close (0-1ms) with no response is likely a client timeout or abort
|
||||
if (elapsedMs <= 1 && !responseCompleted) {
|
||||
logger.error({
|
||||
logger.warn({
|
||||
requestId,
|
||||
reason: clientCloseReason,
|
||||
headers: req.headers,
|
||||
@@ -189,9 +188,29 @@ class RPCProxy {
|
||||
method: requestBody.method,
|
||||
elapsedMs,
|
||||
responseCompleted,
|
||||
xForwardedFor: req.headers['x-forwarded-for'],
|
||||
xRealIp: req.headers['x-real-ip'],
|
||||
}, 'Client aborted connection immediately - likely timeout or network issue');
|
||||
}, 'Client aborted request');
|
||||
}
|
||||
});
|
||||
|
||||
// The 'close' event can fire for various reasons, not just client disconnect
|
||||
// Only consider it a client disconnect if the response hasn't been completed
|
||||
req.on('close', () => {
|
||||
// Only log as client disconnect if response wasn't completed
|
||||
if (!clientClosed && !responseCompleted && !res.headersSent) {
|
||||
clientClosed = true;
|
||||
clientCloseReason = 'connection_closed';
|
||||
const elapsedMs = Date.now() - startTime;
|
||||
|
||||
// Only log as error if it happens very quickly (< 100ms)
|
||||
if (elapsedMs < 100) {
|
||||
logger.debug({
|
||||
requestId,
|
||||
reason: clientCloseReason,
|
||||
method: requestBody.method,
|
||||
elapsedMs,
|
||||
responseCompleted,
|
||||
headersSent: res.headersSent,
|
||||
}, 'Request closed early (may be normal behavior)');
|
||||
} else {
|
||||
logger.warn({
|
||||
requestId,
|
||||
@@ -225,17 +244,16 @@ class RPCProxy {
|
||||
|
||||
// Also track response close events
|
||||
res.on('close', () => {
|
||||
if (!clientClosed) {
|
||||
clientClosed = true;
|
||||
clientCloseReason = 'response_closed';
|
||||
if (!responseCompleted) {
|
||||
logger.warn({
|
||||
requestId,
|
||||
reason: clientCloseReason,
|
||||
reason: 'response_closed',
|
||||
finished: res.finished,
|
||||
headersSent: res.headersSent,
|
||||
method: requestBody.method,
|
||||
elapsedMs: Date.now() - startTime,
|
||||
}, 'Response connection closed');
|
||||
clientClosed,
|
||||
}, 'Response connection closed before completion');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -337,13 +355,8 @@ class RPCProxy {
|
||||
clientCloseReason: getClientCloseReason(),
|
||||
elapsedBeforeRequest: Date.now() - startTime,
|
||||
}, 'Client closed before upstream request could be made');
|
||||
return {
|
||||
statusCode: 0,
|
||||
data: '',
|
||||
size: 0,
|
||||
latency: Date.now() - startTime,
|
||||
contentEncoding: null,
|
||||
};
|
||||
// Don't return early - still try to make the request in case our detection was wrong
|
||||
// The actual response sending will handle the client closed state
|
||||
}
|
||||
|
||||
logger.debug({
|
||||
|
||||
Reference in New Issue
Block a user