You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When the connection to the proxy server is closed with UND_ERR_SOCKET using ProxyAgent an infinite loop is created.
This is actually a double bug; I found this while investigating why ProxyAgent doesn't work with a basic http proxy built with node:http:
import{ok}from"node:assert";import{createServer,requestashttpRequest}from"node:http";import{requestashttpsRequest}from"node:https";import{Client,ProxyAgent,request}from"undici";constserver=createServer((req,res)=>{ok(req.url);consttargetUrl=newURL(req.url);req.pipe((targetUrl.protocol==="https:" ? httpsRequest : httpRequest)({method: req.method,hostname: targetUrl.hostname,port: targetUrl.port,path: targetUrl.pathname+targetUrl.search,headers: req.headers,},(proxiedRes)=>{ok(proxiedRes.statusCode);res.writeHead(proxiedRes.statusCode,proxiedRes.statusMessage,proxiedRes.headers,);proxiedRes.pipe(res);},).once("error",res.destroy.bind(res)),);}).listen();constaddress=server.address();ok(address&&typeofaddress==="object");// This works fine:console.log(awaitnewClient(`http://localhost:${address.port}`).request({method: "GET",path: "http://example.com",headers: {host: "example.com"},}).then((res)=>res.body.text()),);// This doesn't work and creates an infinite loop trying to connect to proxy url// For instance, listening to server.on("connection", console.log) logs infinite timesconsole.log(awaitrequest("http://example.com",{dispatcher: newProxyAgent(`http://localhost:${address.port}`),}).then((res)=>res.body.text()),);
Now here there are two questions:
Why is the connection closing in the first place? Spent hours debugging but honestly couldn't find the reason
Why is it looping until a connection is established? This creates a significant overhead both on the client and on the proxy server that is flooded by requests
The error is caught here where there is already something about "avoiding a loop in client.js#connect"
// Throw a custom error to avoid loop in client.js#connect
callback(newSecureProxyConnectionError(err))
}else{
callback(err)
}
}
Reproducible By
Example above
Expected Behavior
If the connection is closed, the error should be thrown immediately instead of trying infinite times.
Also, I think the example above should be successful considering that using a Client works
Logs & Screenshots
The error (added throw err to avoid loop)
SocketError: other side closed
at Socket.onHttpSocketEnd (D:\-\node_modules\undici\lib\dispatcher\client-h1.js:902:22)
at Socket.emit (node:events:530:35)
at endReadableNT (node:internal/streams/readable:1698:12)
at process.processTicksAndRejections (node:internal/process/task_queues:90:21) {
code: 'UND_ERR_SOCKET',
socket: {
localAddress: '::1',
localPort: 60534,
remoteAddress: '::1',
remotePort: 60533,
remoteFamily: 'IPv6',
timeout: undefined,
bytesWritten: 73,
bytesRead: 0
}
}
Environment
Node v22, all undici versions with ProxyAgent
Additional context
Using ProxyAgent with a "real" proxy works (even if it seems a bit slow?), so I'm not sure what is it expecting from my custom server that is different from a normal proxy
The text was updated successfully, but these errors were encountered:
Tunneling connection is not being made correctly. The server is tearing down the connection on every attempt, causing the agent to attempt to connect once more without success (due to design).
I'd recommend you to check the proxy npm package to have a fully fledge example. (I just debug it, didn't replicate yet what was causing the connection to be drop)
That's a good catch, actually its something that will be interesting to address; as what happens is that, by design, undici detects that there's a request still pending, and as the client has not been marked as destroyed yet, nor the request has failed or aborted, it loops attempting to connect to the downstream.
Bug Description
When the connection to the proxy server is closed with
UND_ERR_SOCKET
usingProxyAgent
an infinite loop is created.This is actually a double bug; I found this while investigating why
ProxyAgent
doesn't work with a basic http proxy built withnode:http
:Now here there are two questions:
The error is caught here where there is already something about "avoiding a loop in client.js#connect"
undici/lib/dispatcher/proxy-agent.js
Lines 97 to 104 in 1cfe094
Reproducible By
Example above
Expected Behavior
If the connection is closed, the error should be thrown immediately instead of trying infinite times.
Also, I think the example above should be successful considering that using a
Client
worksLogs & Screenshots
The error (added
throw err
to avoid loop)Environment
Node v22, all undici versions with
ProxyAgent
Additional context
Using
ProxyAgent
with a "real" proxy works (even if it seems a bit slow?), so I'm not sure what is it expecting from my custom server that is different from a normal proxyThe text was updated successfully, but these errors were encountered: