44// https://www.tldrlegal.com/l/mpl-2.0>. This file may not be copied,
55// modified, or distributed except according to those terms.
66
7- use bytes:: { BufMut , BytesMut } ;
7+ use bytes:: BytesMut ;
88use errors:: * ;
99use futures:: { future, Future } ;
1010use remote:: Runnable ;
@@ -15,14 +15,18 @@ use std::sync::Arc;
1515use std:: net:: SocketAddr ;
1616use super :: { Host , HostType } ;
1717use telemetry:: { self , Telemetry } ;
18- use tokio_core:: net:: TcpStream ;
1918use tokio_core:: reactor:: Handle ;
2019use tokio_io:: { AsyncRead , AsyncWrite } ;
2120use 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 } ;
2323use tokio_proto:: TcpClient ;
24+ use tokio_proto:: util:: client_proxy:: ClientProxy ;
2425use tokio_service:: Service ;
2526
27+ #[ doc( hidden) ]
28+ pub type LineMessage = Message < serde_json:: Value , Body < Vec < u8 > , io:: Error > > ;
29+
2630/// A `Host` type that uses an unencrypted socket.
2731///
2832/// *Warning! An unencrypted host is susceptible to eavesdropping and MITM
@@ -34,12 +38,14 @@ pub struct Plain {
3438}
3539
3640struct Inner {
37- inner : ClientService < TcpStream , JsonProto > ,
41+ inner : ClientProxy < LineMessage , LineMessage , io :: Error > ,
3842 telemetry : Option < Telemetry > ,
3943}
4044
41- pub struct JsonCodec ;
42- pub struct JsonProto ;
45+ pub struct JsonLineCodec {
46+ decoding_head : bool ,
47+ }
48+ pub struct JsonLineProto ;
4349
4450impl Plain {
4551 /// Create a new Host connected to addr.
@@ -51,7 +57,7 @@ impl Plain {
5157
5258 info ! ( "Connecting to host {}" , addr) ;
5359
54- Box :: new ( TcpClient :: new ( JsonProto )
60+ Box :: new ( TcpClient :: new ( JsonLineProto )
5561 . connect ( & addr, handle)
5662 . chain_err ( || "Could not connect to host" )
5763 . and_then ( |client_service| {
@@ -77,16 +83,31 @@ impl Plain {
7783 #[ doc( hidden) ]
7884 pub fn run < D : ' static > ( & self , provider : Runnable ) -> Box < Future < Item = D , Error = Error > >
7985 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 >
8094 {
8195 let value = match serde_json:: to_value ( provider) . chain_err ( || "Could not encode provider to send to host" ) {
8296 Ok ( v) => v,
8397 Err ( e) => return Box :: new ( future:: err ( e) )
8498 } ;
85- Box :: new ( self . call ( value)
99+ Box :: new ( self . inner . inner . call ( Message :: WithoutBody ( value) )
86100 . 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+ } ) )
90111 } ) )
91112 }
92113}
@@ -102,8 +123,8 @@ impl Host for Plain {
102123}
103124
104125impl Service for Plain {
105- type Request = serde_json :: Value ;
106- type Response = serde_json :: Value ;
126+ type Request = LineMessage ;
127+ type Response = LineMessage ;
107128 type Error = io:: Error ;
108129 type Future = Box < Future < Item = Self :: Response , Error = Self :: Error > > ;
109130
@@ -112,58 +133,113 @@ impl Service for Plain {
112133 }
113134}
114135
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 > ;
117138 type Error = io:: Error ;
118139
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+ } ;
127145
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+ }
129175 }
130-
131- Ok ( None )
132176 }
133177}
134178
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 > ;
137181 type Error = io:: Error ;
138182
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 " ) ;
144206
145207 Ok ( ( ) )
146208 }
147209}
148210
149- impl < T : AsyncRead + AsyncWrite + ' static > ClientProto < T > for JsonProto {
211+ impl < T : AsyncRead + AsyncWrite + ' static > ClientProto < T > for JsonLineProto {
150212 type Request = serde_json:: Value ;
213+ type RequestBody = Vec < u8 > ;
151214 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 > ;
154219
155220 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) )
157226 }
158227}
159228
160- impl < T : AsyncRead + AsyncWrite + ' static > ServerProto < T > for JsonProto {
229+ impl < T : AsyncRead + AsyncWrite + ' static > ServerProto < T > for JsonLineProto {
161230 type Request = serde_json:: Value ;
231+ type RequestBody = Vec < u8 > ;
162232 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 > ;
165237
166238 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) )
168244 }
169245}
0 commit comments