Commit 5c642d37 authored by xzj's avatar xzj

修复书写错误

parents
node_modules
\ No newline at end of file
node_modules
\ No newline at end of file
## 介绍
中间件使用了agentkeepalive,通过复用socket来减少资源占用,加快代理响应速度。
## 快速起步
```
const Router = require('koa-router');
const router = new Router();
const proxy = require('request-proxy');
const demo = require('./controller/demo')
router
.use(proxy())
.use('/demo', demo.routes())
```
```
// demo.js
const pipe = async function (ctx) {
await ctx.pipe('http://localhost:7054' + ctx.url.replace('/test/1', '/upload/test/1'))
// no more code ...
}
const curl = async function (ctx) {
let result = await ctx.curl('http://localhost:7054' + ctx.url.replace('/test/1', '/upload/test/1'))
ctx.status = result.status
ctx.body = result.body
}
const router = new Router();
router
.get('/curl/*', curl)
.get('/pipe/*', pipe)
module.exports = router
```
## 注意事项
### 参数问题
```
pipe
option: 对象格式,和request包参数一直
如果是字符串类型,默认会转为{url: 'some string'}
extra: 对象格式,现有两个属性
rawRes: 是否返回接受到的res,默认false
throw: 请求错误的时候是否抛出,中间件会自动捕获,默认true
```
### 如何在bodyParse后透传post请求
```
// 由于bodyParse会读取request流中的body信息,所有透传的时候就会丢失
// 解决方法:使用curl方式,手动将body参数上
if (ctx.method === 'POST') {
let option = {
url: config.api.mall_api + ctx.url.replace('/mall/other', ''),
headers: {
'x-auth-token': ctx.headers['x-auth-token']
}
}
if (ctx.is('json')) {
option.body = ctx.request.body
} else if (ctx.is('urlencoded')) {
option.form = ctx.request.body
}
let result = await ctx.curl(option)
ctx.status = result.status
ctx.body = result.body
return
}
```
### 如何返回headers
```
ctx.set(result.headers)
或者
ctx.res._headers = {'x-auth-token': '123'}
```
'use strict'
const request = require('request')
const debug = require('debug')('request-proxy')
const Agent = require('agentkeepalive');
const HttpsAgent = require('agentkeepalive').HttpsAgent;
module.exports = function (options) {
const optionsDefault = {
agent: {
keepAlive: true,
// 当 socket 超过 60 秒都没有任何活动,就会被当作超时处理掉
timeout: 60000,
// 每个域名最大socket数
maxSockets: 800, // 默认Infinity
// 最大空闲 socket 数
maxFreeSockets: 10, // 默认256
// 空闲的 KeepAlive socket 最长可以存活30秒
freeSocketKeepAliveTimeout: 30000
},
timeout: 15000 // 15秒超时
}
options = Object.assign({}, optionsDefault, options)
/**
* time: 调试请求各阶段时间信息
* followRedirect: 是否重定向
* json: body自动解析为json对象
*/
const curlDefault = {
followRedirect: false,
json: true,
time: false
}
/**
* resRes: 是否返回解压后的response
* throw:error发生时是否抛出异常被 错误中间件 自动捕获。否则把错误返回给代码
*/
const extraDefault = {
rawRes: false,
throw: true
}
const pipeDefault = {
time: false
}
const httpAgent = new Agent(options.agent);
const httpsAgent = new HttpsAgent();
return async function (ctx, next) {
if (ctx.pipe || ctx.curl) return next()
ctx.req.connection.setNoDelay(true)
ctx.curl = function (option, extra) {
if (typeof option === 'string') {
option = {uri: option}
}
if (!option.method) {
option.method = ctx.method
}
option = Object.assign({}, curlDefault, option)
extra = Object.assign({}, extraDefault, extra)
debug(option)
if (!option.agent && !/^https/.test(option.url)) {
option.agent = httpAgent
} else if (!option.agent && /^https/.test(option.url)) {
option.agent = httpsAgent
}
return new Promise(function (resolve, reject) {
request(option, function(err, response, body) {
if (err) {
if (extra.throw) {
reject(err)
} else {
resolve(err)
}
} else {
resolve(extra.rawRes ? response : {
status: response.statusCode,
headers: response.headers,
body: body || {}
})
}
})
})
}
ctx.pipe = function (option) {
if (typeof option === 'string') {
option = {uri: option}
}
option = Object.assign({}, pipeDefault, option)
if (!option.method) {
option.method = ctx.method
}
debug(option)
if (!option.agent && !/^https/.test(option.url)) {
option.agent = httpAgent
} else if (!option.agent && /^https/.test(option.url)) {
option.agent = httpsAgent
}
return new Promise(function (resolve, reject) {
let r = ctx.req.pipe(requestEx(option))
r.on('error', function (err) {
reject(err);
})
.on('response', function (resp) {
ctx.respond = false
r.pipe(ctx.res)
resolve({})
})
})
}
return next()
}
}
\ No newline at end of file
This diff is collapsed.
{
"name": "request-proxy",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"agentkeepalive": "^3.3.0",
"request": "^2.83.0"
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment