starpc 0.52.0 → 0.52.2
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.
- package/README.md +37 -8
- package/dist/echo/client-test.d.ts +1 -1
- package/dist/echo/client-test.js +110 -2
- package/dist/integration/cross-language/tcp-packet-stream.d.ts +3 -0
- package/dist/integration/cross-language/tcp-packet-stream.js +112 -0
- package/dist/integration/cross-language/tcp-packet-stream.test.d.ts +1 -0
- package/dist/integration/cross-language/tcp-packet-stream.test.js +121 -0
- package/dist/integration/cross-language/ts-client.js +50 -37
- package/dist/integration/cross-language/ts-server.js +1 -36
- package/dist/rpcstream/rpcstream.d.ts +5 -1
- package/dist/rpcstream/rpcstream.js +75 -28
- package/dist/rpcstream/rpcstream.test.d.ts +1 -0
- package/dist/rpcstream/rpcstream.test.js +92 -0
- package/dist/srpc/client-rpc.d.ts +1 -0
- package/dist/srpc/client-rpc.js +9 -0
- package/dist/srpc/client-rpc.test.d.ts +1 -0
- package/dist/srpc/client-rpc.test.js +50 -0
- package/dist/srpc/client.js +18 -4
- package/dist/srpc/common-rpc.d.ts +5 -0
- package/dist/srpc/common-rpc.js +37 -8
- package/dist/srpc/common-rpc.test.js +2 -0
- package/dist/srpc/errors.d.ts +2 -0
- package/dist/srpc/errors.js +14 -0
- package/dist/srpc/index.d.ts +1 -1
- package/dist/srpc/index.js +1 -1
- package/dist/srpc/packet-codec.test.d.ts +1 -0
- package/dist/srpc/packet-codec.test.js +75 -0
- package/dist/srpc/packet.d.ts +1 -1
- package/dist/srpc/packet.js +11 -1
- package/dist/srpc/server.js +19 -6
- package/dist/srpc/server.test.js +43 -0
- package/dist/srpc/stream.d.ts +4 -1
- package/dist/srpc/stream.js +62 -3
- package/dist/srpc/stream.test.js +110 -1
- package/dist/srpc/termination.d.ts +27 -0
- package/dist/srpc/termination.js +56 -0
- package/dist/srpc/termination.test.d.ts +1 -0
- package/dist/srpc/termination.test.js +24 -0
- package/dist/testdata/packet-codec-vectors.json +64 -0
- package/echo/Cargo.toml +8 -0
- package/echo/client-test.ts +124 -2
- package/echo/echo_e2e_test.cpp +542 -985
- package/echo/echo_pb2.py +40 -0
- package/echo/echo_pb2.pyi +13 -0
- package/echo/echo_srpc.pb.cpp +3 -5
- package/echo/echo_srpc.pb.go +6 -9
- package/echo/echo_srpc.pb.hpp +23 -3
- package/echo/echo_srpc.pb.rs +61 -26
- package/echo/echo_srpc.py +309 -0
- package/echo/echo_srpc.pyi +85 -0
- package/echo/half_close_test.rs +178 -0
- package/echo/integration_server.rs +14 -21
- package/echo/main.rs +28 -48
- package/go.mod +3 -3
- package/go.sum +6 -8
- package/integration/cross-language/cpp-client.cpp +446 -402
- package/integration/cross-language/cpp-pipe-server.cpp +139 -0
- package/integration/cross-language/cpp-pipe_test.go +114 -0
- package/integration/cross-language/cpp-server.cpp +222 -186
- package/integration/cross-language/go-client/main.go +79 -3
- package/integration/cross-language/python-client.py +146 -0
- package/integration/cross-language/python-server.py +140 -0
- package/integration/cross-language/run.bash +190 -65
- package/integration/cross-language/tcp-packet-stream.test.ts +154 -0
- package/integration/cross-language/tcp-packet-stream.ts +121 -0
- package/integration/cross-language/ts-client.ts +62 -40
- package/integration/cross-language/ts-server.ts +1 -45
- package/mock/mock_pb2.py +38 -0
- package/mock/mock_pb2.pyi +11 -0
- package/mock/mock_srpc.pb.cpp +1 -1
- package/mock/mock_srpc.pb.hpp +1 -1
- package/mock/mock_srpc.pb.rs +10 -9
- package/mock/mock_srpc.py +71 -0
- package/mock/mock_srpc.pyi +27 -0
- package/package.json +19 -5
- package/srpc/CMakeLists.txt +3 -58
- package/srpc/README-cpp.md +69 -0
- package/srpc/__init__.py +0 -0
- package/srpc/accept.go +10 -4
- package/srpc/accept_test.go +25 -0
- package/srpc/build.rs +129 -34
- package/srpc/client-half-close_test.go +152 -0
- package/srpc/client-invoker.go +32 -42
- package/srpc/client-invoker_test.go +53 -0
- package/srpc/client-rpc.cpp +65 -80
- package/srpc/client-rpc.go +32 -33
- package/srpc/client-rpc.hpp +52 -38
- package/srpc/client-rpc.test.ts +67 -0
- package/srpc/client-rpc.ts +10 -0
- package/srpc/client-rpc_test.go +76 -0
- package/srpc/client.cpp +99 -87
- package/srpc/client.hpp +46 -35
- package/srpc/client.rs +78 -38
- package/srpc/client.ts +20 -4
- package/srpc/client_half_close_test.cc +331 -0
- package/srpc/client_invoker.rs +75 -0
- package/srpc/codec.rs +6 -0
- package/srpc/common-rpc.cpp +186 -146
- package/srpc/common-rpc.go +5 -4
- package/srpc/common-rpc.hpp +119 -89
- package/srpc/common-rpc.test.ts +2 -0
- package/srpc/common-rpc.ts +43 -8
- package/srpc/common-rpc_test.go +23 -0
- package/srpc/error.rs +19 -2
- package/srpc/errors.hpp +80 -50
- package/srpc/errors.ts +16 -0
- package/srpc/handler.hpp +9 -7
- package/srpc/handler.rs +7 -45
- package/srpc/index.ts +2 -0
- package/srpc/invoker.hpp +82 -55
- package/srpc/invoker.rs +14 -52
- package/srpc/lib.rs +2 -0
- package/srpc/message.hpp +17 -12
- package/srpc/msg-stream.go +1 -0
- package/srpc/msg-stream.hpp +108 -61
- package/srpc/mux.cpp +84 -84
- package/srpc/mux.hpp +48 -38
- package/srpc/mux.rs +4 -4
- package/srpc/net.go +12 -3
- package/srpc/packet-codec-vectors_test.go +195 -0
- package/srpc/packet-codec.test.ts +139 -0
- package/srpc/packet-rw.go +9 -2
- package/srpc/packet.cpp +60 -58
- package/srpc/packet.hpp +35 -20
- package/srpc/packet.rs +8 -27
- package/srpc/packet.ts +15 -2
- package/srpc/py.typed +0 -0
- package/srpc/rpc.rs +332 -115
- package/srpc/rpc_lifecycle_test.cc +333 -0
- package/srpc/rpcproto_pb2.py +40 -0
- package/srpc/rpcproto_pb2.pyi +40 -0
- package/srpc/server-cancel_test.go +39 -0
- package/srpc/server-rpc.cpp +83 -73
- package/srpc/server-rpc.go +21 -19
- package/srpc/server-rpc.hpp +56 -37
- package/srpc/server.rs +76 -131
- package/srpc/server.test.ts +50 -0
- package/srpc/server.ts +22 -6
- package/srpc/starpc.hpp +4 -2
- package/srpc/stream.go +4 -0
- package/srpc/stream.hpp +95 -34
- package/srpc/stream.rs +7 -2
- package/srpc/stream.test.ts +132 -1
- package/srpc/stream.ts +65 -9
- package/srpc/termination.test.ts +30 -0
- package/srpc/termination.ts +70 -0
- package/srpc/testing.rs +11 -66
- package/srpc/transport.rs +21 -71
- package/srpc/websocket.rs +106 -57
- package/srpc/writer.hpp +46 -32
- package/srpc/yamux.rs +82 -26
- package/srpc/tests/integration_test.rs +0 -495
package/srpc/packet.rs
CHANGED
|
@@ -10,10 +10,8 @@ use bytes::Bytes;
|
|
|
10
10
|
|
|
11
11
|
/// Creates a new CallStart packet.
|
|
12
12
|
///
|
|
13
|
-
///
|
|
14
|
-
///
|
|
15
|
-
/// * `method` - The method ID
|
|
16
|
-
/// * `data` - Optional initial data (None = no data, Some(empty) = empty data)
|
|
13
|
+
/// `None` data sends no payload; `Some(empty)` sends empty data with the
|
|
14
|
+
/// `data_is_zero` flag set.
|
|
17
15
|
pub fn new_call_start(
|
|
18
16
|
service: impl Into<String>,
|
|
19
17
|
method: impl Into<String>,
|
|
@@ -31,10 +29,7 @@ pub fn new_call_start(
|
|
|
31
29
|
}
|
|
32
30
|
}
|
|
33
31
|
|
|
34
|
-
/// Creates a new CallData packet
|
|
35
|
-
///
|
|
36
|
-
/// # Arguments
|
|
37
|
-
/// * `data` - The data to send (can be empty)
|
|
32
|
+
/// Creates a new CallData packet carrying `data`, which may be empty.
|
|
38
33
|
pub fn new_call_data(data: Vec<u8>) -> Packet {
|
|
39
34
|
let data_is_zero = data.is_empty();
|
|
40
35
|
Packet {
|
|
@@ -49,16 +44,9 @@ pub fn new_call_data(data: Vec<u8>) -> Packet {
|
|
|
49
44
|
|
|
50
45
|
/// Creates a new CallData packet with optional data and flags.
|
|
51
46
|
///
|
|
52
|
-
///
|
|
53
|
-
///
|
|
54
|
-
|
|
55
|
-
/// * `complete` - True if this completes the stream
|
|
56
|
-
/// * `error` - Optional error message
|
|
57
|
-
pub fn new_call_data_full(
|
|
58
|
-
data: Option<Bytes>,
|
|
59
|
-
complete: bool,
|
|
60
|
-
error: Option<String>,
|
|
61
|
-
) -> Packet {
|
|
47
|
+
/// Sets `complete` when either `complete` or `error` is set, so an error
|
|
48
|
+
/// always ends the call.
|
|
49
|
+
pub fn new_call_data_full(data: Option<Bytes>, complete: bool, error: Option<String>) -> Packet {
|
|
62
50
|
let (data_bytes, data_is_zero) = encode_optional_data(data);
|
|
63
51
|
|
|
64
52
|
Packet {
|
|
@@ -83,10 +71,7 @@ pub fn new_call_complete() -> Packet {
|
|
|
83
71
|
}
|
|
84
72
|
}
|
|
85
73
|
|
|
86
|
-
/// Creates a new CallData packet
|
|
87
|
-
///
|
|
88
|
-
/// # Arguments
|
|
89
|
-
/// * `error` - The error message
|
|
74
|
+
/// Creates a new CallData packet carrying an error message.
|
|
90
75
|
pub fn new_call_error(error: impl Into<String>) -> Packet {
|
|
91
76
|
Packet {
|
|
92
77
|
body: Some(Body::CallData(CallData {
|
|
@@ -154,11 +139,7 @@ impl Validate for CallData {
|
|
|
154
139
|
// - data_is_zero flag set (indicating intentionally empty data)
|
|
155
140
|
// - complete flag set
|
|
156
141
|
// - error message
|
|
157
|
-
if self.data.is_empty()
|
|
158
|
-
&& !self.data_is_zero
|
|
159
|
-
&& !self.complete
|
|
160
|
-
&& self.error.is_empty()
|
|
161
|
-
{
|
|
142
|
+
if self.data.is_empty() && !self.data_is_zero && !self.complete && self.error.is_empty() {
|
|
162
143
|
return Err(Error::EmptyPacket);
|
|
163
144
|
}
|
|
164
145
|
Ok(())
|
package/srpc/packet.ts
CHANGED
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
buildEncodeMessageTransform,
|
|
8
8
|
} from './message.js'
|
|
9
9
|
|
|
10
|
+
const MAX_MESSAGE_SIZE = 10_000_000
|
|
11
|
+
|
|
10
12
|
// decodePacketSource decodes packets from a binary data stream.
|
|
11
13
|
export const decodePacketSource = buildDecodeMessageTransform<Packet>(Packet)
|
|
12
14
|
|
|
@@ -39,6 +41,9 @@ export async function* lengthPrefixEncode(
|
|
|
39
41
|
for await (const chunk of source) {
|
|
40
42
|
// Encode the length of the chunk.
|
|
41
43
|
const length = chunk instanceof Uint8Array ? chunk.length : chunk.byteLength
|
|
44
|
+
if (length === 0 || length > MAX_MESSAGE_SIZE) {
|
|
45
|
+
throw RangeError(`invalid packet length: ${length}`)
|
|
46
|
+
}
|
|
42
47
|
const lengthEncoded = lengthEncoder(length)
|
|
43
48
|
|
|
44
49
|
// Concatenate the length prefix and the data.
|
|
@@ -50,7 +55,7 @@ export async function* lengthPrefixEncode(
|
|
|
50
55
|
export async function* lengthPrefixDecode(
|
|
51
56
|
source: Source<Uint8Array | Uint8ArrayList>,
|
|
52
57
|
lengthDecoder: typeof uint32LEDecode,
|
|
53
|
-
) {
|
|
58
|
+
): AsyncGenerator<Uint8ArrayList> {
|
|
54
59
|
const buffer = new Uint8ArrayList()
|
|
55
60
|
|
|
56
61
|
for await (const chunk of source) {
|
|
@@ -59,18 +64,26 @@ export async function* lengthPrefixDecode(
|
|
|
59
64
|
// Continue extracting messages while buffer contains enough data for decoding.
|
|
60
65
|
while (buffer.length >= lengthDecoder.bytes) {
|
|
61
66
|
const messageLength = lengthDecoder(buffer)
|
|
67
|
+
if (messageLength === 0 || messageLength > MAX_MESSAGE_SIZE) {
|
|
68
|
+
throw RangeError(`invalid packet length: ${messageLength}`)
|
|
69
|
+
}
|
|
62
70
|
const totalLength = lengthDecoder.bytes + messageLength
|
|
63
71
|
|
|
64
72
|
if (buffer.length < totalLength) break // Wait for more data if the full message hasn't arrived.
|
|
65
73
|
|
|
66
74
|
// Extract the message excluding the length prefix.
|
|
67
|
-
const message =
|
|
75
|
+
const message = new Uint8ArrayList(
|
|
76
|
+
buffer.slice(lengthDecoder.bytes, totalLength),
|
|
77
|
+
)
|
|
68
78
|
yield message
|
|
69
79
|
|
|
70
80
|
// Remove the processed message from the buffer.
|
|
71
81
|
buffer.consume(totalLength)
|
|
72
82
|
}
|
|
73
83
|
}
|
|
84
|
+
if (buffer.length !== 0) {
|
|
85
|
+
throw new RangeError('truncated packet frame')
|
|
86
|
+
}
|
|
74
87
|
}
|
|
75
88
|
|
|
76
89
|
// prependLengthPrefixTransform adds a length prefix to a message source.
|
package/srpc/py.typed
ADDED
|
File without changes
|