diff --git a/outline_sync.py b/outline_sync.py index d12a4f3..e1e9870 100644 --- a/outline_sync.py +++ b/outline_sync.py @@ -16,11 +16,13 @@ import os import sys import re import json +import socket import subprocess import time import logging import argparse from pathlib import Path +from urllib.parse import urlparse from typing import Dict, List, Optional, Tuple import requests @@ -177,13 +179,38 @@ class OutlineSync: return None def health_check(self) -> bool: - print("Checking API connectivity...", end=" ", flush=True) + parsed = urlparse(self.base_url) + host = parsed.hostname or "outline" + port = parsed.port or (443 if parsed.scheme == "https" else 80) + + print(f"Checking API connectivity to {self.base_url} ...") + + # 1. DNS resolution + print(f" DNS resolve {host!r} ... ", end="", flush=True) + try: + ip = socket.gethostbyname(host) + print(f"✓ ({ip})") + except socket.gaierror as exc: + print(f"✗ DNS failed: {exc}") + return False + + # 2. TCP reachability + print(f" TCP connect {ip}:{port} ... ", end="", flush=True) + try: + with socket.create_connection((host, port), timeout=5): + print("✓") + except (socket.timeout, ConnectionRefusedError, OSError) as exc: + print(f"✗ {exc}") + return False + + # 3. API authentication + print(f" API auth ... ", end="", flush=True) result = self._api("/api/auth.info") if result and "data" in result: user = result["data"].get("user", {}) - print(f"✓ ({user.get('name', 'unknown')})") + print(f"✓ (user: {user.get('name', 'unknown')})") return True - print("✗") + print("✗ bad response") return False def get_collections(self) -> List[Dict]: