TDispatchProcessor.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. #ifndef _THRIFT_TDISPATCHPROCESSOR_H_
  20. #define _THRIFT_TDISPATCHPROCESSOR_H_ 1
  21. #include <thrift/TProcessor.h>
  22. namespace apache {
  23. namespace thrift {
  24. /**
  25. * TDispatchProcessor is a helper class to parse the message header then call
  26. * another function to dispatch based on the function name.
  27. *
  28. * Subclasses must implement dispatchCall() to dispatch on the function name.
  29. */
  30. template <class Protocol_>
  31. class TDispatchProcessorT : public TProcessor {
  32. public:
  33. virtual bool process(stdcxx::shared_ptr<protocol::TProtocol> in,
  34. stdcxx::shared_ptr<protocol::TProtocol> out,
  35. void* connectionContext) {
  36. protocol::TProtocol* inRaw = in.get();
  37. protocol::TProtocol* outRaw = out.get();
  38. // Try to dynamic cast to the template protocol type
  39. Protocol_* specificIn = dynamic_cast<Protocol_*>(inRaw);
  40. Protocol_* specificOut = dynamic_cast<Protocol_*>(outRaw);
  41. if (specificIn && specificOut) {
  42. return processFast(specificIn, specificOut, connectionContext);
  43. }
  44. // Log the fact that we have to use the slow path
  45. T_GENERIC_PROTOCOL(this, inRaw, specificIn);
  46. T_GENERIC_PROTOCOL(this, outRaw, specificOut);
  47. std::string fname;
  48. protocol::TMessageType mtype;
  49. int32_t seqid;
  50. inRaw->readMessageBegin(fname, mtype, seqid);
  51. // If this doesn't look like a valid call, log an error and return false so
  52. // that the server will close the connection.
  53. //
  54. // (The old generated processor code used to try to skip a T_STRUCT and
  55. // continue. However, that seems unsafe.)
  56. if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
  57. GlobalOutput.printf("received invalid message type %d from client", mtype);
  58. return false;
  59. }
  60. return this->dispatchCall(inRaw, outRaw, fname, seqid, connectionContext);
  61. }
  62. protected:
  63. bool processFast(Protocol_* in, Protocol_* out, void* connectionContext) {
  64. std::string fname;
  65. protocol::TMessageType mtype;
  66. int32_t seqid;
  67. in->readMessageBegin(fname, mtype, seqid);
  68. if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
  69. GlobalOutput.printf("received invalid message type %d from client", mtype);
  70. return false;
  71. }
  72. return this->dispatchCallTemplated(in, out, fname, seqid, connectionContext);
  73. }
  74. /**
  75. * dispatchCall() methods must be implemented by subclasses
  76. */
  77. virtual bool dispatchCall(apache::thrift::protocol::TProtocol* in,
  78. apache::thrift::protocol::TProtocol* out,
  79. const std::string& fname,
  80. int32_t seqid,
  81. void* callContext) = 0;
  82. virtual bool dispatchCallTemplated(Protocol_* in,
  83. Protocol_* out,
  84. const std::string& fname,
  85. int32_t seqid,
  86. void* callContext) = 0;
  87. };
  88. /**
  89. * Non-templatized version of TDispatchProcessor, that doesn't bother trying to
  90. * perform a dynamic_cast.
  91. */
  92. class TDispatchProcessor : public TProcessor {
  93. public:
  94. virtual bool process(stdcxx::shared_ptr<protocol::TProtocol> in,
  95. stdcxx::shared_ptr<protocol::TProtocol> out,
  96. void* connectionContext) {
  97. std::string fname;
  98. protocol::TMessageType mtype;
  99. int32_t seqid;
  100. in->readMessageBegin(fname, mtype, seqid);
  101. if (mtype != protocol::T_CALL && mtype != protocol::T_ONEWAY) {
  102. GlobalOutput.printf("received invalid message type %d from client", mtype);
  103. return false;
  104. }
  105. return dispatchCall(in.get(), out.get(), fname, seqid, connectionContext);
  106. }
  107. protected:
  108. virtual bool dispatchCall(apache::thrift::protocol::TProtocol* in,
  109. apache::thrift::protocol::TProtocol* out,
  110. const std::string& fname,
  111. int32_t seqid,
  112. void* callContext) = 0;
  113. };
  114. // Specialize TDispatchProcessorT for TProtocol and TDummyProtocol just to use
  115. // the generic TDispatchProcessor.
  116. template <>
  117. class TDispatchProcessorT<protocol::TDummyProtocol> : public TDispatchProcessor {};
  118. template <>
  119. class TDispatchProcessorT<protocol::TProtocol> : public TDispatchProcessor {};
  120. }
  121. } // apache::thrift
  122. #endif // _THRIFT_TDISPATCHPROCESSOR_H_