Allen George | 8b96bfb | 2016-11-02 08:01:08 -0400 | [diff] [blame] | 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 | |
Allen George | ef7a189 | 2018-12-16 18:01:37 -0500 | [diff] [blame] | 20 | use super::{ |
| 21 | TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier, |
| 22 | TSetIdentifier, TStructIdentifier, |
| 23 | }; |
Allen George | 0e22c36 | 2017-01-30 07:15:00 -0500 | [diff] [blame] | 24 | use ProtocolErrorKind; |
Allen George | 8b96bfb | 2016-11-02 08:01:08 -0400 | [diff] [blame] | 25 | |
| 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 George | 8b96bfb | 2016-11-02 08:01:08 -0400 | [diff] [blame] | 45 | /// use thrift::protocol::{TInputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol}; |
| 46 | /// use thrift::protocol::{TBinaryInputProtocol, TBinaryOutputProtocol, TStoredInputProtocol}; |
| 47 | /// use thrift::server::TProcessor; |
Allen George | 0e22c36 | 2017-01-30 07:15:00 -0500 | [diff] [blame] | 48 | /// use thrift::transport::{TIoChannel, TTcpChannel}; |
Allen George | 8b96bfb | 2016-11-02 08:01:08 -0400 | [diff] [blame] | 49 | /// |
| 50 | /// // sample processor |
| 51 | /// struct ActualProcessor; |
| 52 | /// impl TProcessor for ActualProcessor { |
| 53 | /// fn process( |
Allen George | 0e22c36 | 2017-01-30 07:15:00 -0500 | [diff] [blame] | 54 | /// &self, |
Marcin Pajkowski | c630841 | 2019-12-02 11:39:28 +0100 | [diff] [blame^] | 55 | /// _: &mut dyn TInputProtocol, |
| 56 | /// _: &mut dyn TOutputProtocol |
Allen George | 8b96bfb | 2016-11-02 08:01:08 -0400 | [diff] [blame] | 57 | /// ) -> thrift::Result<()> { |
| 58 | /// unimplemented!() |
| 59 | /// } |
| 60 | /// } |
Allen George | 0e22c36 | 2017-01-30 07:15:00 -0500 | [diff] [blame] | 61 | /// let processor = ActualProcessor {}; |
Allen George | 8b96bfb | 2016-11-02 08:01:08 -0400 | [diff] [blame] | 62 | /// |
| 63 | /// // construct the shared transport |
Allen George | 0e22c36 | 2017-01-30 07:15:00 -0500 | [diff] [blame] | 64 | /// let mut channel = TTcpChannel::new(); |
| 65 | /// channel.open("localhost:9090").unwrap(); |
| 66 | /// |
| 67 | /// let (i_chan, o_chan) = channel.split().unwrap(); |
Allen George | 8b96bfb | 2016-11-02 08:01:08 -0400 | [diff] [blame] | 68 | /// |
| 69 | /// // construct the actual input and output protocols |
Allen George | 0e22c36 | 2017-01-30 07:15:00 -0500 | [diff] [blame] | 70 | /// let mut i_prot = TBinaryInputProtocol::new(i_chan, true); |
| 71 | /// let mut o_prot = TBinaryOutputProtocol::new(o_chan, true); |
Allen George | 8b96bfb | 2016-11-02 08:01:08 -0400 | [diff] [blame] | 72 | /// |
| 73 | /// // message identifier received from remote and modified to remove the service name |
| 74 | /// let new_msg_ident = TMessageIdentifier::new("service_call", TMessageType::Call, 1); |
| 75 | /// |
| 76 | /// // construct the proxy input protocol |
| 77 | /// let mut proxy_i_prot = TStoredInputProtocol::new(&mut i_prot, new_msg_ident); |
| 78 | /// let res = processor.process(&mut proxy_i_prot, &mut o_prot); |
| 79 | /// ``` |
Allen George | 0e22c36 | 2017-01-30 07:15:00 -0500 | [diff] [blame] | 80 | // FIXME: implement Debug |
Allen George | 8b96bfb | 2016-11-02 08:01:08 -0400 | [diff] [blame] | 81 | pub struct TStoredInputProtocol<'a> { |
Danny Browning | 77d96c1 | 2019-08-21 13:41:07 -0600 | [diff] [blame] | 82 | inner: &'a mut dyn TInputProtocol, |
Allen George | 8b96bfb | 2016-11-02 08:01:08 -0400 | [diff] [blame] | 83 | message_ident: Option<TMessageIdentifier>, |
| 84 | } |
| 85 | |
| 86 | impl<'a> TStoredInputProtocol<'a> { |
| 87 | /// Create a `TStoredInputProtocol` that delegates all calls other than |
| 88 | /// `TInputProtocol::read_message_begin(...)` to a `wrapped` |
| 89 | /// `TInputProtocol`. `message_ident` is the modified message identifier - |
| 90 | /// with service name stripped - that will be passed to |
| 91 | /// `wrapped.read_message_begin(...)`. |
Allen George | 0e22c36 | 2017-01-30 07:15:00 -0500 | [diff] [blame] | 92 | pub fn new( |
Danny Browning | 77d96c1 | 2019-08-21 13:41:07 -0600 | [diff] [blame] | 93 | wrapped: &mut dyn TInputProtocol, |
Allen George | 0e22c36 | 2017-01-30 07:15:00 -0500 | [diff] [blame] | 94 | message_ident: TMessageIdentifier, |
| 95 | ) -> TStoredInputProtocol { |
Allen George | 8b96bfb | 2016-11-02 08:01:08 -0400 | [diff] [blame] | 96 | TStoredInputProtocol { |
| 97 | inner: wrapped, |
| 98 | message_ident: message_ident.into(), |
| 99 | } |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | impl<'a> TInputProtocol for TStoredInputProtocol<'a> { |
| 104 | fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> { |
Allen George | ef7a189 | 2018-12-16 18:01:37 -0500 | [diff] [blame] | 105 | self.message_ident.take().ok_or_else(|| { |
| 106 | ::errors::new_protocol_error( |
| 107 | ProtocolErrorKind::Unknown, |
| 108 | "message identifier already read", |
Allen George | 0e22c36 | 2017-01-30 07:15:00 -0500 | [diff] [blame] | 109 | ) |
Allen George | ef7a189 | 2018-12-16 18:01:37 -0500 | [diff] [blame] | 110 | }) |
Allen George | 8b96bfb | 2016-11-02 08:01:08 -0400 | [diff] [blame] | 111 | } |
| 112 | |
| 113 | fn read_message_end(&mut self) -> ::Result<()> { |
| 114 | self.inner.read_message_end() |
| 115 | } |
| 116 | |
| 117 | fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> { |
| 118 | self.inner.read_struct_begin() |
| 119 | } |
| 120 | |
| 121 | fn read_struct_end(&mut self) -> ::Result<()> { |
| 122 | self.inner.read_struct_end() |
| 123 | } |
| 124 | |
| 125 | fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> { |
| 126 | self.inner.read_field_begin() |
| 127 | } |
| 128 | |
| 129 | fn read_field_end(&mut self) -> ::Result<()> { |
| 130 | self.inner.read_field_end() |
| 131 | } |
| 132 | |
| 133 | fn read_bytes(&mut self) -> ::Result<Vec<u8>> { |
| 134 | self.inner.read_bytes() |
| 135 | } |
| 136 | |
| 137 | fn read_bool(&mut self) -> ::Result<bool> { |
| 138 | self.inner.read_bool() |
| 139 | } |
| 140 | |
| 141 | fn read_i8(&mut self) -> ::Result<i8> { |
| 142 | self.inner.read_i8() |
| 143 | } |
| 144 | |
| 145 | fn read_i16(&mut self) -> ::Result<i16> { |
| 146 | self.inner.read_i16() |
| 147 | } |
| 148 | |
| 149 | fn read_i32(&mut self) -> ::Result<i32> { |
| 150 | self.inner.read_i32() |
| 151 | } |
| 152 | |
| 153 | fn read_i64(&mut self) -> ::Result<i64> { |
| 154 | self.inner.read_i64() |
| 155 | } |
| 156 | |
| 157 | fn read_double(&mut self) -> ::Result<f64> { |
| 158 | self.inner.read_double() |
| 159 | } |
| 160 | |
| 161 | fn read_string(&mut self) -> ::Result<String> { |
| 162 | self.inner.read_string() |
| 163 | } |
| 164 | |
| 165 | fn read_list_begin(&mut self) -> ::Result<TListIdentifier> { |
| 166 | self.inner.read_list_begin() |
| 167 | } |
| 168 | |
| 169 | fn read_list_end(&mut self) -> ::Result<()> { |
| 170 | self.inner.read_list_end() |
| 171 | } |
| 172 | |
| 173 | fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> { |
| 174 | self.inner.read_set_begin() |
| 175 | } |
| 176 | |
| 177 | fn read_set_end(&mut self) -> ::Result<()> { |
| 178 | self.inner.read_set_end() |
| 179 | } |
| 180 | |
| 181 | fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> { |
| 182 | self.inner.read_map_begin() |
| 183 | } |
| 184 | |
| 185 | fn read_map_end(&mut self) -> ::Result<()> { |
| 186 | self.inner.read_map_end() |
| 187 | } |
| 188 | |
| 189 | // utility |
| 190 | // |
| 191 | |
| 192 | fn read_byte(&mut self) -> ::Result<u8> { |
| 193 | self.inner.read_byte() |
| 194 | } |
| 195 | } |