From fbcc27fd6abfc35d399721ab084ea31851b9c021 Mon Sep 17 00:00:00 2001 From: Dimitri DO BAIRRO Date: Mon, 8 Nov 2021 18:54:03 +0100 Subject: [PATCH 1/6] feat(classes/providers/proxyrack/index.ts): manual strategy implemented --- src/classes/providers/proxyrack/index.ts | 27 ++++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/classes/providers/proxyrack/index.ts b/src/classes/providers/proxyrack/index.ts index 9bd7bc5..8f0a619 100644 --- a/src/classes/providers/proxyrack/index.ts +++ b/src/classes/providers/proxyrack/index.ts @@ -1,23 +1,23 @@ import { AxiosPromise, AxiosRequestConfig } from 'axios'; import * as HttpsProxyAgent from 'https-proxy-agent'; import { HttpProxyAgent } from 'http-proxy-agent'; -import { ICreateProxyConfig } from '../base/types'; +import { EStrategyMode, ICreateProxyConfig } from '../base/types'; import { replacer } from '../../../utils/replacer'; import { Base } from '../base'; -import { IProxyrackConfig } from './types'; +import { TProxyrackConfig } from './types'; /** * @description Proxyrack proxy provider. */ export class Proxyrack extends Base { - private readonly config: IProxyrackConfig; + private readonly config: TProxyrackConfig; private setIpInitialized: boolean; /** * @constructor - * @param {IProxyrackConfig} config + * @param {TProxyrackConfig} config */ - constructor(config: IProxyrackConfig) { + constructor(config: TProxyrackConfig) { super({ axiosConfig: config.axiosConfig }); this.config = config; @@ -34,7 +34,12 @@ export class Proxyrack extends Base { this.setIp(); } - return this.sendRequest(axiosRequestConfig); + if (this.config.strategy === EStrategyMode.CHANGE_IP_EVERY_REQUESTS) { + this.setIp(); + return this.sendRequest(axiosRequestConfig); + } else { + return this.sendRequest(axiosRequestConfig); + } } /** @@ -62,9 +67,17 @@ export class Proxyrack extends Base { password: this.config.proxy.password, }); + let port: number; + if (this.config.strategy === EStrategyMode.CHANGE_IP_EVERY_REQUESTS) { + port = this.config.proxy.port; + } else { + const randomArrayIndex: number = Math.floor(Math.random() * (this.config.proxy.ports.length + 1)); + port = this.config.proxy.ports[randomArrayIndex]; + } + const proxy = { host: this.config.proxy.host, - port: this.config.proxy.port, + port, auth, }; From 1fcf6583f62ba8fc26f588f40217470fda708530 Mon Sep 17 00:00:00 2001 From: Dimitri DO BAIRRO Date: Mon, 8 Nov 2021 18:54:25 +0100 Subject: [PATCH 2/6] feat(classes/providers/proxyrack/types.ts): manual strategy implemented --- src/classes/providers/proxyrack/types.ts | 35 ++++++++++++++++-------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/classes/providers/proxyrack/types.ts b/src/classes/providers/proxyrack/types.ts index ebe57df..1eaf8bc 100644 --- a/src/classes/providers/proxyrack/types.ts +++ b/src/classes/providers/proxyrack/types.ts @@ -1,21 +1,34 @@ import { AxiosRequestConfig } from 'axios'; -import { EStrategyMode, IProviderConfig } from '../base/types'; +import { EStrategyMode } from '../base/types'; -interface IProxyrackProviderConfig extends IProviderConfig { +type TProxyrackProviderConfigStategyChangeIpEveryRequest = { username: string; password: string; -} + host: string; + port: number; +}; + +type TProxyrackProviderConfigStategyManual = { + username: string; + password: string; + host: string; + ports: number[]; +}; -interface IProxyrackConfig { - proxy: IProxyrackProviderConfig; +interface IProxyrackCommonConfig { axiosConfig?: AxiosRequestConfig; - strategy?: TProxyrackStrategy; } -type TProxyrackStrategy = TProxyrackStrategyChangeIpEveryRequest; +interface IProxyrackConfigStategyChangeIpEveryRequest extends IProxyrackCommonConfig { + proxy: TProxyrackProviderConfigStategyChangeIpEveryRequest; + strategy: EStrategyMode.CHANGE_IP_EVERY_REQUESTS; +} -type TProxyrackStrategyChangeIpEveryRequest = { - mode: EStrategyMode.CHANGE_IP_EVERY_REQUESTS; -}; +interface IProxyrackConfigStategyManual extends IProxyrackCommonConfig { + proxy: TProxyrackProviderConfigStategyManual; + strategy: EStrategyMode.MANUAL; +} + +type TProxyrackConfig = IProxyrackConfigStategyChangeIpEveryRequest | IProxyrackConfigStategyManual; -export { IProxyrackConfig, TProxyrackStrategy, TProxyrackStrategyChangeIpEveryRequest }; +export { TProxyrackConfig, IProxyrackConfigStategyChangeIpEveryRequest, IProxyrackConfigStategyManual }; From 18acd6b58089a403a70de679c2099558e193d34f Mon Sep 17 00:00:00 2001 From: Dimitri DO BAIRRO Date: Mon, 8 Nov 2021 18:54:59 +0100 Subject: [PATCH 3/6] tests(__tests__/unit/proxyrack.ts): test case created --- __tests__/unit/proxyrack.ts | 174 ++++++++++++++++++++++++------------ 1 file changed, 115 insertions(+), 59 deletions(-) diff --git a/__tests__/unit/proxyrack.ts b/__tests__/unit/proxyrack.ts index de648b1..b374ad2 100644 --- a/__tests__/unit/proxyrack.ts +++ b/__tests__/unit/proxyrack.ts @@ -5,86 +5,140 @@ describe('Proxyrack', () => { const proxy = { username: 'tictactrip', password: 'secret', - host: 'megaproxy.rotating.proxyrack.net', - port: 222, }; - describe('#constructor', () => { - it('should set an axios default configuration (User-Agent header)', async () => { - const userAgent = - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36'; + describe('#strategy', () => { + describe('CHANGE_IP_EVERY_REQUESTS', () => { + const proxyrack: Proxyrack = new Proxyrack({ + proxy: { + ...proxy, + host: 'megaproxy.rotating.proxyrack.net', + port: 222, + }, + strategy: EStrategyMode.CHANGE_IP_EVERY_REQUESTS, + }); + const response1 = { - ip: '216.74.105.107', - country: 'BE', + ip: '184.174.62.231', + country: 'FR', asn: { asnum: 9009, org_name: 'M247 Ltd', }, geo: { - city: 'Brussels', - region: 'BRU', - region_name: 'Brussels Capital', - postal_code: '1000', - latitude: 50.8336, - longitude: 4.3337, - tz: 'Europe/Brussels', - lum_city: 'brussels', - lum_region: 'bru', + city: 'Paris', + region: 'IDF', + region_name: 'Île-de-France', + postal_code: '75014', + latitude: 48.8579, + longitude: 2.3491, + tz: 'Europe/Paris', + lum_city: 'paris', + lum_region: 'idf', }, }; - const request1Mock = nock('https://lumtest.com') - .get('/myip.json') - .matchHeader('User-Agent', userAgent) - .once() - .reply(200, response1); - - const proxyrack: Proxyrack = new Proxyrack({ - proxy, - axiosConfig: { - headers: { - 'User-Agent': userAgent, - }, + const response2 = { + ip: '178.171.89.101', + country: 'ES', + asn: { + asnum: 9009, + org_name: 'M247 Ltd', }, - }); + geo: { + city: 'Madrid', + region: 'MD', + region_name: 'Madrid', + postal_code: '28001', + latitude: 40.4167, + longitude: -3.6838, + tz: 'Europe/Madrid', + lum_city: 'madrid', + lum_region: 'md', + }, + }; - const { data } = await proxyrack.setIp().fetch({ - method: 'get', - baseURL: 'https://lumtest.com', - url: '/myip.json', - }); + describe('http', () => { + it('should change ip every request', async () => { + const request1Mock = nock('http://lumtest.com').get('/myip.json').once().reply(200, response1); + const request2Mock = nock('http://lumtest.com').get('/myip.json').once().reply(200, response2); - expect(data).toStrictEqual(response1); + const result1 = await proxyrack.fetch({ + method: 'get', + baseURL: 'http://lumtest.com', + url: '/myip.json', + }); - request1Mock.done(); - }); - }); + const result2 = await proxyrack.fetch({ + method: 'get', + baseURL: 'http://lumtest.com', + url: '/myip.json', + }); - describe('#setIp', () => { - let proxyrack: Proxyrack; + expect(result1.data).toStrictEqual(response1); + expect(result2.data).toStrictEqual(response2); - beforeEach(() => { - proxyrack = new Proxyrack({ proxy }); - }); + request1Mock.done(); + request2Mock.done(); + }); + }); - it('should create an agent', async () => { - const agent: Proxyrack = proxyrack.setIp(); + describe('https', () => { + it('should change ip every request', async () => { + const request1Mock = nock('https://lumtest.com').get('/myip.json').once().reply(200, response1); + const request2Mock = nock('https://lumtest.com').get('/myip.json').once().reply(200, response2); - expect(agent).toBeInstanceOf(Proxyrack); - expect(agent.axios.defaults.httpsAgent.proxy.host).toBe('megaproxy.rotating.proxyrack.net'); - expect(agent.axios.defaults.httpsAgent.proxy.port).toBe(222); - expect(agent.axios.defaults.httpsAgent.proxy.rejectUnauthorized).toBe(false); - expect(agent.axios.defaults.httpsAgent.proxy.auth).toMatch(new RegExp(`${proxy.username}:${proxy.password}`)); + const result1 = await proxyrack.fetch({ + method: 'get', + baseURL: 'https://lumtest.com', + url: '/myip.json', + }); + + const result2 = await proxyrack.fetch({ + method: 'get', + baseURL: 'https://lumtest.com', + url: '/myip.json', + }); + + expect(result1.data).toStrictEqual(response1); + expect(result2.data).toStrictEqual(response2); + + request1Mock.done(); + request2Mock.done(); + }); + }); }); - }); - describe('#strategy', () => { - describe('CHANGE_IP_EVERY_REQUESTS', () => { + describe('MANUAL', () => { const proxyrack: Proxyrack = new Proxyrack({ - proxy, - strategy: { - mode: EStrategyMode.CHANGE_IP_EVERY_REQUESTS, + proxy: { + ...proxy, + host: 'mixed.rotating.proxyrack.net', + ports: [ + 10000, 10001, 10002, 10003, 10004, 10005, 10006, 10007, 10008, 10009, 10010, 10011, 10012, 10013, 10014, + 10015, 10016, 10017, 10018, 10019, 10020, 10021, 10022, 10023, 10024, 10025, 10026, 10027, 10028, 10029, + 10030, 10031, 10032, 10033, 10034, 10035, 10036, 10037, 10038, 10039, 10040, 10041, 10042, 10043, 10044, + 10045, 10046, 10047, 10048, 10049, 10050, 10051, 10052, 10053, 10054, 10055, 10056, 10057, 10058, 10059, + 10060, 10061, 10062, 10063, 10064, 10065, 10066, 10067, 10068, 10069, 10070, 10071, 10072, 10073, 10074, + 10075, 10076, 10077, 10078, 10079, 10080, 10081, 10082, 10083, 10084, 10085, 10086, 10087, 10088, 10089, + 10090, 10091, 10092, 10093, 10094, 10095, 10096, 10097, 10098, 10099, 10100, 10101, 10102, 10103, 10104, + 10105, 10106, 10107, 10108, 10109, 10110, 10111, 10112, 10113, 10114, 10115, 10116, 10117, 10118, 10119, + 10120, 10121, 10122, 10123, 10124, 10125, 10126, 10127, 10128, 10129, 10130, 10131, 10132, 10133, 10134, + 10135, 10136, 10137, 10138, 10139, 10140, 10141, 10142, 10143, 10144, 10145, 10146, 10147, 10148, 10149, + 10150, 10151, 10152, 10153, 10154, 10155, 10156, 10157, 10158, 10159, 10160, 10161, 10162, 10163, 10164, + 10165, 10166, 10167, 10168, 10169, 10170, 10171, 10172, 10173, 10174, 10175, 10176, 10177, 10178, 10179, + 10180, 10181, 10182, 10183, 10184, 10185, 10186, 10187, 10188, 10189, 10190, 10191, 10192, 10193, 10194, + 10195, 10196, 10197, 10198, 10199, 10200, 10201, 10202, 10203, 10204, 10205, 10206, 10207, 10208, 10209, + 10210, 10211, 10212, 10213, 10214, 10215, 10216, 10217, 10218, 10219, 10220, 10221, 10222, 10223, 10224, + 10225, 10226, 10227, 10228, 10229, 10230, 10231, 10232, 10233, 10234, 10235, 10236, 10237, 10238, 10239, + 10240, 10241, 10242, 10243, 10244, 10245, 10246, 10247, 10248, 10249, 10250, 10251, 10252, 10253, 10254, + 10255, 10256, 10257, 10258, 10259, 10260, 10261, 10262, 10263, 10264, 10265, 10266, 10267, 10268, 10269, + 10270, 10271, 10272, 10273, 10274, 10275, 10276, 10277, 10278, 10279, 10280, 10281, 10282, 10283, 10284, + 10285, 10286, 10287, 10288, 10289, 10290, 10291, 10292, 10293, 10294, 10295, 10296, 10297, 10298, 10299, + 10300, 10301, 10302, 10303, 10304, 10305, 10306, 10307, 10308, 10309, 10310, 10311, 10312, + ], }, + strategy: EStrategyMode.MANUAL, }); const response1 = { @@ -128,7 +182,7 @@ describe('Proxyrack', () => { }; describe('http', () => { - it('should change ip every request', async () => { + it('should change ip on demand', async () => { const request1Mock = nock('http://lumtest.com').get('/myip.json').once().reply(200, response1); const request2Mock = nock('http://lumtest.com').get('/myip.json').once().reply(200, response2); @@ -138,6 +192,8 @@ describe('Proxyrack', () => { url: '/myip.json', }); + proxyrack.setIp(); + const result2 = await proxyrack.fetch({ method: 'get', baseURL: 'http://lumtest.com', @@ -153,7 +209,7 @@ describe('Proxyrack', () => { }); describe('https', () => { - it('should change ip every request', async () => { + it('should change ip on demand', async () => { const request1Mock = nock('https://lumtest.com').get('/myip.json').once().reply(200, response1); const request2Mock = nock('https://lumtest.com').get('/myip.json').once().reply(200, response2); From 4d60481d0560fbb4a553a0d0009771b22aee153f Mon Sep 17 00:00:00 2001 From: Dimitri DO BAIRRO Date: Mon, 8 Nov 2021 19:05:05 +0100 Subject: [PATCH 4/6] docs(README.md): documentation updated --- README.md | 266 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 223 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 6c37322..3f0dfb7 100644 --- a/README.md +++ b/README.md @@ -37,12 +37,12 @@ Create your instance: import { Luminati } from '@tictactrip/luminator'; const luminati: Luminati = new Luminati({ - proxy: { - username: 'tictactrip', - password: 'secret', - host: 'zproxy.lum-superproxy.io', - port: 22225, - } + proxy: { + username: 'tictactrip', + password: 'secret', + host: 'zproxy.lum-superproxy.io', + port: 22225, + } }); ``` @@ -70,7 +70,7 @@ const agent: Luminati = luminati.setIp({ countries: [ELuminatiCountry.FRANCE], s const agent: Luminati = luminati.setIp({ sessionId }); ``` -#### Strategy: Change ip every requests +#### Strategy: Change IP every requests This strategy aims to make a GET request with a **FR** or **PT** IP randomly every requests. @@ -78,22 +78,22 @@ This strategy aims to make a GET request with a **FR** or **PT** IP randomly eve import { Luminati, EStrategyMode, ELuminatiCountry } from "@tictactrip/luminator"; const luminati: Luminati = new Luminati({ - proxy: { - username: 'tictactrip', - password: 'secret', - host: 'zproxy.lum-superproxy.io', - port: 22225, - }, - strategy: { - mode: EStrategyMode.CHANGE_IP_EVERY_REQUESTS, - countries: [ELuminatiCountry.FRANCE, ELuminatiCountry.SPAIN], - }, + proxy: { + username: 'tictactrip', + password: 'secret', + host: 'zproxy.lum-superproxy.io', + port: 22225, + }, + strategy: { + mode: EStrategyMode.CHANGE_IP_EVERY_REQUESTS, + countries: [ELuminatiCountry.FRANCE, ELuminatiCountry.SPAIN], + }, }); const requestConfig = { - method: 'get', - baseURL: 'https://lumtest.com', - url: '/myip.json', + method: 'get', + baseURL: 'https://lumtest.com', + url: '/myip.json', } const response1 = await luminati.fetch(requestConfig); @@ -111,7 +111,7 @@ console.log(response2.data); "country": "FR", "asn": { "asnum": 9009, - "org_name": "M247 Ltd" + "org_name": "M247 Ltd" }, "geo": { "city": "Paris", @@ -157,16 +157,16 @@ console.log(response2.data); import { Shifter } from '@tictactrip/luminator'; const shifter: Shifter = new Shifter({ - proxy: { - host: '76.34.12.53', - port: 17664, - }, - strategy: { - mapping: { - fr: [17643, 17644], - es: [17645, 17646], + proxy: { + host: '76.34.12.53', + port: 17664, + }, + strategy: { + mapping: { + fr: [17643, 17644], + es: [17645, 17646], + }, }, - }, }); ``` @@ -182,29 +182,165 @@ const agent: Shifter = shifter.setIp(); const agent: Shifter = shifter.setIp({ countries: [EShifterCountry.FRANCE] }); ``` -#### Strategy: Change ip every requests +#### Strategy: Change IP every requests ```typescript import { Shifter, EStrategyMode, EShifterCountry } from "@tictactrip/luminator"; const shifter: Shifter = new Shifter({ - proxy: { - host: '76.34.12.53', - port: 17664, - }, - strategy: { - mode: EStrategyMode.CHANGE_IP_EVERY_REQUESTS, - mapping: { - fr: [17643, 17644], - es: [17645, 17646], + proxy: { + host: '76.34.12.53', + port: 17664, + }, + strategy: { + mode: EStrategyMode.CHANGE_IP_EVERY_REQUESTS, + mapping: { + fr: [17643, 17644], + es: [17645, 17646], + }, + }, +}); + +const requestConfig = { + method: 'get', + baseURL: 'https://lumtest.com', + url: '/myip.json', +} + +const response1 = await shifter.fetch(requestConfig); +const response2 = await shifter.fetch(requestConfig); + +console.log(response1.data); +console.log(response2.data); +``` + + + + + +### Proxyrack + +#### Strategy: Manual + +```typescript +import { Proxyrack } from '@tictactrip/luminator'; + +const proxyrack: Proxyrack = new Proxyrack({ + proxy: { + username: "tictactrip", + password: "secret", + host: 'mixed.rotating.proxyrack.net', + ports: [10000, 10001, 10002, 10003, 10004, 10005, 10006, 10007, 10008, 10009, 10010], }, + strategy: EStrategyMode.MANUAL, +}); + +const requestConfig = { + method: 'get', + baseURL: 'https://lumtest.com', + url: '/myip.json', +} + +const response1 = await proxyrack.fetch(requestConfig); +const response2 = await proxyrack.fetch(requestConfig); + +// Change IP +proxyrack.setIp(); + +const response3 = await proxyrack.fetch(requestConfig); + +console.log(response1.data); +console.log(response3.data); +console.log(response3.data) +``` + +**Response:** + +```json +{ + "ip": "184.174.62.231", + "country": "FR", + "asn": { + "asnum": 9009, + "org_name": "M247 Ltd" + }, + "geo": { + "city": "Paris", + "region": "IDF", + "region_name": "Île-de-France", + "postal_code": "75014", + "latitude": 48.8579, + "longitude": 2.3491, + "tz": "Europe/Paris", + "lum_city": "paris", + "lum_region": "idf" + } +} +``` + +```json +{ + "ip": "184.174.62.231", + "country": "FR", + "asn": { + "asnum": 9009, + "org_name": "M247 Ltd" }, + "geo": { + "city": "Paris", + "region": "IDF", + "region_name": "Île-de-France", + "postal_code": "75014", + "latitude": 48.8579, + "longitude": 2.3491, + "tz": "Europe/Paris", + "lum_city": "paris", + "lum_region": "idf" + } +} +``` + +```json +{ + "ip": "178.171.89.101", + "country": "ES", + "asn": { + "asnum": 9009, + "org_name": "M247 Ltd" + }, + "geo": { + "city": "Madrid", + "region": "MD", + "region_name": "Madrid", + "postal_code": "28001", + "latitude": 40.4167, + "longitude": -3.6838, + "tz": "Europe/Madrid", + "lum_city": "madrid", + "lum_region": "md" + } +} +``` + +#### Strategy: Change IP every requests + +```typescript +import { Shifter, EStrategyMode, EShifterCountry } from "@tictactrip/luminator"; + +const proxyrack: Proxyrack = new Proxyrack({ + proxy: { + username: "tictactrip", + password: "secret", + host: 'megaproxy.rotating.proxyrack.net', + port: 222, + }, + strategy: EStrategyMode.CHANGE_IP_EVERY_REQUESTS, }); const requestConfig = { - method: 'get', - baseURL: 'https://lumtest.com', - url: '/myip.json', + method: 'get', + baseURL: 'https://lumtest.com', + url: '/myip.json', } const response1 = await shifter.fetch(requestConfig); @@ -214,6 +350,50 @@ console.log(response1.data); console.log(response2.data); ``` +```json +{ + "ip": "184.174.62.231", + "country": "FR", + "asn": { + "asnum": 9009, + "org_name": "M247 Ltd" + }, + "geo": { + "city": "Paris", + "region": "IDF", + "region_name": "Île-de-France", + "postal_code": "75014", + "latitude": 48.8579, + "longitude": 2.3491, + "tz": "Europe/Paris", + "lum_city": "paris", + "lum_region": "idf" + } +} +``` + +```json +{ + "ip": "178.171.89.101", + "country": "ES", + "asn": { + "asnum": 9009, + "org_name": "M247 Ltd" + }, + "geo": { + "city": "Madrid", + "region": "MD", + "region_name": "Madrid", + "postal_code": "28001", + "latitude": 40.4167, + "longitude": -3.6838, + "tz": "Europe/Madrid", + "lum_city": "madrid", + "lum_region": "md" + } +} +``` + ## Scripts Run using yarn run `