For*_*vin 5 proxy http socks http-proxy node.js
我正在使用一个 HTTP 请求库,它可以使用http.Agent实例来通过特定代理路由您的请求。让我举一个例子:
const SocksProxyAgent = require('socks-proxy-agent')
const HttpProxyAgent = require('http-proxy-agent') // not used
const axios = require('axios')
// requires Tor service to be running
const torProxyAgent = new SocksProxyAgent('socks://circuit1@127.0.0.1:9050')
// not used
const otherProxyAgent = new HttpProxyAgent('http://admin:1234@localhost:8888')
const axiosConfig = {
httpsAgent: torProxyAgent,
httpAgent: torProxyAgent
}
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)
})
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我指定了多个代理 (torProxyAgent
和otherProxyAgent
),但我只能使用一个。
因此,我正在寻找一种超级代理,我可以将其传递给我的 HTTP 请求库,然后该超级代理通过将所有请求路由到第一个代理,然后通过第二个代理,然后将任意数量的普通代理链接在一起。到第三个,依此类推……
这可能吗?有现成的解决方案吗?
是否有一种方法可以使用Proxy类创建一个假代理,将所有方法调用传递给一个代理,然后传递给第二个代理?
编辑:
虽然我很欣赏lifeisfoo的回答,但它只解决了一个理论问题,我碰巧只使用了两个代理(一个HTTP代理和一个socks代理)。实际上,我不想仅限于两个代理,并且我希望能够指定顺序。
看起来解决方案比我想象的更容易:
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)
})
Run Code Online (Sandbox Code Playgroud)
确保仅当您的袜子代理在本地运行时才使用本地主机 HTTP 代理,否则将无法访问它。显然,socks 和代理 IP 应该使用可用的 IP 进行更新,我使用了在公共代理列表中找到的一些 IP作为测试,但它们不可靠。
Nodejs 文档说代理:
[...] 负责管理 HTTP 客户端的连接持久性和重用。它维护给定主机和端口的待处理请求队列,为每个请求重用单个套接字连接,直到队列为空。
基本上,它公开了一个返回套接字的createConnection函数:
此方法保证返回 <net.Socket> 类(<stream.Duplex> 的子类)的实例,除非用户指定除 <net.Socket> 之外的套接字类型。
如果您查看另一个袜子代理(例如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;
Run Code Online (Sandbox Code Playgroud)
尝试调试请求流,您将看到socks连接数据和http数据都写入了套接字上。在Socks5ClientSocket.prototype.write函数中添加断点或日志
Socks5ClientSocket.prototype.write = function(data, encoding, cb) {
console.log('Writing', data);
return this.socket.write(data, encoding, cb);
};
Run Code Online (Sandbox Code Playgroud)
你会看到这样的东西:
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
Run Code Online (Sandbox Code Playgroud)
前两行是建立与socks代理的socks连接的字节,然后将http数据写入同一套接字,但使用http代理作为目标主机。
因此,从 http 库的角度来看,代理只是一个套接字提供者,因此您可以根据需要创建此套接字,可能会在同一个套接字上链接更多连接(请参阅我的原始答案)。
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)
})
Run Code Online (Sandbox Code Playgroud)
是的,这是可能的,正如您从这个C proxychains 应用程序及其配置文件中看到的那样:
[ProxyList]
# based on you configuration
socks4 127.0.0.1 9050 circuit1
http localhost 8888 admin 1234
Run Code Online (Sandbox Code Playgroud)
但看起来没有一个现有的节点模块能够处理混合类型的代理链(socks、http)。
袜子库可以处理一系列袜子代理,但此功能尚未公开给您正在使用的袜子代理代理。
可以使用http-proxy和此gist中的代码来实现 http 代理链。
所以你有三个选择:
如果您选择最后一个,请务必检查socks库源代码以了解链创建逻辑的createConnectionChain
函数。
也可以看看:
归档时间: |
|
查看次数: |
6689 次 |
最近记录: |