mirror of
https://github.com/FlareSolverr/FlareSolverr.git
synced 2025-06-08 04:25:25 +00:00
Implement request.post method for Firefox
This commit is contained in:
parent
a5b3e08e1f
commit
ccfe21c15a
@ -206,7 +206,7 @@ This is the same as `request.get` but it takes one more param:
|
|||||||
|
|
||||||
Parameter | Notes
|
Parameter | Notes
|
||||||
|--|--|
|
|--|--|
|
||||||
postData | Must be a string. If you want to POST a form with format `application/x-www-form-urlencoded`.
|
postData | Must be a string with `application/x-www-form-urlencoded`. Eg: `postData": "a=b&c=d"`
|
||||||
|
|
||||||
## Environment variables
|
## Environment variables
|
||||||
|
|
||||||
|
@ -120,16 +120,6 @@ export default async function resolveChallenge(url: string, page: Page, response
|
|||||||
{
|
{
|
||||||
throw new Error('No challenge selectors found, unable to proceed.')
|
throw new Error('No challenge selectors found, unable to proceed.')
|
||||||
} else {
|
} else {
|
||||||
// reload the page to make sure we get the real response
|
|
||||||
// do not use page.reload() to avoid #162 #143
|
|
||||||
response = await page.goto(url, { waitUntil: 'domcontentloaded' })
|
|
||||||
|
|
||||||
await page.content()
|
|
||||||
// log.info(response.headers())
|
|
||||||
// while (response.headers() == null) {
|
|
||||||
// await page.waitFor(1000)
|
|
||||||
// }
|
|
||||||
|
|
||||||
log.info('Challenge solved.');
|
log.info('Challenge solved.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ async function resolveChallenge(params: V1Request, session: SessionsCacheItem):
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.debug(`Navigating to... ${params.url}`)
|
log.debug(`Navigating to... ${params.url}`)
|
||||||
let response: Response = await page.goto(params.url, { waitUntil: 'domcontentloaded' })
|
let response: Response = await gotoPage(params, page);
|
||||||
|
|
||||||
// set cookies
|
// set cookies
|
||||||
if (params.cookies) {
|
if (params.cookies) {
|
||||||
@ -71,13 +71,13 @@ async function resolveChallenge(params: V1Request, session: SessionsCacheItem):
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
// reload the page
|
// reload the page
|
||||||
response = await page.goto(params.url, { waitUntil: 'domcontentloaded' })
|
response = await gotoPage(params, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
// log html in debug mode
|
// log html in debug mode
|
||||||
log.html(await page.content())
|
log.html(await page.content())
|
||||||
|
|
||||||
// Detect protection services and solve challenges
|
// detect protection services and solve challenges
|
||||||
try {
|
try {
|
||||||
response = await cloudflareProvider(params.url, page, response);
|
response = await cloudflareProvider(params.url, page, response);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -85,6 +85,9 @@ async function resolveChallenge(params: V1Request, session: SessionsCacheItem):
|
|||||||
message = "Cloudflare " + e.toString();
|
message = "Cloudflare " + e.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reload the page to be sure we get the real page
|
||||||
|
response = await gotoPage(params, page);
|
||||||
|
|
||||||
const payload: ChallengeResolutionT = {
|
const payload: ChallengeResolutionT = {
|
||||||
status,
|
status,
|
||||||
message,
|
message,
|
||||||
@ -117,6 +120,55 @@ async function resolveChallenge(params: V1Request, session: SessionsCacheItem):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function gotoPage(params: V1Request, page: Page): Promise<Response> {
|
||||||
|
const response = await page.goto(params.url, { waitUntil: 'domcontentloaded' });
|
||||||
|
if (params.method == 'POST') {
|
||||||
|
// post hack
|
||||||
|
await page.setContent(
|
||||||
|
`
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function parseQuery(queryString) {
|
||||||
|
var query = {};
|
||||||
|
var pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');
|
||||||
|
for (var i = 0; i < pairs.length; i++) {
|
||||||
|
var pair = pairs[i].split('=');
|
||||||
|
query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');
|
||||||
|
}
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
const form = document.createElement('form');
|
||||||
|
form.method = 'POST';
|
||||||
|
form.action = '${params.url}';
|
||||||
|
|
||||||
|
const params = parseQuery('${params.postData}');
|
||||||
|
for (const key in params) {
|
||||||
|
if (params.hasOwnProperty(key)) {
|
||||||
|
const hiddenField = document.createElement('input');
|
||||||
|
hiddenField.type = 'hidden';
|
||||||
|
hiddenField.name = key;
|
||||||
|
hiddenField.value = params[key];
|
||||||
|
form.appendChild(hiddenField);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.appendChild(form);
|
||||||
|
form.submit();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
await page.waitFor(2000);
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
export async function browserRequest(params: V1Request): Promise<ChallengeResolutionT> {
|
export async function browserRequest(params: V1Request): Promise<ChallengeResolutionT> {
|
||||||
const oneTimeSession = params.session === undefined;
|
const oneTimeSession = params.session === undefined;
|
||||||
|
|
||||||
@ -136,7 +188,6 @@ export async function browserRequest(params: V1Request): Promise<ChallengeResolu
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// const page = await setupPage(params, session.browser)
|
|
||||||
return await resolveChallengeWithTimeout(params, session)
|
return await resolveChallengeWithTimeout(params, session)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw Error("Unable to process browser request. Error: " + error)
|
throw Error("Unable to process browser request. Error: " + error)
|
||||||
|
@ -9,14 +9,17 @@ const app = require("../app");
|
|||||||
const version: string = require('../../package.json').version
|
const version: string = require('../../package.json').version
|
||||||
|
|
||||||
const googleUrl = "https://www.google.com";
|
const googleUrl = "https://www.google.com";
|
||||||
const cfUrl = "https://pirateiro.com/torrents/?search=s";
|
const postUrl = "https://ptsv2.com/t/qv4j3-1634496523";
|
||||||
|
const cfUrl = "https://pirateiro.com/torrents/?search=harry";
|
||||||
const cfCaptchaUrl = "https://idope.se"
|
const cfCaptchaUrl = "https://idope.se"
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
// Init session
|
||||||
|
await testWebBrowserInstallation();
|
||||||
|
});
|
||||||
|
|
||||||
describe("Test '/' path", () => {
|
describe("Test '/' path", () => {
|
||||||
test("GET method should return OK ", async () => {
|
test("GET method should return OK ", async () => {
|
||||||
// Init session
|
|
||||||
await testWebBrowserInstallation();
|
|
||||||
|
|
||||||
const response: Response = await request(app).get("/");
|
const response: Response = await request(app).get("/");
|
||||||
expect(response.statusCode).toBe(200);
|
expect(response.statusCode).toBe(200);
|
||||||
expect(response.body.msg).toBe("FlareSolverr is ready!");
|
expect(response.body.msg).toBe("FlareSolverr is ready!");
|
||||||
@ -62,7 +65,7 @@ describe("Test '/v1' path", () => {
|
|||||||
expect(apiResponse.status).toBe("error");
|
expect(apiResponse.status).toBe("error");
|
||||||
expect(apiResponse.message).toBe("Error: The command 'request.bad' is invalid.");
|
expect(apiResponse.message).toBe("Error: The command 'request.bad' is invalid.");
|
||||||
expect(apiResponse.startTimestamp).toBeGreaterThan(1000);
|
expect(apiResponse.startTimestamp).toBeGreaterThan(1000);
|
||||||
expect(apiResponse.endTimestamp).toBeGreaterThan(apiResponse.startTimestamp);
|
expect(apiResponse.endTimestamp).toBeGreaterThanOrEqual(apiResponse.startTimestamp);
|
||||||
expect(apiResponse.version).toBe(version);
|
expect(apiResponse.version).toBe(version);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -226,6 +229,62 @@ describe("Test '/v1' path", () => {
|
|||||||
expect(solution.userAgent).toContain("Firefox/")
|
expect(solution.userAgent).toContain("Firefox/")
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("Cmd 'request.post' should return OK with no Cloudflare", async () => {
|
||||||
|
const payload = {
|
||||||
|
"cmd": "request.post",
|
||||||
|
"url": postUrl + '/post',
|
||||||
|
"postData": "param1=value1¶m2=value2"
|
||||||
|
}
|
||||||
|
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");
|
||||||
|
expect(apiResponse.message).toBe("");
|
||||||
|
expect(apiResponse.startTimestamp).toBeGreaterThan(1000);
|
||||||
|
expect(apiResponse.endTimestamp).toBeGreaterThan(apiResponse.startTimestamp);
|
||||||
|
expect(apiResponse.version).toBe(version);
|
||||||
|
|
||||||
|
const solution = apiResponse.solution;
|
||||||
|
expect(solution.url).toContain(postUrl)
|
||||||
|
expect(solution.status).toBe(200);
|
||||||
|
expect(Object.keys(solution.headers).length).toBeGreaterThan(0)
|
||||||
|
expect(solution.response).toContain(" I hope you have a lovely day!")
|
||||||
|
expect(Object.keys(solution.cookies).length).toBe(0)
|
||||||
|
expect(solution.userAgent).toContain("Firefox/")
|
||||||
|
|
||||||
|
// check that we sent the date
|
||||||
|
const payload2 = {
|
||||||
|
"cmd": "request.get",
|
||||||
|
"url": postUrl
|
||||||
|
}
|
||||||
|
const response2: Response = await request(app).post("/v1").send(payload2);
|
||||||
|
expect(response2.statusCode).toBe(200);
|
||||||
|
|
||||||
|
const apiResponse2: V1ResponseSolution = response2.body;
|
||||||
|
expect(apiResponse2.status).toBe("ok");
|
||||||
|
|
||||||
|
const solution2 = apiResponse2.solution;
|
||||||
|
expect(solution2.status).toBe(200);
|
||||||
|
expect(solution2.response).toContain(new Date().toISOString().split(':')[0].replace('T', ' '))
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Cmd 'request.post' should fail without 'postData' param", async () => {
|
||||||
|
const payload = {
|
||||||
|
"cmd": "request.post",
|
||||||
|
"url": googleUrl
|
||||||
|
}
|
||||||
|
const response: Response = await request(app).post("/v1").send(payload);
|
||||||
|
expect(response.statusCode).toBe(500);
|
||||||
|
|
||||||
|
const apiResponse: V1ResponseBase = response.body;
|
||||||
|
expect(apiResponse.status).toBe("error");
|
||||||
|
expect(apiResponse.message).toBe("Error: Must send param \"postBody\" when sending a POST request.");
|
||||||
|
expect(apiResponse.startTimestamp).toBeGreaterThan(1000);
|
||||||
|
expect(apiResponse.endTimestamp).toBeGreaterThanOrEqual(apiResponse.startTimestamp);
|
||||||
|
expect(apiResponse.version).toBe(version);
|
||||||
|
});
|
||||||
|
|
||||||
test("Cmd 'sessions.create' should return OK", async () => {
|
test("Cmd 'sessions.create' should return OK", async () => {
|
||||||
const payload = {
|
const payload = {
|
||||||
"cmd": "sessions.create"
|
"cmd": "sessions.create"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user