mirror of
https://github.com/FlareSolverr/FlareSolverr.git
synced 2025-07-23 10:30:08 +00:00
Merge 668e0aeca1e3dbe20dc13d3431b9d9181fb84a90 into 3e51ac11889bc4e1b577e4cedce62ed7c8c056b8
This commit is contained in:
commit
d3ba9a5907
@ -11,3 +11,5 @@ websockets==11.0.3
|
||||
xvfbwrapper==0.2.9; platform_system != "Windows"
|
||||
# only required for windows
|
||||
pefile==2023.2.7; platform_system == "Windows"
|
||||
|
||||
selenium_fetch
|
||||
|
@ -19,6 +19,7 @@ class ChallengeResolutionT:
|
||||
status: str = None
|
||||
message: str = None
|
||||
result: ChallengeResolutionResultT = None
|
||||
response: str = None
|
||||
|
||||
def __init__(self, _dict):
|
||||
self.__dict__.update(_dict)
|
||||
@ -39,6 +40,7 @@ class V1RequestBase(object):
|
||||
|
||||
# V1Request
|
||||
url: str = None
|
||||
contentType: str = None
|
||||
postData: str = None
|
||||
returnOnlyCookies: bool = None
|
||||
download: bool = None # deprecated v2.0.0, not used
|
||||
|
@ -1,3 +1,4 @@
|
||||
import json
|
||||
import logging
|
||||
import platform
|
||||
import sys
|
||||
@ -9,12 +10,13 @@ from urllib.parse import unquote, quote
|
||||
from func_timeout import FunctionTimedOut, func_timeout
|
||||
from selenium.common import TimeoutException
|
||||
from selenium.webdriver.chrome.webdriver import WebDriver
|
||||
from selenium.webdriver.common.action_chains import ActionChains
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
from selenium.webdriver.support.expected_conditions import (
|
||||
presence_of_element_located, staleness_of, title_is)
|
||||
from selenium.webdriver.common.action_chains import ActionChains
|
||||
from selenium.webdriver.support.wait import WebDriverWait
|
||||
from selenium_fetch import fetch, Options
|
||||
|
||||
import utils
|
||||
from dtos import (STATUS_ERROR, STATUS_OK, ChallengeResolutionResultT,
|
||||
@ -148,6 +150,8 @@ def _cmd_request_get(req: V1RequestBase) -> V1ResponseBase:
|
||||
raise Exception("Request parameter 'url' is mandatory in 'request.get' command.")
|
||||
if req.postData is not None:
|
||||
raise Exception("Cannot use 'postBody' when sending a GET request.")
|
||||
if req.contentType is not None:
|
||||
raise Exception("Cannot use 'contentType' when sending a GET request.")
|
||||
if req.returnRawHtml is not None:
|
||||
logging.warning("Request parameter 'returnRawHtml' was removed in FlareSolverr v2.")
|
||||
if req.download is not None:
|
||||
@ -165,6 +169,8 @@ def _cmd_request_post(req: V1RequestBase) -> V1ResponseBase:
|
||||
# do some validations
|
||||
if req.postData is None:
|
||||
raise Exception("Request parameter 'postData' is mandatory in 'request.post' command.")
|
||||
if req.contentType is None:
|
||||
raise Exception("Request parameter 'contentType' is mandatory in 'request.post' command.")
|
||||
if req.returnRawHtml is not None:
|
||||
logging.warning("Request parameter 'returnRawHtml' was removed in FlareSolverr v2.")
|
||||
if req.download is not None:
|
||||
@ -178,6 +184,23 @@ def _cmd_request_post(req: V1RequestBase) -> V1ResponseBase:
|
||||
return res
|
||||
|
||||
|
||||
def _cmd_request_postJSON(req: V1RequestBase) -> V1ResponseBase:
|
||||
# do some validations
|
||||
if req.postData is None:
|
||||
raise Exception("Request parameter 'postData' is mandatory in 'request.post' command.")
|
||||
if req.returnRawHtml is not None:
|
||||
logging.warning("Request parameter 'returnRawHtml' was removed in FlareSolverr v2.")
|
||||
if req.download is not None:
|
||||
logging.warning("Request parameter 'download' was removed in FlareSolverr v2.")
|
||||
|
||||
challenge_res = _resolve_challenge(req, 'POSTJSON')
|
||||
res = V1ResponseBase({})
|
||||
res.status = challenge_res.status
|
||||
res.message = challenge_res.message
|
||||
res.solution = challenge_res.result
|
||||
return res
|
||||
|
||||
|
||||
def _cmd_sessions_create(req: V1RequestBase) -> V1ResponseBase:
|
||||
logging.debug("Creating new session...")
|
||||
|
||||
@ -291,7 +314,7 @@ def _evil_logic(req: V1RequestBase, driver: WebDriver, method: str) -> Challenge
|
||||
# navigate to the page
|
||||
logging.debug(f'Navigating to... {req.url}')
|
||||
if method == 'POST':
|
||||
_post_request(req, driver)
|
||||
res.response = _post_request(req, driver)
|
||||
else:
|
||||
driver.get(req.url)
|
||||
|
||||
@ -303,7 +326,7 @@ def _evil_logic(req: V1RequestBase, driver: WebDriver, method: str) -> Challenge
|
||||
driver.add_cookie(cookie)
|
||||
# reload the page
|
||||
if method == 'POST':
|
||||
_post_request(req, driver)
|
||||
res.response = _post_request(req, driver)
|
||||
else:
|
||||
driver.get(req.url)
|
||||
|
||||
@ -397,31 +420,42 @@ def _evil_logic(req: V1RequestBase, driver: WebDriver, method: str) -> Challenge
|
||||
|
||||
|
||||
def _post_request(req: V1RequestBase, driver: WebDriver):
|
||||
post_form = f'<form id="hackForm" action="{req.url}" method="POST">'
|
||||
query_string = req.postData if req.postData[0] != '?' else req.postData[1:]
|
||||
pairs = query_string.split('&')
|
||||
for pair in pairs:
|
||||
parts = pair.split('=')
|
||||
# noinspection PyBroadException
|
||||
try:
|
||||
name = unquote(parts[0])
|
||||
except Exception:
|
||||
name = parts[0]
|
||||
if name == 'submit':
|
||||
continue
|
||||
# noinspection PyBroadException
|
||||
try:
|
||||
value = unquote(parts[1])
|
||||
except Exception:
|
||||
value = parts[1]
|
||||
post_form += f'<input type="text" name="{escape(quote(name))}" value="{escape(quote(value))}"><br>'
|
||||
post_form += '</form>'
|
||||
html_content = f"""
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
{post_form}
|
||||
<script>document.getElementById('hackForm').submit();</script>
|
||||
</body>
|
||||
</html>"""
|
||||
driver.get("data:text/html;charset=utf-8,{html_content}".format(html_content=html_content))
|
||||
if req.contentType == 'application/x-www-form-urlencoded':
|
||||
post_form = f'<form id="hackForm" action="{req.url}" method="POST">'
|
||||
query_string = req.postData if req.postData[0] != '?' else req.postData[1:]
|
||||
pairs = query_string.split('&')
|
||||
for pair in pairs:
|
||||
parts = pair.split('=')
|
||||
# noinspection PyBroadException
|
||||
try:
|
||||
name = unquote(parts[0])
|
||||
except Exception:
|
||||
name = parts[0]
|
||||
if name == 'submit':
|
||||
continue
|
||||
# noinspection PyBroadException
|
||||
try:
|
||||
value = unquote(parts[1])
|
||||
except Exception:
|
||||
value = parts[1]
|
||||
post_form += f'<input type="text" name="{escape(quote(name))}" value="{escape(quote(value))}"><br>'
|
||||
post_form += '</form>'
|
||||
html_content = f"""
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
{post_form}
|
||||
<script>document.getElementById('hackForm').submit();</script>
|
||||
</body>
|
||||
</html>"""
|
||||
driver.get("data:text/html;charset=utf-8,{html_content}".format(html_content=html_content))
|
||||
return "Success"
|
||||
elif req.contentType == 'application/json':
|
||||
post_data = json.loads(unquote(req.postData))
|
||||
options = Options(method="POST", body=post_data)
|
||||
logging.debug(f"Request => POST /v1 options: {utils.object_to_dict(options)}")
|
||||
response = fetch(driver, req.url, options)
|
||||
logging.debug(f"Response => POST /v1 response: {utils.object_to_dict(response)}")
|
||||
return response.text
|
||||
else:
|
||||
raise Exception(f"Request parameter 'contentType' = '{req.contentType}' is invalid.")
|
||||
|
Loading…
x
Reference in New Issue
Block a user