Add integration tests for requests with proxy param

This commit is contained in:
ngosang 2023-05-23 22:13:52 +02:00
parent efaa5f31b6
commit 3c97c9603a
5 changed files with 109 additions and 11 deletions

View File

@ -242,7 +242,7 @@ def _resolve_challenge(req: V1RequestBase, method: str) -> ChallengeResolutionT:
except FunctionTimedOut: except FunctionTimedOut:
raise Exception(f'Error solving the challenge. Timeout after {timeout} seconds.') raise Exception(f'Error solving the challenge. Timeout after {timeout} seconds.')
except Exception as e: except Exception as e:
raise Exception('Error solving the challenge. ' + str(e)) raise Exception('Error solving the challenge. ' + str(e).replace('\n', '\\n'))
finally: finally:
if not req.session and driver is not None: if not req.session and driver is not None:
driver.quit() driver.quit()

View File

@ -25,7 +25,8 @@ class SessionsStorage:
def __init__(self): def __init__(self):
self.sessions = {} self.sessions = {}
def create(self, session_id: Optional[str] = None, proxyconf: Optional[dict] = None, force_new: Optional[bool] = False) -> Tuple[Session, bool]: def create(self, session_id: Optional[str] = None, proxy: Optional[dict] = None,
force_new: Optional[bool] = False) -> Tuple[Session, bool]:
"""create creates new instance of WebDriver if necessary, """create creates new instance of WebDriver if necessary,
assign defined (or newly generated) session_id to the instance assign defined (or newly generated) session_id to the instance
and returns the session object. If a new session has been created and returns the session object. If a new session has been created
@ -44,7 +45,7 @@ class SessionsStorage:
if self.exists(session_id): if self.exists(session_id):
return self.sessions[session_id], False return self.sessions[session_id], False
driver = utils.get_webdriver(proxyconf=proxyconf) driver = utils.get_webdriver(proxy)
created_at = datetime.now() created_at = datetime.now()
session = Session(session_id, driver, created_at) session = Session(session_id, driver, created_at)

View File

