@bjowes 叉线
这是Joe Ferners的图书馆节点-http-mitm-proxy的叉子(见下文docs). 它的首次发行与原始库的主版完全相同,承诺66ac0f5d3298f66b731f90ebf1e9b430fa5d76eb. 因为我需要npm的密码库 它只用于我自己的图书馆 Cypress -ntl-auth。 冒险吧!
- 2025-01-27: 0.9.6 - 依赖性突起
- 2024-03-27: 0.9.5 - 定制状态信息的补丁,依赖性凸起
- 2022-04-08: 0.9.4 - 地址访问器,打字固定
- 2022-04-04: 0.9.3 - 有IPv6站点的证书文件名的补丁.
- 2022-03-31: 6.9.2 - 因安全问题而更新的依赖关系. 提高HTTPS稳定性. IPv6支持.
- 2019-08-01:因安全问题而更新依赖关系
HTTP MITM 代理服务器
HTTP Man In The Middle (MITM) 代理写作于节点.js. 支持获取和修改请求和响应数据.
安装
npm install --save http-mitm-proxy
节点.js 兼容性
库应该从Node.js 8.x开始工作,但只能对目前支持的从Node.js开始的"Node.js 12.x"版本进行测试. 以非LTS Node.js版本冒险使用.
字体
类型定义现在包括在本项目中,不需要额外步骤.
示例
此示例将修改来自google的任何搜索结果,并将所有结果标题替换为"Pwned!".
var Proxy = require('http-mitm-proxy');
var proxy = Proxy();
proxy.onError(function(ctx, err) {
console.error('proxy error:', err);
});
proxy.onRequest(function(ctx, callback) {
if (ctx.clientToProxyRequest.headers.host == 'www.google.com'
&& ctx.clientToProxyRequest.url.indexOf('/search') == 0) {
ctx.use(Proxy.gunzip);
ctx.onResponseData(function(ctx, chunk, callback) {
chunk = new Buffer(chunk.toString().replace(/<h3.*?<\/h3>/g, '<h3>Pwned!</h3>'));
return callback(null, chunk);
});
}
return callback();
});
proxy.listen({port: 8081});
您可以在 示例目录
SSL 服务器
使用节点-forge允许在代理内自动生成SSL证书. 在运行您的应用程序后, 您将会找到可导入到您的浏览器、 电话等选项 .
API 密码
代理服务器
- 监听(选项)
- 关闭
- 错误( fn)
- 证书要求
- 证书缺失
- 请求(fn)
- 请求数据( fn)
- 请求结束( fn)
- 回应( fn)
- 回复数据( fn)
- 回复结束( fn)
- 在 WebSocket 连接( fn) 上
- 在 WebSocketSend( fn) 上发布
- 在 WebSocketMessage( fn) 上发布
- 在WebSocketFrame(fn)上发布
- 在WebSocketError( fn) 上发布
- 在 WebSocket 关闭( fn) 上
- 使用量(fn)
A. 背景情况
背景函数只影响当前请求/响应. 例如, 您可能只想要启动请求 给某个宿主做的.
- 布尔,
- 客户端toProxy 请求 : 来信, (中文(简体) ),
- 代理客户端回复 : 服务器响应, (中文(简体) ),
- 代理服务器请求 : 客户端请求, (中文(简体) ),
- 服务器 ToProxy 响应 : 来信, (中文(简体) ),
- 错误( fn)
- 请求(fn)
- 请求数据( fn)
- 请求结束( fn)
- 添加请求文件( fn)
- 回应( fn)
- 回复数据( fn)
- 回复结束( fn)
- 添加响应过滤器( fn)
- 使用( mod)
WebSocket 上下文
在 Websocket 处理器中可用的上下文有点不同
- 布尔,
- 客户端 ProxyWebSocket : 网络安全套, (中文(简体) ),
- 代理服务器WebSocket : 网络安全套, (中文(简体) ),
- 在 WebSocket 连接( fn) 上
- 在 WebSocketSend( fn) 上发布
- 在 WebSocketMessage( fn) 上发布
- 在WebSocketFrame(fn)上发布
- 在WebSocketError( fn) 上发布
- 在 WebSocket 关闭( fn) 上
- 使用( mod)
代理服务器
代理服务器. listen
启动代理服务器在指定端口的监听.
参数
- 选项 - 有下列选项的对象:
- 端口 - 用于监听的端口或命名的套接字( 默认: 8080) .
- 主机 - 要监听的主机名或本地地址( 默认为“ localhost ”) 。 Pass ':" 在所有IPv4/IPv6接口上收听.
- sslCaDir - 证书缓存目录的路径( 默认: process.cwd () +'/. http- mitm- proxy)
- 保留Alive - 启用 HTTP 持续连接
- 超时 - 套接字被假定超时前的无活性毫秒数 。 默认为不超时 .
- httpAgent - 该 页:1 探员 用于制作 http 请求。 用于链路代理. (默认: 内部代理)
- httpsAgent - 该 https. (中文(简体) ). 探员 用于制作 https 请求。 用于链路代理. (默认: 内部代理)
- - 使用武力 斯洛文尼亚 由委托人。 允许节点-http-mitm-proxy使用单一的内部服务器处理所有HTTPS请求.
- httpsPort - 用于 https 服务器监听的端口或命名的套接字 . (必须启用FORSNI)
- 强制Chunked Request - 设置此选项将删除代理服务器请求的内容长度, 强制块编码 .
示例
proxy.listen({ port: 80 });
代理服务器。 关闭
停止代理监听 .
示例
proxy.close();
代理.on Error(fn) 或 ctx.on Error(fn) 代理服务器
将函数添加到函数列表中,以便在出现错误时调用.
参数
- fn(ctx, 错误, 错误Kind) - 在错误上调用函数 .
示例
proxy.onError(function(ctx, err, errorKind) {
// ctx may be null
var url = (ctx && ctx.clientToProxyRequest) ? ctx.clientToProxyRequest.url : "";
console.error(errorKind + ' on ' + url + ':', err);
});
代理.on Certificate Required = 函数(主机名,召回)
允许覆盖默认证书名称/路径计算 .
默认行为预期 keys/{hostname}.pem 财务报告和审定财务报表 certs/{hostname}.pem 要保存的文件 self.sslCaDir。 。 。 .
参数
- 主机名 - 请求的主机名 .
- 调用 - 证书文件路径已经计算时要调用的函数 .
实例1
proxy.onCertificateRequired = function(hostname, callback) {
return callback(null, {
keyFile: path.resolve('/ca/certs/', hostname + '.key'),
certFile: path.resolve('/ca/certs/', hostname + '.crt')
});
};
例2: 威尔卡证书
proxy.onCertificateRequired = function(hostname, callback) {
return callback(null, {
keyFile: path.resolve('/ca/certs/', hostname + '.key'),
certFile: path.resolve('/ca/certs/', hostname + '.crt'),
hosts: ["*.mydomain.com"]
});
};
代理.on Certificate Missing = 函数(ctx,文件,回调)
允许您为当前请求处理缺失的证书文件,例如,在苍蝇上创建它们.
参数
- ctx - 有下列属性的上下文
- 主机名称 - 需要证书的主机名
- data.keyFileExists - 是否存在密钥文件
- 数据.certFileExists - 证书文件是否存在
- 文件 - 缺少的文件名( x)
files.keyFile, (中文(简体) ),files.certFile和可选files.hosts(中文(简体) ) - 调回 - 要调回证书数据的函数( N)
keyFileData财务报告和审定财务报表certFileData(中文(简体) )
实例1
proxy.onCertificateMissing = function(ctx, files, callback) {
console.log('Looking for "%s" certificates', ctx.hostname);
console.log('"%s" missing', ctx.files.keyFile);
console.log('"%s" missing', ctx.files.certFile);
// Here you have the last chance to provide certificate files data
// A tipical use case would be creating them on the fly
//
// return callback(null, {
// keyFileData: keyFileData,
// certFileData: certFileData
// });
};
例2: 威尔卡证书
proxy.onCertificateMissing = function(ctx, files, callback) {
return callback(null, {
keyFileData: keyFileData,
certFileData: certFileData,
hosts: ["*.mydomain.com"]
});
};
代理.on request(fn)或ctx.on request(fn)
在请求开头添加一个要调用的函数.
参数
- fn(ctx, callback) - 在每个请求上被调用的函数.
示例
proxy.onRequest(function(ctx, callback) {
console.log('REQUEST:', ctx.clientToProxyRequest.url);
return callback();
});
代理服务器.on requestData(fn) 或 ctx.on RequestData(fn)
为每个请求的数据块(正文)添加一个调用函数.
参数
- fn(ctx,块,回调) - 每个数据块被调用的函数 .
示例
proxy.onRequestData(function(ctx, chunk, callback) {
console.log('REQUEST DATA:', chunk.toString());
return callback(null, chunk);
});
代理.on request End(fn) 或 ctx.on End(fn) 请求
在所有请求的数据(正文)发送时添加一个函数以调用.
参数
- fn(ctx, callback) - 当所有请求的数据(正文)发送时被调用的函数.
示例
var chunks = [];
proxy.onRequestData(function(ctx, chunk, callback) {
chunks.push(chunk);
return callback(null, chunk);
});
proxy.onRequestEnd(function(ctx, callback) {
console.log('REQUEST END', (Buffer.concat(chunks)).toString());
return callback();
});
代理.on Response(fn)或ctx.on Response(fn)
添加一个函数以在响应开头被调用 .
参数
- fn(ctx, callback) - 在每个响应上被调用的函数.
示例
proxy.onResponse(function(ctx, callback) {
console.log('BEGIN RESPONSE');
return callback();
});
代理服务器.onResponseData(fn)或ctx.onResponseData(fn)
为每个响应数据块(正文)添加调用函数.
参数
- fn(ctx,块,回调) - 每个数据块被调用的函数 .
示例
proxy.onResponseData(function(ctx, chunk, callback) {
console.log('RESPONSE DATA:', chunk.toString());
return callback(null, chunk);
});
代理服务器.onResponse End(fn)或ctx.onResponse End(fn)
在服务器代理请求终止时添加一个函数以被调用 .
参数
- fn(ctx, callback) - 当服务器代理请求结束时调用函数 .
示例
proxy.onResponseEnd(function(ctx, callback) {
console.log('RESPONSE END');
return callback();
});
代理.onWebSocketConnection(fn)或tx.onWebSocketConnection(fn)
在 Websocket 连接开头处添加一个调用函数
参数
- fn(ctx, callback) - 每个数据块被调用的函数 .
示例
proxy.onWebSocketConnection(function(ctx, callback) {
console.log('WEBSOCKET CONNECT:', ctx.clientToProxyWebSocket.upgradeReq.url);
return callback();
});
代理.onWebSocketSend(fn)或ctx.onWebSocketSend(fn)
为客户端发送的每个 WebSocket 消息添加一个调用功能.
参数
- fn(ctx,消息,旗帜,回调) - 客户端发送的每个WebSocket消息都会被调用的功能.
示例
proxy.onWebSocketSend(function(ctx, message, flags, callback) {
console.log('WEBSOCKET SEND:', ctx.clientToProxyWebSocket.upgradeReq.url, message);
return callback(null, message, flags);
});
代理.on WebSocketMessage(fn)或ctx.onWebSocketMessage(fn)
为从服务器收到的每个 WebSocket 信件添加一个调用功能 .
参数
- fn(ctx,消息,旗帜,召回) - 对从服务器收到的每个 WebSocket 信件调用功能 .
示例
proxy.onWebSocketMessage(function(ctx, message, flags, callback) {
console.log('WEBSOCKET MESSAGE:', ctx.clientToProxyWebSocket.upgradeReq.url, message);
return callback(null, message, flags);
});
代理. onWebSocketFrame(fn)或ctx.onWebSocketFrame(fn)
为每个交换的 WebSocket 框架添加一个调用函数(message, (中文(简体) ), ping 或者说 pong) (中文(简体) ).
参数
- fn(ctx,类型,来自Server,数据,旗帜,调回) - 每一个交换的WebSocket帧的调取函数.
示例
proxy.onWebSocketFrame(function(ctx, type, fromServer, data, flags, callback) {
console.log('WEBSOCKET FRAME ' + type + ' received from ' + (fromServer ? 'server' : 'client'), ctx.clientToProxyWebSocket.upgradeReq.url, data);
return callback(null, data, flags);
});
代理.onWebSocketError(fn)或ctx.onWebSocketError(fn)
在函数列表中添加一个函数,以便在WebSocket中发生错误时被调用.
参数
- fn(ctx, 错误) - 在 WebSocket 中的一个错误上调用函数 .
示例
proxy.onWebSocketError(function(ctx, err) {
console.log('WEBSOCKET ERROR:', ctx.clientToProxyWebSocket.upgradeReq.url, err);
});
代理.onWebSocketClose(fn)或ctx.onWebSocketClose(fn)
关闭 WebSocket 连接时添加调用函数
参数
- fn(ctx,代码,消息,回调) - WebSocket关闭后获得的函数.
示例
proxy.onWebSocketClose(function(ctx, code, message, callback) {
console.log('WEBSOCKET CLOSED BY '+(ctx.closedByServer ? 'SERVER' : 'CLIENT'), ctx.clientToProxyWebSocket.upgradeReq.url, code, message);
callback(null, code, message);
});
代理.use(模块)或ctx.use(模块)
将模块添加到代理服务器中。 模块将多个生命周期处理功能封装为一个对象.
参数
- 模块 - 要添加的模块 。 模块包含要添加的一散列函数.
示例
proxy.use({
onError: function(ctx, err) { },
onCertificateRequired: function(hostname, callback) { return callback(); },
onCertificateMissing: function(ctx, files, callback) { return callback(); },
onRequest: function(ctx, callback) { return callback(); },
onRequestData: function(ctx, chunk, callback) { return callback(null, chunk); },
onResponse: function(ctx, callback) { return callback(); },
onResponseData: function(ctx, chunk, callback) { return callback(null, chunk); },
onWebSocketConnection: function(ctx, callback) { return callback(); },
onWebSocketSend: function(ctx, message, flags, callback) { return callback(null, message, flags); },
onWebSocketMessage: function(ctx, message, flags, callback) { return callback(null, message, flags); },
onWebSocketError: function(ctx, err) { },
onWebSocketClose: function(ctx, code, message, callback) { },
});
节点-http-mitm-proxy提供一些可供使用模块:
Proxy.gunzipGunzip 响应过滤器( 在 ResponseData 上未压缩 gzipped 内容, 之后压缩后)Proxy.wildcard默认生成 wilcard 证书( 因此生成的证书较少)
A. 背景情况
ctx.add 请求过滤器( 流)
在请求体流中添加一流.
参数
- 溪流 - 读出/写出流来加入请求正文流.
示例
ctx.addRequestFilter(zlib.createGunzip());
ctx.add ResponseFilter( 流线)
在响应体流中添加一流.
参数
- 溪流 - 读出/写出流来加入响应体流.
示例
ctx.addResponseFilter(zlib.createGunzip());
许可证
Copyright (c) 2015 Joe Ferner
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.