blob: 8c559788777d2b213462ed7f492641abbacf84a2 [file] [log] [blame]
Allen George8b96bfb2016-11-02 08:01:08 -04001// 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
18use std::convert::Into;
19
Allen Georgeef7a1892018-12-16 18:01:37 -050020use super::{
21 TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
22 TSetIdentifier, TStructIdentifier,
23};
Allen George0e22c362017-01-30 07:15:00 -050024use ProtocolErrorKind;
Allen George8b96bfb2016-11-02 08:01:08 -040025
26/// `TInputProtocol` required to use a `TMultiplexedProcessor`.
27///
28/// A `TMultiplexedProcessor` reads incoming message identifiers to determine to
29/// which `TProcessor` requests should be forwarded. However, once read, those
30/// message identifier bytes are no longer on the wire. Since downstream
31/// processors expect to read message identifiers from the given input protocol
32/// we need some way of supplying a `TMessageIdentifier` with the service-name
33/// stripped. This implementation stores the received `TMessageIdentifier`
34/// (without the service name) and passes it to the wrapped `TInputProtocol`
35/// when `TInputProtocol::read_message_begin(...)` is called. It delegates all
36/// other calls directly to the wrapped `TInputProtocol`.
37///
38/// This type **should not** be used by application code.
39///
40/// # Examples
41///
42/// Create and use a `TStoredInputProtocol`.
43///
44/// ```no_run
Allen George8b96bfb2016-11-02 08:01:08 -040045/// use thrift;
46/// use thrift::protocol::{TInputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
47/// use thrift::protocol::{TBinaryInputProtocol, TBinaryOutputProtocol, TStoredInputProtocol};
48/// use thrift::server::TProcessor;
Allen George0e22c362017-01-30 07:15:00 -050049/// use thrift::transport::{TIoChannel, TTcpChannel};
Allen George8b96bfb2016-11-02 08:01:08 -040050///
51/// // sample processor
52/// struct ActualProcessor;
53/// impl TProcessor for ActualProcessor {
54/// fn process(
Allen George0e22c362017-01-30 07:15:00 -050055/// &self,
Allen George8b96bfb2016-11-02 08:01:08 -040056/// _: &mut TInputProtocol,
57/// _: &mut TOutputProtocol
58/// ) -> thrift::Result<()> {
59/// unimplemented!()
60/// }
61/// }
Allen George0e22c362017-01-30 07:15:00 -050062/// let processor = ActualProcessor {};
Allen George8b96bfb2016-11-02 08:01:08 -040063///
64/// // construct the shared transport
Allen George0e22c362017-01-30 07:15:00 -050065/// let mut channel = TTcpChannel::new();
66/// channel.open("localhost:9090").unwrap();
67///
68/// let (i_chan, o_chan) = channel.split().unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -040069///
70/// // construct the actual input and output protocols
Allen George0e22c362017-01-30 07:15:00 -050071/// let mut i_prot = TBinaryInputProtocol::new(i_chan, true);
72/// let mut o_prot = TBinaryOutputProtocol::new(o_chan, true);
Allen George8b96bfb2016-11-02 08:01:08 -040073///
74/// // message identifier received from remote and modified to remove the service name
75/// let new_msg_ident = TMessageIdentifier::new("service_call", TMessageType::Call, 1);
76///
77/// // construct the proxy input protocol
78/// let mut proxy_i_prot = TStoredInputProtocol::new(&mut i_prot, new_msg_ident);
79/// let res = processor.process(&mut proxy_i_prot, &mut o_prot);
80/// ```
Allen George0e22c362017-01-30 07:15:00 -050081// FIXME: implement Debug
Allen George8b96bfb2016-11-02 08:01:08 -040082pub struct TStoredInputProtocol<'a> {
83 inner: &'a mut TInputProtocol,
84 message_ident: Option<TMessageIdentifier>,
85}
86
87impl<'a> TStoredInputProtocol<'a> {
88 /// Create a `TStoredInputProtocol` that delegates all calls other than
89 /// `TInputProtocol::read_message_begin(...)` to a `wrapped`
90 /// `TInputProtocol`. `message_ident` is the modified message identifier -
91 /// with service name stripped - that will be passed to
92 /// `wrapped.read_message_begin(...)`.
Allen George0e22c362017-01-30 07:15:00 -050093 pub fn new(
94 wrapped: &mut TInputProtocol,
95 message_ident: TMessageIdentifier,
96 ) -> TStoredInputProtocol {
Allen George8b96bfb2016-11-02 08:01:08 -040097 TStoredInputProtocol {
98 inner: wrapped,
99 message_ident: message_ident.into(),
100 }
101 }
102}
103
104impl<'a> TInputProtocol for TStoredInputProtocol<'a> {
105 fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
Allen Georgeef7a1892018-12-16 18:01:37 -0500106 self.message_ident.take().ok_or_else(|| {
107 ::errors::new_protocol_error(
108 ProtocolErrorKind::Unknown,
109 "message identifier already read",
Allen George0e22c362017-01-30 07:15:00 -0500110 )
Allen Georgeef7a1892018-12-16 18:01:37 -0500111 })
Allen George8b96bfb2016-11-02 08:01:08 -0400112 }
113
114 fn read_message_end(&mut self) -> ::Result<()> {
115 self.inner.read_message_end()
116 }
117
118 fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
119 self.inner.read_struct_begin()
120 }
121
122 fn read_struct_end(&mut self) -> ::Result<()> {
123 self.inner.read_struct_end()
124 }
125
126 fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
127 self.inner.read_field_begin()
128 }
129
130 fn read_field_end(&mut self) -> ::Result<()> {
131 self.inner.read_field_end()
132 }
133
134 fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
135 self.inner.read_bytes()
136 }
137
138 fn read_bool(&mut self) -> ::Result<bool> {
139 self.inner.read_bool()
140 }
141
142 fn read_i8(&mut self) -> ::Result<i8> {
143 self.inner.read_i8()
144 }
145
146 fn read_i16(&mut self) -> ::Result<i16> {
147 self.inner.read_i16()
148 }
149
150 fn read_i32(&mut self) -> ::Result<i32> {
151 self.inner.read_i32()
152 }
153
154 fn read_i64(&mut self) -> ::Result<i64> {
155 self.inner.read_i64()
156 }
157
158 fn read_double(&mut self) -> ::Result<f64> {
159 self.inner.read_double()
160 }
161
162 fn read_string(&mut self) -> ::Result<String> {
163 self.inner.read_string()
164 }
165
166 fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
167 self.inner.read_list_begin()
168 }
169
170 fn read_list_end(&mut self) -> ::Result<()> {
171 self.inner.read_list_end()
172 }
173
174 fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
175 self.inner.read_set_begin()
176 }
177
178 fn read_set_end(&mut self) -> ::Result<()> {
179 self.inner.read_set_end()
180 }
181
182 fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
183 self.inner.read_map_begin()
184 }
185
186 fn read_map_end(&mut self) -> ::Result<()> {
187 self.inner.read_map_end()
188 }
189
190 // utility
191 //
192
193 fn read_byte(&mut self) -> ::Result<u8> {
194 self.inner.read_byte()
195 }
196}