docs+plugin: HTTP-only transport cleanup, install guide, review fixes
- docs/install.md: new end-to-end guide for non-technical users (gateway install, app install, LAN/TLS/remote connection, push, options, troubleshooting); docs/setup.md now points to it - README: new 'Install the gateway' section; pairing section updated for HTTP transport (8791, QR scan on Android) - rename IRIS_WS_HOST -> IRIS_HTTP_HOST (clean rename, no compat fallback); drop dead DEFAULT_PORT=8790 - setup.py: advertise https:// in the printed/QR server URL when IRIS_HTTP_CERT is set - ws_probe.py/e2e.py: default --url http://127.0.0.1:8791, env IRIS_WS_URL -> IRIS_HTTP_URL, honor explicit port + https scheme - plugin.yaml: IRIS_HTTP_* env names, description no longer says 'WebSocket server' - docs 03/09/12/19: fix stale WS-era refs (ws_server.py cites, 8790 smoke test, WSS->HTTPS, 'HTTP fallback' reframed as the only transport) - AGENTS.md: symlink name android -> iris (matches actual install) - test: adapter reads IRIS_HTTP_HOST/CERT/KEY from env; legacy IRIS_WS_* names are not consulted (95/95 pass)
This commit is contained in:
1 parent
a61b47a947
commit
b1c9bac7d8
18 files changed
+472
-317
No files matched your search
@@ -70,7 +70,7 @@ FAIL per scenario plus a summary table; exits 0 if no FAIL, 1 otherwise::
|
||||
|
||||
hermes-agent/.venv/bin/python gateway-plugin/tests/e2e.py
|
||||
hermes-agent/.venv/bin/python gateway-plugin/tests/e2e.py --skip 3,5,7
|
||||
hermes-agent/.venv/bin/python gateway-plugin/tests/e2e.py --url ws://host:8790/ws
|
||||
hermes-agent/.venv/bin/python gateway-plugin/tests/e2e.py --url http://host:8791
|
||||
|
||||
The token is read from `$IRIS_TOKEN`, else `hermes-agent/.env`, else
|
||||
`~/.hermes/.env`. The gateway must already be running (the driver never
|
||||
|
||||
@@ -9,7 +9,7 @@ Usage::
|
||||
|
||||
hermes-agent/.venv/bin/python gateway-plugin/tests/e2e.py
|
||||
hermes-agent/.venv/bin/python gateway-plugin/tests/e2e.py --skip 3,5,7
|
||||
hermes-agent/.venv/bin/python gateway-plugin/tests/e2e.py --url ws://host:8790/ws
|
||||
hermes-agent/.venv/bin/python gateway-plugin/tests/e2e.py --url http://host:8791
|
||||
|
||||
The token is read from $IRIS_TOKEN, else hermes-agent/.env, else
|
||||
~/.hermes/.env. The gateway must already be running (this driver never
|
||||
@@ -40,7 +40,7 @@ REPO = HERE.parent.parent
|
||||
PY = REPO / "hermes-agent" / ".venv" / "bin" / "python"
|
||||
PROBE = HERE / "ws_probe.py"
|
||||
HERMES = REPO / "hermes-agent" / ".venv" / "bin" / "hermes"
|
||||
DEFAULT_URL = "ws://127.0.0.1:8790/ws"
|
||||
DEFAULT_URL = "http://127.0.0.1:8791"
|
||||
|
||||
PASS, PARTIAL, SKIP, FAIL = "PASS", "PARTIAL", "SKIP", "FAIL"
|
||||
|
||||
@@ -309,8 +309,8 @@ def s13_http_fallback(env, url, token):
|
||||
health + POST /v1/frame + SSE /v1/events (no WS involved). The user echo
|
||||
must land on the SSE stream promptly after the POST (< 1.5 s on LAN)."""
|
||||
u = urlparse(url)
|
||||
scheme = "https" if u.scheme == "wss" else "http"
|
||||
http_port = os.getenv("IRIS_HTTP_PORT", "8791")
|
||||
scheme = "https" if u.scheme in ("wss", "https") else "http"
|
||||
http_port = u.port or int(os.getenv("IRIS_HTTP_PORT", "8791"))
|
||||
http_url = f"{scheme}://{u.hostname or '127.0.0.1'}:{http_port}"
|
||||
rc, out, _ = run_probe(env, url, token, "--http", "--http-url", http_url,
|
||||
"--send", "Reply with exactly: e2e http fallback OK",
|
||||
@@ -352,7 +352,7 @@ def main() -> int:
|
||||
p = argparse.ArgumentParser(
|
||||
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
|
||||
)
|
||||
p.add_argument("--url", default=os.getenv("IRIS_WS_URL", DEFAULT_URL))
|
||||
p.add_argument("--url", default=os.getenv("IRIS_HTTP_URL", DEFAULT_URL))
|
||||
p.add_argument("--token", default="")
|
||||
p.add_argument("--skip", default="",
|
||||
help="comma-separated scenario numbers to skip (e.g. 3,5,7)")
|
||||
|
||||
@@ -100,11 +100,11 @@ def adapter(plugin, monkeypatch):
|
||||
monkeypatch.setenv("IRIS_TOKEN", TOKEN)
|
||||
# Clear any IRIS transport overrides leaked into the process env by earlier
|
||||
# tests (e.g. test_interactive_setup_prints_qr runs the real
|
||||
# interactive_setup(), which save_env_value()s IRIS_HTTP_PORT/IRIS_WS_HOST).
|
||||
# interactive_setup(), which save_env_value()s IRIS_HTTP_PORT/IRIS_HTTP_HOST).
|
||||
# Without this, a later adapter would bind the leaked port (8791) instead of
|
||||
# the ephemeral 0 below, colliding with a live gateway on that port.
|
||||
monkeypatch.delenv("IRIS_HTTP_PORT", raising=False)
|
||||
monkeypatch.delenv("IRIS_WS_HOST", raising=False)
|
||||
monkeypatch.delenv("IRIS_HTTP_HOST", raising=False)
|
||||
from gateway.platform_registry import PlatformEntry, platform_registry
|
||||
|
||||
# Platform("iris") resolves only once the platform is registered
|
||||
@@ -139,6 +139,54 @@ def adapter(plugin, monkeypatch):
|
||||
pass
|
||||
|
||||
|
||||
def test_adapter_reads_http_env_overrides(plugin, monkeypatch, tmp_path):
|
||||
"""IRIS_HTTP_HOST / IRIS_HTTP_CERT / IRIS_HTTP_KEY are read from the env
|
||||
(overriding config.yaml extra), and the legacy IRIS_WS_* names are NOT
|
||||
consulted (HTTP-only transport, docs/19)."""
|
||||
monkeypatch.setenv("IRIS_TOKEN", TOKEN)
|
||||
monkeypatch.setenv("IRIS_HTTP_HOST", "192.168.1.50")
|
||||
monkeypatch.setenv("IRIS_HTTP_CERT", str(tmp_path / "cert.pem"))
|
||||
monkeypatch.setenv("IRIS_HTTP_KEY", str(tmp_path / "key.pem"))
|
||||
# Legacy WS-era names must be ignored, even if present.
|
||||
monkeypatch.setenv("IRIS_WS_HOST", "10.9.9.9")
|
||||
monkeypatch.setenv("IRIS_WS_CERT", str(tmp_path / "old.pem"))
|
||||
from gateway.platform_registry import platform_registry
|
||||
|
||||
if not platform_registry.is_registered("iris"):
|
||||
from gateway.platform_registry import PlatformEntry
|
||||
|
||||
platform_registry.register(
|
||||
PlatformEntry(
|
||||
name="iris",
|
||||
label="Android",
|
||||
adapter_factory=lambda cfg: None,
|
||||
check_fn=lambda: True,
|
||||
)
|
||||
)
|
||||
|
||||
config = SimpleNamespace(
|
||||
extra={"host": "127.0.0.1", "http_port": 0},
|
||||
home_channel=None,
|
||||
)
|
||||
a = plugin.adapter.IrisAdapter(config)
|
||||
try:
|
||||
assert a.host == "192.168.1.50" # env wins over extra
|
||||
assert a.http_cert == str(tmp_path / "cert.pem")
|
||||
assert a.http_key == str(tmp_path / "key.pem")
|
||||
# Legacy names are not read: host/cert are not the old values.
|
||||
assert a.host != "10.9.9.9"
|
||||
assert a.http_cert != str(tmp_path / "old.pem")
|
||||
finally:
|
||||
try:
|
||||
a._devices.close()
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
a._outbox.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
class HttpTestClient:
|
||||
"""Mimics the old WS client interface over the HTTP transport (docs/19).
|
||||
|
||||
|
||||
@@ -12,7 +12,9 @@ Usage::
|
||||
--send "hello"
|
||||
|
||||
Options:
|
||||
--url ws://host:port/ws (default ws://127.0.0.1:8790/ws)
|
||||
--url http(s)://host:port (default http://127.0.0.1:8791)
|
||||
(legacy ws(s)://host:8790/ws URLs are still accepted and
|
||||
converted to the HTTP base automatically)
|
||||
--token IRIS_TOKEN (default: $IRIS_TOKEN)
|
||||
--device device_id (default: probe-<rand>)
|
||||
--send TEXT send this message after pairing (default: "hello")
|
||||
@@ -666,7 +668,7 @@ def run_http(args, base: str) -> int:
|
||||
|
||||
def main() -> int:
|
||||
p = argparse.ArgumentParser(description=__doc__)
|
||||
p.add_argument("--url", default=os.getenv("IRIS_WS_URL", "ws://127.0.0.1:8790/ws"))
|
||||
p.add_argument("--url", default=os.getenv("IRIS_HTTP_URL", "http://127.0.0.1:8791"))
|
||||
p.add_argument("--token", default=os.getenv("IRIS_TOKEN", ""))
|
||||
p.add_argument("--device", default=f"probe-{uuid.uuid4().hex[:8]}")
|
||||
p.add_argument("--send", default="hello")
|
||||
@@ -766,15 +768,17 @@ def main() -> int:
|
||||
if args.assert_read_receipt and not args.send:
|
||||
p.error("--assert-read-receipt requires --send (the receipt must follow the sent message)")
|
||||
# HTTP is the only transport (docs/19): derive the http(s) base from the
|
||||
# --url (ws://host:8790/ws -> http://host:8791) unless --http-url is given.
|
||||
# --url (legacy ws(s)://host:8790/ws -> http(s)://host:8791) unless
|
||||
# --http-url is given.
|
||||
if args.http_url:
|
||||
base = args.http_url
|
||||
else:
|
||||
from urllib.parse import urlparse
|
||||
|
||||
u = urlparse(args.url)
|
||||
scheme = "https" if u.scheme == "wss" else "http"
|
||||
base = f"{scheme}://{u.hostname or '127.0.0.1'}:8791"
|
||||
scheme = "https" if u.scheme in ("wss", "https") else "http"
|
||||
port = u.port or 8791
|
||||
base = f"{scheme}://{u.hostname or '127.0.0.1'}:{port}"
|
||||
return run_http(args, base)
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user