GRPCCall.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. *
  3. * Copyright 2015 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. /**
  19. * The gRPC protocol is an RPC protocol on top of HTTP2.
  20. *
  21. * While the most common type of RPC receives only one request message and returns only one response
  22. * message, the protocol also supports RPCs that return multiple individual messages in a streaming
  23. * fashion, RPCs that accept a stream of request messages, or RPCs with both streaming requests and
  24. * responses.
  25. *
  26. * Conceptually, each gRPC call consists of a bidirectional stream of binary messages, with RPCs of
  27. * the "non-streaming type" sending only one message in the corresponding direction (the protocol
  28. * doesn't make any distinction).
  29. *
  30. * Each RPC uses a different HTTP2 stream, and thus multiple simultaneous RPCs can be multiplexed
  31. * transparently on the same TCP connection.
  32. */
  33. #import <Foundation/Foundation.h>
  34. #import <RxLibrary/GRXWriter.h>
  35. #include <AvailabilityMacros.h>
  36. #pragma mark gRPC errors
  37. /** Domain of NSError objects produced by gRPC. */
  38. extern NSString *const kGRPCErrorDomain;
  39. /**
  40. * gRPC error codes.
  41. * Note that a few of these are never produced by the gRPC libraries, but are of general utility for
  42. * server applications to produce.
  43. */
  44. typedef NS_ENUM(NSUInteger, GRPCErrorCode) {
  45. /** The operation was cancelled (typically by the caller). */
  46. GRPCErrorCodeCancelled = 1,
  47. /**
  48. * Unknown error. Errors raised by APIs that do not return enough error information may be
  49. * converted to this error.
  50. */
  51. GRPCErrorCodeUnknown = 2,
  52. /**
  53. * The client specified an invalid argument. Note that this differs from FAILED_PRECONDITION.
  54. * INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the
  55. * server (e.g., a malformed file name).
  56. */
  57. GRPCErrorCodeInvalidArgument = 3,
  58. /**
  59. * Deadline expired before operation could complete. For operations that change the state of the
  60. * server, this error may be returned even if the operation has completed successfully. For
  61. * example, a successful response from the server could have been delayed long enough for the
  62. * deadline to expire.
  63. */
  64. GRPCErrorCodeDeadlineExceeded = 4,
  65. /** Some requested entity (e.g., file or directory) was not found. */
  66. GRPCErrorCodeNotFound = 5,
  67. /** Some entity that we attempted to create (e.g., file or directory) already exists. */
  68. GRPCErrorCodeAlreadyExists = 6,
  69. /**
  70. * The caller does not have permission to execute the specified operation. PERMISSION_DENIED isn't
  71. * used for rejections caused by exhausting some resource (RESOURCE_EXHAUSTED is used instead for
  72. * those errors). PERMISSION_DENIED doesn't indicate a failure to identify the caller
  73. * (UNAUTHENTICATED is used instead for those errors).
  74. */
  75. GRPCErrorCodePermissionDenied = 7,
  76. /**
  77. * The request does not have valid authentication credentials for the operation (e.g. the caller's
  78. * identity can't be verified).
  79. */
  80. GRPCErrorCodeUnauthenticated = 16,
  81. /** Some resource has been exhausted, perhaps a per-user quota. */
  82. GRPCErrorCodeResourceExhausted = 8,
  83. /**
  84. * The RPC was rejected because the server is not in a state required for the procedure's
  85. * execution. For example, a directory to be deleted may be non-empty, etc.
  86. * The client should not retry until the server state has been explicitly fixed (e.g. by
  87. * performing another RPC). The details depend on the service being called, and should be found in
  88. * the NSError's userInfo.
  89. */
  90. GRPCErrorCodeFailedPrecondition = 9,
  91. /**
  92. * The RPC was aborted, typically due to a concurrency issue like sequencer check failures,
  93. * transaction aborts, etc. The client should retry at a higher-level (e.g., restarting a read-
  94. * modify-write sequence).
  95. */
  96. GRPCErrorCodeAborted = 10,
  97. /**
  98. * The RPC was attempted past the valid range. E.g., enumerating past the end of a list.
  99. * Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed if the system state
  100. * changes. For example, an RPC to get elements of a list will generate INVALID_ARGUMENT if asked
  101. * to return the element at a negative index, but it will generate OUT_OF_RANGE if asked to return
  102. * the element at an index past the current size of the list.
  103. */
  104. GRPCErrorCodeOutOfRange = 11,
  105. /** The procedure is not implemented or not supported/enabled in this server. */
  106. GRPCErrorCodeUnimplemented = 12,
  107. /**
  108. * Internal error. Means some invariant expected by the server application or the gRPC library has
  109. * been broken.
  110. */
  111. GRPCErrorCodeInternal = 13,
  112. /**
  113. * The server is currently unavailable. This is most likely a transient condition and may be
  114. * corrected by retrying with a backoff.
  115. */
  116. GRPCErrorCodeUnavailable = 14,
  117. /** Unrecoverable data loss or corruption. */
  118. GRPCErrorCodeDataLoss = 15,
  119. };
  120. /**
  121. * Safety remark of a gRPC method as defined in RFC 2616 Section 9.1
  122. */
  123. typedef NS_ENUM(NSUInteger, GRPCCallSafety) {
  124. /** Signal that there is no guarantees on how the call affects the server state. */
  125. GRPCCallSafetyDefault = 0,
  126. /** Signal that the call is idempotent. gRPC is free to use PUT verb. */
  127. GRPCCallSafetyIdempotentRequest = 1,
  128. /** Signal that the call is cacheable and will not affect server state. gRPC is free to use GET verb. */
  129. GRPCCallSafetyCacheableRequest = 2,
  130. };
  131. /**
  132. * Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by
  133. * the server.
  134. */
  135. extern id const kGRPCHeadersKey;
  136. extern id const kGRPCTrailersKey;
  137. #pragma mark GRPCCall
  138. /** Represents a single gRPC remote call. */
  139. @interface GRPCCall : GRXWriter
  140. /**
  141. * The authority for the RPC. If nil, the default authority will be used. This property must be nil
  142. * when Cronet transport is enabled.
  143. */
  144. @property (atomic, copy, readwrite) NSString *serverName;
  145. /**
  146. * The container of the request headers of an RPC conforms to this protocol, which is a subset of
  147. * NSMutableDictionary's interface. It will become a NSMutableDictionary later on.
  148. * The keys of this container are the header names, which per the HTTP standard are case-
  149. * insensitive. They are stored in lowercase (which is how HTTP/2 mandates them on the wire), and
  150. * can only consist of ASCII characters.
  151. * A header value is a NSString object (with only ASCII characters), unless the header name has the
  152. * suffix "-bin", in which case the value has to be a NSData object.
  153. */
  154. /**
  155. * These HTTP headers will be passed to the server as part of this call. Each HTTP header is a
  156. * name-value pair with string names and either string or binary values.
  157. *
  158. * The passed dictionary has to use NSString keys, corresponding to the header names. The value
  159. * associated to each can be a NSString object or a NSData object. E.g.:
  160. *
  161. * call.requestHeaders = @{@"authorization": @"Bearer ..."};
  162. *
  163. * call.requestHeaders[@"my-header-bin"] = someData;
  164. *
  165. * After the call is started, trying to modify this property is an error.
  166. *
  167. * The property is initialized to an empty NSMutableDictionary.
  168. */
  169. @property(atomic, readonly) NSMutableDictionary *requestHeaders;
  170. /**
  171. * This dictionary is populated with the HTTP headers received from the server. This happens before
  172. * any response message is received from the server. It has the same structure as the request
  173. * headers dictionary: Keys are NSString header names; names ending with the suffix "-bin" have a
  174. * NSData value; the others have a NSString value.
  175. *
  176. * The value of this property is nil until all response headers are received, and will change before
  177. * any of -writeValue: or -writesFinishedWithError: are sent to the writeable.
  178. */
  179. @property(atomic, readonly) NSDictionary *responseHeaders;
  180. /**
  181. * Same as responseHeaders, but populated with the HTTP trailers received from the server before the
  182. * call finishes.
  183. *
  184. * The value of this property is nil until all response trailers are received, and will change
  185. * before -writesFinishedWithError: is sent to the writeable.
  186. */
  187. @property(atomic, readonly) NSDictionary *responseTrailers;
  188. /**
  189. * The request writer has to write NSData objects into the provided Writeable. The server will
  190. * receive each of those separately and in order as distinct messages.
  191. * A gRPC call might not complete until the request writer finishes. On the other hand, the request
  192. * finishing doesn't necessarily make the call to finish, as the server might continue sending
  193. * messages to the response side of the call indefinitely (depending on the semantics of the
  194. * specific remote method called).
  195. * To finish a call right away, invoke cancel.
  196. * host parameter should not contain the scheme (http:// or https://), only the name or IP addr
  197. * and the port number, for example @"localhost:5050".
  198. */
  199. - (instancetype)initWithHost:(NSString *)host
  200. path:(NSString *)path
  201. requestsWriter:(GRXWriter *)requestsWriter NS_DESIGNATED_INITIALIZER;
  202. /**
  203. * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and
  204. * finishes the response side of the call with an error of code CANCELED.
  205. */
  206. - (void)cancel;
  207. /**
  208. * Set the call flag for a specific host path.
  209. *
  210. * Host parameter should not contain the scheme (http:// or https://), only the name or IP addr
  211. * and the port number, for example @"localhost:5050".
  212. */
  213. + (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path;
  214. /**
  215. * Set the dispatch queue to be used for callbacks.
  216. *
  217. * This configuration is only effective before the call starts.
  218. */
  219. - (void)setResponseDispatchQueue:(dispatch_queue_t)queue;
  220. // TODO(jcanizales): Let specify a deadline. As a category of GRXWriter?
  221. @end
  222. #pragma mark Backwards compatibiity
  223. /** This protocol is kept for backwards compatibility with existing code. */
  224. DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.")
  225. @protocol GRPCRequestHeaders <NSObject>
  226. @property(nonatomic, readonly) NSUInteger count;
  227. - (id)objectForKeyedSubscript:(id)key;
  228. - (void)setObject:(id)obj forKeyedSubscript:(id)key;
  229. - (void)removeAllObjects;
  230. - (void)removeObjectForKey:(id)key;
  231. @end
  232. #pragma clang diagnostic push
  233. #pragma clang diagnostic ignored "-Wdeprecated"
  234. /** This is only needed for backwards-compatibility. */
  235. @interface NSMutableDictionary (GRPCRequestHeaders) <GRPCRequestHeaders>
  236. @end
  237. #pragma clang diagnostic pop