zan-proxy
Version:
96 lines • 4.19 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const mime_types_1 = __importDefault(require("mime-types"));
const url_1 = __importDefault(require("url"));
const fsExists = p => {
return new Promise(resolve => {
fs_1.default.exists(p, exists => resolve(exists));
});
};
exports.rule = ({ ruleService, mockDataService, profileService, }) => {
return (ctx, next) => __awaiter(this, void 0, void 0, function* () {
if (ctx.ignore) {
yield next();
return;
}
if (!profileService.enableRule(ctx.userID)) {
yield next();
return;
}
const { userID } = ctx;
const { req } = ctx;
const { method, url } = req;
const urlObj = url_1.default.parse(url);
const processRule = ruleService.getProcessRule(userID, method, urlObj);
if (!processRule) {
yield next();
return;
}
ctx.res.setHeader('zan-proxy-rule-match', processRule.match);
if (urlObj.pathname && mime_types_1.default.lookup(urlObj.pathname)) {
ctx.res.setHeader('Content-Type', mime_types_1.default.lookup(urlObj.pathname));
}
// 规则的响应头先缓存在这里
const resHeaders = {};
for (const action of processRule.actionList) {
const { data } = action;
switch (action.type) {
case 'mockData':
const { dataId } = data;
const content = yield mockDataService.getDataFileContent(userID, dataId);
const contentType = yield mockDataService.getDataFileContentType(userID, dataId);
ctx.res.body = content;
ctx.res.setHeader('Content-Type', contentType);
break;
case 'addRequestHeader':
ctx.req.headers[data.headerKey] = data.headerValue;
break;
case 'addResponseHeader':
resHeaders[data.headerKey] = data.headerValue;
break;
case 'empty':
ctx.res.body = '';
break;
case 'redirect':
const target = profileService.calcPath(userID, urlObj.href, processRule.match, data.target);
if (!target) {
continue;
}
ctx.res.setHeader('zan-proxy-target', target);
if (target.startsWith('http') || target.startsWith('ws')) {
ctx.req.url = target;
}
else {
const exists = yield fsExists(target);
if (exists) {
ctx.res.body = fs_1.default.createReadStream(target);
}
else {
ctx.res.body = `target ${target} does not exist`;
ctx.res.statusCode = 404;
}
}
break;
default:
break;
}
}
yield next();
Object.keys(resHeaders).forEach(headerKey => {
ctx.res.setHeader(headerKey, resHeaders[headerKey]);
});
});
};
//# sourceMappingURL=rule.js.map
;