1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 //   http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied. See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17 
18 use std::convert::Into;
19 
20 use ProtocolErrorKind;
21 use super::{TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
22             TSetIdentifier, TStructIdentifier};
23 
24 /// `TInputProtocol` required to use a `TMultiplexedProcessor`.
25 ///
26 /// A `TMultiplexedProcessor` reads incoming message identifiers to determine to
27 /// which `TProcessor` requests should be forwarded. However, once read, those
28 /// message identifier bytes are no longer on the wire. Since downstream
29 /// processors expect to read message identifiers from the given input protocol
30 /// we need some way of supplying a `TMessageIdentifier` with the service-name
31 /// stripped. This implementation stores the received `TMessageIdentifier`
32 /// (without the service name) and passes it to the wrapped `TInputProtocol`
33 /// when `TInputProtocol::read_message_begin(...)` is called. It delegates all
34 /// other calls directly to the wrapped `TInputProtocol`.
35 ///
36 /// This type **should not** be used by application code.
37 ///
38 /// # Examples
39 ///
40 /// Create and use a `TStoredInputProtocol`.
41 ///
42 /// ```no_run
43 /// use thrift;
44 /// use thrift::protocol::{TInputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
45 /// use thrift::protocol::{TBinaryInputProtocol, TBinaryOutputProtocol, TStoredInputProtocol};
46 /// use thrift::server::TProcessor;
47 /// use thrift::transport::{TIoChannel, TTcpChannel};
48 ///
49 /// // sample processor
50 /// struct ActualProcessor;
51 /// impl TProcessor for ActualProcessor {
52 ///     fn process(
53 ///         &self,
54 ///         _: &mut TInputProtocol,
55 ///         _: &mut TOutputProtocol
56 ///     ) -> thrift::Result<()> {
57 ///         unimplemented!()
58 ///     }
59 /// }
60 /// let processor = ActualProcessor {};
61 ///
62 /// // construct the shared transport
63 /// let mut channel = TTcpChannel::new();
64 /// channel.open("localhost:9090").unwrap();
65 ///
66 /// let (i_chan, o_chan) = channel.split().unwrap();
67 ///
68 /// // construct the actual input and output protocols
69 /// let mut i_prot = TBinaryInputProtocol::new(i_chan, true);
70 /// let mut o_prot = TBinaryOutputProtocol::new(o_chan, true);
71 ///
72 /// // message identifier received from remote and modified to remove the service name
73 /// let new_msg_ident = TMessageIdentifier::new("service_call", TMessageType::Call, 1);
74 ///
75 /// // construct the proxy input protocol
76 /// let mut proxy_i_prot = TStoredInputProtocol::new(&mut i_prot, new_msg_ident);
77 /// let res = processor.process(&mut proxy_i_prot, &mut o_prot);
78 /// ```
79 // FIXME: implement Debug
80 pub struct TStoredInputProtocol<'a> {
81     inner: &'a mut TInputProtocol,
82     message_ident: Option<TMessageIdentifier>,
83 }
84 
85 impl<'a> TStoredInputProtocol<'a> {
86     /// Create a `TStoredInputProtocol` that delegates all calls other than
87     /// `TInputProtocol::read_message_begin(...)` to a `wrapped`
88     /// `TInputProtocol`. `message_ident` is the modified message identifier -
89     /// with service name stripped - that will be passed to
90     /// `wrapped.read_message_begin(...)`.
new( wrapped: &mut TInputProtocol, message_ident: TMessageIdentifier, ) -> TStoredInputProtocol91     pub fn new(
92         wrapped: &mut TInputProtocol,
93         message_ident: TMessageIdentifier,
94     ) -> TStoredInputProtocol {
95         TStoredInputProtocol {
96             inner: wrapped,
97             message_ident: message_ident.into(),
98         }
99     }
100 }
101 
102 impl<'a> TInputProtocol for TStoredInputProtocol<'a> {
read_message_begin(&mut self) -> ::Result<TMessageIdentifier>103     fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
104         self.message_ident
105             .take()
106             .ok_or_else(
107                 || {
108                     ::errors::new_protocol_error(
109                         ProtocolErrorKind::Unknown,
110                         "message identifier already read",
111                     )
112                 },
113             )
114     }
115 
read_message_end(&mut self) -> ::Result<()>116     fn read_message_end(&mut self) -> ::Result<()> {
117         self.inner.read_message_end()
118     }
119 
read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>>120     fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
121         self.inner.read_struct_begin()
122     }
123 
read_struct_end(&mut self) -> ::Result<()>124     fn read_struct_end(&mut self) -> ::Result<()> {
125         self.inner.read_struct_end()
126     }
127 
read_field_begin(&mut self) -> ::Result<TFieldIdentifier>128     fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
129         self.inner.read_field_begin()
130     }
131 
read_field_end(&mut self) -> ::Result<()>132     fn read_field_end(&mut self) -> ::Result<()> {
133         self.inner.read_field_end()
134     }
135 
read_bytes(&mut self) -> ::Result<Vec<u8>>136     fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
137         self.inner.read_bytes()
138     }
139 
read_bool(&mut self) -> ::Result<bool>140     fn read_bool(&mut self) -> ::Result<bool> {
141         self.inner.read_bool()
142     }
143 
read_i8(&mut self) -> ::Result<i8>144     fn read_i8(&mut self) -> ::Result<i8> {
145         self.inner.read_i8()
146     }
147 
read_i16(&mut self) -> ::Result<i16>148     fn read_i16(&mut self) -> ::Result<i16> {
149         self.inner.read_i16()
150     }
151 
read_i32(&mut self) -> ::Result<i32>152     fn read_i32(&mut self) -> ::Result<i32> {
153         self.inner.read_i32()
154     }
155 
read_i64(&mut self) -> ::Result<i64>156     fn read_i64(&mut self) -> ::Result<i64> {
157         self.inner.read_i64()
158     }
159 
read_double(&mut self) -> ::Result<f64>160     fn read_double(&mut self) -> ::Result<f64> {
161         self.inner.read_double()
162     }
163 
read_string(&mut self) -> ::Result<String>164     fn read_string(&mut self) -> ::Result<String> {
165         self.inner.read_string()
166     }
167 
read_list_begin(&mut self) -> ::Result<TListIdentifier>168     fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
169         self.inner.read_list_begin()
170     }
171 
read_list_end(&mut self) -> ::Result<()>172     fn read_list_end(&mut self) -> ::Result<()> {
173         self.inner.read_list_end()
174     }
175 
read_set_begin(&mut self) -> ::Result<TSetIdentifier>176     fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
177         self.inner.read_set_begin()
178     }
179 
read_set_end(&mut self) -> ::Result<()>180     fn read_set_end(&mut self) -> ::Result<()> {
181         self.inner.read_set_end()
182     }
183 
read_map_begin(&mut self) -> ::Result<TMapIdentifier>184     fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
185         self.inner.read_map_begin()
186     }
187 
read_map_end(&mut self) -> ::Result<()>188     fn read_map_end(&mut self) -> ::Result<()> {
189         self.inner.read_map_end()
190     }
191 
192     // utility
193     //
194 
read_byte(&mut self) -> ::Result<u8>195     fn read_byte(&mut self) -> ::Result<u8> {
196         self.inner.read_byte()
197     }
198 }
199