You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

interceptor.h 13 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /*
  2. *
  3. * Copyright 2018 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * 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, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #ifndef GRPCPP_IMPL_CODEGEN_INTERCEPTOR_H
  19. #define GRPCPP_IMPL_CODEGEN_INTERCEPTOR_H
  20. // IWYU pragma: private, include <grpcpp/support/interceptor.h>
  21. #include <map>
  22. #include <memory>
  23. #include <string>
  24. #include <grpc/impl/codegen/grpc_types.h>
  25. #include <grpcpp/impl/codegen/byte_buffer.h>
  26. #include <grpcpp/impl/codegen/config.h>
  27. #include <grpcpp/impl/codegen/core_codegen_interface.h>
  28. #include <grpcpp/impl/codegen/metadata_map.h>
  29. #include <grpcpp/impl/codegen/string_ref.h>
  30. namespace grpc
  31. {
  32. class ChannelInterface;
  33. class Status;
  34. namespace experimental
  35. {
  36. /// An enumeration of different possible points at which the \a Intercept
  37. /// method of the \a Interceptor interface may be called. Any given call
  38. /// to \a Intercept will include one or more of these hook points, and
  39. /// each hook point makes certain types of information available to the
  40. /// interceptor.
  41. /// In these enumeration names, PRE_SEND means that an interception has taken
  42. /// place between the time the application provided a certain type of data
  43. /// (e.g., initial metadata, status) and the time that that data goes to the
  44. /// other side. POST_SEND means that the data has been committed for going to
  45. /// the other side (even if it has not yet been received at the other side).
  46. /// PRE_RECV means an interception between the time that a certain
  47. /// operation has been requested and it is available. POST_RECV means that a
  48. /// result is available but has not yet been passed back to the application.
  49. /// A batch of interception points will only contain either PRE or POST hooks
  50. /// but not both types. For example, a batch with PRE_SEND hook points will not
  51. /// contain POST_RECV or POST_SEND ops. Likewise, a batch with POST_* ops can
  52. /// not contain PRE_* ops.
  53. enum class InterceptionHookPoints
  54. {
  55. /// The first three in this list are for clients and servers
  56. PRE_SEND_INITIAL_METADATA,
  57. PRE_SEND_MESSAGE,
  58. POST_SEND_MESSAGE,
  59. PRE_SEND_STATUS, // server only
  60. PRE_SEND_CLOSE, // client only: WritesDone for stream; after write in unary
  61. /// The following three are for hijacked clients only. A batch with PRE_RECV_*
  62. /// hook points will never contain hook points of other types.
  63. PRE_RECV_INITIAL_METADATA,
  64. PRE_RECV_MESSAGE,
  65. PRE_RECV_STATUS,
  66. /// The following two are for all clients and servers
  67. POST_RECV_INITIAL_METADATA,
  68. POST_RECV_MESSAGE,
  69. POST_RECV_STATUS, // client only
  70. POST_RECV_CLOSE, // server only
  71. /// This is a special hook point available to both clients and servers when
  72. /// TryCancel() is performed.
  73. /// - No other hook points will be present along with this.
  74. /// - It is illegal for an interceptor to block/delay this operation.
  75. /// - ALL interceptors see this hook point irrespective of whether the
  76. /// RPC was hijacked or not.
  77. PRE_SEND_CANCEL,
  78. NUM_INTERCEPTION_HOOKS
  79. };
  80. /// Class that is passed as an argument to the \a Intercept method
  81. /// of the application's \a Interceptor interface implementation. It has five
  82. /// purposes:
  83. /// 1. Indicate which hook points are present at a specific interception
  84. /// 2. Allow an interceptor to inform the library that an RPC should
  85. /// continue to the next stage of its processing (which may be another
  86. /// interceptor or the main path of the library)
  87. /// 3. Allow an interceptor to hijack the processing of the RPC (only for
  88. /// client-side RPCs with PRE_SEND_INITIAL_METADATA) so that it does not
  89. /// proceed with normal processing beyond that stage
  90. /// 4. Access the relevant fields of an RPC at each interception point
  91. /// 5. Set some fields of an RPC at each interception point, when possible
  92. class InterceptorBatchMethods
  93. {
  94. public:
  95. virtual ~InterceptorBatchMethods()
  96. {
  97. }
  98. /// Determine whether the current batch has an interception hook point
  99. /// of type \a type
  100. virtual bool QueryInterceptionHookPoint(InterceptionHookPoints type) = 0;
  101. /// Signal that the interceptor is done intercepting the current batch of the
  102. /// RPC. Every interceptor must either call Proceed or Hijack on each
  103. /// interception. In most cases, only Proceed will be used. Explicit use of
  104. /// Proceed is what enables interceptors to delay the processing of RPCs
  105. /// while they perform other work.
  106. /// Proceed is a no-op if the batch contains PRE_SEND_CANCEL. Simply returning
  107. /// from the Intercept method does the job of continuing the RPC in this case.
  108. /// This is because PRE_SEND_CANCEL is always in a separate batch and is not
  109. /// allowed to be delayed.
  110. virtual void Proceed() = 0;
  111. /// Indicate that the interceptor has hijacked the RPC (only valid if the
  112. /// batch contains send_initial_metadata on the client side). Later
  113. /// interceptors in the interceptor list will not be called. Later batches
  114. /// on the same RPC will go through interception, but only up to the point
  115. /// of the hijacking interceptor.
  116. virtual void Hijack() = 0;
  117. /// Send Message Methods
  118. /// GetSerializedSendMessage and GetSendMessage/ModifySendMessage are the
  119. /// available methods to view and modify the request payload. An interceptor
  120. /// can access the payload in either serialized form or non-serialized form
  121. /// but not both at the same time.
  122. /// gRPC performs serialization in a lazy manner, which means
  123. /// that a call to GetSerializedSendMessage will result in a serialization
  124. /// operation if the payload stored is not in the serialized form already; the
  125. /// non-serialized form will be lost and GetSendMessage will no longer return
  126. /// a valid pointer, and this will remain true for later interceptors too.
  127. /// This can change however if ModifySendMessage is used to replace the
  128. /// current payload. Note that ModifySendMessage requires a new payload
  129. /// message in the non-serialized form. This will overwrite the existing
  130. /// payload irrespective of whether it had been serialized earlier. Also note
  131. /// that gRPC Async API requires early serialization of the payload which
  132. /// means that the payload would be available in the serialized form only
  133. /// unless an interceptor replaces the payload with ModifySendMessage.
  134. /// Returns a modifable ByteBuffer holding the serialized form of the message
  135. /// that is going to be sent. Valid for PRE_SEND_MESSAGE interceptions.
  136. /// A return value of nullptr indicates that this ByteBuffer is not valid.
  137. virtual ByteBuffer* GetSerializedSendMessage() = 0;
  138. /// Returns a non-modifiable pointer to the non-serialized form of the message
  139. /// to be sent. Valid for PRE_SEND_MESSAGE interceptions. A return value of
  140. /// nullptr indicates that this field is not valid.
  141. virtual const void* GetSendMessage() = 0;
  142. /// Overwrites the message to be sent with \a message. \a message should be in
  143. /// the non-serialized form expected by the method. Valid for PRE_SEND_MESSAGE
  144. /// interceptions. Note that the interceptor is responsible for maintaining
  145. /// the life of the message till it is serialized or it receives the
  146. /// POST_SEND_MESSAGE interception point, whichever happens earlier. The
  147. /// modifying interceptor may itself force early serialization by calling
  148. /// GetSerializedSendMessage.
  149. virtual void ModifySendMessage(const void* message) = 0;
  150. /// Checks whether the SEND MESSAGE op succeeded. Valid for POST_SEND_MESSAGE
  151. /// interceptions.
  152. virtual bool GetSendMessageStatus() = 0;
  153. /// Returns a modifiable multimap of the initial metadata to be sent. Valid
  154. /// for PRE_SEND_INITIAL_METADATA interceptions. A value of nullptr indicates
  155. /// that this field is not valid.
  156. virtual std::multimap<std::string, std::string>* GetSendInitialMetadata() = 0;
  157. /// Returns the status to be sent. Valid for PRE_SEND_STATUS interceptions.
  158. virtual Status GetSendStatus() = 0;
  159. /// Overwrites the status with \a status. Valid for PRE_SEND_STATUS
  160. /// interceptions.
  161. virtual void ModifySendStatus(const Status& status) = 0;
  162. /// Returns a modifiable multimap of the trailing metadata to be sent. Valid
  163. /// for PRE_SEND_STATUS interceptions. A value of nullptr indicates
  164. /// that this field is not valid.
  165. virtual std::multimap<std::string, std::string>*
  166. GetSendTrailingMetadata() = 0;
  167. /// Returns a pointer to the modifiable received message. Note that the
  168. /// message is already deserialized but the type is not set; the interceptor
  169. /// should static_cast to the appropriate type before using it. This is valid
  170. /// for PRE_RECV_MESSAGE and POST_RECV_MESSAGE interceptions; nullptr for not
  171. /// valid
  172. virtual void* GetRecvMessage() = 0;
  173. /// Returns a modifiable multimap of the received initial metadata.
  174. /// Valid for PRE_RECV_INITIAL_METADATA and POST_RECV_INITIAL_METADATA
  175. /// interceptions; nullptr if not valid
  176. virtual std::multimap<grpc::string_ref, grpc::string_ref>*
  177. GetRecvInitialMetadata() = 0;
  178. /// Returns a modifiable view of the received status on PRE_RECV_STATUS and
  179. /// POST_RECV_STATUS interceptions; nullptr if not valid.
  180. virtual Status* GetRecvStatus() = 0;
  181. /// Returns a modifiable multimap of the received trailing metadata on
  182. /// PRE_RECV_STATUS and POST_RECV_STATUS interceptions; nullptr if not valid
  183. virtual std::multimap<grpc::string_ref, grpc::string_ref>*
  184. GetRecvTrailingMetadata() = 0;
  185. /// Gets an intercepted channel. When a call is started on this interceptor,
  186. /// only interceptors after the current interceptor are created from the
  187. /// factory objects registered with the channel. This allows calls to be
  188. /// started from interceptors without infinite regress through the interceptor
  189. /// list.
  190. virtual std::unique_ptr<ChannelInterface> GetInterceptedChannel() = 0;
  191. /// On a hijacked RPC, an interceptor can decide to fail a PRE_RECV_MESSAGE
  192. /// op. This would be a signal to the reader that there will be no more
  193. /// messages, or the stream has failed or been cancelled.
  194. virtual void FailHijackedRecvMessage() = 0;
  195. /// On a hijacked RPC/ to-be hijacked RPC, this can be called to fail a SEND
  196. /// MESSAGE op
  197. virtual void FailHijackedSendMessage() = 0;
  198. };
  199. /// Interface for an interceptor. Interceptor authors must create a class
  200. /// that derives from this parent class.
  201. class Interceptor
  202. {
  203. public:
  204. virtual ~Interceptor()
  205. {
  206. }
  207. /// The one public method of an Interceptor interface. Override this to
  208. /// trigger the desired actions at the hook points described above.
  209. virtual void Intercept(InterceptorBatchMethods* methods) = 0;
  210. };
  211. } // namespace experimental
  212. } // namespace grpc
  213. #endif // GRPCPP_IMPL_CODEGEN_INTERCEPTOR_H