mirror of
https://github.com/FlareSolverr/FlareSolverr.git
synced 2025-12-06 17:48:40 +01:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc6ac68e52 | ||
|
|
a9ab2569bc | ||
|
|
b1a6ad7688 | ||
|
|
642d67b927 | ||
|
|
c4ef6a472e | ||
|
|
a24b665bd1 | ||
|
|
6576e1908d |
@@ -5,8 +5,8 @@
|
|||||||
[](https://github.com/FlareSolverr/FlareSolverr/issues)
|
[](https://github.com/FlareSolverr/FlareSolverr/issues)
|
||||||
[](https://github.com/FlareSolverr/FlareSolverr/pulls)
|
[](https://github.com/FlareSolverr/FlareSolverr/pulls)
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=X5NJLLX5GLTV6&source=url)
|
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=X5NJLLX5GLTV6&source=url)
|
||||||
[](https://www.buymeacoffee.com/ngosang)
|
[](https://en.cryptobadges.io/donate/13Hcv77AdnFWEUZ9qUpoPBttQsUT7q9TTh)
|
||||||
[](https://en.cryptobadges.io/donate/13Hcv77AdnFWEUZ9qUpoPBttQsUT7q9TTh)
|
[](https://en.cryptobadges.io/donate/0x0D1549BbB00926BF3D92c1A8A58695e982f1BE2E)
|
||||||
|
|
||||||
FlareSolverr is a proxy server to bypass Cloudflare protection.
|
FlareSolverr is a proxy server to bypass Cloudflare protection.
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ session | Optional. Will send the request from and existing browser instance. If
|
|||||||
maxTimeout | Optional, default value 60000. Max timeout to solve the challenge in milliseconds.
|
maxTimeout | Optional, default value 60000. Max timeout to solve the challenge in milliseconds.
|
||||||
cookies | Optional. Will be used by the headless browser. Follow [this](https://github.com/puppeteer/puppeteer/blob/v3.3.0/docs/api.md#pagesetcookiecookies) format.
|
cookies | Optional. Will be used by the headless browser. Follow [this](https://github.com/puppeteer/puppeteer/blob/v3.3.0/docs/api.md#pagesetcookiecookies) format.
|
||||||
returnOnlyCookies | Optional, default false. Only returns the cookies. Response data, headers and other parts of the response are removed.
|
returnOnlyCookies | Optional, default false. Only returns the cookies. Response data, headers and other parts of the response are removed.
|
||||||
proxy | Optional, default disabled. Eg: `"proxy": {"url": "http://127.0.0.1:8888"}`. Authorization (username/password) is not supported.
|
proxy | Optional, default disabled. Eg: `"proxy": {"url": "http://127.0.0.1:8888"}`. You must include the proxy schema in the URL: `http://`, `socks4://` or `socks5://`. Authorization (username/password) is not supported.
|
||||||
|
|
||||||
:warning: If you want to use Cloudflare clearance cookie in your scripts, make sure you use the FlareSolverr User-Agent too. If they don't match you will see the challenge.
|
:warning: If you want to use Cloudflare clearance cookie in your scripts, make sure you use the FlareSolverr User-Agent too. If they don't match you will see the challenge.
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ This is the same as `request.get` but it takes one more param:
|
|||||||
|
|
||||||
Parameter | Notes
|
Parameter | Notes
|
||||||
|--|--|
|
|--|--|
|
||||||
postData | Must be a string with `application/x-www-form-urlencoded`. Eg: `postData": "a=b&c=d"`
|
postData | Must be a string with `application/x-www-form-urlencoded`. Eg: `a=b&c=d`
|
||||||
|
|
||||||
## Environment variables
|
## Environment variables
|
||||||
|
|
||||||
@@ -222,6 +222,7 @@ CAPTCHA_SOLVER | none | Captcha solving method. It is used when a captcha is enc
|
|||||||
TZ | UTC | Timezone used in the logs and the web browser. Example: `TZ=Europe/London`.
|
TZ | UTC | Timezone used in the logs and the web browser. Example: `TZ=Europe/London`.
|
||||||
HEADLESS | true | Only for debugging. To run the web browser in headless mode or visible.
|
HEADLESS | true | Only for debugging. To run the web browser in headless mode or visible.
|
||||||
BROWSER_TIMEOUT | 30000 | If you are experiencing errors/timeouts because your system is slow, you can try to increase this value. Remember to increase the `maxTimeout` parameter too.
|
BROWSER_TIMEOUT | 30000 | If you are experiencing errors/timeouts because your system is slow, you can try to increase this value. Remember to increase the `maxTimeout` parameter too.
|
||||||
|
TEST_URL | https://www.google.com | FlareSolverr makes a request on start to make sure the web browser is working. You can change that URL if it is blocked in your country.
|
||||||
PORT | 8191 | Listening port. You don't need to change this if you are running on Docker.
|
PORT | 8191 | Listening port. You don't need to change this if you are running on Docker.
|
||||||
HOST | 0.0.0.0 | Listening interface. You don't need to change this if you are running on Docker.
|
HOST | 0.0.0.0 | Listening interface. You don't need to change this if you are running on Docker.
|
||||||
|
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "flaresolverr",
|
"name": "flaresolverr",
|
||||||
"version": "2.0.2",
|
"version": "2.1.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "flaresolverr",
|
"name": "flaresolverr",
|
||||||
"version": "2.0.0",
|
"version": "2.0.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"await-timeout": "^1.1.1",
|
"await-timeout": "^1.1.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "flaresolverr",
|
"name": "flaresolverr",
|
||||||
"version": "2.0.2",
|
"version": "2.1.0",
|
||||||
"description": "Proxy server to bypass Cloudflare protection.",
|
"description": "Proxy server to bypass Cloudflare protection.",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./dist/server.js",
|
"start": "node ./dist/server.js",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import log from "../services/log";
|
|||||||
* This class contains the logic to solve protections provided by CloudFlare
|
* This class contains the logic to solve protections provided by CloudFlare
|
||||||
**/
|
**/
|
||||||
|
|
||||||
const BAN_SELECTORS = ['span[data-translate="error"]'];
|
const BAN_SELECTORS = ['.text-gray-600'];
|
||||||
const CHALLENGE_SELECTORS = ['#trk_jschal_js', '.ray_id', '.attack-box', '#cf-please-wait'];
|
const CHALLENGE_SELECTORS = ['#trk_jschal_js', '.ray_id', '.attack-box', '#cf-please-wait'];
|
||||||
const CAPTCHA_SELECTORS = ['input[name="cf_captcha_kind"]'];
|
const CAPTCHA_SELECTORS = ['input[name="cf_captcha_kind"]'];
|
||||||
|
|
||||||
|
|||||||
@@ -46,8 +46,9 @@ function buildExtraPrefsFirefox(proxy: Proxy): object {
|
|||||||
"startup.homepage_welcome_url": "about:blank",
|
"startup.homepage_welcome_url": "about:blank",
|
||||||
"startup.homepage_welcome_url.additional": "",
|
"startup.homepage_welcome_url.additional": "",
|
||||||
|
|
||||||
// Disable images to speed up load
|
// Detected !
|
||||||
"permissions.default.image": 2,
|
// // Disable images to speed up load
|
||||||
|
// "permissions.default.image": 2,
|
||||||
|
|
||||||
// Limit content processes to 1
|
// Limit content processes to 1
|
||||||
"dom.ipc.processCount": 1
|
"dom.ipc.processCount": 1
|
||||||
@@ -59,18 +60,35 @@ function buildExtraPrefsFirefox(proxy: Proxy): object {
|
|||||||
const port = parseInt(portStr);
|
const port = parseInt(portStr);
|
||||||
|
|
||||||
const proxyPrefs = {
|
const proxyPrefs = {
|
||||||
// Proxy configuration
|
"network.proxy.type": 1,
|
||||||
|
"network.proxy.share_proxy_settings": true
|
||||||
|
}
|
||||||
|
if (proxy.url.indexOf("socks") != -1) {
|
||||||
|
// SOCKSv4 & SOCKSv5
|
||||||
|
Object.assign(proxyPrefs, {
|
||||||
|
"network.proxy.socks": host,
|
||||||
|
"network.proxy.socks_port": port,
|
||||||
|
"network.proxy.socks_remote_dns": true
|
||||||
|
});
|
||||||
|
if (proxy.url.indexOf("socks4") != -1) {
|
||||||
|
Object.assign(proxyPrefs, {
|
||||||
|
"network.proxy.socks_version": 4
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Object.assign(proxyPrefs, {
|
||||||
|
"network.proxy.socks_version": 5
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// HTTP
|
||||||
|
Object.assign(proxyPrefs, {
|
||||||
"network.proxy.ftp": host,
|
"network.proxy.ftp": host,
|
||||||
"network.proxy.ftp_port": port,
|
"network.proxy.ftp_port": port,
|
||||||
"network.proxy.http": host,
|
"network.proxy.http": host,
|
||||||
"network.proxy.http_port": port,
|
"network.proxy.http_port": port,
|
||||||
"network.proxy.share_proxy_settings": true,
|
|
||||||
"network.proxy.socks": host,
|
|
||||||
"network.proxy.socks_port": port,
|
|
||||||
"network.proxy.socks_remote_dns": true,
|
|
||||||
"network.proxy.ssl": host,
|
"network.proxy.ssl": host,
|
||||||
"network.proxy.ssl_port": port,
|
"network.proxy.ssl_port": port
|
||||||
"network.proxy.type": 1
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// merge objects
|
// merge objects
|
||||||
@@ -93,16 +111,18 @@ export async function testWebBrowserInstallation(): Promise<void> {
|
|||||||
log.debug("FlareSolverr user home directory is OK: " + homeDir)
|
log.debug("FlareSolverr user home directory is OK: " + homeDir)
|
||||||
|
|
||||||
// test web browser
|
// test web browser
|
||||||
|
const testUrl = process.env.TEST_URL || "https://www.google.com";
|
||||||
|
log.debug("Test URL: " + testUrl)
|
||||||
const session = await create(null, {
|
const session = await create(null, {
|
||||||
oneTimeSession: true
|
oneTimeSession: true
|
||||||
})
|
})
|
||||||
const page = await session.browser.newPage()
|
const page = await session.browser.newPage()
|
||||||
await page.goto("https://www.google.com")
|
await page.goto(testUrl)
|
||||||
webBrowserUserAgent = await page.evaluate(() => navigator.userAgent)
|
webBrowserUserAgent = await page.evaluate(() => navigator.userAgent)
|
||||||
|
|
||||||
// replace Linux ARM user-agent because it's detected
|
// replace Linux ARM user-agent because it's detected
|
||||||
if (webBrowserUserAgent.toLocaleLowerCase().includes('linux arm')) {
|
if (["arm", "aarch64"].some(arch => webBrowserUserAgent.toLocaleLowerCase().includes('linux ' + arch))) {
|
||||||
webBrowserUserAgent = webBrowserUserAgent.replace(/linux arm[^;]+;/i, 'Linux x86_64;')
|
webBrowserUserAgent = webBrowserUserAgent.replace(/linux \w+;/i, 'Linux x86_64;')
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("FlareSolverr User-Agent: " + webBrowserUserAgent)
|
log.info("FlareSolverr User-Agent: " + webBrowserUserAgent)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ const sessions = require('../services/sessions');
|
|||||||
const version: string = 'v' + require('../../package.json').version
|
const version: string = 'v' + require('../../package.json').version
|
||||||
|
|
||||||
const proxyUrl = "http://127.0.0.1:8888"
|
const proxyUrl = "http://127.0.0.1:8888"
|
||||||
|
const proxySocksUrl = "socks5://127.0.0.1:1080"
|
||||||
const googleUrl = "https://www.google.com";
|
const googleUrl = "https://www.google.com";
|
||||||
const postUrl = "https://ptsv2.com/t/qv4j3-1634496523";
|
const postUrl = "https://ptsv2.com/t/qv4j3-1634496523";
|
||||||
const cfUrl = "https://pirateiro.com/torrents/?search=harry";
|
const cfUrl = "https://pirateiro.com/torrents/?search=harry";
|
||||||
@@ -221,7 +222,7 @@ describe("Test '/v1' path", () => {
|
|||||||
expect(solution.userAgent).toBe(null)
|
expect(solution.userAgent).toBe(null)
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Cmd 'request.get' should return OK with 'proxy' param", async () => {
|
test("Cmd 'request.get' should return OK with HTTP 'proxy' param", async () => {
|
||||||
/*
|
/*
|
||||||
To configure TinyProxy in local:
|
To configure TinyProxy in local:
|
||||||
* sudo vim /etc/tinyproxy/tinyproxy.conf
|
* sudo vim /etc/tinyproxy/tinyproxy.conf
|
||||||
@@ -249,7 +250,7 @@ describe("Test '/v1' path", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// todo: credentials are not working
|
// todo: credentials are not working
|
||||||
test.skip("Cmd 'request.get' should return OK with 'proxy' param with credentials", async () => {
|
test.skip("Cmd 'request.get' should return OK with HTTP 'proxy' param with credentials", async () => {
|
||||||
/*
|
/*
|
||||||
To configure TinyProxy in local:
|
To configure TinyProxy in local:
|
||||||
* sudo vim /etc/tinyproxy/tinyproxy.conf
|
* sudo vim /etc/tinyproxy/tinyproxy.conf
|
||||||
@@ -279,6 +280,32 @@ describe("Test '/v1' path", () => {
|
|||||||
expect(solution.status).toContain(200)
|
expect(solution.status).toContain(200)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("Cmd 'request.get' should return OK with SOCKSv5 'proxy' param", async () => {
|
||||||
|
/*
|
||||||
|
To configure Dante in local:
|
||||||
|
* https://linuxhint.com/set-up-a-socks5-proxy-on-ubuntu-with-dante/
|
||||||
|
* sudo vim /etc/sockd.conf
|
||||||
|
* sudo systemctl restart sockd.service
|
||||||
|
* curl --socks5 socks5://127.0.0.1:1080 https://www.google.com
|
||||||
|
*/
|
||||||
|
const payload = {
|
||||||
|
"cmd": "request.get",
|
||||||
|
"url": googleUrl,
|
||||||
|
"proxy": {
|
||||||
|
"url": proxySocksUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const response: Response = await request(app).post("/v1").send(payload);
|
||||||
|
expect(response.statusCode).toBe(200);
|
||||||
|
|
||||||
|
const apiResponse: V1ResponseSolution = response.body;
|
||||||
|
expect(apiResponse.status).toBe("ok");
|
||||||
|
|
||||||
|
const solution = apiResponse.solution;
|
||||||
|
expect(solution.url).toContain(googleUrl)
|
||||||
|
expect(solution.status).toBe(200);
|
||||||
|
});
|
||||||
|
|
||||||
test("Cmd 'request.get' should fail with wrong 'proxy' param", async () => {
|
test("Cmd 'request.get' should fail with wrong 'proxy' param", async () => {
|
||||||
const payload = {
|
const payload = {
|
||||||
"cmd": "request.get",
|
"cmd": "request.get",
|
||||||
|
|||||||
Reference in New Issue
Block a user