meshsocket 0.3.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {meshsocket-0.3.0 → meshsocket-0.4.0}/PKG-INFO +1 -1
- {meshsocket-0.3.0 → meshsocket-0.4.0}/meshsocket/__init__.py +1 -1
- {meshsocket-0.3.0 → meshsocket-0.4.0}/meshsocket.egg-info/PKG-INFO +1 -1
- {meshsocket-0.3.0 → meshsocket-0.4.0}/pyproject.toml +1 -1
- {meshsocket-0.3.0 → meshsocket-0.4.0}/socket_server.py +29 -2
- {meshsocket-0.3.0 → meshsocket-0.4.0}/LICENSE +0 -0
- {meshsocket-0.3.0 → meshsocket-0.4.0}/README.md +0 -0
- {meshsocket-0.3.0 → meshsocket-0.4.0}/meshsocket.egg-info/SOURCES.txt +0 -0
- {meshsocket-0.3.0 → meshsocket-0.4.0}/meshsocket.egg-info/dependency_links.txt +0 -0
- {meshsocket-0.3.0 → meshsocket-0.4.0}/meshsocket.egg-info/requires.txt +0 -0
- {meshsocket-0.3.0 → meshsocket-0.4.0}/meshsocket.egg-info/top_level.txt +0 -0
- {meshsocket-0.3.0 → meshsocket-0.4.0}/setup.cfg +0 -0
- {meshsocket-0.3.0 → meshsocket-0.4.0}/socketCore.py +0 -0
|
@@ -7,4 +7,4 @@ so existing code keeps running while it migrates to the package name.
|
|
|
7
7
|
from socketCore import MeshSocket, LogColors, sanitize_identity, valid_ident, IDENT_RE, NAMESPACED_RE
|
|
8
8
|
|
|
9
9
|
__all__ = ["MeshSocket", "LogColors", "sanitize_identity", "valid_ident", "IDENT_RE", "NAMESPACED_RE"]
|
|
10
|
-
__version__ = "0.
|
|
10
|
+
__version__ = "0.4.0"
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "meshsocket"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.4.0"
|
|
8
8
|
description = "Lightweight WebSocket mesh networking — broadcast, direct routing, and request/response over a simple JSON wire protocol."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -19,6 +19,26 @@ class MeshServerConfigError(RuntimeError):
|
|
|
19
19
|
"""The server refused to start because its configuration is unsafe."""
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
# The key the relay writes on every routed payload (0.4.0): the sender's
|
|
23
|
+
# authenticated name, as this relay registered it at identify (through the
|
|
24
|
+
# carter-relay gateway that is the namespaced `<account>.<principal>_<name>`).
|
|
25
|
+
SENDER_KEY = "_from"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def stamp_sender(payload: Any, sender_name: str) -> Any:
|
|
29
|
+
"""`payload` with `SENDER_KEY` set to `sender_name`, overwriting any value the
|
|
30
|
+
sender wrote. Only a dict payload is stamped. On an E2EE envelope
|
|
31
|
+
(`{"e2ee": 2, "s", "n", "ct"}`) the key lands on the outer, unsealed object
|
|
32
|
+
beside the ciphertext, which is where receivers read the relay's stamp; the
|
|
33
|
+
sealed body is never touched. Other payloads (lists, strings, null) pass
|
|
34
|
+
unchanged. Returns a copy; the caller's dict is not modified."""
|
|
35
|
+
if not isinstance(payload, dict):
|
|
36
|
+
return payload
|
|
37
|
+
stamped = dict(payload)
|
|
38
|
+
stamped[SENDER_KEY] = sender_name
|
|
39
|
+
return stamped
|
|
40
|
+
|
|
41
|
+
|
|
22
42
|
def _env_int(name: str, default: int) -> int:
|
|
23
43
|
raw = os.getenv(name)
|
|
24
44
|
if raw is None or not raw.strip():
|
|
@@ -459,7 +479,8 @@ class MeshServer:
|
|
|
459
479
|
return {"error": "malformed route", "status": "failed"}
|
|
460
480
|
target_id = payload.get('target_id')
|
|
461
481
|
msg_type = payload.get('type')
|
|
462
|
-
|
|
482
|
+
# The target learns who sent this from the relay, not the sender.
|
|
483
|
+
data = stamp_sender(payload.get('payload'), client.name)
|
|
463
484
|
if not isinstance(target_id, str) or not isinstance(msg_type, str):
|
|
464
485
|
return {"error": "malformed route", "status": "failed"}
|
|
465
486
|
|
|
@@ -499,7 +520,7 @@ class MeshServer:
|
|
|
499
520
|
return {"error": "malformed route", "status": "failed"}
|
|
500
521
|
target_name = payload.get('target_name')
|
|
501
522
|
msg_type = payload.get('type')
|
|
502
|
-
data = payload.get('payload')
|
|
523
|
+
data = stamp_sender(payload.get('payload'), client.name)
|
|
503
524
|
if not isinstance(target_name, str) or not isinstance(msg_type, str):
|
|
504
525
|
return {"error": "malformed route", "status": "failed"}
|
|
505
526
|
|
|
@@ -608,6 +629,12 @@ class MeshServer:
|
|
|
608
629
|
await self._fan_out(sends, targets, "roster")
|
|
609
630
|
|
|
610
631
|
async def broadcast(self, type: str, payload: dict, sender: MeshSocket | None = None):
|
|
632
|
+
# Broadcasts are NOT stamped (only routed payloads are; see stamp_sender).
|
|
633
|
+
# Peers already put their own `_from` on broadcasts and match replies
|
|
634
|
+
# against it: CAR-TER writes its bare name on an ack'd command and drops a
|
|
635
|
+
# `command_ack` whose `to` differs, and carterkit acks to the outer `_from`
|
|
636
|
+
# of a sealed frame when there is one. Behind the gateway the relay name is
|
|
637
|
+
# namespaced, so stamping broadcasts would break those acks.
|
|
611
638
|
if not self.clients:
|
|
612
639
|
return
|
|
613
640
|
sends, targets = [], []
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|