@reptilestyle/grpc-js 1.9.14-compression.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (436) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +79 -0
  3. package/build/src/admin.d.ts +11 -0
  4. package/build/src/admin.js +30 -0
  5. package/build/src/admin.js.map +1 -0
  6. package/build/src/backoff-timeout.d.ts +90 -0
  7. package/build/src/backoff-timeout.js +174 -0
  8. package/build/src/backoff-timeout.js.map +1 -0
  9. package/build/src/call-credentials.d.ts +56 -0
  10. package/build/src/call-credentials.js +153 -0
  11. package/build/src/call-credentials.js.map +1 -0
  12. package/build/src/call-interface.d.ts +85 -0
  13. package/build/src/call-interface.js +84 -0
  14. package/build/src/call-interface.js.map +1 -0
  15. package/build/src/call-number.d.ts +1 -0
  16. package/build/src/call-number.js +24 -0
  17. package/build/src/call-number.js.map +1 -0
  18. package/build/src/call.d.ts +80 -0
  19. package/build/src/call.js +136 -0
  20. package/build/src/call.js.map +1 -0
  21. package/build/src/channel-credentials.d.ts +81 -0
  22. package/build/src/channel-credentials.js +177 -0
  23. package/build/src/channel-credentials.js.map +1 -0
  24. package/build/src/channel-options.d.ts +72 -0
  25. package/build/src/channel-options.js +69 -0
  26. package/build/src/channel-options.js.map +1 -0
  27. package/build/src/channel.d.ts +76 -0
  28. package/build/src/channel.js +68 -0
  29. package/build/src/channel.js.map +1 -0
  30. package/build/src/channelz.d.ts +108 -0
  31. package/build/src/channelz.js +637 -0
  32. package/build/src/channelz.js.map +1 -0
  33. package/build/src/client-interceptors.d.ts +120 -0
  34. package/build/src/client-interceptors.js +428 -0
  35. package/build/src/client-interceptors.js.map +1 -0
  36. package/build/src/client.d.ts +74 -0
  37. package/build/src/client.js +431 -0
  38. package/build/src/client.js.map +1 -0
  39. package/build/src/compression-algorithms.d.ts +5 -0
  40. package/build/src/compression-algorithms.js +26 -0
  41. package/build/src/compression-algorithms.js.map +1 -0
  42. package/build/src/compression-filter.d.ts +26 -0
  43. package/build/src/compression-filter.js +257 -0
  44. package/build/src/compression-filter.js.map +1 -0
  45. package/build/src/connectivity-state.d.ts +7 -0
  46. package/build/src/connectivity-state.js +28 -0
  47. package/build/src/connectivity-state.js.map +1 -0
  48. package/build/src/constants.d.ts +38 -0
  49. package/build/src/constants.js +64 -0
  50. package/build/src/constants.js.map +1 -0
  51. package/build/src/control-plane-status.d.ts +5 -0
  52. package/build/src/control-plane-status.js +42 -0
  53. package/build/src/control-plane-status.js.map +1 -0
  54. package/build/src/deadline.d.ts +14 -0
  55. package/build/src/deadline.js +97 -0
  56. package/build/src/deadline.js.map +1 -0
  57. package/build/src/duration.d.ts +7 -0
  58. package/build/src/duration.js +34 -0
  59. package/build/src/duration.js.map +1 -0
  60. package/build/src/error.d.ts +2 -0
  61. package/build/src/error.js +40 -0
  62. package/build/src/error.js.map +1 -0
  63. package/build/src/events.d.ts +9 -0
  64. package/build/src/events.js +19 -0
  65. package/build/src/events.js.map +1 -0
  66. package/build/src/experimental.d.ts +16 -0
  67. package/build/src/experimental.js +39 -0
  68. package/build/src/experimental.js.map +1 -0
  69. package/build/src/filter-stack.d.ts +21 -0
  70. package/build/src/filter-stack.js +82 -0
  71. package/build/src/filter-stack.js.map +1 -0
  72. package/build/src/filter.d.ts +25 -0
  73. package/build/src/filter.js +38 -0
  74. package/build/src/filter.js.map +1 -0
  75. package/build/src/generated/channelz.d.ts +72 -0
  76. package/build/src/generated/channelz.js +3 -0
  77. package/build/src/generated/channelz.js.map +1 -0
  78. package/build/src/generated/google/protobuf/Any.d.ts +9 -0
  79. package/build/src/generated/google/protobuf/Any.js +4 -0
  80. package/build/src/generated/google/protobuf/Any.js.map +1 -0
  81. package/build/src/generated/google/protobuf/BoolValue.d.ts +6 -0
  82. package/build/src/generated/google/protobuf/BoolValue.js +4 -0
  83. package/build/src/generated/google/protobuf/BoolValue.js.map +1 -0
  84. package/build/src/generated/google/protobuf/BytesValue.d.ts +6 -0
  85. package/build/src/generated/google/protobuf/BytesValue.js +4 -0
  86. package/build/src/generated/google/protobuf/BytesValue.js.map +1 -0
  87. package/build/src/generated/google/protobuf/DoubleValue.d.ts +6 -0
  88. package/build/src/generated/google/protobuf/DoubleValue.js +4 -0
  89. package/build/src/generated/google/protobuf/DoubleValue.js.map +1 -0
  90. package/build/src/generated/google/protobuf/Duration.d.ts +9 -0
  91. package/build/src/generated/google/protobuf/Duration.js +4 -0
  92. package/build/src/generated/google/protobuf/Duration.js.map +1 -0
  93. package/build/src/generated/google/protobuf/FloatValue.d.ts +6 -0
  94. package/build/src/generated/google/protobuf/FloatValue.js +4 -0
  95. package/build/src/generated/google/protobuf/FloatValue.js.map +1 -0
  96. package/build/src/generated/google/protobuf/Int32Value.d.ts +6 -0
  97. package/build/src/generated/google/protobuf/Int32Value.js +4 -0
  98. package/build/src/generated/google/protobuf/Int32Value.js.map +1 -0
  99. package/build/src/generated/google/protobuf/Int64Value.d.ts +7 -0
  100. package/build/src/generated/google/protobuf/Int64Value.js +4 -0
  101. package/build/src/generated/google/protobuf/Int64Value.js.map +1 -0
  102. package/build/src/generated/google/protobuf/StringValue.d.ts +6 -0
  103. package/build/src/generated/google/protobuf/StringValue.js +4 -0
  104. package/build/src/generated/google/protobuf/StringValue.js.map +1 -0
  105. package/build/src/generated/google/protobuf/Timestamp.d.ts +9 -0
  106. package/build/src/generated/google/protobuf/Timestamp.js +4 -0
  107. package/build/src/generated/google/protobuf/Timestamp.js.map +1 -0
  108. package/build/src/generated/google/protobuf/UInt32Value.d.ts +6 -0
  109. package/build/src/generated/google/protobuf/UInt32Value.js +4 -0
  110. package/build/src/generated/google/protobuf/UInt32Value.js.map +1 -0
  111. package/build/src/generated/google/protobuf/UInt64Value.d.ts +7 -0
  112. package/build/src/generated/google/protobuf/UInt64Value.js +4 -0
  113. package/build/src/generated/google/protobuf/UInt64Value.js.map +1 -0
  114. package/build/src/generated/grpc/channelz/v1/Address.d.ts +79 -0
  115. package/build/src/generated/grpc/channelz/v1/Address.js +4 -0
  116. package/build/src/generated/grpc/channelz/v1/Address.js.map +1 -0
  117. package/build/src/generated/grpc/channelz/v1/Channel.d.ts +64 -0
  118. package/build/src/generated/grpc/channelz/v1/Channel.js +4 -0
  119. package/build/src/generated/grpc/channelz/v1/Channel.js.map +1 -0
  120. package/build/src/generated/grpc/channelz/v1/ChannelConnectivityState.d.ts +24 -0
  121. package/build/src/generated/grpc/channelz/v1/ChannelConnectivityState.js +14 -0
  122. package/build/src/generated/grpc/channelz/v1/ChannelConnectivityState.js.map +1 -0
  123. package/build/src/generated/grpc/channelz/v1/ChannelData.d.ts +72 -0
  124. package/build/src/generated/grpc/channelz/v1/ChannelData.js +4 -0
  125. package/build/src/generated/grpc/channelz/v1/ChannelData.js.map +1 -0
  126. package/build/src/generated/grpc/channelz/v1/ChannelRef.d.ts +27 -0
  127. package/build/src/generated/grpc/channelz/v1/ChannelRef.js +4 -0
  128. package/build/src/generated/grpc/channelz/v1/ChannelRef.js.map +1 -0
  129. package/build/src/generated/grpc/channelz/v1/ChannelTrace.d.ts +41 -0
  130. package/build/src/generated/grpc/channelz/v1/ChannelTrace.js +4 -0
  131. package/build/src/generated/grpc/channelz/v1/ChannelTrace.js.map +1 -0
  132. package/build/src/generated/grpc/channelz/v1/ChannelTraceEvent.d.ts +74 -0
  133. package/build/src/generated/grpc/channelz/v1/ChannelTraceEvent.js +15 -0
  134. package/build/src/generated/grpc/channelz/v1/ChannelTraceEvent.js.map +1 -0
  135. package/build/src/generated/grpc/channelz/v1/Channelz.d.ts +159 -0
  136. package/build/src/generated/grpc/channelz/v1/Channelz.js +4 -0
  137. package/build/src/generated/grpc/channelz/v1/Channelz.js.map +1 -0
  138. package/build/src/generated/grpc/channelz/v1/GetChannelRequest.d.ts +13 -0
  139. package/build/src/generated/grpc/channelz/v1/GetChannelRequest.js +4 -0
  140. package/build/src/generated/grpc/channelz/v1/GetChannelRequest.js.map +1 -0
  141. package/build/src/generated/grpc/channelz/v1/GetChannelResponse.d.ts +15 -0
  142. package/build/src/generated/grpc/channelz/v1/GetChannelResponse.js +4 -0
  143. package/build/src/generated/grpc/channelz/v1/GetChannelResponse.js.map +1 -0
  144. package/build/src/generated/grpc/channelz/v1/GetServerRequest.d.ts +13 -0
  145. package/build/src/generated/grpc/channelz/v1/GetServerRequest.js +4 -0
  146. package/build/src/generated/grpc/channelz/v1/GetServerRequest.js.map +1 -0
  147. package/build/src/generated/grpc/channelz/v1/GetServerResponse.d.ts +15 -0
  148. package/build/src/generated/grpc/channelz/v1/GetServerResponse.js +4 -0
  149. package/build/src/generated/grpc/channelz/v1/GetServerResponse.js.map +1 -0
  150. package/build/src/generated/grpc/channelz/v1/GetServerSocketsRequest.d.ts +35 -0
  151. package/build/src/generated/grpc/channelz/v1/GetServerSocketsRequest.js +4 -0
  152. package/build/src/generated/grpc/channelz/v1/GetServerSocketsRequest.js.map +1 -0
  153. package/build/src/generated/grpc/channelz/v1/GetServerSocketsResponse.d.ts +29 -0
  154. package/build/src/generated/grpc/channelz/v1/GetServerSocketsResponse.js +4 -0
  155. package/build/src/generated/grpc/channelz/v1/GetServerSocketsResponse.js.map +1 -0
  156. package/build/src/generated/grpc/channelz/v1/GetServersRequest.d.ts +33 -0
  157. package/build/src/generated/grpc/channelz/v1/GetServersRequest.js +4 -0
  158. package/build/src/generated/grpc/channelz/v1/GetServersRequest.js.map +1 -0
  159. package/build/src/generated/grpc/channelz/v1/GetServersResponse.d.ts +29 -0
  160. package/build/src/generated/grpc/channelz/v1/GetServersResponse.js +4 -0
  161. package/build/src/generated/grpc/channelz/v1/GetServersResponse.js.map +1 -0
  162. package/build/src/generated/grpc/channelz/v1/GetSocketRequest.d.ts +25 -0
  163. package/build/src/generated/grpc/channelz/v1/GetSocketRequest.js +4 -0
  164. package/build/src/generated/grpc/channelz/v1/GetSocketRequest.js.map +1 -0
  165. package/build/src/generated/grpc/channelz/v1/GetSocketResponse.d.ts +15 -0
  166. package/build/src/generated/grpc/channelz/v1/GetSocketResponse.js +4 -0
  167. package/build/src/generated/grpc/channelz/v1/GetSocketResponse.js.map +1 -0
  168. package/build/src/generated/grpc/channelz/v1/GetSubchannelRequest.d.ts +13 -0
  169. package/build/src/generated/grpc/channelz/v1/GetSubchannelRequest.js +4 -0
  170. package/build/src/generated/grpc/channelz/v1/GetSubchannelRequest.js.map +1 -0
  171. package/build/src/generated/grpc/channelz/v1/GetSubchannelResponse.d.ts +15 -0
  172. package/build/src/generated/grpc/channelz/v1/GetSubchannelResponse.js +4 -0
  173. package/build/src/generated/grpc/channelz/v1/GetSubchannelResponse.js.map +1 -0
  174. package/build/src/generated/grpc/channelz/v1/GetTopChannelsRequest.d.ts +33 -0
  175. package/build/src/generated/grpc/channelz/v1/GetTopChannelsRequest.js +4 -0
  176. package/build/src/generated/grpc/channelz/v1/GetTopChannelsRequest.js.map +1 -0
  177. package/build/src/generated/grpc/channelz/v1/GetTopChannelsResponse.d.ts +29 -0
  178. package/build/src/generated/grpc/channelz/v1/GetTopChannelsResponse.js +4 -0
  179. package/build/src/generated/grpc/channelz/v1/GetTopChannelsResponse.js.map +1 -0
  180. package/build/src/generated/grpc/channelz/v1/Security.d.ts +79 -0
  181. package/build/src/generated/grpc/channelz/v1/Security.js +4 -0
  182. package/build/src/generated/grpc/channelz/v1/Security.js.map +1 -0
  183. package/build/src/generated/grpc/channelz/v1/Server.d.ts +41 -0
  184. package/build/src/generated/grpc/channelz/v1/Server.js +4 -0
  185. package/build/src/generated/grpc/channelz/v1/Server.js.map +1 -0
  186. package/build/src/generated/grpc/channelz/v1/ServerData.d.ts +53 -0
  187. package/build/src/generated/grpc/channelz/v1/ServerData.js +4 -0
  188. package/build/src/generated/grpc/channelz/v1/ServerData.js.map +1 -0
  189. package/build/src/generated/grpc/channelz/v1/ServerRef.d.ts +27 -0
  190. package/build/src/generated/grpc/channelz/v1/ServerRef.js +4 -0
  191. package/build/src/generated/grpc/channelz/v1/ServerRef.js.map +1 -0
  192. package/build/src/generated/grpc/channelz/v1/Socket.d.ts +66 -0
  193. package/build/src/generated/grpc/channelz/v1/Socket.js +4 -0
  194. package/build/src/generated/grpc/channelz/v1/Socket.js.map +1 -0
  195. package/build/src/generated/grpc/channelz/v1/SocketData.d.ts +146 -0
  196. package/build/src/generated/grpc/channelz/v1/SocketData.js +4 -0
  197. package/build/src/generated/grpc/channelz/v1/SocketData.js.map +1 -0
  198. package/build/src/generated/grpc/channelz/v1/SocketOption.d.ts +43 -0
  199. package/build/src/generated/grpc/channelz/v1/SocketOption.js +4 -0
  200. package/build/src/generated/grpc/channelz/v1/SocketOption.js.map +1 -0
  201. package/build/src/generated/grpc/channelz/v1/SocketOptionLinger.d.ts +29 -0
  202. package/build/src/generated/grpc/channelz/v1/SocketOptionLinger.js +4 -0
  203. package/build/src/generated/grpc/channelz/v1/SocketOptionLinger.js.map +1 -0
  204. package/build/src/generated/grpc/channelz/v1/SocketOptionTcpInfo.d.ts +70 -0
  205. package/build/src/generated/grpc/channelz/v1/SocketOptionTcpInfo.js +4 -0
  206. package/build/src/generated/grpc/channelz/v1/SocketOptionTcpInfo.js.map +1 -0
  207. package/build/src/generated/grpc/channelz/v1/SocketOptionTimeout.d.ts +15 -0
  208. package/build/src/generated/grpc/channelz/v1/SocketOptionTimeout.js +4 -0
  209. package/build/src/generated/grpc/channelz/v1/SocketOptionTimeout.js.map +1 -0
  210. package/build/src/generated/grpc/channelz/v1/SocketRef.d.ts +27 -0
  211. package/build/src/generated/grpc/channelz/v1/SocketRef.js +4 -0
  212. package/build/src/generated/grpc/channelz/v1/SocketRef.js.map +1 -0
  213. package/build/src/generated/grpc/channelz/v1/Subchannel.d.ts +66 -0
  214. package/build/src/generated/grpc/channelz/v1/Subchannel.js +4 -0
  215. package/build/src/generated/grpc/channelz/v1/Subchannel.js.map +1 -0
  216. package/build/src/generated/grpc/channelz/v1/SubchannelRef.d.ts +27 -0
  217. package/build/src/generated/grpc/channelz/v1/SubchannelRef.js +4 -0
  218. package/build/src/generated/grpc/channelz/v1/SubchannelRef.js.map +1 -0
  219. package/build/src/http_proxy.d.ts +15 -0
  220. package/build/src/http_proxy.js +259 -0
  221. package/build/src/http_proxy.js.map +1 -0
  222. package/build/src/index.d.ts +76 -0
  223. package/build/src/index.js +140 -0
  224. package/build/src/index.js.map +1 -0
  225. package/build/src/internal-channel.d.ts +118 -0
  226. package/build/src/internal-channel.js +535 -0
  227. package/build/src/internal-channel.js.map +1 -0
  228. package/build/src/load-balancer-child-handler.d.ts +24 -0
  229. package/build/src/load-balancer-child-handler.js +151 -0
  230. package/build/src/load-balancer-child-handler.js.map +1 -0
  231. package/build/src/load-balancer-outlier-detection.d.ts +61 -0
  232. package/build/src/load-balancer-outlier-detection.js +608 -0
  233. package/build/src/load-balancer-outlier-detection.js.map +1 -0
  234. package/build/src/load-balancer-pick-first.d.ts +97 -0
  235. package/build/src/load-balancer-pick-first.js +393 -0
  236. package/build/src/load-balancer-pick-first.js.map +1 -0
  237. package/build/src/load-balancer-round-robin.d.ts +21 -0
  238. package/build/src/load-balancer-round-robin.js +174 -0
  239. package/build/src/load-balancer-round-robin.js.map +1 -0
  240. package/build/src/load-balancer.d.ts +97 -0
  241. package/build/src/load-balancer.js +102 -0
  242. package/build/src/load-balancer.js.map +1 -0
  243. package/build/src/load-balancing-call.d.ts +44 -0
  244. package/build/src/load-balancing-call.js +269 -0
  245. package/build/src/load-balancing-call.js.map +1 -0
  246. package/build/src/logging.d.ts +7 -0
  247. package/build/src/logging.js +114 -0
  248. package/build/src/logging.js.map +1 -0
  249. package/build/src/make-client.d.ts +71 -0
  250. package/build/src/make-client.js +143 -0
  251. package/build/src/make-client.js.map +1 -0
  252. package/build/src/max-message-size-filter.d.ts +15 -0
  253. package/build/src/max-message-size-filter.js +86 -0
  254. package/build/src/max-message-size-filter.js.map +1 -0
  255. package/build/src/metadata.d.ts +84 -0
  256. package/build/src/metadata.js +249 -0
  257. package/build/src/metadata.js.map +1 -0
  258. package/build/src/object-stream.d.ts +27 -0
  259. package/build/src/object-stream.js +19 -0
  260. package/build/src/object-stream.js.map +1 -0
  261. package/build/src/picker.d.ts +91 -0
  262. package/build/src/picker.js +78 -0
  263. package/build/src/picker.js.map +1 -0
  264. package/build/src/resolver-dns.d.ts +13 -0
  265. package/build/src/resolver-dns.js +328 -0
  266. package/build/src/resolver-dns.js.map +1 -0
  267. package/build/src/resolver-ip.d.ts +1 -0
  268. package/build/src/resolver-ip.js +104 -0
  269. package/build/src/resolver-ip.js.map +1 -0
  270. package/build/src/resolver-uds.d.ts +1 -0
  271. package/build/src/resolver-uds.js +50 -0
  272. package/build/src/resolver-uds.js.map +1 -0
  273. package/build/src/resolver.d.ts +105 -0
  274. package/build/src/resolver.js +87 -0
  275. package/build/src/resolver.js.map +1 -0
  276. package/build/src/resolving-call.d.ts +44 -0
  277. package/build/src/resolving-call.js +273 -0
  278. package/build/src/resolving-call.js.map +1 -0
  279. package/build/src/resolving-load-balancer.d.ts +67 -0
  280. package/build/src/resolving-load-balancer.js +304 -0
  281. package/build/src/resolving-load-balancer.js.map +1 -0
  282. package/build/src/retrying-call.d.ts +94 -0
  283. package/build/src/retrying-call.js +639 -0
  284. package/build/src/retrying-call.js.map +1 -0
  285. package/build/src/server-call.d.ts +159 -0
  286. package/build/src/server-call.js +700 -0
  287. package/build/src/server-call.js.map +1 -0
  288. package/build/src/server-credentials.d.ts +11 -0
  289. package/build/src/server-credentials.js +81 -0
  290. package/build/src/server-credentials.js.map +1 -0
  291. package/build/src/server.d.ts +56 -0
  292. package/build/src/server.js +892 -0
  293. package/build/src/server.js.map +1 -0
  294. package/build/src/service-config.d.ts +56 -0
  295. package/build/src/service-config.js +416 -0
  296. package/build/src/service-config.js.map +1 -0
  297. package/build/src/status-builder.d.ts +28 -0
  298. package/build/src/status-builder.js +68 -0
  299. package/build/src/status-builder.js.map +1 -0
  300. package/build/src/stream-decoder.d.ts +10 -0
  301. package/build/src/stream-decoder.js +96 -0
  302. package/build/src/stream-decoder.js.map +1 -0
  303. package/build/src/subchannel-address.d.ts +18 -0
  304. package/build/src/subchannel-address.js +65 -0
  305. package/build/src/subchannel-address.js.map +1 -0
  306. package/build/src/subchannel-call.d.ts +61 -0
  307. package/build/src/subchannel-call.js +461 -0
  308. package/build/src/subchannel-call.js.map +1 -0
  309. package/build/src/subchannel-interface.d.ts +49 -0
  310. package/build/src/subchannel-interface.js +59 -0
  311. package/build/src/subchannel-interface.js.map +1 -0
  312. package/build/src/subchannel-pool.d.ts +40 -0
  313. package/build/src/subchannel-pool.js +137 -0
  314. package/build/src/subchannel-pool.js.map +1 -0
  315. package/build/src/subchannel.d.ts +119 -0
  316. package/build/src/subchannel.js +353 -0
  317. package/build/src/subchannel.js.map +1 -0
  318. package/build/src/tls-helpers.d.ts +2 -0
  319. package/build/src/tls-helpers.js +34 -0
  320. package/build/src/tls-helpers.js.map +1 -0
  321. package/build/src/transport.d.ts +130 -0
  322. package/build/src/transport.js +640 -0
  323. package/build/src/transport.js.map +1 -0
  324. package/build/src/uri-parser.d.ts +12 -0
  325. package/build/src/uri-parser.js +110 -0
  326. package/build/src/uri-parser.js.map +1 -0
  327. package/package.json +85 -0
  328. package/proto/channelz.proto +564 -0
  329. package/src/admin.ts +45 -0
  330. package/src/backoff-timeout.ts +196 -0
  331. package/src/call-credentials.ts +226 -0
  332. package/src/call-interface.ts +173 -0
  333. package/src/call-number.ts +22 -0
  334. package/src/call.ts +200 -0
  335. package/src/channel-credentials.ts +267 -0
  336. package/src/channel-options.ts +119 -0
  337. package/src/channel.ts +174 -0
  338. package/src/channelz.ts +886 -0
  339. package/src/client-interceptors.ts +577 -0
  340. package/src/client.ts +715 -0
  341. package/src/compression-algorithms.ts +22 -0
  342. package/src/compression-filter.ts +315 -0
  343. package/src/connectivity-state.ts +24 -0
  344. package/src/constants.ts +66 -0
  345. package/src/control-plane-status.ts +43 -0
  346. package/src/deadline.ts +95 -0
  347. package/src/duration.ts +36 -0
  348. package/src/error.ts +37 -0
  349. package/src/events.ts +26 -0
  350. package/src/experimental.ts +48 -0
  351. package/src/filter-stack.ts +100 -0
  352. package/src/filter.ts +63 -0
  353. package/src/generated/channelz.ts +73 -0
  354. package/src/generated/google/protobuf/Any.ts +13 -0
  355. package/src/generated/google/protobuf/BoolValue.ts +10 -0
  356. package/src/generated/google/protobuf/BytesValue.ts +10 -0
  357. package/src/generated/google/protobuf/DoubleValue.ts +10 -0
  358. package/src/generated/google/protobuf/Duration.ts +13 -0
  359. package/src/generated/google/protobuf/FloatValue.ts +10 -0
  360. package/src/generated/google/protobuf/Int32Value.ts +10 -0
  361. package/src/generated/google/protobuf/Int64Value.ts +11 -0
  362. package/src/generated/google/protobuf/StringValue.ts +10 -0
  363. package/src/generated/google/protobuf/Timestamp.ts +13 -0
  364. package/src/generated/google/protobuf/UInt32Value.ts +10 -0
  365. package/src/generated/google/protobuf/UInt64Value.ts +11 -0
  366. package/src/generated/grpc/channelz/v1/Address.ts +89 -0
  367. package/src/generated/grpc/channelz/v1/Channel.ts +68 -0
  368. package/src/generated/grpc/channelz/v1/ChannelConnectivityState.ts +45 -0
  369. package/src/generated/grpc/channelz/v1/ChannelData.ts +76 -0
  370. package/src/generated/grpc/channelz/v1/ChannelRef.ts +31 -0
  371. package/src/generated/grpc/channelz/v1/ChannelTrace.ts +45 -0
  372. package/src/generated/grpc/channelz/v1/ChannelTraceEvent.ts +91 -0
  373. package/src/generated/grpc/channelz/v1/Channelz.ts +178 -0
  374. package/src/generated/grpc/channelz/v1/GetChannelRequest.ts +17 -0
  375. package/src/generated/grpc/channelz/v1/GetChannelResponse.ts +19 -0
  376. package/src/generated/grpc/channelz/v1/GetServerRequest.ts +17 -0
  377. package/src/generated/grpc/channelz/v1/GetServerResponse.ts +19 -0
  378. package/src/generated/grpc/channelz/v1/GetServerSocketsRequest.ts +39 -0
  379. package/src/generated/grpc/channelz/v1/GetServerSocketsResponse.ts +33 -0
  380. package/src/generated/grpc/channelz/v1/GetServersRequest.ts +37 -0
  381. package/src/generated/grpc/channelz/v1/GetServersResponse.ts +33 -0
  382. package/src/generated/grpc/channelz/v1/GetSocketRequest.ts +29 -0
  383. package/src/generated/grpc/channelz/v1/GetSocketResponse.ts +19 -0
  384. package/src/generated/grpc/channelz/v1/GetSubchannelRequest.ts +17 -0
  385. package/src/generated/grpc/channelz/v1/GetSubchannelResponse.ts +19 -0
  386. package/src/generated/grpc/channelz/v1/GetTopChannelsRequest.ts +37 -0
  387. package/src/generated/grpc/channelz/v1/GetTopChannelsResponse.ts +33 -0
  388. package/src/generated/grpc/channelz/v1/Security.ts +87 -0
  389. package/src/generated/grpc/channelz/v1/Server.ts +45 -0
  390. package/src/generated/grpc/channelz/v1/ServerData.ts +57 -0
  391. package/src/generated/grpc/channelz/v1/ServerRef.ts +31 -0
  392. package/src/generated/grpc/channelz/v1/Socket.ts +70 -0
  393. package/src/generated/grpc/channelz/v1/SocketData.ts +150 -0
  394. package/src/generated/grpc/channelz/v1/SocketOption.ts +47 -0
  395. package/src/generated/grpc/channelz/v1/SocketOptionLinger.ts +33 -0
  396. package/src/generated/grpc/channelz/v1/SocketOptionTcpInfo.ts +74 -0
  397. package/src/generated/grpc/channelz/v1/SocketOptionTimeout.ts +19 -0
  398. package/src/generated/grpc/channelz/v1/SocketRef.ts +31 -0
  399. package/src/generated/grpc/channelz/v1/Subchannel.ts +70 -0
  400. package/src/generated/grpc/channelz/v1/SubchannelRef.ts +31 -0
  401. package/src/http_proxy.ts +311 -0
  402. package/src/index.ts +284 -0
  403. package/src/internal-channel.ts +832 -0
  404. package/src/load-balancer-child-handler.ts +169 -0
  405. package/src/load-balancer-outlier-detection.ts +882 -0
  406. package/src/load-balancer-pick-first.ts +487 -0
  407. package/src/load-balancer-round-robin.ts +249 -0
  408. package/src/load-balancer.ts +230 -0
  409. package/src/load-balancing-call.ts +351 -0
  410. package/src/logging.ts +123 -0
  411. package/src/make-client.ts +238 -0
  412. package/src/max-message-size-filter.ts +88 -0
  413. package/src/metadata.ts +298 -0
  414. package/src/object-stream.ts +66 -0
  415. package/src/picker.ts +146 -0
  416. package/src/resolver-dns.ts +412 -0
  417. package/src/resolver-ip.ts +120 -0
  418. package/src/resolver-uds.ts +63 -0
  419. package/src/resolver.ts +180 -0
  420. package/src/resolving-call.ts +331 -0
  421. package/src/resolving-load-balancer.ts +403 -0
  422. package/src/retrying-call.ts +821 -0
  423. package/src/server-call.ts +1033 -0
  424. package/src/server-credentials.ts +108 -0
  425. package/src/server.ts +1300 -0
  426. package/src/service-config.ts +542 -0
  427. package/src/status-builder.ts +80 -0
  428. package/src/stream-decoder.ts +105 -0
  429. package/src/subchannel-address.ts +88 -0
  430. package/src/subchannel-call.ts +539 -0
  431. package/src/subchannel-interface.ts +97 -0
  432. package/src/subchannel-pool.ts +176 -0
  433. package/src/subchannel.ts +482 -0
  434. package/src/tls-helpers.ts +35 -0
  435. package/src/transport.ts +824 -0
  436. package/src/uri-parser.ts +114 -0
