1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//! # Subduction HTTP Long-Poll Transport
//!
//! An HTTP long-poll transport layer for the Subduction sync protocol,
//! providing an alternative to WebSocket for environments where WebSocket
//! connections are unreliable or unavailable (e.g., restrictive proxies,
//! corporate firewalls, some serverless platforms).
//!
//! # Protocol
//!
//! The transport maps Subduction's bidirectional message stream onto HTTP
//! request-response pairs:
//!
//! ```text
//! ┌────────┐ ┌────────┐
//! │ Client │ │ Server │
//! └───┬────┘ └───┬────┘
//! │ │
//! │ POST /lp/handshake │
//! │ Body: Signed<Challenge> (157 B) │
//! │ ──────────────────────────────────────► │
//! │ 200 + Signed<Response> (140 B) │
//! │ X-Session-Id: <session_id> │
//! │ ◄────────────────────────────────────── │
//! │ │
//! │ POST /lp/send │
//! │ X-Session-Id: <id> │
//! │ Body: SyncMessage (binary) │
//! │ ──────────────────────────────────────► │
//! │ 204 No Content │
//! │ ◄────────────────────────────────────── │
//! │ │
//! │ POST /lp/recv │
//! │ X-Session-Id: <id> │
//! │ ──────────────────────────────────────► │
//! │ ... (blocks) ... │
//! │ 200 + SyncMessage (binary) │
//! │ ◄────────────────────────────────────── │
//! │ │
//! │ POST /lp/disconnect │
//! │ X-Session-Id: <id> │
//! │ ──────────────────────────────────────► │
//! │ 204 No Content │
//! │ ◄────────────────────────────────────── │
//! ```
//!
//! # Architecture
//!
//! The server maintains per-session state with async channels that mirror
//! the WebSocket transport's internal architecture:
//!
//! ```text
//! ┌─────────────────────────────────────────────────┐
//! │ HttpLongPollTransport │
//! │ │
//! │ outbound_tx ──► [bounded channel] ──► /recv │
//! │ /send ──► [bounded channel] ──► inbound_reader │
//! │ pending: Map<RequestId, oneshot::Tx> │
//! └─────────────────────────────────────────────────┘
//! ```
extern crate alloc;
/// Default long-poll timeout in seconds.
///
/// If no message is available after this duration, the `/lp/recv`
/// endpoint returns 204 No Content and the client should re-poll.
pub const DEFAULT_POLL_TIMEOUT_SECS: u64 = 30;
/// Default maximum HTTP request body size (50 MB).
///
/// Matches the WebSocket transport's `DEFAULT_MAX_MESSAGE_SIZE`.
pub const DEFAULT_MAX_BODY_SIZE: usize = 50 * 1024 * 1024;
/// Session ID header name.
pub const SESSION_ID_HEADER: &str = "x-session-id";