4
4
// https://www.tldrlegal.com/l/mpl-2.0>. This file may not be copied,
5
5
// modified, or distributed except according to those terms.
6
6
7
- use bytes:: { BufMut , BytesMut } ;
7
+ use bytes:: BytesMut ;
8
8
use errors:: * ;
9
9
use futures:: { future, Future } ;
10
10
use remote:: Runnable ;
@@ -15,14 +15,18 @@ use std::sync::Arc;
15
15
use std:: net:: SocketAddr ;
16
16
use super :: { Host , HostType } ;
17
17
use telemetry:: { self , Telemetry } ;
18
- use tokio_core:: net:: TcpStream ;
19
18
use tokio_core:: reactor:: Handle ;
20
19
use tokio_io:: { AsyncRead , AsyncWrite } ;
21
20
use tokio_io:: codec:: { Encoder , Decoder , Framed } ;
22
- use tokio_proto:: pipeline:: { ClientProto , ClientService , ServerProto } ;
21
+ use tokio_proto:: streaming:: { Body , Message } ;
22
+ use tokio_proto:: streaming:: pipeline:: { ClientProto , Frame , ServerProto } ;
23
23
use tokio_proto:: TcpClient ;
24
+ use tokio_proto:: util:: client_proxy:: ClientProxy ;
24
25
use tokio_service:: Service ;
25
26
27
+ #[ doc( hidden) ]
28
+ pub type LineMessage = Message < serde_json:: Value , Body < Vec < u8 > , io:: Error > > ;
29
+
26
30
/// A `Host` type that uses an unencrypted socket.
27
31
///
28
32
/// *Warning! An unencrypted host is susceptible to eavesdropping and MITM
@@ -34,12 +38,14 @@ pub struct Plain {
34
38
}
35
39
36
40
struct Inner {
37
- inner : ClientService < TcpStream , JsonProto > ,
41
+ inner : ClientProxy < LineMessage , LineMessage , io :: Error > ,
38
42
telemetry : Option < Telemetry > ,
39
43
}
40
44
41
- pub struct JsonCodec ;
42
- pub struct JsonProto ;
45
+ pub struct JsonLineCodec {
46
+ decoding_head : bool ,
47
+ }
48
+ pub struct JsonLineProto ;
43
49
44
50
impl Plain {
45
51
/// Create a new Host connected to addr.
@@ -51,7 +57,7 @@ impl Plain {
51
57
52
58
info ! ( "Connecting to host {}" , addr) ;
53
59
54
- Box :: new ( TcpClient :: new ( JsonProto )
60
+ Box :: new ( TcpClient :: new ( JsonLineProto )
55
61
. connect ( & addr, handle)
56
62
. chain_err ( || "Could not connect to host" )
57
63
. and_then ( |client_service| {
@@ -77,16 +83,31 @@ impl Plain {
77
83
#[ doc( hidden) ]
78
84
pub fn run < D : ' static > ( & self , provider : Runnable ) -> Box < Future < Item = D , Error = Error > >
79
85
where for < ' de > D : Deserialize < ' de >
86
+ {
87
+ Box :: new ( self . run_msg :: < D > ( provider)
88
+ . map ( |msg| msg. into_inner ( ) ) )
89
+ }
90
+
91
+ #[ doc( hidden) ]
92
+ pub fn run_msg < D : ' static > ( & self , provider : Runnable ) -> Box < Future < Item = Message < D , Body < Vec < u8 > , io:: Error > > , Error = Error > >
93
+ where for < ' de > D : Deserialize < ' de >
80
94
{
81
95
let value = match serde_json:: to_value ( provider) . chain_err ( || "Could not encode provider to send to host" ) {
82
96
Ok ( v) => v,
83
97
Err ( e) => return Box :: new ( future:: err ( e) )
84
98
} ;
85
- Box :: new ( self . call ( value)
99
+ Box :: new ( self . inner . inner . call ( Message :: WithoutBody ( value) )
86
100
. chain_err ( || "Error while running provider on host" )
87
- . and_then ( |v| match serde_json:: from_value :: < D > ( v) . chain_err ( || "Could not understand response from host" ) {
88
- Ok ( d) => future:: ok ( d) ,
89
- Err ( e) => future:: err ( e)
101
+ . and_then ( |mut msg| {
102
+ let body = msg. take_body ( ) ;
103
+ let msg = match serde_json:: from_value :: < D > ( msg. into_inner ( ) ) . chain_err ( || "Could not understand response from host" ) {
104
+ Ok ( d) => d,
105
+ Err ( e) => return Box :: new ( future:: err ( e) ) ,
106
+ } ;
107
+ Box :: new ( future:: ok ( match body {
108
+ Some ( b) => Message :: WithBody ( msg, b) ,
109
+ None => Message :: WithoutBody ( msg) ,
110
+ } ) )
90
111
} ) )
91
112
}
92
113
}
@@ -102,8 +123,8 @@ impl Host for Plain {
102
123
}
103
124
104
125
impl Service for Plain {
105
- type Request = serde_json :: Value ;
106
- type Response = serde_json :: Value ;
126
+ type Request = LineMessage ;
127
+ type Response = LineMessage ;
107
128
type Error = io:: Error ;
108
129
type Future = Box < Future < Item = Self :: Response , Error = Self :: Error > > ;
109
130
@@ -112,58 +133,113 @@ impl Service for Plain {
112
133
}
113
134
}
114
135
115
- impl Decoder for JsonCodec {
116
- type Item = serde_json:: Value ;
136
+ impl Decoder for JsonLineCodec {
137
+ type Item = Frame < serde_json:: Value , Vec < u8 > , io :: Error > ;
117
138
type Error = io:: Error ;
118
139
119
- fn decode ( & mut self , buf : & mut BytesMut ) -> result:: Result < Option < Self :: Item > , Self :: Error > {
120
- // Check to see if the frame contains a new line
121
- if let Some ( n) = buf. as_ref ( ) . iter ( ) . position ( |b| * b == b'\n' ) {
122
- // remove the serialized frame from the buffer.
123
- let line = buf. split_to ( n) ;
124
-
125
- // Also remove the '\n'
126
- buf. split_to ( 1 ) ;
140
+ fn decode ( & mut self , buf : & mut BytesMut ) -> io:: Result < Option < Self :: Item > > {
141
+ let line = match buf. iter ( ) . position ( |b| * b == b'\n' ) {
142
+ Some ( n) => buf. split_to ( n) ,
143
+ None => return Ok ( None ) ,
144
+ } ;
127
145
128
- return Ok ( Some ( serde_json:: from_slice ( & line) . unwrap ( ) ) ) ;
146
+ buf. split_to ( 1 ) ;
147
+
148
+ if line. is_empty ( ) {
149
+ let decoding_head = self . decoding_head ;
150
+ self . decoding_head = !decoding_head;
151
+
152
+ if decoding_head {
153
+ Ok ( Some ( Frame :: Message {
154
+ message : serde_json:: Value :: Null ,
155
+ body : true ,
156
+ } ) )
157
+ } else {
158
+ Ok ( Some ( Frame :: Body {
159
+ chunk : None
160
+ } ) )
161
+ }
162
+ } else {
163
+ if self . decoding_head {
164
+ Ok ( Some ( Frame :: Message {
165
+ message : serde_json:: from_slice ( & line) . map_err ( |e| {
166
+ io:: Error :: new ( io:: ErrorKind :: Other , e)
167
+ } ) ?,
168
+ body : false ,
169
+ } ) )
170
+ } else {
171
+ Ok ( Some ( Frame :: Body {
172
+ chunk : Some ( line. to_vec ( ) ) ,
173
+ } ) )
174
+ }
129
175
}
130
-
131
- Ok ( None )
132
176
}
133
177
}
134
178
135
- impl Encoder for JsonCodec {
136
- type Item = serde_json:: Value ;
179
+ impl Encoder for JsonLineCodec {
180
+ type Item = Frame < serde_json:: Value , Vec < u8 > , io :: Error > ;
137
181
type Error = io:: Error ;
138
182
139
- fn encode ( & mut self , value : Self :: Item , buf : & mut BytesMut ) -> io:: Result < ( ) > {
140
- let json = serde_json:: to_string ( & value) . unwrap ( ) ;
141
- buf. reserve ( json. len ( ) + 1 ) ;
142
- buf. extend ( json. as_bytes ( ) ) ;
143
- buf. put_u8 ( b'\n' ) ;
183
+ fn encode ( & mut self , msg : Self :: Item , buf : & mut BytesMut ) -> io:: Result < ( ) > {
184
+ match msg {
185
+ Frame :: Message { message, body } => {
186
+ // Our protocol dictates that a message head that
187
+ // includes a streaming body is an empty string.
188
+ assert ! ( message. is_null( ) == body) ;
189
+
190
+ let json = serde_json:: to_vec ( & message)
191
+ . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: Other , e) ) ?;
192
+ buf. extend ( & json) ;
193
+ }
194
+ Frame :: Body { chunk } => {
195
+ if let Some ( chunk) = chunk {
196
+ buf. extend ( & chunk) ;
197
+ }
198
+ }
199
+ Frame :: Error { error } => {
200
+ // @todo Support error frames
201
+ return Err ( error)
202
+ }
203
+ }
204
+
205
+ buf. extend ( b"\n " ) ;
144
206
145
207
Ok ( ( ) )
146
208
}
147
209
}
148
210
149
- impl < T : AsyncRead + AsyncWrite + ' static > ClientProto < T > for JsonProto {
211
+ impl < T : AsyncRead + AsyncWrite + ' static > ClientProto < T > for JsonLineProto {
150
212
type Request = serde_json:: Value ;
213
+ type RequestBody = Vec < u8 > ;
151
214
type Response = serde_json:: Value ;
152
- type Transport = Framed < T , JsonCodec > ;
153
- type BindTransport = result:: Result < Self :: Transport , io:: Error > ;
215
+ type ResponseBody = Vec < u8 > ;
216
+ type Error = io:: Error ;
217
+ type Transport = Framed < T , JsonLineCodec > ;
218
+ type BindTransport = result:: Result < Self :: Transport , Self :: Error > ;
154
219
155
220
fn bind_transport ( & self , io : T ) -> Self :: BindTransport {
156
- Ok ( io. framed ( JsonCodec ) )
221
+ let codec = JsonLineCodec {
222
+ decoding_head : true ,
223
+ } ;
224
+
225
+ Ok ( io. framed ( codec) )
157
226
}
158
227
}
159
228
160
- impl < T : AsyncRead + AsyncWrite + ' static > ServerProto < T > for JsonProto {
229
+ impl < T : AsyncRead + AsyncWrite + ' static > ServerProto < T > for JsonLineProto {
161
230
type Request = serde_json:: Value ;
231
+ type RequestBody = Vec < u8 > ;
162
232
type Response = serde_json:: Value ;
163
- type Transport = Framed < T , JsonCodec > ;
164
- type BindTransport = result:: Result < Self :: Transport , io:: Error > ;
233
+ type ResponseBody = Vec < u8 > ;
234
+ type Error = io:: Error ;
235
+ type Transport = Framed < T , JsonLineCodec > ;
236
+ type BindTransport = result:: Result < Self :: Transport , Self :: Error > ;
165
237
166
238
fn bind_transport ( & self , io : T ) -> Self :: BindTransport {
167
- Ok ( io. framed ( JsonCodec ) )
239
+ let codec = JsonLineCodec {
240
+ decoding_head : true ,
241
+ } ;
242
+
243
+ Ok ( io. framed ( codec) )
168
244
}
169
245
}
0 commit comments