package/src/server.ts ADDED
@@ -0,0 +1,1300 @@
1
+ /*
2
+ * Copyright 2019 gRPC authors.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ */
17
+
18
+ import * as http2 from 'http2';
19
+ import { AddressInfo } from 'net';
20
+
21
+ import { ServiceError } from './call';
22
+ import { Status, LogVerbosity } from './constants';
23
+ import { Deserialize, Serialize, ServiceDefinition } from './make-client';
24
+ import { Metadata } from './metadata';
25
+ import {
26
+ BidiStreamingHandler,
27
+ ClientStreamingHandler,
28
+ HandleCall,
29
+ Handler,
30
+ HandlerType,
31
+ Http2ServerCallStream,
32
+ sendUnaryData,
33
+ ServerDuplexStream,
34
+ ServerDuplexStreamImpl,
35
+ ServerReadableStream,
36
+ ServerReadableStreamImpl,
37
+ ServerStreamingHandler,
38
+ ServerUnaryCall,
39
+ ServerUnaryCallImpl,
40
+ ServerWritableStream,
41
+ ServerWritableStreamImpl,
42
+ UnaryHandler,
43
+ ServerErrorResponse,
44
+ ServerStatusResponse,
45
+ } from './server-call';
46
+ import { ServerCredentials } from './server-credentials';
47
+ import { ChannelOptions } from './channel-options';
48
+ import {
49
+ createResolver,
50
+ ResolverListener,
51
+ mapUriDefaultScheme,
52
+ } from './resolver';
53
+ import * as logging from './logging';
54
+ import {
55
+ SubchannelAddress,
56
+ TcpSubchannelAddress,
57
+ isTcpSubchannelAddress,
58
+ subchannelAddressToString,
59
+ stringToSubchannelAddress,
60
+ } from './subchannel-address';
61
+ import { parseUri } from './uri-parser';
62
+ import {
63
+ ChannelzCallTracker,
64
+ ChannelzChildrenTracker,
65
+ ChannelzTrace,
66
+ registerChannelzServer,
67
+ registerChannelzSocket,
68
+ ServerInfo,
69
+ ServerRef,
70
+ SocketInfo,
71
+ SocketRef,
72
+ TlsInfo,
73
+ unregisterChannelzRef,
74
+ } from './channelz';
75
+ import { CipherNameAndProtocol, TLSSocket } from 'tls';
76
+
77
+ const UNLIMITED_CONNECTION_AGE_MS = ~(1 << 31);
78
+ const KEEPALIVE_MAX_TIME_MS = ~(1 << 31);
79
+ const KEEPALIVE_TIMEOUT_MS = 20000;
80
+
81
+ const { HTTP2_HEADER_PATH } = http2.constants;
82
+
83
+ const TRACER_NAME = 'server';
84
+
85
+ interface BindResult {
86
+ port: number;
87
+ count: number;
88
+ }
89
+
90
+ function noop(): void {}
91
+
92
+ function getUnimplementedStatusResponse(
93
+ methodName: string
94
+ ): Partial<ServiceError> {
95
+ return {
96
+ code: Status.UNIMPLEMENTED,
97
+ details: `The server does not implement the method ${methodName}`,
98
+ };
99
+ }
100
+
101
+ /* eslint-disable @typescript-eslint/no-explicit-any */
102
+ type UntypedUnaryHandler = UnaryHandler<any, any>;
103
+ type UntypedClientStreamingHandler = ClientStreamingHandler<any, any>;
104
+ type UntypedServerStreamingHandler = ServerStreamingHandler<any, any>;
105
+ type UntypedBidiStreamingHandler = BidiStreamingHandler<any, any>;
106
+ export type UntypedHandleCall = HandleCall<any, any>;
107
+ type UntypedHandler = Handler<any, any>;
108
+ export interface UntypedServiceImplementation {
109
+ [name: string]: UntypedHandleCall;
110
+ }
111
+
112
+ function getDefaultHandler(handlerType: HandlerType, methodName: string) {
113
+ const unimplementedStatusResponse =
114
+ getUnimplementedStatusResponse(methodName);
115
+ switch (handlerType) {
116
+ case 'unary':
117
+ return (
118
+ call: ServerUnaryCall<any, any>,
119
+ callback: sendUnaryData<any>
120
+ ) => {
121
+ callback(unimplementedStatusResponse as ServiceError, null);
122
+ };
123
+ case 'clientStream':
124
+ return (
125
+ call: ServerReadableStream<any, any>,
126
+ callback: sendUnaryData<any>
127
+ ) => {
128
+ callback(unimplementedStatusResponse as ServiceError, null);
129
+ };
130
+ case 'serverStream':
131
+ return (call: ServerWritableStream<any, any>) => {
132
+ call.emit('error', unimplementedStatusResponse);
133
+ };
134
+ case 'bidi':
135
+ return (call: ServerDuplexStream<any, any>) => {
136
+ call.emit('error', unimplementedStatusResponse);
137
+ };
138
+ default:
139
+ throw new Error(`Invalid handlerType ${handlerType}`);
140
+ }
141
+ }
142
+
143
+ interface ChannelzSessionInfo {
144
+ ref: SocketRef;
145
+ streamTracker: ChannelzCallTracker;
146
+ messagesSent: number;
147
+ messagesReceived: number;
148
+ lastMessageSentTimestamp: Date | null;
149
+ lastMessageReceivedTimestamp: Date | null;
150
+ }
151
+
152
+ export class Server {
153
+ private http2ServerList: {
154
+ server: http2.Http2Server | http2.Http2SecureServer;
155
+ channelzRef: SocketRef;
156
+ }[] = [];
157
+
158
+ private handlers: Map<string, UntypedHandler> = new Map<
159
+ string,
160
+ UntypedHandler
161
+ >();
162
+ private sessions = new Map<http2.ServerHttp2Session, ChannelzSessionInfo>();
163
+ private started = false;
164
+ private shutdown = false;
165
+ private options: ChannelOptions;
166
+ private serverAddressString = 'null';
167
+
168
+ // Channelz Info
169
+ private readonly channelzEnabled: boolean = true;
170
+ private channelzRef: ServerRef;
171
+ private channelzTrace = new ChannelzTrace();
172
+ private callTracker = new ChannelzCallTracker();
173
+ private listenerChildrenTracker = new ChannelzChildrenTracker();
174
+ private sessionChildrenTracker = new ChannelzChildrenTracker();
175
+
176
+ private readonly maxConnectionAgeMs: number;
177
+ private readonly maxConnectionAgeGraceMs: number;
178
+
179
+ private readonly keepaliveTimeMs: number;
180
+ private readonly keepaliveTimeoutMs: number;
181
+
182
+ constructor(options?: ChannelOptions) {
183
+ this.options = options ?? {};
184
+ if (this.options['grpc.enable_channelz'] === 0) {
185
+ this.channelzEnabled = false;
186
+ }
187
+ this.channelzRef = registerChannelzServer(
188
+ () => this.getChannelzInfo(),
189
+ this.channelzEnabled
190
+ );
191
+ if (this.channelzEnabled) {
192
+ this.channelzTrace.addTrace('CT_INFO', 'Server created');
193
+ }
194
+ this.maxConnectionAgeMs =
195
+ this.options['grpc.max_connection_age_ms'] ?? UNLIMITED_CONNECTION_AGE_MS;
196
+ this.maxConnectionAgeGraceMs =
197
+ this.options['grpc.max_connection_age_grace_ms'] ??
198
+ UNLIMITED_CONNECTION_AGE_MS;
199
+ this.keepaliveTimeMs =
200
+ this.options['grpc.keepalive_time_ms'] ?? KEEPALIVE_MAX_TIME_MS;
201
+ this.keepaliveTimeoutMs =
202
+ this.options['grpc.keepalive_timeout_ms'] ?? KEEPALIVE_TIMEOUT_MS;
203
+ this.trace('Server constructed');
204
+ }
205
+
206
+ private getChannelzInfo(): ServerInfo {
207
+ return {
208
+ trace: this.channelzTrace,
209
+ callTracker: this.callTracker,
210
+ listenerChildren: this.listenerChildrenTracker.getChildLists(),
211
+ sessionChildren: this.sessionChildrenTracker.getChildLists(),
212
+ };
213
+ }
214
+
215
+ private getChannelzSessionInfoGetter(
216
+ session: http2.ServerHttp2Session
217
+ ): () => SocketInfo {
218
+ return () => {
219
+ const sessionInfo = this.sessions.get(session)!;
220
+ const sessionSocket = session.socket;
221
+ const remoteAddress = sessionSocket.remoteAddress
222
+ ? stringToSubchannelAddress(
223
+ sessionSocket.remoteAddress,
224
+ sessionSocket.remotePort
225
+ )
226
+ : null;
227
+ const localAddress = sessionSocket.localAddress
228
+ ? stringToSubchannelAddress(
229
+ sessionSocket.localAddress!,
230
+ sessionSocket.localPort
231
+ )
232
+ : null;
233
+ let tlsInfo: TlsInfo | null;
234
+ if (session.encrypted) {
235
+ const tlsSocket: TLSSocket = sessionSocket as TLSSocket;
236
+ const cipherInfo: CipherNameAndProtocol & { standardName?: string } =
237
+ tlsSocket.getCipher();
238
+ const certificate = tlsSocket.getCertificate();
239
+ const peerCertificate = tlsSocket.getPeerCertificate();
240
+ tlsInfo = {
241
+ cipherSuiteStandardName: cipherInfo.standardName ?? null,
242
+ cipherSuiteOtherName: cipherInfo.standardName
243
+ ? null
244
+ : cipherInfo.name,
245
+ localCertificate:
246
+ certificate && 'raw' in certificate ? certificate.raw : null,
247
+ remoteCertificate:
248
+ peerCertificate && 'raw' in peerCertificate
249
+ ? peerCertificate.raw
250
+ : null,
251
+ };
252
+ } else {
253
+ tlsInfo = null;
254
+ }
255
+ const socketInfo: SocketInfo = {
256
+ remoteAddress: remoteAddress,
257
+ localAddress: localAddress,
258
+ security: tlsInfo,
259
+ remoteName: null,
260
+ streamsStarted: sessionInfo.streamTracker.callsStarted,
261
+ streamsSucceeded: sessionInfo.streamTracker.callsSucceeded,
262
+ streamsFailed: sessionInfo.streamTracker.callsFailed,
263
+ messagesSent: sessionInfo.messagesSent,
264
+ messagesReceived: sessionInfo.messagesReceived,
265
+ keepAlivesSent: 0,
266
+ lastLocalStreamCreatedTimestamp: null,
267
+ lastRemoteStreamCreatedTimestamp:
268
+ sessionInfo.streamTracker.lastCallStartedTimestamp,
269
+ lastMessageSentTimestamp: sessionInfo.lastMessageSentTimestamp,
270
+ lastMessageReceivedTimestamp: sessionInfo.lastMessageReceivedTimestamp,
271
+ localFlowControlWindow: session.state.localWindowSize ?? null,
272
+ remoteFlowControlWindow: session.state.remoteWindowSize ?? null,
273
+ };
274
+ return socketInfo;
275
+ };
276
+ }
277
+
278
+ private trace(text: string): void {
279
+ logging.trace(
280
+ LogVerbosity.DEBUG,
281
+ TRACER_NAME,
282
+ '(' + this.channelzRef.id + ') ' + text
283
+ );
284
+ }
285
+
286
+ addProtoService(): never {
287
+ throw new Error('Not implemented. Use addService() instead');
288
+ }
289
+
290
+ addService(
291
+ service: ServiceDefinition,
292
+ implementation: UntypedServiceImplementation
293
+ ): void {
294
+ if (
295
+ service === null ||
296
+ typeof service !== 'object' ||
297
+ implementation === null ||
298
+ typeof implementation !== 'object'
299
+ ) {
300
+ throw new Error('addService() requires two objects as arguments');
301
+ }
302
+
303
+ const serviceKeys = Object.keys(service);
304
+
305
+ if (serviceKeys.length === 0) {
306
+ throw new Error('Cannot add an empty service to a server');
307
+ }
308
+
309
+ serviceKeys.forEach(name => {
310
+ const attrs = service[name];
311
+ let methodType: HandlerType;
312
+
313
+ if (attrs.requestStream) {
314
+ if (attrs.responseStream) {
315
+ methodType = 'bidi';
316
+ } else {
317
+ methodType = 'clientStream';
318
+ }
319
+ } else {
320
+ if (attrs.responseStream) {
321
+ methodType = 'serverStream';
322
+ } else {
323
+ methodType = 'unary';
324
+ }
325
+ }
326
+
327
+ let implFn = implementation[name];
328
+ let impl;
329
+
330
+ if (implFn === undefined && typeof attrs.originalName === 'string') {
331
+ implFn = implementation[attrs.originalName];
332
+ }
333
+
334
+ if (implFn !== undefined) {
335
+ impl = implFn.bind(implementation);
336
+ } else {
337
+ impl = getDefaultHandler(methodType, name);
338
+ }
339
+
340
+ const success = this.register(
341
+ attrs.path,
342
+ impl as UntypedHandleCall,
343
+ attrs.responseSerialize,
344
+ attrs.requestDeserialize,
345
+ methodType
346
+ );
347
+
348
+ if (success === false) {
349
+ throw new Error(`Method handler for ${attrs.path} already provided.`);
350
+ }
351
+ });
352
+ }
353
+
354
+ removeService(service: ServiceDefinition): void {
355
+ if (service === null || typeof service !== 'object') {
356
+ throw new Error('removeService() requires object as argument');
357
+ }
358
+
359
+ const serviceKeys = Object.keys(service);
360
+ serviceKeys.forEach(name => {
361
+ const attrs = service[name];
362
+ this.unregister(attrs.path);
363
+ });
364
+ }
365
+
366
+ bind(port: string, creds: ServerCredentials): never {
367
+ throw new Error('Not implemented. Use bindAsync() instead');
368
+ }
369
+
370
+ bindAsync(
371
+ port: string,
372
+ creds: ServerCredentials,
373
+ callback: (error: Error | null, port: number) => void
374
+ ): void {
375
+ if (this.started === true) {
376
+ throw new Error('server is already started');
377
+ }
378
+
379
+ if (this.shutdown) {
380
+ throw new Error('bindAsync called after shutdown');
381
+ }
382
+
383
+ if (typeof port !== 'string') {
384
+ throw new TypeError('port must be a string');
385
+ }
386
+
387
+ if (creds === null || !(creds instanceof ServerCredentials)) {
388
+ throw new TypeError('creds must be a ServerCredentials object');
389
+ }
390
+
391
+ if (typeof callback !== 'function') {
392
+ throw new TypeError('callback must be a function');
393
+ }
394
+
395
+ const initialPortUri = parseUri(port);
396
+ if (initialPortUri === null) {
397
+ throw new Error(`Could not parse port "${port}"`);
398
+ }
399
+ const portUri = mapUriDefaultScheme(initialPortUri);
400
+ if (portUri === null) {
401
+ throw new Error(`Could not get a default scheme for port "${port}"`);
402
+ }
403
+
404
+ const serverOptions: http2.ServerOptions = {
405
+ maxSendHeaderBlockLength: Number.MAX_SAFE_INTEGER,
406
+ };
407
+ if ('grpc-node.max_session_memory' in this.options) {
408
+ serverOptions.maxSessionMemory =
409
+ this.options['grpc-node.max_session_memory'];
410
+ } else {
411
+ /* By default, set a very large max session memory limit, to effectively
412
+ * disable enforcement of the limit. Some testing indicates that Node's
413
+ * behavior degrades badly when this limit is reached, so we solve that
414
+ * by disabling the check entirely. */
415
+ serverOptions.maxSessionMemory = Number.MAX_SAFE_INTEGER;
416
+ }
417
+ if ('grpc.max_concurrent_streams' in this.options) {
418
+ serverOptions.settings = {
419
+ maxConcurrentStreams: this.options['grpc.max_concurrent_streams'],
420
+ };
421
+ }
422
+
423
+ const deferredCallback = (error: Error | null, port: number) => {
424
+ process.nextTick(() => callback(error, port));
425
+ };
426
+
427
+ const setupServer = (): http2.Http2Server | http2.Http2SecureServer => {
428
+ let http2Server: http2.Http2Server | http2.Http2SecureServer;
429
+ if (creds._isSecure()) {
430
+ const secureServerOptions = Object.assign(
431
+ serverOptions,
432
+ creds._getSettings()!
433
+ );
434
+ secureServerOptions.enableTrace =
435
+ this.options['grpc-node.tls_enable_trace'] === 1;
436
+ http2Server = http2.createSecureServer(secureServerOptions);
437
+ http2Server.on('secureConnection', (socket: TLSSocket) => {
438
+ /* These errors need to be handled by the user of Http2SecureServer,
439
+ * according to https://github.com/nodejs/node/issues/35824 */
440
+ socket.on('error', (e: Error) => {
441
+ this.trace(
442
+ 'An incoming TLS connection closed with error: ' + e.message
443
+ );
444
+ });
445
+ });
446
+ } else {
447
+ http2Server = http2.createServer(serverOptions);
448
+ }
449
+
450
+ http2Server.setTimeout(0, noop);
451
+ this._setupHandlers(http2Server);
452
+ return http2Server;
453
+ };
454
+
455
+ const bindSpecificPort = (
456
+ addressList: SubchannelAddress[],
457
+ portNum: number,
458
+ previousCount: number
459
+ ): Promise<BindResult> => {
460
+ if (addressList.length === 0) {
461
+ return Promise.resolve({ port: portNum, count: previousCount });
462
+ }
463
+ return Promise.all(
464
+ addressList.map(address => {
465
+ this.trace(
466
+ 'Attempting to bind ' + subchannelAddressToString(address)
467
+ );
468
+ let addr: SubchannelAddress;
469
+ if (isTcpSubchannelAddress(address)) {
470
+ addr = {
471
+ host: (address as TcpSubchannelAddress).host,
472
+ port: portNum,
473
+ };
474
+ } else {
475
+ addr = address;
476
+ }
477
+
478
+ const http2Server = setupServer();
479
+ return new Promise<number | Error>((resolve, reject) => {
480
+ const onError = (err: Error) => {
481
+ this.trace(
482
+ 'Failed to bind ' +
483
+ subchannelAddressToString(address) +
484
+ ' with error ' +
485
+ err.message
486
+ );
487
+ resolve(err);
488
+ };
489
+
490
+ http2Server.once('error', onError);
491
+
492
+ http2Server.listen(addr, () => {
493
+ if (this.shutdown) {
494
+ http2Server.close();
495
+ resolve(new Error('bindAsync failed because server is shutdown'));
496
+ return;
497
+ }
498
+ const boundAddress = http2Server.address()!;
499
+ let boundSubchannelAddress: SubchannelAddress;
500
+ if (typeof boundAddress === 'string') {
501
+ boundSubchannelAddress = {
502
+ path: boundAddress,
503
+ };
504
+ } else {
505
+ boundSubchannelAddress = {
506
+ host: boundAddress.address,
507
+ port: boundAddress.port,
508
+ };
509
+ }
510
+
511
+ const channelzRef = registerChannelzSocket(
512
+ subchannelAddressToString(boundSubchannelAddress),
513
+ () => {
514
+ return {
515
+ localAddress: boundSubchannelAddress,
516
+ remoteAddress: null,
517
+ security: null,
518
+ remoteName: null,
519
+ streamsStarted: 0,
520
+ streamsSucceeded: 0,
521
+ streamsFailed: 0,
522
+ messagesSent: 0,
523
+ messagesReceived: 0,
524
+ keepAlivesSent: 0,
525
+ lastLocalStreamCreatedTimestamp: null,
526
+ lastRemoteStreamCreatedTimestamp: null,
527
+ lastMessageSentTimestamp: null,
528
+ lastMessageReceivedTimestamp: null,
529
+ localFlowControlWindow: null,
530
+ remoteFlowControlWindow: null,
531
+ };
532
+ },
533
+ this.channelzEnabled
534
+ );
535
+ if (this.channelzEnabled) {
536
+ this.listenerChildrenTracker.refChild(channelzRef);
537
+ }
538
+ this.http2ServerList.push({
539
+ server: http2Server,
540
+ channelzRef: channelzRef,
541
+ });
542
+ this.trace(
543
+ 'Successfully bound ' +
544
+ subchannelAddressToString(boundSubchannelAddress)
545
+ );
546
+ resolve(
547
+ 'port' in boundSubchannelAddress
548
+ ? boundSubchannelAddress.port
549
+ : portNum
550
+ );
551
+ http2Server.removeListener('error', onError);
552
+ });
553
+ });
554
+ })
555
+ ).then(results => {
556
+ let count = 0;
557
+ for (const result of results) {
558
+ if (typeof result === 'number') {
559
+ count += 1;
560
+ if (result !== portNum) {
561
+ throw new Error(
562
+ 'Invalid state: multiple port numbers added from single address'
563
+ );
564
+ }
565
+ }
566
+ }
567
+ return {
568
+ port: portNum,
569
+ count: count + previousCount,
570
+ };
571
+ });
572
+ };
573
+
574
+ const bindWildcardPort = (
575
+ addressList: SubchannelAddress[]
576
+ ): Promise<BindResult> => {
577
+ if (addressList.length === 0) {
578
+ return Promise.resolve<BindResult>({ port: 0, count: 0 });
579
+ }
580
+ const address = addressList[0];
581
+ const http2Server = setupServer();
582
+ return new Promise<BindResult>((resolve, reject) => {
583
+ const onError = (err: Error) => {
584
+ this.trace(
585
+ 'Failed to bind ' +
586
+ subchannelAddressToString(address) +
587
+ ' with error ' +
588
+ err.message
589
+ );
590
+ resolve(bindWildcardPort(addressList.slice(1)));
591
+ };
592
+
593
+ http2Server.once('error', onError);
594
+
595
+ http2Server.listen(address, () => {
596
+ if (this.shutdown) {
597
+ http2Server.close();
598
+ resolve({port: 0, count: 0});
599
+ return;
600
+ }
601
+ const boundAddress = http2Server.address() as AddressInfo;
602
+ const boundSubchannelAddress: SubchannelAddress = {
603
+ host: boundAddress.address,
604
+ port: boundAddress.port,
605
+ };
606
+ const channelzRef = registerChannelzSocket(
607
+ subchannelAddressToString(boundSubchannelAddress),
608
+ () => {
609
+ return {
610
+ localAddress: boundSubchannelAddress,
611
+ remoteAddress: null,
612
+ security: null,
613
+ remoteName: null,
614
+ streamsStarted: 0,
615
+ streamsSucceeded: 0,
616
+ streamsFailed: 0,
617
+ messagesSent: 0,
618
+ messagesReceived: 0,
619
+ keepAlivesSent: 0,
620
+ lastLocalStreamCreatedTimestamp: null,
621
+ lastRemoteStreamCreatedTimestamp: null,
622
+ lastMessageSentTimestamp: null,
623
+ lastMessageReceivedTimestamp: null,
624
+ localFlowControlWindow: null,
625
+ remoteFlowControlWindow: null,
626
+ };
627
+ },
628
+ this.channelzEnabled
629
+ );
630
+ if (this.channelzEnabled) {
631
+ this.listenerChildrenTracker.refChild(channelzRef);
632
+ }
633
+ this.http2ServerList.push({
634
+ server: http2Server,
635
+ channelzRef: channelzRef,
636
+ });
637
+ this.trace(
638
+ 'Successfully bound ' +
639
+ subchannelAddressToString(boundSubchannelAddress)
640
+ );
641
+ resolve(bindSpecificPort(addressList.slice(1), boundAddress.port, 1));
642
+ http2Server.removeListener('error', onError);
643
+ });
644
+ });
645
+ };
646
+
647
+ const resolverListener: ResolverListener = {
648
+ onSuccessfulResolution: (
649
+ addressList,
650
+ serviceConfig,
651
+ serviceConfigError
652
+ ) => {
653
+ // We only want one resolution result. Discard all future results
654
+ resolverListener.onSuccessfulResolution = () => {};
655
+ if (this.shutdown) {
656
+ deferredCallback(
657
+ new Error(`bindAsync failed because server is shutdown`),
658
+ 0
659
+ );
660
+ }
661
+ if (addressList.length === 0) {
662
+ deferredCallback(
663
+ new Error(`No addresses resolved for port ${port}`),
664
+ 0
665
+ );
666
+ return;
667
+ }
668
+ let bindResultPromise: Promise<BindResult>;
669
+ if (isTcpSubchannelAddress(addressList[0])) {
670
+ if (addressList[0].port === 0) {
671
+ bindResultPromise = bindWildcardPort(addressList);
672
+ } else {
673
+ bindResultPromise = bindSpecificPort(
674
+ addressList,
675
+ addressList[0].port,
676
+ 0
677
+ );
678
+ }
679
+ } else {
680
+ // Use an arbitrary non-zero port for non-TCP addresses
681
+ bindResultPromise = bindSpecificPort(addressList, 1, 0);
682
+ }
683
+ bindResultPromise.then(
684
+ bindResult => {
685
+ if (bindResult.count === 0) {
686
+ const errorString = `No address added out of total ${addressList.length} resolved`;
687
+ logging.log(LogVerbosity.ERROR, errorString);
688
+ deferredCallback(new Error(errorString), 0);
689
+ } else {
690
+ if (bindResult.count < addressList.length) {
691
+ logging.log(
692
+ LogVerbosity.INFO,
693
+ `WARNING Only ${bindResult.count} addresses added out of total ${addressList.length} resolved`
694
+ );
695
+ }
696
+ deferredCallback(null, bindResult.port);
697
+ }
698
+ },
699
+ error => {
700
+ const errorString = `No address added out of total ${addressList.length} resolved`;
701
+ logging.log(LogVerbosity.ERROR, errorString);
702
+ deferredCallback(new Error(errorString), 0);
703
+ }
704
+ );
705
+ },
706
+ onError: error => {
707
+ deferredCallback(new Error(error.details), 0);
708
+ },
709
+ };
710
+
711
+ const resolver = createResolver(portUri, resolverListener, this.options);
712
+ resolver.updateResolution();
713
+ }
714
+
715
+ forceShutdown(): void {
716
+ // Close the server if it is still running.
717
+
718
+ for (const { server: http2Server, channelzRef: ref } of this
719
+ .http2ServerList) {
720
+ if (http2Server.listening) {
721
+ http2Server.close(() => {
722
+ if (this.channelzEnabled) {
723
+ this.listenerChildrenTracker.unrefChild(ref);
724
+ unregisterChannelzRef(ref);
725
+ }
726
+ });
727
+ }
728
+ }
729
+
730
+ this.started = false;
731
+ this.shutdown = true;
732
+
733
+ // Always destroy any available sessions. It's possible that one or more
734
+ // tryShutdown() calls are in progress. Don't wait on them to finish.
735
+ this.sessions.forEach((channelzInfo, session) => {
736
+ // Cast NGHTTP2_CANCEL to any because TypeScript doesn't seem to
737
+ // recognize destroy(code) as a valid signature.
738
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
739
+ session.destroy(http2.constants.NGHTTP2_CANCEL as any);
740
+ });
741
+ this.sessions.clear();
742
+ if (this.channelzEnabled) {
743
+ unregisterChannelzRef(this.channelzRef);
744
+ }
745
+ }
746
+
747
+ register<RequestType, ResponseType>(
748
+ name: string,
749
+ handler: HandleCall<RequestType, ResponseType>,
750
+ serialize: Serialize<ResponseType>,
751
+ deserialize: Deserialize<RequestType>,
752
+ type: string
753
+ ): boolean {
754
+ if (this.handlers.has(name)) {
755
+ return false;
756
+ }
757
+
758
+ this.handlers.set(name, {
759
+ func: handler,
760
+ serialize,
761
+ deserialize,
762
+ type,
763
+ path: name,
764
+ } as UntypedHandler);
765
+ return true;
766
+ }
767
+
768
+ unregister(name: string): boolean {
769
+ return this.handlers.delete(name);
770
+ }
771
+
772
+ start(): void {
773
+ if (
774
+ this.http2ServerList.length === 0 ||
775
+ this.http2ServerList.every(
776
+ ({ server: http2Server }) => http2Server.listening !== true
777
+ )
778
+ ) {
779
+ throw new Error('server must be bound in order to start');
780
+ }
781
+
782
+ if (this.started === true) {
783
+ throw new Error('server is already started');
784
+ }
785
+ if (this.channelzEnabled) {
786
+ this.channelzTrace.addTrace('CT_INFO', 'Starting');
787
+ }
788
+ this.started = true;
789
+ }
790
+
791
+ tryShutdown(callback: (error?: Error) => void): void {
792
+ const wrappedCallback = (error?: Error) => {
793
+ if (this.channelzEnabled) {
794
+ unregisterChannelzRef(this.channelzRef);
795
+ }
796
+ callback(error);
797
+ };
798
+ let pendingChecks = 0;
799
+
800
+ function maybeCallback(): void {
801
+ pendingChecks--;
802
+
803
+ if (pendingChecks === 0) {
804
+ wrappedCallback();
805
+ }
806
+ }
807
+
808
+ // Close the server if necessary.
809
+ this.started = false;
810
+ this.shutdown = true;
811
+
812
+ for (const { server: http2Server, channelzRef: ref } of this
813
+ .http2ServerList) {
814
+ if (http2Server.listening) {
815
+ pendingChecks++;
816
+ http2Server.close(() => {
817
+ if (this.channelzEnabled) {
818
+ this.listenerChildrenTracker.unrefChild(ref);
819
+ unregisterChannelzRef(ref);
820
+ }
821
+ maybeCallback();
822
+ });
823
+ }
824
+ }
825
+
826
+ this.sessions.forEach((channelzInfo, session) => {
827
+ if (!session.closed) {
828
+ pendingChecks += 1;
829
+ session.close(maybeCallback);
830
+ }
831
+ });
832
+ if (pendingChecks === 0) {
833
+ wrappedCallback();
834
+ }
835
+ }
836
+
837
+ addHttp2Port(): never {
838
+ throw new Error('Not yet implemented');
839
+ }
840
+
841
+ /**
842
+ * Get the channelz reference object for this server. The returned value is
843
+ * garbage if channelz is disabled for this server.
844
+ * @returns
845
+ */
846
+ getChannelzRef() {
847
+ return this.channelzRef;
848
+ }
849
+
850
+ private _verifyContentType(
851
+ stream: http2.ServerHttp2Stream,
852
+ headers: http2.IncomingHttpHeaders
853
+ ): boolean {
854
+ const contentType = headers[http2.constants.HTTP2_HEADER_CONTENT_TYPE];
855
+
856
+ if (
857
+ typeof contentType !== 'string' ||
858
+ !contentType.startsWith('application/grpc')
859
+ ) {
860
+ stream.respond(
861
+ {
862
+ [http2.constants.HTTP2_HEADER_STATUS]:
863
+ http2.constants.HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE,
864
+ },
865
+ { endStream: true }
866
+ );
867
+ return false;
868
+ }
869
+
870
+ return true;
871
+ }
872
+
873
+ private _retrieveHandler(path: string): Handler<any, any> | null {
874
+ this.trace(
875
+ 'Received call to method ' +
876
+ path +
877
+ ' at address ' +
878
+ this.serverAddressString
879
+ );
880
+
881
+ const handler = this.handlers.get(path);
882
+
883
+ if (handler === undefined) {
884
+ this.trace(
885
+ 'No handler registered for method ' +
886
+ path +
887
+ '. Sending UNIMPLEMENTED status.'
888
+ );
889
+ return null;
890
+ }
891
+
892
+ return handler;
893
+ }
894
+
895
+ private _respondWithError<T extends Partial<ServiceError>>(
896
+ err: T,
897
+ stream: http2.ServerHttp2Stream,
898
+ channelzSessionInfo: ChannelzSessionInfo | null = null
899
+ ) {
900
+ const call = new Http2ServerCallStream(stream, null!, this.options);
901
+
902
+ if (err.code === undefined) {
903
+ err.code = Status.INTERNAL;
904
+ }
905
+
906
+ if (this.channelzEnabled) {
907
+ this.callTracker.addCallFailed();
908
+ channelzSessionInfo?.streamTracker.addCallFailed();
909
+ }
910
+
911
+ call.sendError(err);
912
+ }
913
+
914
+ private _channelzHandler(
915
+ stream: http2.ServerHttp2Stream,
916
+ headers: http2.IncomingHttpHeaders
917
+ ) {
918
+ const channelzSessionInfo = this.sessions.get(
919
+ stream.session as http2.ServerHttp2Session
920
+ );
921
+
922
+ this.callTracker.addCallStarted();
923
+ channelzSessionInfo?.streamTracker.addCallStarted();
924
+
925
+ if (!this._verifyContentType(stream, headers)) {
926
+ this.callTracker.addCallFailed();
927
+ channelzSessionInfo?.streamTracker.addCallFailed();
928
+ return;
929
+ }
930
+
931
+ const path = headers[HTTP2_HEADER_PATH] as string;
932
+
933
+ const handler = this._retrieveHandler(path);
934
+ if (!handler) {
935
+ this._respondWithError(
936
+ getUnimplementedStatusResponse(path),
937
+ stream,
938
+ channelzSessionInfo
939
+ );
940
+ return;
941
+ }
942
+
943
+ const call = new Http2ServerCallStream(stream, handler, this.options);
944
+
945
+ call.once('callEnd', (code: Status) => {
946
+ if (code === Status.OK) {
947
+ this.callTracker.addCallSucceeded();
948
+ } else {
949
+ this.callTracker.addCallFailed();
950
+ }
951
+ });
952
+
953
+ if (channelzSessionInfo) {
954
+ call.once('streamEnd', (success: boolean) => {
955
+ if (success) {
956
+ channelzSessionInfo.streamTracker.addCallSucceeded();
957
+ } else {
958
+ channelzSessionInfo.streamTracker.addCallFailed();
959
+ }
960
+ });
961
+ call.on('sendMessage', () => {
962
+ channelzSessionInfo.messagesSent += 1;
963
+ channelzSessionInfo.lastMessageSentTimestamp = new Date();
964
+ });
965
+ call.on('receiveMessage', () => {
966
+ channelzSessionInfo.messagesReceived += 1;
967
+ channelzSessionInfo.lastMessageReceivedTimestamp = new Date();
968
+ });
969
+ }
970
+
971
+ if (!this._runHandlerForCall(call, handler, headers)) {
972
+ this.callTracker.addCallFailed();
973
+ channelzSessionInfo?.streamTracker.addCallFailed();
974
+
975
+ call.sendError({
976
+ code: Status.INTERNAL,
977
+ details: `Unknown handler type: ${handler.type}`,
978
+ });
979
+ }
980
+ }
981
+
982
+ private _streamHandler(
983
+ stream: http2.ServerHttp2Stream,
984
+ headers: http2.IncomingHttpHeaders
985
+ ) {
986
+ if (this._verifyContentType(stream, headers) !== true) {
987
+ return;
988
+ }
989
+
990
+ const path = headers[HTTP2_HEADER_PATH] as string;
991
+
992
+ const handler = this._retrieveHandler(path);
993
+ if (!handler) {
994
+ this._respondWithError(
995
+ getUnimplementedStatusResponse(path),
996
+ stream,
997
+ null
998
+ );
999
+ return;
1000
+ }
1001
+
1002
+ const call = new Http2ServerCallStream(stream, handler, this.options);
1003
+ if (!this._runHandlerForCall(call, handler, headers)) {
1004
+ call.sendError({
1005
+ code: Status.INTERNAL,
1006
+ details: `Unknown handler type: ${handler.type}`,
1007
+ });
1008
+ }
1009
+ }
1010
+
1011
+ private _runHandlerForCall(
1012
+ call: Http2ServerCallStream<any, any>,
1013
+ handler: Handler<any, any>,
1014
+ headers: http2.IncomingHttpHeaders
1015
+ ): boolean {
1016
+ const metadata = call.receiveMetadata(headers);
1017
+ const encoding =
1018
+ (metadata.get('grpc-encoding')[0] as string | undefined) ?? 'identity';
1019
+ metadata.remove('grpc-encoding');
1020
+
1021
+ const { type } = handler;
1022
+ if (type === 'unary') {
1023
+ handleUnary(call, handler as UntypedUnaryHandler, metadata, encoding);
1024
+ } else if (type === 'clientStream') {
1025
+ handleClientStreaming(
1026
+ call,
1027
+ handler as UntypedClientStreamingHandler,
1028
+ metadata,
1029
+ encoding
1030
+ );
1031
+ } else if (type === 'serverStream') {
1032
+ handleServerStreaming(
1033
+ call,
1034
+ handler as UntypedServerStreamingHandler,
1035
+ metadata,
1036
+ encoding
1037
+ );
1038
+ } else if (type === 'bidi') {
1039
+ handleBidiStreaming(
1040
+ call,
1041
+ handler as UntypedBidiStreamingHandler,
1042
+ metadata,
1043
+ encoding
1044
+ );
1045
+ } else {
1046
+ return false;
1047
+ }
1048
+
1049
+ return true;
1050
+ }
1051
+
1052
+ private _setupHandlers(
1053
+ http2Server: http2.Http2Server | http2.Http2SecureServer
1054
+ ): void {
1055
+ if (http2Server === null) {
1056
+ return;
1057
+ }
1058
+
1059
+ const serverAddress = http2Server.address();
1060
+ let serverAddressString = 'null';
1061
+ if (serverAddress) {
1062
+ if (typeof serverAddress === 'string') {
1063
+ serverAddressString = serverAddress;
1064
+ } else {
1065
+ serverAddressString = serverAddress.address + ':' + serverAddress.port;
1066
+ }
1067
+ }
1068
+ this.serverAddressString = serverAddressString;
1069
+
1070
+ const handler = this.channelzEnabled
1071
+ ? this._channelzHandler
1072
+ : this._streamHandler;
1073
+
1074
+ http2Server.on('stream', handler.bind(this));
1075
+ http2Server.on('session', session => {
1076
+ if (!this.started) {
1077
+ session.destroy();
1078
+ return;
1079
+ }
1080
+
1081
+ const channelzRef = registerChannelzSocket(
1082
+ session.socket.remoteAddress ?? 'unknown',
1083
+ this.getChannelzSessionInfoGetter(session),
1084
+ this.channelzEnabled
1085
+ );
1086
+
1087
+ const channelzSessionInfo: ChannelzSessionInfo = {
1088
+ ref: channelzRef,
1089
+ streamTracker: new ChannelzCallTracker(),
1090
+ messagesSent: 0,
1091
+ messagesReceived: 0,
1092
+ lastMessageSentTimestamp: null,
1093
+ lastMessageReceivedTimestamp: null,
1094
+ };
1095
+
1096
+ this.sessions.set(session, channelzSessionInfo);
1097
+ const clientAddress = session.socket.remoteAddress;
1098
+ if (this.channelzEnabled) {
1099
+ this.channelzTrace.addTrace(
1100
+ 'CT_INFO',
1101
+ 'Connection established by client ' + clientAddress
1102
+ );
1103
+ this.sessionChildrenTracker.refChild(channelzRef);
1104
+ }
1105
+ let connectionAgeTimer: NodeJS.Timeout | null = null;
1106
+ let connectionAgeGraceTimer: NodeJS.Timeout | null = null;
1107
+ let sessionClosedByServer = false;
1108
+ if (this.maxConnectionAgeMs !== UNLIMITED_CONNECTION_AGE_MS) {
1109
+ // Apply a random jitter within a +/-10% range
1110
+ const jitterMagnitude = this.maxConnectionAgeMs / 10;
1111
+ const jitter = Math.random() * jitterMagnitude * 2 - jitterMagnitude;
1112
+ connectionAgeTimer = setTimeout(() => {
1113
+ sessionClosedByServer = true;
1114
+ if (this.channelzEnabled) {
1115
+ this.channelzTrace.addTrace(
1116
+ 'CT_INFO',
1117
+ 'Connection dropped by max connection age from ' + clientAddress
1118
+ );
1119
+ }
1120
+ try {
1121
+ session.goaway(
1122
+ http2.constants.NGHTTP2_NO_ERROR,
1123
+ ~(1 << 31),
1124
+ Buffer.from('max_age')
1125
+ );
1126
+ } catch (e) {
1127
+ // The goaway can't be sent because the session is already closed
1128
+ session.destroy();
1129
+ return;
1130
+ }
1131
+ session.close();
1132
+ /* Allow a grace period after sending the GOAWAY before forcibly
1133
+ * closing the connection. */
1134
+ if (this.maxConnectionAgeGraceMs !== UNLIMITED_CONNECTION_AGE_MS) {
1135
+ connectionAgeGraceTimer = setTimeout(() => {
1136
+ session.destroy();
1137
+ }, this.maxConnectionAgeGraceMs).unref?.();
1138
+ }
1139
+ }, this.maxConnectionAgeMs + jitter).unref?.();
1140
+ }
1141
+ const keeapliveTimeTimer: NodeJS.Timeout | null = setInterval(() => {
1142
+ const timeoutTImer = setTimeout(() => {
1143
+ sessionClosedByServer = true;
1144
+ if (this.channelzEnabled) {
1145
+ this.channelzTrace.addTrace(
1146
+ 'CT_INFO',
1147
+ 'Connection dropped by keepalive timeout from ' + clientAddress
1148
+ );
1149
+ }
1150
+ session.close();
1151
+ }, this.keepaliveTimeoutMs).unref?.();
1152
+ try {
1153
+ session.ping(
1154
+ (err: Error | null, duration: number, payload: Buffer) => {
1155
+ clearTimeout(timeoutTImer);
1156
+ }
1157
+ );
1158
+ } catch (e) {
1159
+ // The ping can't be sent because the session is already closed
1160
+ session.destroy();
1161
+ }
1162
+ }, this.keepaliveTimeMs).unref?.();
1163
+ session.on('close', () => {
1164
+ if (this.channelzEnabled) {
1165
+ if (!sessionClosedByServer) {
1166
+ this.channelzTrace.addTrace(
1167
+ 'CT_INFO',
1168
+ 'Connection dropped by client ' + clientAddress
1169
+ );
1170
+ }
1171
+ this.sessionChildrenTracker.unrefChild(channelzRef);
1172
+ unregisterChannelzRef(channelzRef);
1173
+ }
1174
+ if (connectionAgeTimer) {
1175
+ clearTimeout(connectionAgeTimer);
1176
+ }
1177
+ if (connectionAgeGraceTimer) {
1178
+ clearTimeout(connectionAgeGraceTimer);
1179
+ }
1180
+ if (keeapliveTimeTimer) {
1181
+ clearTimeout(keeapliveTimeTimer);
1182
+ }
1183
+ this.sessions.delete(session);
1184
+ });
1185
+ });
1186
+ }
1187
+ }
1188
+
1189
+ async function handleUnary<RequestType, ResponseType>(
1190
+ call: Http2ServerCallStream<RequestType, ResponseType>,
1191
+ handler: UnaryHandler<RequestType, ResponseType>,
1192
+ metadata: Metadata,
1193
+ encoding: string
1194
+ ): Promise<void> {
1195
+ try {
1196
+ const request = await call.receiveUnaryMessage(encoding);
1197
+
1198
+ if (request === undefined || call.cancelled) {
1199
+ return;
1200
+ }
1201
+
1202
+ const emitter = new ServerUnaryCallImpl<RequestType, ResponseType>(
1203
+ call,
1204
+ metadata,
1205
+ request
1206
+ );
1207
+
1208
+ handler.func(
1209
+ emitter,
1210
+ (
1211
+ err: ServerErrorResponse | ServerStatusResponse | null,
1212
+ value?: ResponseType | null,
1213
+ trailer?: Metadata,
1214
+ flags?: number
1215
+ ) => {
1216
+ call.sendUnaryMessage(err, value, trailer, flags);
1217
+ }
1218
+ );
1219
+ } catch (err) {
1220
+ call.sendError(err as ServerErrorResponse);
1221
+ }
1222
+ }
1223
+
1224
+ function handleClientStreaming<RequestType, ResponseType>(
1225
+ call: Http2ServerCallStream<RequestType, ResponseType>,
1226
+ handler: ClientStreamingHandler<RequestType, ResponseType>,
1227
+ metadata: Metadata,
1228
+ encoding: string
1229
+ ): void {
1230
+ const stream = new ServerReadableStreamImpl<RequestType, ResponseType>(
1231
+ call,
1232
+ metadata,
1233
+ handler.deserialize,
1234
+ encoding
1235
+ );
1236
+
1237
+ function respond(
1238
+ err: ServerErrorResponse | ServerStatusResponse | null,
1239
+ value?: ResponseType | null,
1240
+ trailer?: Metadata,
1241
+ flags?: number
1242
+ ) {
1243
+ stream.destroy();
1244
+ call.sendUnaryMessage(err, value, trailer, flags);
1245
+ }
1246
+
1247
+ if (call.cancelled) {
1248
+ return;
1249
+ }
1250
+
1251
+ stream.on('error', respond);
1252
+ handler.func(stream, respond);
1253
+ }
1254
+
1255
+ async function handleServerStreaming<RequestType, ResponseType>(
1256
+ call: Http2ServerCallStream<RequestType, ResponseType>,
1257
+ handler: ServerStreamingHandler<RequestType, ResponseType>,
1258
+ metadata: Metadata,
1259
+ encoding: string
1260
+ ): Promise<void> {
1261
+ try {
1262
+ const request = await call.receiveUnaryMessage(encoding);
1263
+
1264
+ if (request === undefined || call.cancelled) {
1265
+ return;
1266
+ }
1267
+
1268
+ const stream = new ServerWritableStreamImpl<RequestType, ResponseType>(
1269
+ call,
1270
+ metadata,
1271
+ handler.serialize,
1272
+ request
1273
+ );
1274
+
1275
+ handler.func(stream);
1276
+ } catch (err) {
1277
+ call.sendError(err as ServerErrorResponse);
1278
+ }
1279
+ }
1280
+
1281
+ function handleBidiStreaming<RequestType, ResponseType>(
1282
+ call: Http2ServerCallStream<RequestType, ResponseType>,
1283
+ handler: BidiStreamingHandler<RequestType, ResponseType>,
1284
+ metadata: Metadata,
1285
+ encoding: string
1286
+ ): void {
1287
+ const stream = new ServerDuplexStreamImpl<RequestType, ResponseType>(
1288
+ call,
1289
+ metadata,
1290
+ handler.serialize,
1291
+ handler.deserialize,
1292
+ encoding
1293
+ );
1294
+
1295
+ if (call.cancelled) {
1296
+ return;
1297
+ }
1298
+
1299
+ handler.func(stream);
1300
+ }