node-socksInTheMiddle
use a socks server for web request modification
This module starts a socks server and handle HTTP, HTTPS, WebSocket and UDP requests, it can be used to modify these requests and their responses.
TCP requests are only checked whether those are HTTP requests, or the request will be recognized as a HTTPS request, so don't send other protocols' requests to this server.
This module can just be a HTTP interceptor or HTTP proxy server without socks part.
Install
npm i socksinthemiddle
Examples
Launch a server
const {SocksInTheMiddle}=require('socksInTheMiddle');
const fs=require('fs');
let server=new SocksInTheMiddle({
socksPort:1090,
httpPort:0,
httpsPort:0,
httpsOptions:{
key:fs.readFileSync("/your/path/to/server.key"),
cert:fs.readFileSync('/your/path/to/server.crt'),
}
});
Then set your application's socks5 proxy setting to 127.0.0.1:1090
.
If http(s)Port
or the socksPort
is not a number, that server will not be created. You must fill the httpsOptions
option if you want to create a server that supports HTTPS protocol.
About Certificate
You can create a CA yourself and sign a certificate for the target domain then fill TLS options in httpsOptions
.
Modify HTTP request and response
server.setHTTPModder(requestModder : Function, responseModder : Function)
Both modder functions can modify http headers for the request or the response.
If the function returns a Transform stream, raw data will be piped in and the stream will be piped to the target.
If the function returns just a Readable stream, raw data will be ignored, and the stream will be piped to the target.
const {BufferModder}=require('socksInTheMiddle');
const fs=require('fs');
server.setHTTPModder(async (headers,reqFromClient,resToClient,overrideRequestOptions)=>{
console.log('client request headers:',headers);
reqFromClient;
resToClient;
if(reqFromClient.url.startsWith('/favicon.ico')){
delete headers['etag'];
}
resToClient.end('blocked');
return;
overrideRequestOptions;
overrideRequestOptions.rejectUnauthorized=true;
overrideRequestOptions.path='/blabla';
},(headers,resFromServer,reqFromClient)=>{
console.log('server response headers:',headers);
reqFromClient;
resFromServer;
if(reqFromClient.url.startsWith('/?')){
return new BufferModder(buf=>{
let str=buf.toString();
return str.replace(/更多/g,'超级多');
});
}else if(reqFromClient.url.startsWith('/test')){
return fs.createReadStream('path/to/test.txt');
}
});
Modify UDP request and response
server.setUDPModder(async (fromClient,packet)=>{
fromClient;
packet.address;
packet.port;
packet.data;
packet.address='127.0.0.1';
packet.port=12345;
});
Modify WebSocket message
server.setWebSocketModder((req,source,data)=>{
console.log(source,data);
return data;
});
Just use this module as a HTTP interceptor
You can ignore the socks part and just use this module as a HTTP interceptor or HTTP proxy server.
const {SocksInTheMiddle,BufferModder}=require('socksinthemiddle');
let server=new SocksInTheMiddle({
socksPort:false,
httpPort:5607,
httpsPort:false,
httpLog:true,
});
server.setHTTPModder(async (headers,reqFromClient,resToClient,overrideRequestOptions)=>{
if(reqFromClient.url.startsWith('/taiko')){
headers.host='taiko.luojia.me';
headers.origin='https://luojia.me/';
headers.referer='https://luojia.me/';
Object.assign(overrideRequestOptions,{
path:reqFromClient.url.replace(/^\/taiko/,''),
protocol:'https',
});
}else{
headers.host='luojia.me';
Object.assign(overrideRequestOptions,{
protocol:'https',
});
}
},(headers,resFromServer,reqFromClient)=>{
const mime=headers['content-type'];
if(!mime)return;
if (mime.endsWith('javascript')|| mime.startsWith('text') || mime.endsWith('json')) {
return new BufferModder(buf=>{
let str=buf.toString();
return str.replaceAll('https://taiko.luojia.me','/taiko');
});
}
});
Then you can visit http://127.0.0.1:5607
for the proxied website.