3 * Copyright 2018 gRPC authors.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #import "GRPCCallOptions.h"
20 #import "internal/GRPCCallOptions+Internal.h"
22 // The default values for the call options.
23 static NSString *const kDefaultServerAuthority = nil;
24 static const NSTimeInterval kDefaultTimeout = 0;
25 static const BOOL kDefaultFlowControlEnabled = NO;
26 static NSDictionary *const kDefaultInitialMetadata = nil;
27 static NSString *const kDefaultUserAgentPrefix = nil;
28 static const NSUInteger kDefaultResponseSizeLimit = 0;
29 static const GRPCCompressionAlgorithm kDefaultCompressionAlgorithm = GRPCCompressNone;
30 static const BOOL kDefaultRetryEnabled = YES;
31 static const NSTimeInterval kDefaultKeepaliveInterval = 0;
32 static const NSTimeInterval kDefaultKeepaliveTimeout = 0;
33 static const NSTimeInterval kDefaultConnectMinTimeout = 0;
34 static const NSTimeInterval kDefaultConnectInitialBackoff = 0;
35 static const NSTimeInterval kDefaultConnectMaxBackoff = 0;
36 static NSDictionary *const kDefaultAdditionalChannelArgs = nil;
37 static NSString *const kDefaultPEMRootCertificates = nil;
38 static NSString *const kDefaultPEMPrivateKey = nil;
39 static NSString *const kDefaultPEMCertificateChain = nil;
40 static NSString *const kDefaultOauth2AccessToken = nil;
41 static const id<GRPCAuthorizationProtocol> kDefaultAuthTokenProvider = nil;
42 static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeChttp2BoringSSL;
43 static NSString *const kDefaultHostNameOverride = nil;
44 static const id kDefaultLogContext = nil;
45 static NSString *const kDefaultChannelPoolDomain = nil;
46 static const NSUInteger kDefaultChannelID = 0;
48 // Check if two objects are equal. Returns YES if both are nil;
49 static BOOL areObjectsEqual(id obj1, id obj2) {
53 if (obj1 == nil || obj2 == nil) {
56 return [obj1 isEqual:obj2];
59 @implementation GRPCCallOptions {
61 NSString *_serverAuthority;
62 NSTimeInterval _timeout;
63 BOOL _flowControlEnabled;
64 NSString *_oauth2AccessToken;
65 id<GRPCAuthorizationProtocol> _authTokenProvider;
66 NSDictionary *_initialMetadata;
67 NSString *_userAgentPrefix;
68 NSUInteger _responseSizeLimit;
69 GRPCCompressionAlgorithm _compressionAlgorithm;
71 NSTimeInterval _keepaliveInterval;
72 NSTimeInterval _keepaliveTimeout;
73 NSTimeInterval _connectMinTimeout;
74 NSTimeInterval _connectInitialBackoff;
75 NSTimeInterval _connectMaxBackoff;
76 NSDictionary *_additionalChannelArgs;
77 NSString *_PEMRootCertificates;
78 NSString *_PEMPrivateKey;
79 NSString *_PEMCertificateChain;
80 GRPCTransportType _transportType;
81 NSString *_hostNameOverride;
82 id<NSObject> _logContext;
83 NSString *_channelPoolDomain;
84 NSUInteger _channelID;
87 @synthesize serverAuthority = _serverAuthority;
88 @synthesize timeout = _timeout;
89 @synthesize flowControlEnabled = _flowControlEnabled;
90 @synthesize oauth2AccessToken = _oauth2AccessToken;
91 @synthesize authTokenProvider = _authTokenProvider;
92 @synthesize initialMetadata = _initialMetadata;
93 @synthesize userAgentPrefix = _userAgentPrefix;
94 @synthesize responseSizeLimit = _responseSizeLimit;
95 @synthesize compressionAlgorithm = _compressionAlgorithm;
96 @synthesize retryEnabled = _retryEnabled;
97 @synthesize keepaliveInterval = _keepaliveInterval;
98 @synthesize keepaliveTimeout = _keepaliveTimeout;
99 @synthesize connectMinTimeout = _connectMinTimeout;
100 @synthesize connectInitialBackoff = _connectInitialBackoff;
101 @synthesize connectMaxBackoff = _connectMaxBackoff;
102 @synthesize additionalChannelArgs = _additionalChannelArgs;
103 @synthesize PEMRootCertificates = _PEMRootCertificates;
104 @synthesize PEMPrivateKey = _PEMPrivateKey;
105 @synthesize PEMCertificateChain = _PEMCertificateChain;
106 @synthesize transportType = _transportType;
107 @synthesize hostNameOverride = _hostNameOverride;
108 @synthesize logContext = _logContext;
109 @synthesize channelPoolDomain = _channelPoolDomain;
110 @synthesize channelID = _channelID;
112 - (instancetype)init {
113 return [self initWithServerAuthority:kDefaultServerAuthority
114 timeout:kDefaultTimeout
115 flowControlEnabled:kDefaultFlowControlEnabled
116 oauth2AccessToken:kDefaultOauth2AccessToken
117 authTokenProvider:kDefaultAuthTokenProvider
118 initialMetadata:kDefaultInitialMetadata
119 userAgentPrefix:kDefaultUserAgentPrefix
120 responseSizeLimit:kDefaultResponseSizeLimit
121 compressionAlgorithm:kDefaultCompressionAlgorithm
122 retryEnabled:kDefaultRetryEnabled
123 keepaliveInterval:kDefaultKeepaliveInterval
124 keepaliveTimeout:kDefaultKeepaliveTimeout
125 connectMinTimeout:kDefaultConnectMinTimeout
126 connectInitialBackoff:kDefaultConnectInitialBackoff
127 connectMaxBackoff:kDefaultConnectMaxBackoff
128 additionalChannelArgs:kDefaultAdditionalChannelArgs
129 PEMRootCertificates:kDefaultPEMRootCertificates
130 PEMPrivateKey:kDefaultPEMPrivateKey
131 PEMCertificateChain:kDefaultPEMCertificateChain
132 transportType:kDefaultTransportType
133 hostNameOverride:kDefaultHostNameOverride
134 logContext:kDefaultLogContext
135 channelPoolDomain:kDefaultChannelPoolDomain
136 channelID:kDefaultChannelID];
139 - (instancetype)initWithServerAuthority:(NSString *)serverAuthority
140 timeout:(NSTimeInterval)timeout
141 flowControlEnabled:(BOOL)flowControlEnabled
142 oauth2AccessToken:(NSString *)oauth2AccessToken
143 authTokenProvider:(id<GRPCAuthorizationProtocol>)authTokenProvider
144 initialMetadata:(NSDictionary *)initialMetadata
145 userAgentPrefix:(NSString *)userAgentPrefix
146 responseSizeLimit:(NSUInteger)responseSizeLimit
147 compressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm
148 retryEnabled:(BOOL)retryEnabled
149 keepaliveInterval:(NSTimeInterval)keepaliveInterval
150 keepaliveTimeout:(NSTimeInterval)keepaliveTimeout
151 connectMinTimeout:(NSTimeInterval)connectMinTimeout
152 connectInitialBackoff:(NSTimeInterval)connectInitialBackoff
153 connectMaxBackoff:(NSTimeInterval)connectMaxBackoff
154 additionalChannelArgs:(NSDictionary *)additionalChannelArgs
155 PEMRootCertificates:(NSString *)PEMRootCertificates
156 PEMPrivateKey:(NSString *)PEMPrivateKey
157 PEMCertificateChain:(NSString *)PEMCertificateChain
158 transportType:(GRPCTransportType)transportType
159 hostNameOverride:(NSString *)hostNameOverride
160 logContext:(id)logContext
161 channelPoolDomain:(NSString *)channelPoolDomain
162 channelID:(NSUInteger)channelID {
163 if ((self = [super init])) {
164 _serverAuthority = [serverAuthority copy];
165 _timeout = timeout < 0 ? 0 : timeout;
166 _flowControlEnabled = flowControlEnabled;
167 _oauth2AccessToken = [oauth2AccessToken copy];
168 _authTokenProvider = authTokenProvider;
170 initialMetadata == nil
172 : [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES];
173 _userAgentPrefix = [userAgentPrefix copy];
174 _responseSizeLimit = responseSizeLimit;
175 _compressionAlgorithm = compressionAlgorithm;
176 _retryEnabled = retryEnabled;
177 _keepaliveInterval = keepaliveInterval < 0 ? 0 : keepaliveInterval;
178 _keepaliveTimeout = keepaliveTimeout < 0 ? 0 : keepaliveTimeout;
179 _connectMinTimeout = connectMinTimeout < 0 ? 0 : connectMinTimeout;
180 _connectInitialBackoff = connectInitialBackoff < 0 ? 0 : connectInitialBackoff;
181 _connectMaxBackoff = connectMaxBackoff < 0 ? 0 : connectMaxBackoff;
182 _additionalChannelArgs =
183 additionalChannelArgs == nil
185 : [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES];
186 _PEMRootCertificates = [PEMRootCertificates copy];
187 _PEMPrivateKey = [PEMPrivateKey copy];
188 _PEMCertificateChain = [PEMCertificateChain copy];
189 _transportType = transportType;
190 _hostNameOverride = [hostNameOverride copy];
191 _logContext = logContext;
192 _channelPoolDomain = [channelPoolDomain copy];
193 _channelID = channelID;
198 - (nonnull id)copyWithZone:(NSZone *)zone {
199 GRPCCallOptions *newOptions =
200 [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority
202 flowControlEnabled:_flowControlEnabled
203 oauth2AccessToken:_oauth2AccessToken
204 authTokenProvider:_authTokenProvider
205 initialMetadata:_initialMetadata
206 userAgentPrefix:_userAgentPrefix
207 responseSizeLimit:_responseSizeLimit
208 compressionAlgorithm:_compressionAlgorithm
209 retryEnabled:_retryEnabled
210 keepaliveInterval:_keepaliveInterval
211 keepaliveTimeout:_keepaliveTimeout
212 connectMinTimeout:_connectMinTimeout
213 connectInitialBackoff:_connectInitialBackoff
214 connectMaxBackoff:_connectMaxBackoff
215 additionalChannelArgs:_additionalChannelArgs
216 PEMRootCertificates:_PEMRootCertificates
217 PEMPrivateKey:_PEMPrivateKey
218 PEMCertificateChain:_PEMCertificateChain
219 transportType:_transportType
220 hostNameOverride:_hostNameOverride
221 logContext:_logContext
222 channelPoolDomain:_channelPoolDomain
223 channelID:_channelID];
227 - (nonnull id)mutableCopyWithZone:(NSZone *)zone {
228 GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone]
229 initWithServerAuthority:[_serverAuthority copy]
231 flowControlEnabled:_flowControlEnabled
232 oauth2AccessToken:[_oauth2AccessToken copy]
233 authTokenProvider:_authTokenProvider
234 initialMetadata:[[NSDictionary alloc] initWithDictionary:_initialMetadata
236 userAgentPrefix:[_userAgentPrefix copy]
237 responseSizeLimit:_responseSizeLimit
238 compressionAlgorithm:_compressionAlgorithm
239 retryEnabled:_retryEnabled
240 keepaliveInterval:_keepaliveInterval
241 keepaliveTimeout:_keepaliveTimeout
242 connectMinTimeout:_connectMinTimeout
243 connectInitialBackoff:_connectInitialBackoff
244 connectMaxBackoff:_connectMaxBackoff
245 additionalChannelArgs:[[NSDictionary alloc] initWithDictionary:_additionalChannelArgs
247 PEMRootCertificates:[_PEMRootCertificates copy]
248 PEMPrivateKey:[_PEMPrivateKey copy]
249 PEMCertificateChain:[_PEMCertificateChain copy]
250 transportType:_transportType
251 hostNameOverride:[_hostNameOverride copy]
252 logContext:_logContext
253 channelPoolDomain:[_channelPoolDomain copy]
254 channelID:_channelID];
258 - (BOOL)hasChannelOptionsEqualTo:(GRPCCallOptions *)callOptions {
259 if (callOptions == nil) return NO;
260 if (!areObjectsEqual(callOptions.userAgentPrefix, _userAgentPrefix)) return NO;
261 if (!(callOptions.responseSizeLimit == _responseSizeLimit)) return NO;
262 if (!(callOptions.compressionAlgorithm == _compressionAlgorithm)) return NO;
263 if (!(callOptions.retryEnabled == _retryEnabled)) return NO;
264 if (!(callOptions.keepaliveInterval == _keepaliveInterval)) return NO;
265 if (!(callOptions.keepaliveTimeout == _keepaliveTimeout)) return NO;
266 if (!(callOptions.connectMinTimeout == _connectMinTimeout)) return NO;
267 if (!(callOptions.connectInitialBackoff == _connectInitialBackoff)) return NO;
268 if (!(callOptions.connectMaxBackoff == _connectMaxBackoff)) return NO;
269 if (!areObjectsEqual(callOptions.additionalChannelArgs, _additionalChannelArgs)) return NO;
270 if (!areObjectsEqual(callOptions.PEMRootCertificates, _PEMRootCertificates)) return NO;
271 if (!areObjectsEqual(callOptions.PEMPrivateKey, _PEMPrivateKey)) return NO;
272 if (!areObjectsEqual(callOptions.PEMCertificateChain, _PEMCertificateChain)) return NO;
273 if (!areObjectsEqual(callOptions.hostNameOverride, _hostNameOverride)) return NO;
274 if (!(callOptions.transportType == _transportType)) return NO;
275 if (!areObjectsEqual(callOptions.logContext, _logContext)) return NO;
276 if (!areObjectsEqual(callOptions.channelPoolDomain, _channelPoolDomain)) return NO;
277 if (!(callOptions.channelID == _channelID)) return NO;
282 - (NSUInteger)channelOptionsHash {
283 NSUInteger result = 0;
284 result ^= _userAgentPrefix.hash;
285 result ^= _responseSizeLimit;
286 result ^= _compressionAlgorithm;
287 result ^= _retryEnabled;
288 result ^= (unsigned int)(_keepaliveInterval * 1000);
289 result ^= (unsigned int)(_keepaliveTimeout * 1000);
290 result ^= (unsigned int)(_connectMinTimeout * 1000);
291 result ^= (unsigned int)(_connectInitialBackoff * 1000);
292 result ^= (unsigned int)(_connectMaxBackoff * 1000);
293 result ^= _additionalChannelArgs.hash;
294 result ^= _PEMRootCertificates.hash;
295 result ^= _PEMPrivateKey.hash;
296 result ^= _PEMCertificateChain.hash;
297 result ^= _hostNameOverride.hash;
298 result ^= _transportType;
299 result ^= _logContext.hash;
300 result ^= _channelPoolDomain.hash;
301 result ^= _channelID;
308 @implementation GRPCMutableCallOptions
310 @dynamic serverAuthority;
312 @dynamic flowControlEnabled;
313 @dynamic oauth2AccessToken;
314 @dynamic authTokenProvider;
315 @dynamic initialMetadata;
316 @dynamic userAgentPrefix;
317 @dynamic responseSizeLimit;
318 @dynamic compressionAlgorithm;
319 @dynamic retryEnabled;
320 @dynamic keepaliveInterval;
321 @dynamic keepaliveTimeout;
322 @dynamic connectMinTimeout;
323 @dynamic connectInitialBackoff;
324 @dynamic connectMaxBackoff;
325 @dynamic additionalChannelArgs;
326 @dynamic PEMRootCertificates;
327 @dynamic PEMPrivateKey;
328 @dynamic PEMCertificateChain;
329 @dynamic transportType;
330 @dynamic hostNameOverride;
332 @dynamic channelPoolDomain;
335 - (instancetype)init {
336 return [self initWithServerAuthority:kDefaultServerAuthority
337 timeout:kDefaultTimeout
338 flowControlEnabled:kDefaultFlowControlEnabled
339 oauth2AccessToken:kDefaultOauth2AccessToken
340 authTokenProvider:kDefaultAuthTokenProvider
341 initialMetadata:kDefaultInitialMetadata
342 userAgentPrefix:kDefaultUserAgentPrefix
343 responseSizeLimit:kDefaultResponseSizeLimit
344 compressionAlgorithm:kDefaultCompressionAlgorithm
345 retryEnabled:kDefaultRetryEnabled
346 keepaliveInterval:kDefaultKeepaliveInterval
347 keepaliveTimeout:kDefaultKeepaliveTimeout
348 connectMinTimeout:kDefaultConnectMinTimeout
349 connectInitialBackoff:kDefaultConnectInitialBackoff
350 connectMaxBackoff:kDefaultConnectMaxBackoff
351 additionalChannelArgs:kDefaultAdditionalChannelArgs
352 PEMRootCertificates:kDefaultPEMRootCertificates
353 PEMPrivateKey:kDefaultPEMPrivateKey
354 PEMCertificateChain:kDefaultPEMCertificateChain
355 transportType:kDefaultTransportType
356 hostNameOverride:kDefaultHostNameOverride
357 logContext:kDefaultLogContext
358 channelPoolDomain:kDefaultChannelPoolDomain
359 channelID:kDefaultChannelID];
362 - (nonnull id)copyWithZone:(NSZone *)zone {
363 GRPCCallOptions *newOptions =
364 [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority
366 flowControlEnabled:_flowControlEnabled
367 oauth2AccessToken:_oauth2AccessToken
368 authTokenProvider:_authTokenProvider
369 initialMetadata:_initialMetadata
370 userAgentPrefix:_userAgentPrefix
371 responseSizeLimit:_responseSizeLimit
372 compressionAlgorithm:_compressionAlgorithm
373 retryEnabled:_retryEnabled
374 keepaliveInterval:_keepaliveInterval
375 keepaliveTimeout:_keepaliveTimeout
376 connectMinTimeout:_connectMinTimeout
377 connectInitialBackoff:_connectInitialBackoff
378 connectMaxBackoff:_connectMaxBackoff
379 additionalChannelArgs:_additionalChannelArgs
380 PEMRootCertificates:_PEMRootCertificates
381 PEMPrivateKey:_PEMPrivateKey
382 PEMCertificateChain:_PEMCertificateChain
383 transportType:_transportType
384 hostNameOverride:_hostNameOverride
385 logContext:_logContext
386 channelPoolDomain:_channelPoolDomain
387 channelID:_channelID];
391 - (nonnull id)mutableCopyWithZone:(NSZone *)zone {
392 GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone]
393 initWithServerAuthority:_serverAuthority
395 flowControlEnabled:_flowControlEnabled
396 oauth2AccessToken:_oauth2AccessToken
397 authTokenProvider:_authTokenProvider
398 initialMetadata:_initialMetadata
399 userAgentPrefix:_userAgentPrefix
400 responseSizeLimit:_responseSizeLimit
401 compressionAlgorithm:_compressionAlgorithm
402 retryEnabled:_retryEnabled
403 keepaliveInterval:_keepaliveInterval
404 keepaliveTimeout:_keepaliveTimeout
405 connectMinTimeout:_connectMinTimeout
406 connectInitialBackoff:_connectInitialBackoff
407 connectMaxBackoff:_connectMaxBackoff
408 additionalChannelArgs:[_additionalChannelArgs copy]
409 PEMRootCertificates:_PEMRootCertificates
410 PEMPrivateKey:_PEMPrivateKey
411 PEMCertificateChain:_PEMCertificateChain
412 transportType:_transportType
413 hostNameOverride:_hostNameOverride
414 logContext:_logContext
415 channelPoolDomain:_channelPoolDomain
416 channelID:_channelID];
420 - (void)setServerAuthority:(NSString *)serverAuthority {
421 _serverAuthority = [serverAuthority copy];
424 - (void)setTimeout:(NSTimeInterval)timeout {
432 - (void)setFlowControlEnabled:(BOOL)flowControlEnabled {
433 _flowControlEnabled = flowControlEnabled;
436 - (void)setOauth2AccessToken:(NSString *)oauth2AccessToken {
437 _oauth2AccessToken = [oauth2AccessToken copy];
440 - (void)setAuthTokenProvider:(id<GRPCAuthorizationProtocol>)authTokenProvider {
441 _authTokenProvider = authTokenProvider;
444 - (void)setInitialMetadata:(NSDictionary *)initialMetadata {
445 _initialMetadata = [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES];
448 - (void)setUserAgentPrefix:(NSString *)userAgentPrefix {
449 _userAgentPrefix = [userAgentPrefix copy];
452 - (void)setResponseSizeLimit:(NSUInteger)responseSizeLimit {
453 _responseSizeLimit = responseSizeLimit;
456 - (void)setCompressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm {
457 _compressionAlgorithm = compressionAlgorithm;
460 - (void)setRetryEnabled:(BOOL)retryEnabled {
461 _retryEnabled = retryEnabled;
464 - (void)setKeepaliveInterval:(NSTimeInterval)keepaliveInterval {
465 if (keepaliveInterval < 0) {
466 _keepaliveInterval = 0;
468 _keepaliveInterval = keepaliveInterval;
472 - (void)setKeepaliveTimeout:(NSTimeInterval)keepaliveTimeout {
473 if (keepaliveTimeout < 0) {
474 _keepaliveTimeout = 0;
476 _keepaliveTimeout = keepaliveTimeout;
480 - (void)setConnectMinTimeout:(NSTimeInterval)connectMinTimeout {
481 if (connectMinTimeout < 0) {
482 _connectMinTimeout = 0;
484 _connectMinTimeout = connectMinTimeout;
488 - (void)setConnectInitialBackoff:(NSTimeInterval)connectInitialBackoff {
489 if (connectInitialBackoff < 0) {
490 _connectInitialBackoff = 0;
492 _connectInitialBackoff = connectInitialBackoff;
496 - (void)setConnectMaxBackoff:(NSTimeInterval)connectMaxBackoff {
497 if (connectMaxBackoff < 0) {
498 _connectMaxBackoff = 0;
500 _connectMaxBackoff = connectMaxBackoff;
504 - (void)setAdditionalChannelArgs:(NSDictionary *)additionalChannelArgs {
505 _additionalChannelArgs =
506 [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES];
509 - (void)setPEMRootCertificates:(NSString *)PEMRootCertificates {
510 _PEMRootCertificates = [PEMRootCertificates copy];
513 - (void)setPEMPrivateKey:(NSString *)PEMPrivateKey {
514 _PEMPrivateKey = [PEMPrivateKey copy];
517 - (void)setPEMCertificateChain:(NSString *)PEMCertificateChain {
518 _PEMCertificateChain = [PEMCertificateChain copy];
521 - (void)setTransportType:(GRPCTransportType)transportType {
522 _transportType = transportType;
525 - (void)setHostNameOverride:(NSString *)hostNameOverride {
526 _hostNameOverride = [hostNameOverride copy];
529 - (void)setLogContext:(id)logContext {
530 _logContext = logContext;
533 - (void)setChannelPoolDomain:(NSString *)channelPoolDomain {
534 _channelPoolDomain = [channelPoolDomain copy];
537 - (void)setChannelID:(NSUInteger)channelID {
538 _channelID = channelID;