feature: proxy、redirect拦截器配置,支持域名正则匹配占位符替换。(之前仅支持path匹配替换)
parent
217ce9d972
commit
e47cf82d34
|
@ -111,7 +111,7 @@ function checkIsLimitConfig (id, api) {
|
|||
module.exports = {
|
||||
name: 'baiduOcr',
|
||||
priority: 131,
|
||||
requestIntercept (context, interceptOpt, req, res, ssl, next, matched) {
|
||||
requestIntercept (context, interceptOpt, req, res, ssl, next) {
|
||||
const { rOptions, log } = context
|
||||
|
||||
const headers = {
|
||||
|
|
|
@ -1,21 +1,29 @@
|
|||
const url = require('node:url')
|
||||
const lodash = require('lodash')
|
||||
|
||||
function replacePlaceholder0 (url, matched, pre) {
|
||||
if (matched) {
|
||||
for (let i = 0; i < matched.length; i++) {
|
||||
url = url.replace(`\${${pre}[${i}]}`, matched[i] || '')
|
||||
}
|
||||
if (matched.groups) {
|
||||
for (const key in matched.groups) {
|
||||
url = url.replace(`\${${key}}`, matched.groups[key] || '')
|
||||
}
|
||||
}
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
// 替换占位符
|
||||
function replacePlaceholder (url, rOptions, matched) {
|
||||
function replacePlaceholder (url, rOptions, pathMatched, hostnameMatched) {
|
||||
if (url.includes('${')) {
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
url = url.replace('${host}', rOptions.hostname)
|
||||
|
||||
if (matched && url.includes('${')) {
|
||||
for (let i = 0; i < matched.length; i++) {
|
||||
url = url.replace(`\${m[${i}]}`, matched[i] == null ? '' : matched[i])
|
||||
}
|
||||
if (matched.groups) {
|
||||
for (const key in matched.groups) {
|
||||
url = url.replace(`\${${key}}`, matched.groups[key] == null ? '' : matched.groups[key])
|
||||
}
|
||||
}
|
||||
if (url.includes('${')) {
|
||||
url = replacePlaceholder0(url, pathMatched, 'p')
|
||||
url = replacePlaceholder0(url, hostnameMatched, 'h')
|
||||
}
|
||||
|
||||
// 移除多余的占位符
|
||||
|
@ -27,7 +35,7 @@ function replacePlaceholder (url, rOptions, matched) {
|
|||
return url
|
||||
}
|
||||
|
||||
function buildTargetUrl (rOptions, urlConf, interceptOpt, matched) {
|
||||
function buildTargetUrl (rOptions, urlConf, interceptOpt, matched, hostnameMatched) {
|
||||
let targetUrl
|
||||
if (interceptOpt && interceptOpt.replace) {
|
||||
const regexp = new RegExp(interceptOpt.replace)
|
||||
|
@ -45,7 +53,7 @@ function buildTargetUrl (rOptions, urlConf, interceptOpt, matched) {
|
|||
}
|
||||
|
||||
// 替换占位符
|
||||
targetUrl = replacePlaceholder(targetUrl, rOptions, matched)
|
||||
targetUrl = replacePlaceholder(targetUrl, rOptions, matched, hostnameMatched)
|
||||
|
||||
// 拼接协议
|
||||
targetUrl = targetUrl.indexOf('http:') === 0 || targetUrl.indexOf('https:') === 0 ? targetUrl : `${rOptions.protocol}//${targetUrl}`
|
||||
|
@ -53,9 +61,9 @@ function buildTargetUrl (rOptions, urlConf, interceptOpt, matched) {
|
|||
return targetUrl
|
||||
}
|
||||
|
||||
function doProxy (proxyConf, rOptions, req, interceptOpt, matched) {
|
||||
function doProxy (proxyConf, rOptions, req, interceptOpt, matched, hostnameMatched) {
|
||||
// 获取代理目标地址
|
||||
const proxyTarget = buildTargetUrl(rOptions, proxyConf, interceptOpt, matched)
|
||||
const proxyTarget = buildTargetUrl(rOptions, proxyConf, interceptOpt, matched, hostnameMatched)
|
||||
|
||||
// 替换rOptions的属性
|
||||
// eslint-disable-next-line node/no-deprecated-api
|
||||
|
@ -81,7 +89,7 @@ module.exports = {
|
|||
replacePlaceholder,
|
||||
buildTargetUrl,
|
||||
doProxy,
|
||||
requestIntercept (context, interceptOpt, req, res, ssl, next, matched) {
|
||||
requestIntercept (context, interceptOpt, req, res, ssl, next, matched, hostnameMatched) {
|
||||
const { rOptions, log, RequestCounter } = context
|
||||
|
||||
const originHostname = rOptions.hostname
|
||||
|
@ -112,7 +120,7 @@ module.exports = {
|
|||
}
|
||||
|
||||
// 替换 rOptions 中的地址,并返回代理目标地址
|
||||
const proxyTarget = doProxy(proxyConf, rOptions, req, interceptOpt, matched)
|
||||
const proxyTarget = doProxy(proxyConf, rOptions, req, interceptOpt, matched, hostnameMatched)
|
||||
|
||||
if (context.requestCount) {
|
||||
log.info('proxy choice:', JSON.stringify(context.requestCount))
|
||||
|
|
|
@ -3,11 +3,11 @@ const proxyApi = require('./proxy')
|
|||
module.exports = {
|
||||
name: 'redirect',
|
||||
priority: 105,
|
||||
requestIntercept (context, interceptOpt, req, res, ssl, next, matched) {
|
||||
requestIntercept (context, interceptOpt, req, res, ssl, next, matched, hostnameMatched) {
|
||||
const { rOptions, log } = context
|
||||
|
||||
// 获取重定向目标地址
|
||||
const redirect = proxyApi.buildTargetUrl(rOptions, interceptOpt.redirect, interceptOpt, matched)
|
||||
const redirect = proxyApi.buildTargetUrl(rOptions, interceptOpt.redirect, interceptOpt, matched, hostnameMatched)
|
||||
|
||||
const headers = {
|
||||
'Location': redirect,
|
||||
|
|
|
@ -186,12 +186,12 @@ module.exports = (serverConfig) => {
|
|||
if (impl.requestIntercept) {
|
||||
// req拦截器
|
||||
interceptor.requestIntercept = (context, req, res, ssl, next) => {
|
||||
return impl.requestIntercept(context, interceptOpt, req, res, ssl, next, matched)
|
||||
return impl.requestIntercept(context, interceptOpt, req, res, ssl, next, matched, interceptOpts.matched)
|
||||
}
|
||||
} else if (impl.responseIntercept) {
|
||||
// res拦截器
|
||||
interceptor.responseIntercept = (context, req, res, proxyReq, proxyRes, ssl, next) => {
|
||||
return impl.responseIntercept(context, interceptOpt, req, res, proxyReq, proxyRes, ssl, next, matched)
|
||||
return impl.responseIntercept(context, interceptOpt, req, res, proxyReq, proxyRes, ssl, next, matched, interceptOpts.matched)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -141,10 +141,29 @@ function matchHostnameAll (hostMap, hostname, action) {
|
|||
// }
|
||||
|
||||
// 正则表达式匹配
|
||||
if (hostname.match(regexp)) {
|
||||
const matched = hostname.match(regexp)
|
||||
if (matched) {
|
||||
value = hostMap[regexp]
|
||||
log.debug(`matchHostname-one: ${action}: '${hostname}' -> { "${regexp}": ${JSON.stringify(value)} }`)
|
||||
values = merge(values, value)
|
||||
|
||||
// 设置matched
|
||||
if (matched.length > 1) {
|
||||
if (values.matched) {
|
||||
// 合并array
|
||||
matched.shift()
|
||||
values.matched = [...values.matched, ...matched] // 拼接上多个matched
|
||||
|
||||
// 合并groups
|
||||
if (matched.groups) {
|
||||
values.matched.groups = merge(values.matched.groups, matched.groups)
|
||||
} else {
|
||||
values.matched.groups = matched.groups
|
||||
}
|
||||
} else {
|
||||
values.matched = matched
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue