feature: 新增 githubSpeedUp.js,定制github的加速策略,目前加速了仓库内图片的访问速度。 (#290)
							parent
							
								
									55906b828e
								
							
						
					
					
						commit
						e67f051a4e
					
				|  | @ -78,6 +78,11 @@ module.exports = { | |||
|         '^(/[^/]+){2}/pull/\\d+/open_with_menu.*$': { | ||||
|           cacheDays: 7, | ||||
|           desc: 'PR详情页:标题右边那个Code按钮的HTML代理请求地址,感觉上应该可以缓存。暂时先设置为缓存7天' | ||||
|         }, | ||||
|         '^(/[^/]+){2,}\\.(jpg|jpeg|png|gif)(\\?.*)?$': { | ||||
|           githubSpeedUp: true, | ||||
|           cacheDays: 7, | ||||
|           desc: '仓库内图片,重定向改为代理,并缓存7天。' | ||||
|         } | ||||
|       }, | ||||
|       'github-releases.githubusercontent.com': { | ||||
|  |  | |||
|  | @ -0,0 +1,37 @@ | |||
| const proxyApi = require('./proxy') | ||||
| 
 | ||||
| module.exports = { | ||||
|   name: 'githubSpeedUp', | ||||
|   priority: 131, | ||||
|   requestIntercept (context, interceptOpt, req, res, ssl, next) { | ||||
|     const { rOptions, log } = context | ||||
| 
 | ||||
|     // 目前,只拦截github.com,后续可以继续拦截其他域名,做一些特殊处理
 | ||||
|     if (rOptions.hostname !== 'github.com') { | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     const url = `${rOptions.method} ➜ ${rOptions.protocol}//${rOptions.hostname}:${rOptions.port}${req.url}` | ||||
| 
 | ||||
|     // 判断是否为仓库内的图片文件
 | ||||
|     const matched = req.url.match('^(/[^/]+){2}/raw(/[^/]+)+\\.(jpg|jpeg|png|gif)(\\?.*)?$') | ||||
|     if (matched) { | ||||
|       // 拼接代理地址
 | ||||
|       const proxyConf = 'https://raw.githubusercontent.com' + req.url.replace('/raw/', '/') | ||||
| 
 | ||||
|       // 执行代理
 | ||||
|       const proxyTarget = proxyApi.doProxy(proxyConf, rOptions, req) | ||||
| 
 | ||||
|       res.setHeader('DS-Interceptor', `githubSpeedUp: proxy -> ${proxyTarget}`) | ||||
| 
 | ||||
|       log.info(`githubSpeedUp intercept: ${url} -> ${proxyConf}`) | ||||
| 
 | ||||
|       return true | ||||
|     } | ||||
| 
 | ||||
|     return true // true代表请求结束
 | ||||
|   }, | ||||
|   is (interceptOpt) { | ||||
|     return !!interceptOpt.githubSpeedUp | ||||
|   } | ||||
| } | ||||
|  | @ -1,8 +1,51 @@ | |||
| const url = require('url') | ||||
| const lodash = require('lodash') | ||||
| 
 | ||||
| function doProxy (proxyConf, rOptions, req, interceptOpt) { | ||||
|   // 获取代理目标地址
 | ||||
|   let proxyTarget | ||||
|   if (interceptOpt && interceptOpt.replace) { | ||||
|     const regexp = new RegExp(interceptOpt.replace) | ||||
|     proxyTarget = req.url.replace(regexp, proxyConf) | ||||
|   } else if (proxyConf.indexOf('http:') === 0 || proxyConf.indexOf('https:') === 0) { | ||||
|     proxyTarget = proxyConf | ||||
|   } else { | ||||
|     let uri = req.url | ||||
|     if (uri.indexOf('http') === 0) { | ||||
|       // eslint-disable-next-line node/no-deprecated-api
 | ||||
|       const URL = url.parse(uri) | ||||
|       uri = URL.path | ||||
|     } | ||||
|     proxyTarget = proxyConf + uri | ||||
|   } | ||||
| 
 | ||||
|   // eslint-disable-next-line
 | ||||
|   // no-template-curly-in-string
 | ||||
|   // eslint-disable-next-line no-template-curly-in-string
 | ||||
|   proxyTarget = proxyTarget.replace('${host}', rOptions.hostname) | ||||
| 
 | ||||
|   const proxy = proxyTarget.indexOf('http:') === 0 || proxyTarget.indexOf('https:') === 0 ? proxyTarget : rOptions.protocol + '//' + proxyTarget | ||||
|   // eslint-disable-next-line node/no-deprecated-api
 | ||||
|   const URL = url.parse(proxy) | ||||
|   rOptions.origional = lodash.cloneDeep(rOptions) // 备份原始请求参数
 | ||||
|   delete rOptions.origional.agent | ||||
|   delete rOptions.origional.headers | ||||
|   rOptions.protocol = URL.protocol | ||||
|   rOptions.hostname = URL.host | ||||
|   rOptions.host = URL.host | ||||
|   rOptions.headers.host = URL.host | ||||
|   rOptions.path = URL.path | ||||
|   if (URL.port == null) { | ||||
|     rOptions.port = rOptions.protocol === 'https:' ? 443 : 80 | ||||
|   } | ||||
| 
 | ||||
|   return proxyTarget | ||||
| } | ||||
| 
 | ||||
| module.exports = { | ||||
|   name: 'proxy', | ||||
|   priority: 121, | ||||
|   doProxy, | ||||
|   requestIntercept (context, interceptOpt, req, res, ssl, next) { | ||||
|     const { rOptions, log, RequestCounter } = context | ||||
| 
 | ||||
|  | @ -33,42 +76,8 @@ module.exports = { | |||
|       } | ||||
|     } | ||||
| 
 | ||||
|     // 获取代理目标地址
 | ||||
|     let proxyTarget | ||||
|     if (interceptOpt.replace) { | ||||
|       const regexp = new RegExp(interceptOpt.replace) | ||||
|       proxyTarget = req.url.replace(regexp, proxyConf) | ||||
|     } else if (proxyConf.indexOf('http:') === 0 || proxyConf.indexOf('https:') === 0) { | ||||
|       proxyTarget = proxyConf | ||||
|     } else { | ||||
|       let uri = req.url | ||||
|       if (uri.indexOf('http') === 0) { | ||||
|         // eslint-disable-next-line node/no-deprecated-api
 | ||||
|         const URL = url.parse(uri) | ||||
|         uri = URL.path | ||||
|       } | ||||
|       proxyTarget = proxyConf + uri | ||||
|     } | ||||
| 
 | ||||
|     // eslint-disable-next-line
 | ||||
|     // no-template-curly-in-string
 | ||||
|     // eslint-disable-next-line no-template-curly-in-string
 | ||||
|     proxyTarget = proxyTarget.replace('${host}', rOptions.hostname) | ||||
| 
 | ||||
|     const proxy = proxyTarget.indexOf('http') === 0 ? proxyTarget : rOptions.protocol + '//' + proxyTarget | ||||
|     // eslint-disable-next-line node/no-deprecated-api
 | ||||
|     const URL = url.parse(proxy) | ||||
|     rOptions.origional = lodash.cloneDeep(rOptions) // 备份原始请求参数
 | ||||
|     delete rOptions.origional.agent | ||||
|     delete rOptions.origional.headers | ||||
|     rOptions.protocol = URL.protocol | ||||
|     rOptions.hostname = URL.host | ||||
|     rOptions.host = URL.host | ||||
|     rOptions.headers.host = URL.host | ||||
|     rOptions.path = URL.path | ||||
|     if (URL.port == null) { | ||||
|       rOptions.port = rOptions.protocol === 'https:' ? 443 : 80 | ||||
|     } | ||||
|     // 替换 rOptions 中的地址,并返回代理目标地址
 | ||||
|     const proxyTarget = doProxy(proxyConf, rOptions, req, interceptOpt) | ||||
| 
 | ||||
|     if (context.requestCount) { | ||||
|       log.info('proxy choice:', JSON.stringify(context.requestCount)) | ||||
|  |  | |||
|  | @ -10,6 +10,8 @@ const cacheReq = require('./impl/req/cacheReq') | |||
| const proxy = require('./impl/req/proxy') | ||||
| const sni = require('./impl/req/sni') | ||||
| 
 | ||||
| const githubSpeedUp = require('./impl/req/githubSpeedUp') | ||||
| 
 | ||||
| // response interceptor impls
 | ||||
| const cacheRes = require('./impl/res/cacheRes') | ||||
| const script = require('./impl/res/script') | ||||
|  | @ -20,6 +22,7 @@ module.exports = [ | |||
|   success, redirect, abort, | ||||
|   cacheReq, | ||||
|   proxy, sni, | ||||
|   githubSpeedUp, | ||||
| 
 | ||||
|   // response interceptor impls
 | ||||
|   cacheRes, script | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 王良
						王良