From a841d67745a1cb24595f97584b4cdfabb9710b96 Mon Sep 17 00:00:00 2001 From: ngosang Date: Mon, 18 Oct 2021 11:13:49 +0200 Subject: [PATCH] Build native packages with Firefox --- README.md | 5 ++-- build-binaries.js | 55 +++++++++++++++++++++++++++++----------- package-lock.json | 2 +- package.json | 2 +- src/services/sessions.ts | 5 ++-- 5 files changed, 47 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index a7a01a9..411b515 100644 --- a/README.md +++ b/README.md @@ -68,8 +68,9 @@ This is the recommended way for Windows users. This is the recommended way for macOS users and for developers. * Install [NodeJS](https://nodejs.org/). * Clone this repository and open a shell in that path. -* Run `PUPPETEER_PRODUCT=firefox npm install` command to install FlareSolverr dependencies. -* Run `PUPPETEER_PRODUCT=firefox node node_modules/puppeteer/install.js` to install Firefox. +* Run `export PUPPETEER_PRODUCT=firefox` (Linux/macOS) or `set PUPPETEER_PRODUCT=firefox` (Windows). +* Run `npm install` command to install FlareSolverr dependencies. +* Run `node node_modules/puppeteer/install.js` to install Firefox. * Run `npm run build` command to compile TypeScript code. * Run `npm start` command to start FlareSolverr. diff --git a/build-binaries.js b/build-binaries.js index 5524f49..fac1b47 100644 --- a/build-binaries.js +++ b/build-binaries.js @@ -2,16 +2,39 @@ const fs = require('fs') const path = require('path') const { execSync } = require('child_process') const archiver = require('archiver') +const https = require('https') const puppeteer = require('puppeteer') const version = 'v' + require('./package.json').version; -// todo: package firefox +function getFirefoxNightlyVersion() { + const firefoxVersions = 'https://product-details.mozilla.org/1.0/firefox_versions.json'; + return new Promise((resolve, reject) => { + let data = ''; + https + .get(firefoxVersions, (r) => { + if (r.statusCode >= 400) + return reject(new Error(`Got status code ${r.statusCode}`)); + r.on('data', (chunk) => { + data += chunk; + }); + r.on('end', () => { + try { + const versions = JSON.parse(data); + return resolve(versions.FIREFOX_NIGHTLY); + } catch { + return reject(new Error('Firefox version not found')); + } + }); + }) + .on('error', reject); + }); +} + (async () => { const builds = [ { platform: 'linux', - version: 756035, - chromeFolder: 'chrome-linux', + firefoxFolder: 'firefox', fsExec: 'flaresolverr-linux', fsZipExec: 'flaresolverr', fsZipName: 'linux-x64', @@ -19,18 +42,16 @@ const version = 'v' + require('./package.json').version; }, { platform: 'win64', - version: 756035, - chromeFolder: 'chrome-win', + firefoxFolder: 'firefox', fsExec: 'flaresolverr-win.exe', fsZipExec: 'flaresolverr.exe', fsZipName: 'windows-x64', fsLicenseName: 'LICENSE.txt' } - // todo: this is working but changes are required in sessions.ts to find chrome path + // todo: this has to be build in macOS (hdiutil is required). changes required in sessions.ts too // { // platform: 'mac', - // version: 756035, - // chromeFolder: 'chrome-mac', + // firefoxFolder: 'firefox', // fsExec: 'flaresolverr-macos', // fsZipExec: 'flaresolverr', // fsZipName: 'macos', @@ -43,20 +64,24 @@ const version = 'v' + require('./package.json').version; if (fs.existsSync('bin')) { fs.rmSync('bin', { recursive: true }) } - execSync('pkg -t node14-win-x64,node14-linux-x64 --out-path bin .') - // execSync('pkg -t node14-win-x64,node14-mac-x64,node14-linux-x64 --out-path bin .') + execSync('./node_modules/.bin/pkg -t node14-win-x64,node14-linux-x64 --out-path bin .') + // execSync('./node_modules/.bin/pkg -t node14-win-x64,node14-mac-x64,node14-linux-x64 --out-path bin .') - // download Chrome and zip together + // get firefox revision + const revision = await getFirefoxNightlyVersion(); + + // download firefox and zip together for (const os of builds) { console.log('Building ' + os.fsZipName + ' artifact') - // download chrome - console.log('Downloading Chrome...') + // download firefox + console.log(`Downloading firefox ${revision} for ${os.platform} ...`) const f = puppeteer.createBrowserFetcher({ + product: 'firefox', platform: os.platform, path: path.join(__dirname, 'bin', 'puppeteer') }) - await f.download(os.version) + await f.download(revision) // compress in zip console.log('Compressing zip file...') @@ -76,7 +101,7 @@ const version = 'v' + require('./package.json').version; archive.file('LICENSE', { name: 'flaresolverr/' + os.fsLicenseName }) archive.file('bin/' + os.fsExec, { name: 'flaresolverr/' + os.fsZipExec }) - archive.directory('bin/puppeteer/' + os.platform + '-' + os.version + '/' + os.chromeFolder, 'flaresolverr/chrome') + archive.directory('bin/puppeteer/' + os.platform + '-' + revision + '/' + os.firefoxFolder, 'flaresolverr/firefox') if (os.platform === 'linux') { archive.file('flaresolverr.service', { name: 'flaresolverr/flaresolverr.service' }) } diff --git a/package-lock.json b/package-lock.json index ec2d260..23bb451 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "uuid": "^8.3.2" }, "bin": { - "flaresolverr": "dist/index.js" + "flaresolverr": "dist/server.js" }, "devDependencies": { "@types/await-timeout": "^0.3.1", diff --git a/package.json b/package.json index 8695c89..14ef033 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "url": "https://github.com/ngosang/FlareSolverr" }, "bin": { - "flaresolverr": "dist/index.js" + "flaresolverr": "dist/server.js" }, "dependencies": { "await-timeout": "^1.1.1", diff --git a/src/services/sessions.ts b/src/services/sessions.ts index 2e4617e..8fe95d8 100644 --- a/src/services/sessions.ts +++ b/src/services/sessions.ts @@ -111,11 +111,10 @@ export async function create(session: string, options: SessionCreateOptions): Pr log.debug('Creating userDataDir for session.') puppeteerOptions.userDataDir = prepareBrowserProfile(sessionId, options.proxy) - // todo: fix native package with firefox // if we are running inside executable binary, change browser path if (typeof (process as any).pkg !== 'undefined') { - const exe = process.platform === "win32" ? 'chrome.exe' : 'chrome'; - puppeteerOptions.executablePath = path.join(path.dirname(process.execPath), 'chrome', exe) + const exe = process.platform === "win32" ? 'firefox.exe' : 'firefox'; + puppeteerOptions.executablePath = path.join(path.dirname(process.execPath), 'firefox', exe) } log.debug('Launching web browser...')