@ -1,4 +1,5 @@
import unittest import unittest
from typing import Optional
from webtest import TestApp from webtest import TestApp
@ -7,7 +8,7 @@ import flaresolverr
import utils import utils
def _find_obj_by_key(key: str, value: str, _list: list) -> dict | None: def _find_obj_by_key(key: str, value: str, _list: list) -> Optional[dict]:
for obj in _list: for obj in _list:
if obj[key] == value: if obj[key] == value:
return obj return obj
@ -28,6 +29,8 @@ class TestFlareSolverr(unittest.TestCase):
cloudflare_blocked_url = "https://cpasbiens3.fr/index.php?do=search&subaction=search" cloudflare_blocked_url = "https://cpasbiens3.fr/index.php?do=search&subaction=search"
app = TestApp(flaresolverr.app) app = TestApp(flaresolverr.app)
# wait until the server is ready
app.get('/')
def test_wrong_endpoint(self): def test_wrong_endpoint(self):
res = self.app.get('/wrong', status=404) res = self.app.get('/wrong', status=404)
@ -261,10 +264,88 @@ class TestFlareSolverr(unittest.TestCase):
self.assertGreater(len(solution.cookies), 0) self.assertGreater(len(solution.cookies), 0)
self.assertIn("Chrome/", solution.userAgent) self.assertIn("Chrome/", solution.userAgent)
# todo: test Cmd 'request.get' should return OK with HTTP 'proxy' param def test_v1_endpoint_request_get_proxy_http_param(self):
# todo: test Cmd 'request.get' should return OK with HTTP 'proxy' param with credentials """
# todo: test Cmd 'request.get' should return OK with SOCKSv5 'proxy' param To configure TinyProxy in local:
# todo: test Cmd 'request.get' should fail with wrong 'proxy' param * sudo vim /etc/tinyproxy/tinyproxy.conf
* edit => LogFile "/tmp/tinyproxy.log"
* edit => Syslog Off
* sudo tinyproxy -d
* sudo tail -f /tmp/tinyproxy.log
"""
res = self.app.post_json('/v1', {
"cmd": "request.get",
"url": self.google_url,
"proxy": {
"url": self.proxy_url
}
})
self.assertEqual(res.status_code, 200)
body = V1ResponseBase(res.json)
self.assertEqual(STATUS_OK, body.status)
self.assertEqual("Challenge not detected!", body.message)
self.assertGreater(body.startTimestamp, 10000)
self.assertGreaterEqual(body.endTimestamp, body.startTimestamp)
self.assertEqual(utils.get_flaresolverr_version(), body.version)
solution = body.solution
self.assertIn(self.google_url, solution.url)
self.assertEqual(solution.status, 200)
self.assertIs(len(solution.headers), 0)
self.assertIn("<title>Google</title>", solution.response)
self.assertGreater(len(solution.cookies), 0)
self.assertIn("Chrome/", solution.userAgent)
def test_v1_endpoint_request_get_proxy_socks_param(self):
"""
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
"""
res = self.app.post_json('/v1', {
"cmd": "request.get",
"url": self.google_url,
"proxy": {
"url": self.proxy_socks_url
}
})
self.assertEqual(res.status_code, 200)
body = V1ResponseBase(res.json)
self.assertEqual(STATUS_OK, body.status)
self.assertEqual("Challenge not detected!", body.message)
self.assertGreater(body.startTimestamp, 10000)
self.assertGreaterEqual(body.endTimestamp, body.startTimestamp)
self.assertEqual(utils.get_flaresolverr_version(), body.version)
solution = body.solution
self.assertIn(self.google_url, solution.url)
self.assertEqual(solution.status, 200)
self.assertIs(len(solution.headers), 0)
self.assertIn("<title>Google</title>", solution.response)
self.assertGreater(len(solution.cookies), 0)
self.assertIn("Chrome/", solution.userAgent)
def test_v1_endpoint_request_get_proxy_wrong_param(self):
res = self.app.post_json('/v1', {
"cmd": "request.get",
"url": self.google_url,
"proxy": {
"url": "http://127.0.0.1:43210"
}
}, status=500)
self.assertEqual(res.status_code, 500)
body = V1ResponseBase(res.json)
self.assertEqual(STATUS_ERROR, body.status)
self.assertIn("Error: Error solving the challenge. Message: unknown error: net::ERR_PROXY_CONNECTION_FAILED",
body.message)
self.assertGreater(body.startTimestamp, 10000)
self.assertGreaterEqual(body.endTimestamp, body.startTimestamp)
self.assertEqual(utils.get_flaresolverr_version(), body.version)
def test_v1_endpoint_request_get_fail_timeout(self): def test_v1_endpoint_request_get_fail_timeout(self):
res = self.app.post_json('/v1', { res = self.app.post_json('/v1', {
@ -401,6 +482,20 @@ class TestFlareSolverr(unittest.TestCase):
self.assertEqual("Session created successfully.", body.message) self.assertEqual("Session created successfully.", body.message)
self.assertEqual(body.session, "test_create_session") self.assertEqual(body.session, "test_create_session")
def test_v1_endpoint_sessions_create_with_proxy(self):
res = self.app.post_json('/v1', {
"cmd": "sessions.create",
"proxy": {
"url": self.proxy_url
}
})
self.assertEqual(res.status_code, 200)
body = V1ResponseBase(res.json)
self.assertEqual(STATUS_OK, body.status)
self.assertEqual("Session created successfully.", body.message)
self.assertIsNotNone(body.session)
def test_v1_endpoint_sessions_list(self): def test_v1_endpoint_sessions_list(self):
self.app.post_json('/v1', { self.app.post_json('/v1', {
"cmd": "sessions.create", "cmd": "sessions.create",

View File

@ -39,6 +39,8 @@ def asset_cloudflare_solution(self, res, site_url, site_text):
class TestFlareSolverr(unittest.TestCase): class TestFlareSolverr(unittest.TestCase):
app = TestApp(flaresolverr.app) app = TestApp(flaresolverr.app)
# wait until the server is ready
app.get('/')
def test_v1_endpoint_request_get_cloudflare(self): def test_v1_endpoint_request_get_cloudflare(self):
sites_get = [ sites_get = [

View File

@ -36,7 +36,7 @@ def get_flaresolverr_version() -> str:
return FLARESOLVERR_VERSION return FLARESOLVERR_VERSION
def get_webdriver(proxyconf: dict=None) -> WebDriver: def get_webdriver(proxy: dict = None) -> WebDriver:
global PATCHED_DRIVER_PATH global PATCHED_DRIVER_PATH
logging.debug('Launching web browser...') logging.debug('Launching web browser...')
@ -55,8 +55,8 @@ def get_webdriver(proxyconf: dict=None) -> WebDriver:
options.add_argument('--ignore-certificate-errors') options.add_argument('--ignore-certificate-errors')
options.add_argument('--ignore-ssl-errors') options.add_argument('--ignore-ssl-errors')
if proxyconf: if proxy and 'url' in proxy:
proxy_url = proxyconf['url'] proxy_url = proxy['url']
logging.debug("Using webdriver proxy: %s", proxy_url) logging.debug("Using webdriver proxy: %s", proxy_url)
options.add_argument('--proxy-server=%s' % proxy_url) options.add_argument('--proxy-server=%s' % proxy_url)