diff --git a/app.js b/app.js index b356f7d4ddb36547a153ede749cad8db1166c287..8191e0653bdcb2d026e432661eea64fcacbec3f1 100644 --- a/app.js +++ b/app.js @@ -42,14 +42,6 @@ app.use(cache('2 minutes', onlyStatus200)) app.use(express.static(path.resolve(__dirname, 'public'))) -app.use(function(req, res, next) { - const proxy = req.query.proxy - if (proxy) { - req.headers.cookie += `__proxy__${proxy}` - } - next() -}) - // 补全缺失的cookie const { completeCookie } = require('./util/init') app.use(function(req, res, next) { @@ -59,6 +51,24 @@ app.use(function(req, res, next) { next() }) +// cookie parser +app.use(function(req, res, next) { + req.cookies = {}, (req.headers.cookie || '').split(/\s*;\s*/).forEach(pair => { + let crack = pair.indexOf('=') + if(crack < 1 || crack == pair.length - 1) return + req.cookies[decodeURIComponent(pair.slice(0, crack)).trim()] = decodeURIComponent(pair.slice(crack + 1)).trim() + }) + next() +}) + +app.use(function(req, res, next) { + const proxy = req.query.proxy + if (proxy) { + req.headers.cookie += `__proxy__${proxy}` + } + next() +}) + // 因为这几个文件对外所注册的路由 和 其他文件对外注册的路由规则不一样, 所以专门写个MAP对这些文件做特殊处理 const UnusualRouteFileMap = { // key 为文件名, value 为对外注册的路由 @@ -72,66 +82,41 @@ const { createWebAPIRequest, request } = require('./util/util') const Wrap = fn => (req, res) => fn(req, res, createWebAPIRequest, request) // 同步读取 router 目录中的js文件, 根据命名规则, 自动注册路由 -fs.readdirSync(path.resolve(__dirname, 'router')) - .reverse() - .forEach(file => { - if (/\.js$/i.test(file) === false) { - return - } - - let route - - if (typeof UnusualRouteFileMap[file] !== 'undefined') { - route = UnusualRouteFileMap[file] - } else { - route = - '/' + - file - .replace(/\.js$/i, '') - .replace(/_/g, '/') - } - - app.use(route, Wrap(require('./router/' + file))) - }) - - const requestMod = require('./util/request') - let dev = express() - fs.readdirSync(path.resolve(__dirname, 'module')) - .reverse() - .forEach(file => { - if (/\.js$/i.test(file) === false) { - return - } - - let route +fs.readdirSync(path.join(__dirname, 'router')) +.reverse() +.forEach(file => { + if (!/\.js$/i.test(file)) return + let route = (file in UnusualRouteFileMap) ? UnusualRouteFileMap[file] : '/' + file.replace(/\.js$/i, '').replace(/_/g, '/') + app.use(route, Wrap(path.join(__dirname, 'router', file))) +}) - if (typeof UnusualRouteFileMap[file] !== 'undefined') { - route = UnusualRouteFileMap[file] - } else { - route = - '/' + - file - .replace(/\.js$/i, '') - .replace(/_/g, '/') - } - dev.use(route, (req, res) => { - let question = require('./module/' + file) - let query = {...req.query, cookie: req.headers.cookie} - question(query, requestMod) - .then(answer => { - console.log('[OK]', req.originalUrl) - res.append('Set-Cookie', answer.cookie) - res.status(answer.code).send(answer.body) - }) - .catch( answer => { - console.log('[ERROR]', req.originalUrl) - res.append('Set-Cookie', answer.cookie) - res.status(answer.code).send(answer.body) - }) +// 改写router为module +const requestMod = require('./util/request') +let dev = express() +fs.readdirSync(path.join(__dirname, 'module')) +.reverse() +.forEach(file => { + if (!(/\.js$/i.test(file))) return + let route = (file in UnusualRouteFileMap) ? UnusualRouteFileMap[file] : '/' + file.replace(/\.js$/i, '').replace(/_/g, '/') + let question = require(path.join(__dirname, 'module', file)) + + dev.use(route, (req, res) => { + let query = {...req.query, cookie: req.cookies} + question(query, requestMod) + .then(answer => { + console.log('[OK]', decodeURIComponent(req.originalUrl)) + res.append('Set-Cookie', answer.cookie) + res.status(answer.status).send(answer.body) + }) + .catch(answer => { + console.log('[ERR]', decodeURIComponent(req.originalUrl)) + res.append('Set-Cookie', answer.cookie) + res.status(answer.status).send(answer.body) }) }) - app.use('/dev', dev) +}) +app.use('/dev', dev) const port = process.env.PORT || 3000 diff --git a/util/init.js b/util/init.js index 1aa3a744658fc3ab00154030841dee45c5fe50de..c6c10f87f77f46ce45321b5f045bcb98c133c363 100644 --- a/util/init.js +++ b/util/init.js @@ -1,5 +1,5 @@ function randomString(pattern, length){ - return Array.apply(null, {length: length}).map(() => (pattern[Math.floor(Math.random() * pattern.length)])).join('') + return Array.apply(null, {length: length}).map(() => (pattern[Math.floor(Math.random() * pattern.length)])).join('') } function completeCookie(cookie){ diff --git a/util/request.js b/util/request.js index 709fad87e5d5a4c322876cf5c652171a658dc3ad..3ff5f0a22ece3ecfcad9aed7b64083276e3cd72e 100644 --- a/util/request.js +++ b/util/request.js @@ -2,7 +2,7 @@ const encrypt = require('./crypto.js') const request = require('request') const queryString = require('querystring') -request.debug = false +// request.debug = false function chooseUserAgent(ua) { const userAgentList = [ @@ -36,27 +36,28 @@ function chooseUserAgent(ua) { function createRequest(method, url, data, options){ return new Promise((resolve, reject) => { - if(options.crypto == 'weapi'){ - const csrfToken = (options.cookie || '').match(/_csrf=([^(;|$)]+)/) - data.csrf_token = (csrfToken ? csrfToken[1] : '') - data = encrypt(data) - } - let headers = {'User-Agent': chooseUserAgent(options.ua)} - if(options.cookie) headers['Cookie'] = options.cookie if(method.toUpperCase() == 'POST') headers['Content-Type'] = 'application/x-www-form-urlencoded' if(url.indexOf('music.163.com') != -1) headers['Referer'] = 'http://music.163.com' + // headers['X-Real-IP'] = '118.88.88.88' - const answer = { - code: 502, - body: {code: 502}, - cookie: [] + if(typeof(options.cookie) === 'object') + headers['Cookie'] = Object.keys(options.cookie).map(key => (encodeURIComponent(key) + '=' + encodeURIComponent(options.cookie[key]))).join('; ') + else if(options.cookie) + headers['Cookie'] = options.cookie + + if(options.crypto == 'weapi'){ + const csrfToken = (headers['Cookie'] || '').match(/_csrf=([^(;|$)]+)/) + data.csrf_token = (csrfToken ? csrfToken[1] : '') + data = encrypt(data) } + const answer = {status: 500, body: {}, cookie: []} request( {method: method, url: url, headers: headers, body: queryString.stringify(data), proxy: options.proxy}, (err, res, body) => { if(err){ + answer.status = 502 answer.body = {code: 502, msg: err.stack} reject(answer) }