()
| 17733 | |
| 17734 | CLOUDFLARED_URL = None |
| 17735 | CLOUDFLARED_PROC = None |
| 17736 | |
| 17737 | TOR_ONION = None |
| 17738 | TOR_PROC = None |
| 17739 | TOR_HS_DIR = None |
| 17740 | |
| 17741 | def start_cloudflared(port: int): |
| 17742 | """Start a Cloudflare quick tunnel (best-effort) and set CLOUDFLARED_URL. |
| 17743 | |
| 17744 | Uses the more robust output-parsing logic from Connections.py. |
| 17745 | """ |
| 17746 | global CLOUDFLARED_URL, CLOUDFLARED_PROC |
| 17747 | try: |
| 17748 | if not have_cmd("cloudflared") and _is_termux(): |
| 17749 | termux_pkg_install("cloudflared") |
| 17750 | if not have_cmd("cloudflared"): |
| 17751 | log.warning("cloudflared not available") |
| 17752 | return |
| 17753 | |
| 17754 | cmd = ["cloudflared", "tunnel", "--url", f"https://localhost:{port}", "--no-autoupdate", "--no-tls-verify"] |
| 17755 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1) |
| 17756 | CLOUDFLARED_PROC = proc |
| 17757 | |
| 17758 | start_time = time.time() |
| 17759 | # Wait up to 180s for the public URL (some devices are slow on first run) |
| 17760 | while time.time() - start_time < 180: |
| 17761 | if proc.stdout is None: |
| 17762 | break |
| 17763 | line = proc.stdout.readline() |
| 17764 | if not line: |
| 17765 | if proc.poll() is not None: |
| 17766 | break |
| 17767 | time.sleep(0.2) |
| 17768 | continue |
| 17769 | m = re.search(r"https://[a-zA-Z0-9-]+\.trycloudflare\.com", line) |
| 17770 | if m: |
| 17771 | CLOUDFLARED_URL = m.group(0) |
| 17772 | return |
nothing calls this directly
no test coverage detected