feature: 新增 requestReplace 拦截器,目前只支持替换请求头。 (#297)
parent
1569026bc5
commit
f4e00a5ff9
|
@ -56,7 +56,7 @@ function getLastModifiedTimeFromIfModifiedSince (rOptions, log) {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'cacheReq',
|
name: 'cacheReq',
|
||||||
priority: 111,
|
priority: 104,
|
||||||
requestIntercept (context, interceptOpt, req, res, ssl, next) {
|
requestIntercept (context, interceptOpt, req, res, ssl, next) {
|
||||||
const { rOptions, log } = context
|
const { rOptions, log } = context
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
const REMOVE = '[remove]'
|
||||||
|
|
||||||
|
function replaceRequestHeaders (rOptions, headers, log) {
|
||||||
|
for (const key in headers) {
|
||||||
|
let value = headers[key]
|
||||||
|
if (value === REMOVE) {
|
||||||
|
value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
log.debug(`[DS-RequestReplace-Interceptor] replace '${key}': '${rOptions.headers[key.toLowerCase()]}' -> '${value}'`)
|
||||||
|
rOptions.headers[key.toLowerCase()] = value
|
||||||
|
} else if (rOptions.headers[key.toLowerCase()]) {
|
||||||
|
log.debug(`[DS-RequestReplace-Interceptor] remove '${key}': '${rOptions.headers[key.toLowerCase()]}'`)
|
||||||
|
delete rOptions.headers[key.toLowerCase()]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug(`[DS-RequestReplace-Interceptor] 最终headers: \r\n${JSON.stringify(rOptions.headers, null, '\t')}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'requestReplace',
|
||||||
|
priority: 111,
|
||||||
|
requestIntercept (context, interceptOpt, req, res, ssl, next) {
|
||||||
|
const { rOptions, log } = context
|
||||||
|
|
||||||
|
const requestReplaceConfig = interceptOpt.requestReplace
|
||||||
|
|
||||||
|
let actions = ''
|
||||||
|
|
||||||
|
// 替换请求头
|
||||||
|
if (requestReplaceConfig.headers) {
|
||||||
|
replaceRequestHeaders(rOptions, requestReplaceConfig.headers, log)
|
||||||
|
actions += 'headers'
|
||||||
|
}
|
||||||
|
|
||||||
|
res.setHeader('DS-RequestReplace-Interceptor', actions)
|
||||||
|
},
|
||||||
|
is (interceptOpt) {
|
||||||
|
return !!interceptOpt.requestReplace
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ const cacheReq = require('../req/cacheReq')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'cacheRes',
|
name: 'cacheRes',
|
||||||
priority: 201,
|
priority: 202,
|
||||||
responseIntercept (context, interceptOpt, req, res, proxyReq, proxyRes, ssl, next) {
|
responseIntercept (context, interceptOpt, req, res, proxyReq, proxyRes, ssl, next) {
|
||||||
const { rOptions, log } = context
|
const { rOptions, log } = context
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
const lodash = require('lodash')
|
const lodash = require('lodash')
|
||||||
|
const REMOVE = '[remove]'
|
||||||
|
|
||||||
function replaceHeaders (newHeaders, res, proxyRes) {
|
// 替换响应头
|
||||||
|
function replaceResponseHeaders (newHeaders, res, proxyRes) {
|
||||||
if (newHeaders && !lodash.isEmpty(newHeaders)) {
|
if (newHeaders && !lodash.isEmpty(newHeaders)) {
|
||||||
// 响应头Key统一转小写
|
// 响应头Key统一转小写
|
||||||
for (const headerKey in newHeaders) {
|
for (const headerKey in newHeaders) {
|
||||||
|
@ -24,12 +26,21 @@ function replaceHeaders (newHeaders, res, proxyRes) {
|
||||||
const newHeaderValue = newHeaders[headerKeyLower]
|
const newHeaderValue = newHeaders[headerKeyLower]
|
||||||
if (newHeaderValue && newHeaderValue !== proxyRes.rawHeaders[i + 1]) {
|
if (newHeaderValue && newHeaderValue !== proxyRes.rawHeaders[i + 1]) {
|
||||||
preHeaders[headerKeyLower] = proxyRes.rawHeaders[i + 1] // 先保存原先响应头
|
preHeaders[headerKeyLower] = proxyRes.rawHeaders[i + 1] // 先保存原先响应头
|
||||||
proxyRes.rawHeaders[i + 1] = newHeaderValue === '[remove]' ? '' : newHeaderValue // 由于拦截配置中不允许配置null,会被删,所以配置一个[remove],当作删除响应头的意思
|
if (newHeaderValue === REMOVE) { // 由于拦截配置中不允许配置null,会被删,所以配置一个[remove],当作删除响应头的意思
|
||||||
|
proxyRes.rawHeaders[i + 1] = ''
|
||||||
|
} else {
|
||||||
|
proxyRes.rawHeaders[i + 1] = newHeaderValue
|
||||||
|
}
|
||||||
delete newHeaders[headerKeyLower]
|
delete newHeaders[headerKeyLower]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 新增响应头
|
// 新增响应头
|
||||||
for (const headerKey in newHeaders) {
|
for (const headerKey in newHeaders) {
|
||||||
|
const headerValue = newHeaders[headerKey]
|
||||||
|
if (!headerValue || headerValue === REMOVE) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
res.setHeader(headerKey, newHeaders[headerKey])
|
res.setHeader(headerKey, newHeaders[headerKey])
|
||||||
preHeaders[headerKey] = null // 标记原先响应头为null
|
preHeaders[headerKey] = null // 标记原先响应头为null
|
||||||
}
|
}
|
||||||
|
@ -43,8 +54,8 @@ function replaceHeaders (newHeaders, res, proxyRes) {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'responseReplace',
|
name: 'responseReplace',
|
||||||
priority: 203,
|
priority: 201,
|
||||||
replaceHeaders,
|
replaceResponseHeaders,
|
||||||
responseIntercept (context, interceptOpt, req, res, proxyReq, proxyRes, ssl, next) {
|
responseIntercept (context, interceptOpt, req, res, proxyReq, proxyRes, ssl, next) {
|
||||||
const { log } = context
|
const { log } = context
|
||||||
|
|
||||||
|
@ -52,21 +63,21 @@ module.exports = {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const responseConfig = interceptOpt.response
|
const responseConfig = interceptOpt.responseReplace
|
||||||
|
|
||||||
let actions = ''
|
let actions = ''
|
||||||
|
|
||||||
// 替换响应头
|
// 替换响应头
|
||||||
if (replaceHeaders(responseConfig.headers, res, proxyRes)) {
|
if (replaceResponseHeaders(responseConfig.headers, res, proxyRes)) {
|
||||||
actions += 'headers'
|
actions += 'headers'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actions) {
|
if (actions) {
|
||||||
res.setHeader('DS-Response-Interceptor', actions)
|
res.setHeader('DS-ResponseReplace-Interceptor', actions)
|
||||||
log.info('response intercept: ' + actions)
|
log.info('response intercept: ' + actions)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
is (interceptOpt) {
|
is (interceptOpt) {
|
||||||
return !!interceptOpt.response
|
return !!interceptOpt.responseReplace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ function getScriptByUrlOrPath (scriptUrlOrPath) {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'script',
|
name: 'script',
|
||||||
priority: 202,
|
priority: 203,
|
||||||
responseIntercept (context, interceptOpt, req, res, proxyReq, proxyRes, ssl, next) {
|
responseIntercept (context, interceptOpt, req, res, proxyReq, proxyRes, ssl, next) {
|
||||||
const { rOptions, log, setting } = context
|
const { rOptions, log, setting } = context
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,10 @@ const OPTIONS = require('./impl/req/OPTIONS.js')
|
||||||
const success = require('./impl/req/success')
|
const success = require('./impl/req/success')
|
||||||
const redirect = require('./impl/req/redirect')
|
const redirect = require('./impl/req/redirect')
|
||||||
const abort = require('./impl/req/abort')
|
const abort = require('./impl/req/abort')
|
||||||
|
|
||||||
const cacheReq = require('./impl/req/cacheReq')
|
const cacheReq = require('./impl/req/cacheReq')
|
||||||
|
|
||||||
|
const requestReplace = require('./impl/req/requestReplace')
|
||||||
|
|
||||||
const proxy = require('./impl/req/proxy')
|
const proxy = require('./impl/req/proxy')
|
||||||
const sni = require('./impl/req/sni')
|
const sni = require('./impl/req/sni')
|
||||||
|
|
||||||
|
@ -18,10 +19,10 @@ const responseReplace = require('./impl/res/responseReplace')
|
||||||
module.exports = [
|
module.exports = [
|
||||||
// request interceptor impls
|
// request interceptor impls
|
||||||
OPTIONS,
|
OPTIONS,
|
||||||
success, redirect, abort,
|
success, redirect, abort, cacheReq,
|
||||||
cacheReq,
|
requestReplace,
|
||||||
proxy, sni,
|
proxy, sni,
|
||||||
|
|
||||||
// response interceptor impls
|
// response interceptor impls
|
||||||
cacheRes, script, responseReplace
|
responseReplace, cacheRes, script
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue