## proxy ```js const Pooy = require('pooy'); const proxy = new Pooy(); ``` ## proxy.on ### proxy.on('request', function) ```js proxy.on('request', (ctx) => { // set request header ctx.setHeader('user-agent', 'pooy@proxy'); }); ``` ### proxy.on('requestEnd', function) ```js proxy.on('requestEnd', (ctx) => { // show request end info consle.log('request end:', `${ctx.method} -> ${ctx.host}${ctx.url}`); }); ``` ### proxy.on('response', function) ```js proxy.on('response', (ctx) => { // set response header ctx.setHeader('proxy-agent', 'pooy@0.0.1-alpha1'); }); ``` ### proxy.on('responseEnd', function) ```js proxy.on('requestEnd', (ctx) => { // show response end info consle.log('response end:', `${ctx.method} -> ${ctx.host}${ctx.url}`); }); ``` ### proxy.on('error', function) ```js proxy.on('error', (err, ctx) => { // error handler console.log('oops, something went wrong!', err); consle.log(ctx); }); ``` ## proxy.listen ```js proxy.listen(9696, () => { console.log('proxy server run at 9696...'); }); ``` ## proxy.useRules ```js const rules = [{ test: (ctx) => { return ctx.url === 'www.baidu.com' && ctx.method === 'GET'; }, response: { statusCode: 400, body: (body) => body + ``, headers: {}, throttling: { download: 1024 } } }]; proxy.useRules(rules); ``` ## proxy.direct ```js proxy.direct = true; ``` 为 `true` 时系统直连,反之流量走 proxy ## context ### context.id 唯一标识 id ### context.request proxy request 对象,支持重写(仅在 request 时) ```js { options: { host: '请求 host', port: '目标端口: https 默认 443, http 默认80', path: '请求路径', method: '请求方法: GET POST PUT DELETE OPTIONS 等', headers: '请求头', protocol: '协议: http or https' }, headers: '请求头', req: '原生 node request 对象' } ``` ### context.response proxy response 对象,支持重写(仅在 response 时) ```js { body: '响应内容', res: '原生 node response 对象' }; ``` ### context.clientRequest 来自系统的当前请求,原生 node request 对象 ### context.remoteResponse 来自真实服务的响应,原生 node response 对象 ### context.throttling 网络节流控制 ```js proxy.on('request', (ctx) => { ctx.throttling({ upload: 1024 // 每秒传输的字节数 }); }); proxy.on('response', (ctx) => { ctx.throttling({ download: 1024 // 每秒传输的字节数 }); }); ``` ### context.protocol 当前请求的协议 http or https,支持重写(仅在 request 时) ### context.method 当前请求的方法,支持重写(仅在 request 时) ### context.url 当前请求的路径,支持重写(仅在 request 时) ### context.host 当前请求的 host,支持重写(仅在 request 时) ### context.getBody 获取响应内容,这是一个异步方法 ```js proxy.on('response', async (ctx) => { const contextType = ctx.getHeader('content-type'); const body = await ctx.getBody(); if (/html/.test(contentType)) { ctx.body = body + ``; } } ``` ### context.setBody 设置响应体,效果等同于直接赋值给 `ctx.body` ```js proxy.on('response', async (ctx) => { ctx.setBody('hello world.'); } ``` ### context.pause ```js proxy.on('response', async (ctx) => { ctx.pause(); } ``` ### context.resume ```js proxy.on('response', async (ctx) => { ctx.resume(); } ``` ### proxy.useRules ```js proxy.useRules([{ testField: 'url', // url requestHeaders responseHeaders test: /baidu\.com/, request: { protocol: 'https', host: 'hxtao.xyz:8001', pathname: '/some', hash: '#12', method: 'GET', throttling: { upload: 1024 }, body: (body) => body + '..', headers: (headers) => ({ ...headers, ...{ 'cookies': 'name=hxtao' } }) }, response: { statusCode: 200, throttling: { download: 1024 }, body: (body) => body + '..', headers: (headers) => ({ ...headers, ...{ 'hello': 'world' } }) }, desc: '这是一个描述' }]); ```