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 NSDictionary *const kDefaultInitialMetadata = nil;
26 static NSString *const kDefaultUserAgentPrefix = nil;
27 static const NSUInteger kDefaultResponseSizeLimit = 0;
28 static const GRPCCompressionAlgorithm kDefaultCompressionAlgorithm = GRPCCompressNone;
29 static const BOOL kDefaultRetryEnabled = YES;
30 static const NSTimeInterval kDefaultKeepaliveInterval = 0;
31 static const NSTimeInterval kDefaultKeepaliveTimeout = 0;
32 static const NSTimeInterval kDefaultConnectMinTimeout = 0;
33 static const NSTimeInterval kDefaultConnectInitialBackoff = 0;
34 static const NSTimeInterval kDefaultConnectMaxBackoff = 0;
35 static NSDictionary *const kDefaultAdditionalChannelArgs = nil;
36 static NSString *const kDefaultPEMRootCertificates = nil;
37 static NSString *const kDefaultPEMPrivateKey = nil;
38 static NSString *const kDefaultPEMCertificateChain = nil;
39 static NSString *const kDefaultOauth2AccessToken = nil;
40 static const id<GRPCAuthorizationProtocol> kDefaultAuthTokenProvider = nil;
41 static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeChttp2BoringSSL;
42 static NSString *const kDefaultHostNameOverride = nil;
43 static const id kDefaultLogContext = nil;
44 static NSString *const kDefaultChannelPoolDomain = nil;
45 static const NSUInteger kDefaultChannelID = 0;
47 // Check if two objects are equal. Returns YES if both are nil;
48 static BOOL areObjectsEqual(id obj1, id obj2) {
52 if (obj1 == nil || obj2 == nil) {
55 return [obj1 isEqual:obj2];
58 @implementation GRPCCallOptions {
60 NSString *_serverAuthority;
61 NSTimeInterval _timeout;
62 NSString *_oauth2AccessToken;
63 id<GRPCAuthorizationProtocol> _authTokenProvider;
64 NSDictionary *_initialMetadata;
65 NSString *_userAgentPrefix;
66 NSUInteger _responseSizeLimit;
67 GRPCCompressionAlgorithm _compressionAlgorithm;
69 NSTimeInterval _keepaliveInterval;
70 NSTimeInterval _keepaliveTimeout;
71 NSTimeInterval _connectMinTimeout;
72 NSTimeInterval _connectInitialBackoff;
73 NSTimeInterval _connectMaxBackoff;
74 NSDictionary *_additionalChannelArgs;
75 NSString *_PEMRootCertificates;
76 NSString *_PEMPrivateKey;
77 NSString *_PEMCertificateChain;
78 GRPCTransportType _transportType;
79 NSString *_hostNameOverride;
80 id<NSObject> _logContext;
81 NSString *_channelPoolDomain;
82 NSUInteger _channelID;
85 @synthesize serverAuthority = _serverAuthority;
86 @synthesize timeout = _timeout;
87 @synthesize oauth2AccessToken = _oauth2AccessToken;
88 @synthesize authTokenProvider = _authTokenProvider;
89 @synthesize initialMetadata = _initialMetadata;
90 @synthesize userAgentPrefix = _userAgentPrefix;
91 @synthesize responseSizeLimit = _responseSizeLimit;
92 @synthesize compressionAlgorithm = _compressionAlgorithm;
93 @synthesize retryEnabled = _retryEnabled;
94 @synthesize keepaliveInterval = _keepaliveInterval;
95 @synthesize keepaliveTimeout = _keepaliveTimeout;
96 @synthesize connectMinTimeout = _connectMinTimeout;
97 @synthesize connectInitialBackoff = _connectInitialBackoff;
98 @synthesize connectMaxBackoff = _connectMaxBackoff;
99 @synthesize additionalChannelArgs = _additionalChannelArgs;
100 @synthesize PEMRootCertificates = _PEMRootCertificates;
101 @synthesize PEMPrivateKey = _PEMPrivateKey;
102 @synthesize PEMCertificateChain = _PEMCertificateChain;
103 @synthesize transportType = _transportType;
104 @synthesize hostNameOverride = _hostNameOverride;
105 @synthesize logContext = _logContext;
106 @synthesize channelPoolDomain = _channelPoolDomain;
107 @synthesize channelID = _channelID;
109 - (instancetype)init {
110 return [self initWithServerAuthority:kDefaultServerAuthority
111 timeout:kDefaultTimeout
112 oauth2AccessToken:kDefaultOauth2AccessToken
113 authTokenProvider:kDefaultAuthTokenProvider
114 initialMetadata:kDefaultInitialMetadata
115 userAgentPrefix:kDefaultUserAgentPrefix
116 responseSizeLimit:kDefaultResponseSizeLimit
117 compressionAlgorithm:kDefaultCompressionAlgorithm
118 retryEnabled:kDefaultRetryEnabled
119 keepaliveInterval:kDefaultKeepaliveInterval
120 keepaliveTimeout:kDefaultKeepaliveTimeout
121 connectMinTimeout:kDefaultConnectMinTimeout
122 connectInitialBackoff:kDefaultConnectInitialBackoff
123 connectMaxBackoff:kDefaultConnectMaxBackoff
124 additionalChannelArgs:kDefaultAdditionalChannelArgs
125 PEMRootCertificates:kDefaultPEMRootCertificates
126 PEMPrivateKey:kDefaultPEMPrivateKey
127 PEMCertificateChain:kDefaultPEMCertificateChain
128 transportType:kDefaultTransportType
129 hostNameOverride:kDefaultHostNameOverride
130 logContext:kDefaultLogContext
131 channelPoolDomain:kDefaultChannelPoolDomain
132 channelID:kDefaultChannelID];
135 - (instancetype)initWithServerAuthority:(NSString *)serverAuthority
136 timeout:(NSTimeInterval)timeout
137 oauth2AccessToken:(NSString *)oauth2AccessToken
138 authTokenProvider:(id<GRPCAuthorizationProtocol>)authTokenProvider
139 initialMetadata:(NSDictionary *)initialMetadata
140 userAgentPrefix:(NSString *)userAgentPrefix
141 responseSizeLimit:(NSUInteger)responseSizeLimit
142 compressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm
143 retryEnabled:(BOOL)retryEnabled
144 keepaliveInterval:(NSTimeInterval)keepaliveInterval
145 keepaliveTimeout:(NSTimeInterval)keepaliveTimeout
146 connectMinTimeout:(NSTimeInterval)connectMinTimeout
147 connectInitialBackoff:(NSTimeInterval)connectInitialBackoff
148 connectMaxBackoff:(NSTimeInterval)connectMaxBackoff
149 additionalChannelArgs:(NSDictionary *)additionalChannelArgs
150 PEMRootCertificates:(NSString *)PEMRootCertificates
151 PEMPrivateKey:(NSString *)PEMPrivateKey
152 PEMCertificateChain:(NSString *)PEMCertificateChain
153 transportType:(GRPCTransportType)transportType
154 hostNameOverride:(NSString *)hostNameOverride
155 logContext:(id)logContext
156 channelPoolDomain:(NSString *)channelPoolDomain
157 channelID:(NSUInteger)channelID {
158 if ((self = [super init])) {
159 _serverAuthority = [serverAuthority copy];
160 _timeout = timeout < 0 ? 0 : timeout;
161 _oauth2AccessToken = [oauth2AccessToken copy];
162 _authTokenProvider = authTokenProvider;
164 initialMetadata == nil
166 : [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES];
167 _userAgentPrefix = [userAgentPrefix copy];
168 _responseSizeLimit = responseSizeLimit;
169 _compressionAlgorithm = compressionAlgorithm;
170 _retryEnabled = retryEnabled;
171 _keepaliveInterval = keepaliveInterval < 0 ? 0 : keepaliveInterval;
172 _keepaliveTimeout = keepaliveTimeout < 0 ? 0 : keepaliveTimeout;
173 _connectMinTimeout = connectMinTimeout < 0 ? 0 : connectMinTimeout;
174 _connectInitialBackoff = connectInitialBackoff < 0 ? 0 : connectInitialBackoff;
175 _connectMaxBackoff = connectMaxBackoff < 0 ? 0 : connectMaxBackoff;
176 _additionalChannelArgs =
177 additionalChannelArgs == nil
179 : [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES];
180 _PEMRootCertificates = [PEMRootCertificates copy];
181 _PEMPrivateKey = [PEMPrivateKey copy];
182 _PEMCertificateChain = [PEMCertificateChain copy];
183 _transportType = transportType;
184 _hostNameOverride = [hostNameOverride copy];
185 _logContext = logContext;
186 _channelPoolDomain = [channelPoolDomain copy];
187 _channelID = channelID;
192 - (nonnull id)copyWithZone:(NSZone *)zone {
193 GRPCCallOptions *newOptions =
194 [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority
196 oauth2AccessToken:_oauth2AccessToken
197 authTokenProvider:_authTokenProvider
198 initialMetadata:_initialMetadata
199 userAgentPrefix:_userAgentPrefix
200 responseSizeLimit:_responseSizeLimit
201 compressionAlgorithm:_compressionAlgorithm
202 retryEnabled:_retryEnabled
203 keepaliveInterval:_keepaliveInterval
204 keepaliveTimeout:_keepaliveTimeout
205 connectMinTimeout:_connectMinTimeout
206 connectInitialBackoff:_connectInitialBackoff
207 connectMaxBackoff:_connectMaxBackoff
208 additionalChannelArgs:_additionalChannelArgs
209 PEMRootCertificates:_PEMRootCertificates
210 PEMPrivateKey:_PEMPrivateKey
211 PEMCertificateChain:_PEMCertificateChain
212 transportType:_transportType
213 hostNameOverride:_hostNameOverride
214 logContext:_logContext
215 channelPoolDomain:_channelPoolDomain
216 channelID:_channelID];
220 - (nonnull id)mutableCopyWithZone:(NSZone *)zone {
221 GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone]
222 initWithServerAuthority:[_serverAuthority copy]
224 oauth2AccessToken:[_oauth2AccessToken copy]
225 authTokenProvider:_authTokenProvider
226 initialMetadata:[[NSDictionary alloc] initWithDictionary:_initialMetadata
228 userAgentPrefix:[_userAgentPrefix copy]
229 responseSizeLimit:_responseSizeLimit
230 compressionAlgorithm:_compressionAlgorithm
231 retryEnabled:_retryEnabled
232 keepaliveInterval:_keepaliveInterval
233 keepaliveTimeout:_keepaliveTimeout
234 connectMinTimeout:_connectMinTimeout
235 connectInitialBackoff:_connectInitialBackoff
236 connectMaxBackoff:_connectMaxBackoff
237 additionalChannelArgs:[[NSDictionary alloc] initWithDictionary:_additionalChannelArgs
239 PEMRootCertificates:[_PEMRootCertificates copy]
240 PEMPrivateKey:[_PEMPrivateKey copy]
241 PEMCertificateChain:[_PEMCertificateChain copy]
242 transportType:_transportType
243 hostNameOverride:[_hostNameOverride copy]
244 logContext:_logContext
245 channelPoolDomain:[_channelPoolDomain copy]
246 channelID:_channelID];
250 - (BOOL)hasChannelOptionsEqualTo:(GRPCCallOptions *)callOptions {
251 if (callOptions == nil) return NO;
252 if (!areObjectsEqual(callOptions.userAgentPrefix, _userAgentPrefix)) return NO;
253 if (!(callOptions.responseSizeLimit == _responseSizeLimit)) return NO;
254 if (!(callOptions.compressionAlgorithm == _compressionAlgorithm)) return NO;
255 if (!(callOptions.retryEnabled == _retryEnabled)) return NO;
256 if (!(callOptions.keepaliveInterval == _keepaliveInterval)) return NO;
257 if (!(callOptions.keepaliveTimeout == _keepaliveTimeout)) return NO;
258 if (!(callOptions.connectMinTimeout == _connectMinTimeout)) return NO;
259 if (!(callOptions.connectInitialBackoff == _connectInitialBackoff)) return NO;
260 if (!(callOptions.connectMaxBackoff == _connectMaxBackoff)) return NO;
261 if (!areObjectsEqual(callOptions.additionalChannelArgs, _additionalChannelArgs)) return NO;
262 if (!areObjectsEqual(callOptions.PEMRootCertificates, _PEMRootCertificates)) return NO;
263 if (!areObjectsEqual(callOptions.PEMPrivateKey, _PEMPrivateKey)) return NO;
264 if (!areObjectsEqual(callOptions.PEMCertificateChain, _PEMCertificateChain)) return NO;
265 if (!areObjectsEqual(callOptions.hostNameOverride, _hostNameOverride)) return NO;
266 if (!(callOptions.transportType == _transportType)) return NO;
267 if (!areObjectsEqual(callOptions.logContext, _logContext)) return NO;
268 if (!areObjectsEqual(callOptions.channelPoolDomain, _channelPoolDomain)) return NO;
269 if (!(callOptions.channelID == _channelID)) return NO;
274 - (NSUInteger)channelOptionsHash {
275 NSUInteger result = 0;
276 result ^= _userAgentPrefix.hash;
277 result ^= _responseSizeLimit;
278 result ^= _compressionAlgorithm;
279 result ^= _retryEnabled;
280 result ^= (unsigned int)(_keepaliveInterval * 1000);
281 result ^= (unsigned int)(_keepaliveTimeout * 1000);
282 result ^= (unsigned int)(_connectMinTimeout * 1000);
283 result ^= (unsigned int)(_connectInitialBackoff * 1000);
284 result ^= (unsigned int)(_connectMaxBackoff * 1000);
285 result ^= _additionalChannelArgs.hash;
286 result ^= _PEMRootCertificates.hash;
287 result ^= _PEMPrivateKey.hash;
288 result ^= _PEMCertificateChain.hash;
289 result ^= _hostNameOverride.hash;
290 result ^= _transportType;
291 result ^= _logContext.hash;
292 result ^= _channelPoolDomain.hash;
293 result ^= _channelID;
300 @implementation GRPCMutableCallOptions
302 @dynamic serverAuthority;
304 @dynamic oauth2AccessToken;
305 @dynamic authTokenProvider;
306 @dynamic initialMetadata;
307 @dynamic userAgentPrefix;
308 @dynamic responseSizeLimit;
309 @dynamic compressionAlgorithm;
310 @dynamic retryEnabled;
311 @dynamic keepaliveInterval;
312 @dynamic keepaliveTimeout;
313 @dynamic connectMinTimeout;
314 @dynamic connectInitialBackoff;
315 @dynamic connectMaxBackoff;
316 @dynamic additionalChannelArgs;
317 @dynamic PEMRootCertificates;
318 @dynamic PEMPrivateKey;
319 @dynamic PEMCertificateChain;
320 @dynamic transportType;
321 @dynamic hostNameOverride;
323 @dynamic channelPoolDomain;
326 - (instancetype)init {
327 return [self initWithServerAuthority:kDefaultServerAuthority
328 timeout:kDefaultTimeout
329 oauth2AccessToken:kDefaultOauth2AccessToken
330 authTokenProvider:kDefaultAuthTokenProvider
331 initialMetadata:kDefaultInitialMetadata
332 userAgentPrefix:kDefaultUserAgentPrefix
333 responseSizeLimit:kDefaultResponseSizeLimit
334 compressionAlgorithm:kDefaultCompressionAlgorithm
335 retryEnabled:kDefaultRetryEnabled
336 keepaliveInterval:kDefaultKeepaliveInterval
337 keepaliveTimeout:kDefaultKeepaliveTimeout
338 connectMinTimeout:kDefaultConnectMinTimeout
339 connectInitialBackoff:kDefaultConnectInitialBackoff
340 connectMaxBackoff:kDefaultConnectMaxBackoff
341 additionalChannelArgs:kDefaultAdditionalChannelArgs
342 PEMRootCertificates:kDefaultPEMRootCertificates
343 PEMPrivateKey:kDefaultPEMPrivateKey
344 PEMCertificateChain:kDefaultPEMCertificateChain
345 transportType:kDefaultTransportType
346 hostNameOverride:kDefaultHostNameOverride
347 logContext:kDefaultLogContext
348 channelPoolDomain:kDefaultChannelPoolDomain
349 channelID:kDefaultChannelID];
352 - (nonnull id)copyWithZone:(NSZone *)zone {
353 GRPCCallOptions *newOptions =
354 [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority
356 oauth2AccessToken:_oauth2AccessToken
357 authTokenProvider:_authTokenProvider
358 initialMetadata:_initialMetadata
359 userAgentPrefix:_userAgentPrefix
360 responseSizeLimit:_responseSizeLimit
361 compressionAlgorithm:_compressionAlgorithm
362 retryEnabled:_retryEnabled
363 keepaliveInterval:_keepaliveInterval
364 keepaliveTimeout:_keepaliveTimeout
365 connectMinTimeout:_connectMinTimeout
366 connectInitialBackoff:_connectInitialBackoff
367 connectMaxBackoff:_connectMaxBackoff
368 additionalChannelArgs:_additionalChannelArgs
369 PEMRootCertificates:_PEMRootCertificates
370 PEMPrivateKey:_PEMPrivateKey
371 PEMCertificateChain:_PEMCertificateChain
372 transportType:_transportType
373 hostNameOverride:_hostNameOverride
374 logContext:_logContext
375 channelPoolDomain:_channelPoolDomain
376 channelID:_channelID];
380 - (nonnull id)mutableCopyWithZone:(NSZone *)zone {
381 GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone]
382 initWithServerAuthority:_serverAuthority
384 oauth2AccessToken:_oauth2AccessToken
385 authTokenProvider:_authTokenProvider
386 initialMetadata:_initialMetadata
387 userAgentPrefix:_userAgentPrefix
388 responseSizeLimit:_responseSizeLimit
389 compressionAlgorithm:_compressionAlgorithm
390 retryEnabled:_retryEnabled
391 keepaliveInterval:_keepaliveInterval
392 keepaliveTimeout:_keepaliveTimeout
393 connectMinTimeout:_connectMinTimeout
394 connectInitialBackoff:_connectInitialBackoff
395 connectMaxBackoff:_connectMaxBackoff
396 additionalChannelArgs:[_additionalChannelArgs copy]
397 PEMRootCertificates:_PEMRootCertificates
398 PEMPrivateKey:_PEMPrivateKey
399 PEMCertificateChain:_PEMCertificateChain
400 transportType:_transportType
401 hostNameOverride:_hostNameOverride
402 logContext:_logContext
403 channelPoolDomain:_channelPoolDomain
404 channelID:_channelID];
408 - (void)setServerAuthority:(NSString *)serverAuthority {
409 _serverAuthority = [serverAuthority copy];
412 - (void)setTimeout:(NSTimeInterval)timeout {
420 - (void)setOauth2AccessToken:(NSString *)oauth2AccessToken {
421 _oauth2AccessToken = [oauth2AccessToken copy];
424 - (void)setAuthTokenProvider:(id<GRPCAuthorizationProtocol>)authTokenProvider {
425 _authTokenProvider = authTokenProvider;
428 - (void)setInitialMetadata:(NSDictionary *)initialMetadata {
429 _initialMetadata = [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES];
432 - (void)setUserAgentPrefix:(NSString *)userAgentPrefix {
433 _userAgentPrefix = [userAgentPrefix copy];
436 - (void)setResponseSizeLimit:(NSUInteger)responseSizeLimit {
437 _responseSizeLimit = responseSizeLimit;
440 - (void)setCompressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm {
441 _compressionAlgorithm = compressionAlgorithm;
444 - (void)setRetryEnabled:(BOOL)retryEnabled {
445 _retryEnabled = retryEnabled;
448 - (void)setKeepaliveInterval:(NSTimeInterval)keepaliveInterval {
449 if (keepaliveInterval < 0) {
450 _keepaliveInterval = 0;
452 _keepaliveInterval = keepaliveInterval;
456 - (void)setKeepaliveTimeout:(NSTimeInterval)keepaliveTimeout {
457 if (keepaliveTimeout < 0) {
458 _keepaliveTimeout = 0;
460 _keepaliveTimeout = keepaliveTimeout;
464 - (void)setConnectMinTimeout:(NSTimeInterval)connectMinTimeout {
465 if (connectMinTimeout < 0) {
466 _connectMinTimeout = 0;
468 _connectMinTimeout = connectMinTimeout;
472 - (void)setConnectInitialBackoff:(NSTimeInterval)connectInitialBackoff {
473 if (connectInitialBackoff < 0) {
474 _connectInitialBackoff = 0;
476 _connectInitialBackoff = connectInitialBackoff;
480 - (void)setConnectMaxBackoff:(NSTimeInterval)connectMaxBackoff {
481 if (connectMaxBackoff < 0) {
482 _connectMaxBackoff = 0;
484 _connectMaxBackoff = connectMaxBackoff;
488 - (void)setAdditionalChannelArgs:(NSDictionary *)additionalChannelArgs {
489 _additionalChannelArgs =
490 [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES];
493 - (void)setPEMRootCertificates:(NSString *)PEMRootCertificates {
494 _PEMRootCertificates = [PEMRootCertificates copy];
497 - (void)setPEMPrivateKey:(NSString *)PEMPrivateKey {
498 _PEMPrivateKey = [PEMPrivateKey copy];
501 - (void)setPEMCertificateChain:(NSString *)PEMCertificateChain {
502 _PEMCertificateChain = [PEMCertificateChain copy];
505 - (void)setTransportType:(GRPCTransportType)transportType {
506 _transportType = transportType;
509 - (void)setHostNameOverride:(NSString *)hostNameOverride {
510 _hostNameOverride = [hostNameOverride copy];
513 - (void)setLogContext:(id)logContext {
514 _logContext = logContext;
517 - (void)setChannelPoolDomain:(NSString *)channelPoolDomain {
518 _channelPoolDomain = [channelPoolDomain copy];
521 - (void)setChannelID:(NSUInteger)channelID {
522 _channelID = channelID;