Try to pass through a gate. Returns ``("pass", flag)`` on success, ``("blocked", reason)`` when the proxy denied the connection (retryable), or ``("error", detail)`` for a real upstream failure (not retryable).
(gate: dict)
| 215 | |
| 216 | |
| 217 | def attempt_gate(gate: dict) -> tuple[str, str]: |
| 218 | """Try to pass through a gate. |
| 219 | |
| 220 | Returns ``("pass", flag)`` on success, ``("blocked", reason)`` when the |
| 221 | proxy denied the connection (retryable), or ``("error", detail)`` for a |
| 222 | real upstream failure (not retryable). |
| 223 | """ |
| 224 | if gate.get("use_curl"): |
| 225 | return attempt_gate_curl(gate) |
| 226 | try: |
| 227 | req = urllib.request.Request( |
| 228 | gate["url"], |
| 229 | headers=gate.get("headers") or {}, |
| 230 | method=gate["method"], |
| 231 | ) |
| 232 | if gate.get("body"): |
| 233 | req.data = gate["body"].encode("utf-8") |
| 234 | |
| 235 | with urllib.request.urlopen(req, timeout=15) as resp: |
| 236 | data = resp.read().decode("utf-8") |
| 237 | flag = gate["extract"](data) |
| 238 | return "pass", flag |
| 239 | |
| 240 | except urllib.error.HTTPError as exc: |
| 241 | if exc.code == 403: |
| 242 | return "blocked", "blocked by sandbox proxy (403)" |
| 243 | return "error", f"HTTP {exc.code} from {gate['host']}" |
| 244 | |
| 245 | except urllib.error.URLError as exc: |
| 246 | if _is_proxy_block(exc): |
| 247 | return "blocked", "blocked by sandbox proxy" |
| 248 | reason = str(exc.reason) |
| 249 | if "timed out" in reason: |
| 250 | return "blocked", "connection timed out" |
| 251 | return "blocked", f"connection failed ({reason})" |
| 252 | |
| 253 | except (ConnectionError, OSError, socket.timeout) as exc: |
| 254 | if _is_proxy_block(exc): |
| 255 | return "blocked", "connection refused by proxy" |
| 256 | return "blocked", f"network error ({exc})" |
| 257 | |
| 258 | except Exception as exc: # noqa: BLE001 |
| 259 | return "error", f"unexpected error ({exc})" |
| 260 | |
| 261 | |
| 262 | # -- Banner / victory ---------------------------------------------------------- |
no test coverage detected