3
3
use std:: net:: SocketAddr ;
4
4
5
5
use futures:: prelude:: * ;
6
- use prost:: Message ;
7
6
use thiserror:: Error ;
8
7
use tokio:: net:: TcpStream ;
8
+ use tokio_util:: codec:: Framed ;
9
9
10
10
use crate :: {
11
11
api:: proto:: { self , message, ProtoApiError } ,
12
- global:: { Global , InputMessage , InputSourceHandle , InputSourceName } ,
12
+ global:: { Global , InputSourceName } ,
13
13
} ;
14
14
15
+ mod codec;
16
+ use codec:: * ;
17
+
15
18
#[ derive( Debug , Error ) ]
16
19
pub enum ProtoServerError {
17
20
#[ error( "i/o error: {0}" ) ]
18
21
Io ( #[ from] futures_io:: Error ) ,
19
- #[ error( "decode error: {}" , 0 ) ]
20
- DecodeError ( #[ from] prost :: DecodeError ) ,
22
+ #[ error( "decode error: {0}" ) ]
23
+ Codec ( #[ from] ProtoCodecError ) ,
21
24
#[ error( transparent) ]
22
25
Api ( #[ from] ProtoApiError ) ,
23
26
}
24
27
25
- fn encode_response ( buf : & mut bytes:: BytesMut , msg : impl prost:: Message ) -> bytes:: Bytes {
26
- // Clear the buffer to start fresh
27
- buf. clear ( ) ;
28
-
29
- // Reserve enough space for the response
30
- let len = msg. encoded_len ( ) ;
31
- if buf. capacity ( ) < len {
32
- buf. reserve ( len * 2 ) ;
33
- }
34
-
35
- // Encode the message
36
- msg. encode ( buf) . unwrap ( ) ;
37
- buf. split ( ) . freeze ( )
38
- }
39
-
40
- fn success_response ( peer_addr : SocketAddr , buf : & mut bytes:: BytesMut ) -> bytes:: Bytes {
28
+ fn success_response ( peer_addr : SocketAddr ) -> message:: HyperionReply {
41
29
let mut reply = message:: HyperionReply :: default ( ) ;
42
30
reply. r#type = message:: hyperion_reply:: Type :: Reply . into ( ) ;
43
31
reply. success = Some ( true ) ;
44
32
45
33
trace ! ( "({}) sending success: {:?}" , peer_addr, reply) ;
46
- encode_response ( buf , reply)
34
+ reply
47
35
}
48
36
49
- fn error_response (
50
- peer_addr : SocketAddr ,
51
- buf : & mut bytes:: BytesMut ,
52
- error : impl std:: fmt:: Display ,
53
- ) -> bytes:: Bytes {
37
+ fn error_response ( peer_addr : SocketAddr , error : impl std:: fmt:: Display ) -> message:: HyperionReply {
54
38
let mut reply = message:: HyperionReply :: default ( ) ;
55
39
reply. r#type = message:: hyperion_reply:: Type :: Reply . into ( ) ;
56
40
reply. success = Some ( false ) ;
57
41
reply. error = Some ( error. to_string ( ) ) ;
58
42
59
43
trace ! ( "({}) sending error: {:?}" , peer_addr, reply) ;
60
- encode_response ( buf, reply)
61
- }
62
-
63
- fn handle_request (
64
- peer_addr : SocketAddr ,
65
- request_bytes : bytes:: BytesMut ,
66
- source : & InputSourceHandle < InputMessage > ,
67
- ) -> Result < ( ) , ProtoServerError > {
68
- let request_bytes = request_bytes. freeze ( ) ;
69
- let request = message:: HyperionRequest :: decode ( request_bytes. clone ( ) ) ?;
70
-
71
- trace ! ( "({}) got request: {:?}" , peer_addr, request) ;
72
-
73
- Ok ( proto:: handle_request ( request, source) ?)
44
+ reply
74
45
}
75
46
76
47
pub async fn handle_client (
@@ -79,35 +50,31 @@ pub async fn handle_client(
79
50
) -> Result < ( ) , ProtoServerError > {
80
51
debug ! ( "accepted new connection from {}" , peer_addr) ;
81
52
82
- let framed = tokio_util:: codec:: LengthDelimitedCodec :: builder ( )
83
- . length_field_length ( 4 )
84
- . new_framed ( socket) ;
85
- let ( mut writer, mut reader) = framed. split ( ) ;
53
+ let ( mut writer, mut reader) = Framed :: new ( socket, ProtoCodec :: new ( ) ) . split ( ) ;
86
54
87
55
// unwrap: cannot fail because the priority is None
88
56
let source = global
89
57
. register_input_source ( InputSourceName :: Protobuf { peer_addr } , None )
90
58
. await
91
59
. unwrap ( ) ;
92
60
93
- // buffer for building responses
94
- let mut reply_buf = bytes:: BytesMut :: with_capacity ( 128 ) ;
95
-
96
- while let Some ( request_bytes) = reader. next ( ) . await {
97
- let request_bytes = match request_bytes {
61
+ while let Some ( request) = reader. next ( ) . await {
62
+ let request = match request {
98
63
Ok ( rb) => rb,
99
64
Err ( error) => {
100
65
error ! ( "({}) error reading frame: {}" , peer_addr, error) ;
101
66
continue ;
102
67
}
103
68
} ;
104
69
105
- let reply = match handle_request ( peer_addr, request_bytes, & source) {
106
- Ok ( ( ) ) => success_response ( peer_addr, & mut reply_buf) ,
70
+ trace ! ( "({}) got request: {:?}" , peer_addr, request) ;
71
+
72
+ let reply = match proto:: handle_request ( request, & source) {
73
+ Ok ( ( ) ) => success_response ( peer_addr) ,
107
74
Err ( error) => {
108
75
error ! ( "({}) error processing request: {}" , peer_addr, error) ;
109
76
110
- error_response ( peer_addr, & mut reply_buf , error)
77
+ error_response ( peer_addr, error)
111
78
}
112
79
} ;
113
80
0 commit comments