From 19a2355655469282f7305e9d96e46b98c74d79eb Mon Sep 17 00:00:00 2001 From: Oleg Doronin Date: Thu, 16 May 2024 20:27:26 +0300 Subject: [PATCH] returning a lost file TDispatchProcessor.h (#4622) --- .../thrift/thrift/TDispatchProcessor.h | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 contrib/restricted/thrift/thrift/TDispatchProcessor.h diff --git a/contrib/restricted/thrift/thrift/TDispatchProcessor.h b/contrib/restricted/thrift/thrift/TDispatchProcessor.h new file mode 100644 index 000000000000..dadc87b5c056 --- /dev/null +++ b/contrib/restricted/thrift/thrift/TDispatchProcessor.h @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#ifndef _THRIFT_TDISPATCHPROCESSOR_H_ +#define _THRIFT_TDISPATCHPROCESSOR_H_ 1 + +#include + +namespace apache { +namespace thrift { + +/** + * TDispatchProcessor is a helper class to parse the message header then call + * another function to dispatch based on the function name. + * + * Subclasses must implement dispatchCall() to dispatch on the function name. + */ +template +class TDispatchProcessorT : public TProcessor { +public: + virtual bool process(stdcxx::shared_ptr in, + stdcxx::shared_ptr out, + void* connectionContext) { + protocol::TProtocol* inRaw = in.get(); + protocol::TProtocol* outRaw = out.get(); + + // Try to dynamic cast to the template protocol type + Protocol_* specificIn = dynamic_cast(inRaw); + Protocol_* specificOut = dynamic_cast(outRaw); + if (specificIn && specificOut) { + return processFast(specificIn, specificOut, connectionContext); + } + + // Log the fact that we have to use the slow path + T_GENERIC_PROTOCOL(this, inRaw, specificIn); + T_GENERIC_PROTOCOL(this, outRaw, specificOut); + + std::string fname; + protocol::TMessageType mtype; + int32_t seqid; + inRaw->readMessageBegin(fname, mtype, seqid); + + // If this doesn't look like a valid call, log an error and return false so + // that the server will close the connection. + // + // (The old generated processor code used to try to skip a T_STRUCT and + // continue. However, that seems unsafe.) + if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) { + GlobalOutput.printf("received invalid message type %d from client", mtype); + return false; + } + + return this->dispatchCall(inRaw, outRaw, fname, seqid, connectionContext); + } + +protected: + bool processFast(Protocol_* in, Protocol_* out, void* connectionContext) { + std::string fname; + protocol::TMessageType mtype; + int32_t seqid; + in->readMessageBegin(fname, mtype, seqid); + + if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) { + GlobalOutput.printf("received invalid message type %d from client", mtype); + return false; + } + + return this->dispatchCallTemplated(in, out, fname, seqid, connectionContext); + } + + /** + * dispatchCall() methods must be implemented by subclasses + */ + virtual bool dispatchCall(apache::thrift::protocol::TProtocol* in, + apache::thrift::protocol::TProtocol* out, + const std::string& fname, + int32_t seqid, + void* callContext) = 0; + + virtual bool dispatchCallTemplated(Protocol_* in, + Protocol_* out, + const std::string& fname, + int32_t seqid, + void* callContext) = 0; +}; + +/** + * Non-templatized version of TDispatchProcessor, that doesn't bother trying to + * perform a dynamic_cast. + */ +class TDispatchProcessor : public TProcessor { +public: + virtual bool process(stdcxx::shared_ptr in, + stdcxx::shared_ptr out, + void* connectionContext) { + std::string fname; + protocol::TMessageType mtype; + int32_t seqid; + in->readMessageBegin(fname, mtype, seqid); + + if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) { + GlobalOutput.printf("received invalid message type %d from client", mtype); + return false; + } + + return dispatchCall(in.get(), out.get(), fname, seqid, connectionContext); + } + +protected: + virtual bool dispatchCall(apache::thrift::protocol::TProtocol* in, + apache::thrift::protocol::TProtocol* out, + const std::string& fname, + int32_t seqid, + void* callContext) = 0; +}; + +// Specialize TDispatchProcessorT for TProtocol and TDummyProtocol just to use +// the generic TDispatchProcessor. +template <> +class TDispatchProcessorT : public TDispatchProcessor {}; +template <> +class TDispatchProcessorT : public TDispatchProcessor {}; +} +} // apache::thrift + +#endif // _THRIFT_TDISPATCHPROCESSOR_H_