diff --git a/lib/utils/request-wrapper.js b/lib/utils/request-wrapper.js index 79a7097662..01d02a8ccf 100644 --- a/lib/utils/request-wrapper.js +++ b/lib/utils/request-wrapper.js @@ -58,6 +58,9 @@ const requestWrapper = (url, options) => { options.agent = agentResult; if (config.proxy.auth) { + if (!options.headers) { + options.headers = {}; + } options.headers['Proxy-Authorization'] = `Basic ${config.proxy.auth}`; } logger.info(`Proxy for ${url}`); @@ -69,6 +72,9 @@ const requestWrapper = (url, options) => { } } if (!hasUA) { + if (!options.headers) { + options.headers = {}; + } options.headers['user-agent'] = config.ua; } options.headers['x-app'] = 'RSSHub'; diff --git a/test/utils/got.js b/test/utils/got.js index 317116cefc..1e1fd3a671 100644 --- a/test/utils/got.js +++ b/test/utils/got.js @@ -1,22 +1,13 @@ -let got = require('../../lib/utils/got'); +const got = require('../../lib/utils/got'); const config = require('../../lib/config'); const nock = require('nock'); -afterEach(() => { - delete process.env.PROXY_PROTOCOL; - delete process.env.PROXY_HOST; - delete process.env.PROXY_PORT; - delete process.env.PROXY_AUTH; - delete process.env.PROXY_URL_REGEX; -}); - describe('got', () => { it('headers', async () => { nock('http://rsshub.test') .get('/test') .reply(function() { expect(this.req.headers['user-agent']).toBe(config.ua); - expect(this.req.headers['x-app']).toBe('RSSHub'); return [200, '']; }); @@ -81,127 +72,4 @@ describe('got', () => { }, }); }); - - it('proxy socks', async () => { - process.env.PROXY_PROTOCOL = 'socks'; - process.env.PROXY_HOST = 'rsshub.proxy'; - process.env.PROXY_PORT = '2333'; - jest.resetModules(); - got = require('../../lib/utils/got'); - nock('http://rsshub.test') - .get('/proxy') - .reply(() => [200, '']); - - await got.get('http://rsshub.test/proxy', { - hooks: { - beforeRequest: [ - (options) => { - expect(options.agent.constructor.name).toBe('SocksProxyAgent'); - expect(options.agent.options.href).toBe('socks://rsshub.proxy:2333'); - }, - ], - }, - }); - }); - - it('proxy http', async () => { - process.env.PROXY_PROTOCOL = 'http'; - process.env.PROXY_HOST = 'rsshub.proxy'; - process.env.PROXY_PORT = '2333'; - jest.resetModules(); - got = require('../../lib/utils/got'); - nock('http://rsshub.test') - .get('/proxy') - .reply(() => [200, '']); - - await got.get('http://rsshub.test/proxy', { - hooks: { - beforeRequest: [ - (options) => { - expect(options.agent.constructor.name).toBe('TunnelingAgent'); - expect(options.agent.options.proxy.host).toBe('rsshub.proxy'); - expect(options.agent.options.proxy.port).toBe(2333); - }, - ], - }, - }); - }); - - it('proxy https', async () => { - process.env.PROXY_PROTOCOL = 'https'; - process.env.PROXY_HOST = 'rsshub.proxy'; - process.env.PROXY_PORT = '2333'; - jest.resetModules(); - got = require('../../lib/utils/got'); - nock('http://rsshub.test') - .get('/proxy') - .reply(() => [200, '']); - - await got.get('http://rsshub.test/proxy', { - hooks: { - beforeRequest: [ - (options) => { - expect(options.agent.constructor.name).toBe('TunnelingAgent'); - expect(options.agent.options.proxy.host).toBe('rsshub.proxy'); - expect(options.agent.options.proxy.port).toBe(2333); - }, - ], - }, - }); - }); - - it('auth', async () => { - process.env.PROXY_AUTH = 'testtest'; - process.env.PROXY_PROTOCOL = 'socks'; - process.env.PROXY_HOST = 'rsshub.proxy'; - process.env.PROXY_PORT = '2333'; - jest.resetModules(); - got = require('../../lib/utils/got'); - nock('http://rsshub.test') - .get('/auth') - .reply(function() { - expect(this.req.headers['user-agent']).toBe(config.ua); - expect(this.req.headers['proxy-authorization']).toBe('Basic testtest'); - return [200, '']; - }); - - await got.get('http://rsshub.test/auth'); - }); - - it('url_regex', async () => { - process.env.PROXY_URL_REGEX = 'url_regex'; - process.env.PROXY_PROTOCOL = 'socks'; - process.env.PROXY_HOST = 'rsshub.proxy'; - process.env.PROXY_PORT = '2333'; - jest.resetModules(); - got = require('../../lib/utils/got'); - - nock('http://rsshub.test') - .get('/url_regex') - .reply(() => [200, '']); - nock('http://rsshub.test') - .get('/proxy') - .reply(() => [200, '']); - - await got.get('http://rsshub.test/url_regex', { - hooks: { - beforeRequest: [ - (options) => { - expect(options.agent.constructor.name).toBe('SocksProxyAgent'); - expect(options.agent.options.href).toBe('socks://rsshub.proxy:2333'); - }, - ], - }, - }); - - await got.get('http://rsshub.test/proxy', { - hooks: { - beforeRequest: [ - (options) => { - expect(options.agent).toBe(undefined); - }, - ], - }, - }); - }); }); diff --git a/test/utils/request-wrapper.js b/test/utils/request-wrapper.js new file mode 100644 index 0000000000..1577f79930 --- /dev/null +++ b/test/utils/request-wrapper.js @@ -0,0 +1,167 @@ +const got = require('../../lib/utils/got'); +const parser = require('../../lib/utils/rss-parser'); +const nock = require('nock'); +require('../../lib/utils/request-wrapper'); +let check = () => {}; +const simpleResponse = ''; + +afterEach(() => { + delete process.env.PROXY_PROTOCOL; + delete process.env.PROXY_HOST; + delete process.env.PROXY_PORT; + delete process.env.PROXY_AUTH; + delete process.env.PROXY_URL_REGEX; + + nock.restore(); + nock.activate(); + check = () => {}; + + const http = require('http'); + const httpWrap = (func) => { + const origin = func; + return function(url, request) { + if (typeof url === 'object') { + check(url); + } else { + check(request); + } + return origin.apply(this, arguments); + }; + }; + http.get = httpWrap(http.get); + http.request = httpWrap(http.request); +}); + +describe('got', () => { + it('headers', async () => { + nock('http://rsshub.test') + .get('/test') + .times(2) + .reply(function() { + expect(this.req.headers['x-app']).toBe('RSSHub'); + return [200, simpleResponse]; + }); + + await got.get('http://rsshub.test/test'); + await parser.parseURL('http://rsshub.test/test'); + }); + + it('proxy socks', async () => { + process.env.PROXY_PROTOCOL = 'socks'; + process.env.PROXY_HOST = 'rsshub.proxy'; + process.env.PROXY_PORT = '2333'; + + jest.resetModules(); + require('../../lib/utils/request-wrapper'); + check = (request) => { + expect(request.agent.constructor.name).toBe('SocksProxyAgent'); + expect(request.agent.options.href).toBe('socks://rsshub.proxy:2333'); + }; + + nock('http://rsshub.test') + .get('/proxy') + .times(2) + .reply(200, simpleResponse); + + await got.get('http://rsshub.test/proxy'); + await parser.parseURL('http://rsshub.test/proxy'); + }); + + it('proxy http', async () => { + process.env.PROXY_PROTOCOL = 'http'; + process.env.PROXY_HOST = 'rsshub.proxy'; + process.env.PROXY_PORT = '2333'; + + jest.resetModules(); + require('../../lib/utils/request-wrapper'); + check = (request) => { + expect(request.agent.constructor.name).toBe('TunnelingAgent'); + expect(request.agent.options.proxy.host).toBe('rsshub.proxy'); + expect(request.agent.options.proxy.port).toBe(2333); + }; + + nock('http://rsshub.test') + .get('/proxy') + .times(2) + .reply(200, simpleResponse); + + await got.get('http://rsshub.test/proxy'); + await parser.parseURL('http://rsshub.test/proxy'); + }); + + it('proxy https', async () => { + process.env.PROXY_PROTOCOL = 'https'; + process.env.PROXY_HOST = 'rsshub.proxy'; + process.env.PROXY_PORT = '2333'; + + jest.resetModules(); + require('../../lib/utils/request-wrapper'); + check = (request) => { + expect(request.agent.constructor.name).toBe('TunnelingAgent'); + expect(request.agent.options.proxy.host).toBe('rsshub.proxy'); + expect(request.agent.options.proxy.port).toBe(2333); + }; + + nock('http://rsshub.test') + .get('/proxy') + .times(2) + .reply(200, simpleResponse); + + await got.get('http://rsshub.test/proxy'); + await parser.parseURL('http://rsshub.test/proxy'); + }); + + it('auth', async () => { + process.env.PROXY_AUTH = 'testtest'; + process.env.PROXY_PROTOCOL = 'socks'; + process.env.PROXY_HOST = 'rsshub.proxy'; + process.env.PROXY_PORT = '2333'; + + jest.resetModules(); + require('../../lib/utils/request-wrapper'); + + nock('http://rsshub.test') + .get('/auth') + .times(2) + .reply(function() { + expect(this.req.headers['proxy-authorization']).toBe('Basic testtest'); + return [200, simpleResponse]; + }); + + await got.get('http://rsshub.test/auth'); + await parser.parseURL('http://rsshub.test/auth'); + }); + + it('url_regex', async () => { + process.env.PROXY_URL_REGEX = 'url_regex'; + process.env.PROXY_PROTOCOL = 'socks'; + process.env.PROXY_HOST = 'rsshub.proxy'; + process.env.PROXY_PORT = '2333'; + + jest.resetModules(); + require('../../lib/utils/request-wrapper'); + check = (request) => { + if (request.path === '/url_regex') { + expect(request.agent.constructor.name).toBe('SocksProxyAgent'); + expect(request.agent.options.href).toBe('socks://rsshub.proxy:2333'); + } else if (request.path === '/proxy') { + expect(request.agent).toBe(undefined); + } + }; + + nock('http://rsshub.test') + .get('/url_regex') + .times(2) + .reply(() => [200, simpleResponse]); + nock('http://rsshub.test') + .get('/proxy') + .times(2) + .reply(() => [200, simpleResponse]); + + await got.get('http://rsshub.test/url_regex'); + await parser.parseURL('http://rsshub.test/url_regex'); + + await got.get('http://rsshub.test/proxy'); + await parser.parseURL('http://rsshub.test/proxy'); + }); +}); diff --git a/test/utils/rss-parser.js b/test/utils/rss-parser.js new file mode 100644 index 0000000000..b72763c5d1 --- /dev/null +++ b/test/utils/rss-parser.js @@ -0,0 +1,16 @@ +const parser = require('../../lib/utils/rss-parser'); +const config = require('../../lib/config'); +const nock = require('nock'); + +describe('got', () => { + it('headers', async () => { + nock('http://rsshub.test') + .get('/test') + .reply(function() { + expect(this.req.headers['user-agent']).toBe(config.ua); + return [200, '']; + }); + + await parser.parseURL('http://rsshub.test/test'); + }); +});