Updated answer - axios + socks-proxy-agent + http proxy
Looks like the solution is easier than I thoght:
const SocksProxyAgent = require('socks-proxy-agent')
const axios = require('axios')
const torProxyAgent = new SocksProxyAgent('socks://circuit1@127.0.0.1:9050')
const axiosConfig = {
httpsAgent: torProxyAgent,
httpAgent: torProxyAgent,
proxy: {
protocol: 'http', //'http',
host: '89.208.35.81', // your http proxy ip
port: 3128, // your http proxy port
// optional - add it if your proxy require auth
auth: {
username: 'myuser',
password: 'mypass'
}
}
}
const axiosInstance = axios.create(axiosConfig)
axiosInstance.get('https://ifconfig.io/ip')
.then(res => {
console.log('Public IP address:', res.data)
}).catch(err => {
console.log(err)
})
Be sure to use a localhost HTTP proxy ONLY if your socks proxy is running locally, otherwise it will not be reached. Obviously socks and proxy IPs should be update with working ones, I used some IPs found on a public proxy list as a test but they're unreliable.
How it works
The nodejs docs sasys that an Agent:
[...] is responsible for managing connection persistence and reuse for HTTP clients. It maintains a queue of pending requests for a given host and port, reusing a single socket connection for each until the queue is empty.
Basically, it exposes a createConnection function that return a socket:
This method is guaranteed to return an instance of the <net.Socket> class, a subclass of <stream.Duplex>, unless the user specifies a socket type other than <net.Socket>.
This behaviour it's easy to see if you look at the source code of another socks agent like socks5-http-client/lib/Agent:
var http = require('http');
var inherits = require('util').inherits;
var socksClient = require('socks5-client');
function Agent(options) {
http.Agent.call(this, options);
this.createConnection = socksClient.createConnection;
}
inherits(Agent, http.Agent);
module.exports = Agent;
Try debugging the request flow and you'll see that both socks connection data and http data are written on the socket. Add a breakpoint or a log in Socks5ClientSocket.prototype.write function
Socks5ClientSocket.prototype.write = function(data, encoding, cb) {
console.log('Writing', data);
return this.socket.write(data, encoding, cb);
};
And you'll see something like this:
Writing <Buffer 05 01 00>
Writing <Buffer 05 01 00 01 59 d0 23 51 0c 38>
Writing GET http://ip-api.com/json HTTP/1.1 ....// http request data
The first two lines are bytes to establish the socks connection to the socks proxy, then the http data are written on the same socket but using the http proxy as the target host.
So, from the http library point of view, an agent is just a socket provider and so you can create this socket as you want, possibly chaining more connections on the same socket (see my original answer).
axios + socks5-http-client + http proxy
var Agent = require('socks5-http-client/lib/Agent');
var axios = require('axios');
const socksProxyOpts = {
socksHost: '5.189.130.21',
socksPort: 1080
};
const socksAgent = new Agent(socksProxyOpts);
const axiosConfig = {
httpAgent: socksAgent,
proxy: {
protocol: 'http',
host: '89.208.35.81',// or '45.33.99.194',
port: 3128 // or 8888
}
}
const axiosInstance = axios.create(axiosConfig)
axiosInstance.get('http://ip-api.com/json')
.then(res => {
console.log('Public IP address:', res.data)
}).catch(err => {
console.log(err)
})
Original answer
Yes, it's possible as you can see from this C proxychains application and from its configuration file:
[ProxyList]
# based on you configuration
socks4 127.0.0.1 9050 circuit1
http localhost 8888 admin 1234
But looks like there isn't an existing node modules capable to handle a chain of mixed kind of proxies (socks, http).
The socks library can handle a chain of socks proxies but this feature isn't already exposed to the socks-proxy-agent you're using.
A http proxies chain can be achieved using http-proxy and code from this gist.
So you have three options:
- use the existing proxychains application
- use a chain of socks proxies using socks
- hack the socks library to add support for http proxies in the chain
If you choose the last one be sure to check the socks library source code for the createConnectionChain
function for the chain creation logic.
See also: