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