mirror of
https://github.com/karust/openserp.git
synced 2026-08-15 21:15:56 +08:00
Add custom browser path support
This commit is contained in:
@@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
version = "0.5.5"
|
||||
version = "0.5.6"
|
||||
defaultConfigFilename = "config"
|
||||
envPrefix = "OPENSERP"
|
||||
)
|
||||
@@ -37,6 +37,7 @@ type AppConfig struct {
|
||||
Port int `mapstructure:"port"`
|
||||
Timeout int `mapstructure:"timeout"`
|
||||
ConfigPath string `mapstructure:"config_path"`
|
||||
BrowserPath string `mapstructure:"browser_path"`
|
||||
IsBrowserHead bool `mapstructure:"head"`
|
||||
IsLeaveHead bool `mapstructure:"leave_head"`
|
||||
IsLeakless bool `mapstructure:"leakless"`
|
||||
@@ -52,6 +53,7 @@ var config = Config{}
|
||||
|
||||
var flagToConfigKey = map[string]string{
|
||||
"config": "app.config_path",
|
||||
"browser-path": "app.browser_path",
|
||||
"leave": "app.leave_head",
|
||||
"raw": "app.raw_requests",
|
||||
"2captcha_key": "2captcha.apikey",
|
||||
@@ -163,6 +165,7 @@ func init() {
|
||||
RootCmd.PersistentFlags().StringVarP(&config.App.Host, "host", "a", "127.0.0.1", "Host address to run server")
|
||||
RootCmd.PersistentFlags().IntVarP(&config.App.Timeout, "timeout", "t", 30, "Timeout to fail request")
|
||||
RootCmd.PersistentFlags().StringVarP(&config.App.ConfigPath, "config", "c", "", "Configuration file path")
|
||||
RootCmd.PersistentFlags().StringVarP(&config.App.BrowserPath, "browser-path", "", "", "Custom browser binary path (Chrome/Chromium/Edge/Brave..)")
|
||||
RootCmd.PersistentFlags().BoolVarP(&config.App.IsVerbose, "verbose", "v", false, "Use verbose output")
|
||||
RootCmd.PersistentFlags().BoolVarP(&config.App.IsDebug, "debug", "d", false, "Use debug output. Disable headless browser")
|
||||
RootCmd.PersistentFlags().BoolVarP(&config.App.IsBrowserHead, "head", "", false, "Enable browser UI")
|
||||
|
||||
@@ -70,6 +70,7 @@ func searchBrowser(engineType string, query core.Query) ([]core.SearchResult, er
|
||||
Timeout: time.Second * time.Duration(config.App.Timeout),
|
||||
LeavePageOpen: config.App.IsLeaveHead,
|
||||
CaptchaSolverApiKey: config.Config2Capcha.ApiKey,
|
||||
BrowserPath: config.App.BrowserPath,
|
||||
ProxyURL: config.App.ProxyURL,
|
||||
Insecure: config.App.Insecure,
|
||||
UseStealth: config.App.IsStealth,
|
||||
|
||||
@@ -80,6 +80,7 @@ func serve(cmd *cobra.Command, args []string) {
|
||||
Timeout: time.Second * time.Duration(config.App.Timeout),
|
||||
LeavePageOpen: config.App.IsLeaveHead,
|
||||
CaptchaSolverApiKey: config.Config2Capcha.ApiKey,
|
||||
BrowserPath: config.App.BrowserPath,
|
||||
ProxyURL: config.App.ProxyURL,
|
||||
Insecure: config.App.Insecure,
|
||||
UseStealth: config.App.IsStealth,
|
||||
|
||||
@@ -10,6 +10,9 @@ app:
|
||||
stealth: false
|
||||
insecure: true
|
||||
|
||||
# Optional custom browser binary path (chrome/chromium/edge..)
|
||||
#browser_path: "C:/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe"
|
||||
|
||||
2captcha:
|
||||
apikey: "123123123123123"
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package core
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -23,6 +24,7 @@ type BrowserOpts struct {
|
||||
LeavePageOpen bool // Leave pages and browser open
|
||||
WaitLoadTime time.Duration // Time to wait till page loads
|
||||
CaptchaSolverApiKey string // 2Captcha api key
|
||||
BrowserPath string // Explicit browser executable path
|
||||
ProxyURL string // Proxy URL
|
||||
Insecure bool // Allow insecure TLS connections
|
||||
UseStealth bool // Use go-rod stealth plugin
|
||||
@@ -51,12 +53,18 @@ func NewBrowser(opts BrowserOpts) (*Browser, error) {
|
||||
opts.Check()
|
||||
logrus.Debugf("Browser options: %+v", opts)
|
||||
|
||||
path, has := launcher.LookPath()
|
||||
logrus.Debug("Browser found: ", has)
|
||||
path, err := resolveBrowserBinaryPath(opts.BrowserPath, launcher.LookPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create launcher
|
||||
l := launcher.New().Bin(path).Leakless(opts.IsLeakless).Headless(opts.IsHeadless).Set("disable-blink-features", "AutomationControlled").
|
||||
l := launcher.New().Leakless(opts.IsLeakless).Headless(opts.IsHeadless).Set("disable-blink-features", "AutomationControlled").
|
||||
Delete("enable-automation")
|
||||
if path != "" {
|
||||
logrus.Debugf("Using browser binary: %s", path)
|
||||
l = l.Bin(path)
|
||||
}
|
||||
|
||||
// Configure proxy if specified
|
||||
if opts.ProxyURL != "" {
|
||||
@@ -79,7 +87,6 @@ func NewBrowser(opts BrowserOpts) (*Browser, error) {
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
b := Browser{BrowserOpts: opts}
|
||||
b.browserAddr, err = l.Launch()
|
||||
|
||||
@@ -91,6 +98,35 @@ func NewBrowser(opts BrowserOpts) (*Browser, error) {
|
||||
return &b, err
|
||||
}
|
||||
|
||||
func validateBrowserBinaryPath(path string) error {
|
||||
info, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() {
|
||||
return fmt.Errorf("path points to a directory")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// resolveBrowserBinaryPath prefers an explicit browser path. If no explicit path is provided,
|
||||
// it falls back to launcher autodiscovery and lets Rod handle auto-download when no binary is found.
|
||||
func resolveBrowserBinaryPath(browserPath string, lookPath func() (string, bool)) (string, error) {
|
||||
if browserPath != "" {
|
||||
if err := validateBrowserBinaryPath(browserPath); err != nil {
|
||||
return "", fmt.Errorf("invalid browser_path %q: %w", browserPath, err)
|
||||
}
|
||||
return browserPath, nil
|
||||
}
|
||||
|
||||
path, has := lookPath()
|
||||
if has {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Check whether browser instance is already created
|
||||
func (b *Browser) IsInitialized() bool {
|
||||
if b.browserAddr != "" {
|
||||
|
||||
Reference in New Issue
Block a user