Files
fn_registry/functions/browser/cdp_close.go
T
Egutierrez ccfa5bc78b feat(browser): funciones anti-deteccion + perfiles para web_scraping
Funciones nuevas del dominio browser (grupo navegator):
- cdp_move_mouse_human / cdp_click_human: movimiento de raton con curva
  de Bezier cubica, easing y micro-jitter para imitar comportamiento
  humano y reducir deteccion de automatizacion.
- cdp_wait_idle: espera network-idle contando requests en vuelo via
  eventos CDP Network.*; inmune a extensiones que mutan el DOM
  (Dark Reader, uBlock) y a animaciones JS.
- list_chrome_profiles: lista perfiles de un user-data-dir (extensiones,
  nombre legible, preferencias).
- prepare_chrome_profile (bash): clona un user-data-dir conservando solo
  una whitelist de extensiones (default uBlock Origin Lite).

Modificadas:
- chrome_launch: Linux-first (chromium/google-chrome/brave antes que
  chrome.exe), KeepExtensions y Setpgid para matar el arbol con cdp_close.
- cdp_close: kill por grupo de proceso.

Todas con tests verdes (go test ./functions/browser ok).
2026-06-05 16:25:11 +02:00

44 lines
1.3 KiB
Go

package browser
import (
"fmt"
"os"
"syscall"
)
// CdpClose cierra la conexion WebSocket CDP y, si pid > 0, mata el proceso Chrome.
// En Linux nativo mata el grupo de proceso completo (chromium lanza zygote, gpu,
// renderers como hijos del mismo grupo cuando ChromeLaunch seteo Setpgid: true).
// Siempre intenta cerrar la conexion aunque el kill falle, y viceversa.
// Retorna el primer error encontrado.
func CdpClose(c *CDPConn, pid int) error {
var firstErr error
if c != nil && !c.closed {
c.closed = true
if err := c.conn.Close(); err != nil {
firstErr = fmt.Errorf("cdp close: cerrar websocket: %w", err)
}
}
if pid > 0 {
// Intentar matar el grupo de proceso completo (pid == pgid cuando Setpgid=true).
// syscall.Kill con pid negativo envia la señal a todos los procesos del grupo.
if err := syscall.Kill(-pid, syscall.SIGKILL); err != nil {
// Fallback: matar solo el proceso raiz si el grupo falla
// (ej: proceso ya terminado, o chrome.exe en WSL sin Setpgid).
if proc, e := os.FindProcess(pid); e == nil {
if killErr := proc.Kill(); killErr != nil {
if firstErr == nil {
firstErr = fmt.Errorf("cdp close: matar proceso %d: %w", pid, killErr)
}
}
} else if firstErr == nil {
firstErr = fmt.Errorf("cdp close: encontrar proceso %d: %w", pid, e)
}
}
}
return firstErr
}