diff options
author | Jorge Canizales <jcanizales@google.com> | 2016-06-24 12:48:43 -0700 |
---|---|---|
committer | Jorge Canizales <jcanizales@google.com> | 2016-06-24 12:48:43 -0700 |
commit | 8a556b7fe34355faf6573d8958cdb0730dd41956 (patch) | |
tree | 06ca945c0cb9d31c640b13eda3fcb1de4b084aff /src/objective-c/GRPCClient | |
parent | fa70dacf95b93486b7dfe0c21ada90d75a5d5bcd (diff) | |
parent | 0140f7c9e6c20fe78035d9635a3f5725d51ad35a (diff) |
Merge master into let-invalidate-channels
Had to manually resolve import conflicts in InteropTests.m
To be fair, the merge algorithm should have been able to do it.
Diffstat (limited to 'src/objective-c/GRPCClient')
-rw-r--r-- | src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h | 4 | ||||
-rw-r--r-- | src/objective-c/GRPCClient/GRPCCall+Cronet.h | 57 | ||||
-rw-r--r-- | src/objective-c/GRPCClient/GRPCCall+Cronet.m | 56 | ||||
-rw-r--r-- | src/objective-c/GRPCClient/GRPCCall.h | 2 | ||||
-rw-r--r-- | src/objective-c/GRPCClient/GRPCCall.m | 55 | ||||
-rw-r--r-- | src/objective-c/GRPCClient/private/GRPCChannel.h | 7 | ||||
-rw-r--r-- | src/objective-c/GRPCClient/private/GRPCChannel.m | 38 | ||||
-rw-r--r-- | src/objective-c/GRPCClient/private/GRPCHost.m | 20 | ||||
-rw-r--r-- | src/objective-c/GRPCClient/private/GRPCWrappedCall.m | 2 |
9 files changed, 213 insertions, 28 deletions
diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h b/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h index 343dd48a14..ac2a37d75f 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h @@ -41,7 +41,7 @@ */ + (BOOL)setTLSPEMRootCerts:(nullable NSString *)pemRootCert forHost:(nonnull NSString *)host - error:(NSError **)errorPtr; + error:(NSError * _Nullable * _Nullable)errorPtr; /** * Configures @c host with TLS/SSL Client Credentials and optionally trusted root Certificate * Authorities. If @c pemRootCerts is nil, the default CA Certificates bundled with gRPC will be @@ -51,6 +51,6 @@ withPrivateKey:(nullable NSString *)pemPrivateKey withCertChain:(nullable NSString *)pemCertChain forHost:(nonnull NSString *)host - error:(NSError **)errorPtr; + error:(NSError * _Nullable * _Nullable)errorPtr; @end diff --git a/src/objective-c/GRPCClient/GRPCCall+Cronet.h b/src/objective-c/GRPCClient/GRPCCall+Cronet.h new file mode 100644 index 0000000000..2d8f7ac8fb --- /dev/null +++ b/src/objective-c/GRPCClient/GRPCCall+Cronet.h @@ -0,0 +1,57 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifdef GRPC_COMPILE_WITH_CRONET +#import <Cronet/Cronet.h> + +#import "GRPCCall.h" + +/** + * Methods for using cronet transport. + */ +@interface GRPCCall (Cronet) + +/** + * This method should be called before issuing the first RPC. It should be + * called only once. Create an instance of Cronet engine in your app elsewhere + * and pass the instance pointer in the cronet_engine parameter. Once set, + * all subsequent RPCs will use Cronet transport. The method is not thread + * safe. + */ ++(void)useCronetWithEngine:(cronet_engine *)engine; + ++(cronet_engine *)cronetEngine; + ++(BOOL)isUsingCronet; + +@end +#endif diff --git a/src/objective-c/GRPCClient/GRPCCall+Cronet.m b/src/objective-c/GRPCClient/GRPCCall+Cronet.m new file mode 100644 index 0000000000..76ca1a2537 --- /dev/null +++ b/src/objective-c/GRPCClient/GRPCCall+Cronet.m @@ -0,0 +1,56 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import "GRPCCall+Cronet.h" + +#ifdef GRPC_COMPILE_WITH_CRONET +static BOOL useCronet = NO; +static cronet_engine *globalCronetEngine; + +@implementation GRPCCall (Cronet) + ++ (void)useCronetWithEngine:(cronet_engine *)engine { + useCronet = YES; + globalCronetEngine = engine; +} + ++ (cronet_engine *)cronetEngine { + return globalCronetEngine; +} + ++ (BOOL)isUsingCronet { + return useCronet; +} + +@end +#endif diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 7a77ae60b6..b9e741dfa8 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -220,6 +220,8 @@ extern id const kGRPCTrailersKey; * messages to the response side of the call indefinitely (depending on the semantics of the * specific remote method called). * To finish a call right away, invoke cancel. + * host parameter should not contain the scheme (http:// or https://), only the name or IP addr + * and the port number, for example @"localhost:5050". */ - (instancetype)initWithHost:(NSString *)host path:(NSString *)path diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 1847d6016f..e9678f38a9 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -76,7 +76,6 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey"; NSString *_host; NSString *_path; GRPCWrappedCall *_wrappedCall; - dispatch_once_t _callAlreadyInvoked; GRPCConnectivityMonitor *_connectivityMonitor; // The C gRPC library has less guarantees on the ordering of events than we @@ -136,6 +135,10 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey"; #pragma mark Finish - (void)finishWithError:(NSError *)errorOrNil { + @synchronized(self) { + _state = GRXWriterStateFinished; + } + // If the call isn't retained anywhere else, it can be deallocated now. _retainSelf = nil; @@ -342,6 +345,10 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey"; #pragma mark GRXWriter implementation - (void)startWithWriteable:(id<GRXWriteable>)writeable { + @synchronized(self) { + _state = GRXWriterStateStarted; + } + // Create a retain cycle so that this instance lives until the RPC finishes (or is cancelled). // This makes RPCs in which the call isn't externally retained possible (as long as it is started // before being autoreleased). @@ -375,30 +382,32 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey"; } - (void)setState:(GRXWriterState)newState { - // Manual transitions are only allowed from the started or paused states. - if (_state == GRXWriterStateNotStarted || _state == GRXWriterStateFinished) { - return; - } - - switch (newState) { - case GRXWriterStateFinished: - _state = newState; - // Per GRXWriter's contract, setting the state to Finished manually - // means one doesn't wish the writeable to be messaged anymore. - [_responseWriteable cancelSilently]; - _responseWriteable = nil; - return; - case GRXWriterStatePaused: - _state = newState; + @synchronized(self) { + // Manual transitions are only allowed from the started or paused states. + if (_state == GRXWriterStateNotStarted || _state == GRXWriterStateFinished) { return; - case GRXWriterStateStarted: - if (_state == GRXWriterStatePaused) { + } + + switch (newState) { + case GRXWriterStateFinished: _state = newState; - [self startNextRead]; - } - return; - case GRXWriterStateNotStarted: - return; + // Per GRXWriter's contract, setting the state to Finished manually + // means one doesn't wish the writeable to be messaged anymore. + [_responseWriteable cancelSilently]; + _responseWriteable = nil; + return; + case GRXWriterStatePaused: + _state = newState; + return; + case GRXWriterStateStarted: + if (_state == GRXWriterStatePaused) { + _state = newState; + [self startNextRead]; + } + return; + case GRXWriterStateNotStarted: + return; + } } } diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 70d1a9bd2f..40e78a92d6 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -56,6 +56,13 @@ struct grpc_channel_credentials; + (nullable GRPCChannel *)secureChannelWithHost:(nonnull NSString *)host; /** + * Creates a secure channel to the specified @c host using Cronet as a transport mechanism. + */ +#ifdef GRPC_COMPILE_WITH_CRONET ++ (nullable GRPCChannel *)secureCronetChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *)channelArgs; +#endif +/** * Creates a secure channel to the specified @c host using the specified @c credentials and * @c channelArgs. Only in tests should @c GRPC_SSL_TARGET_NAME_OVERRIDE_ARG channel arg be set. */ diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 203ef58c0d..d3192c983d 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -34,10 +34,17 @@ #import "GRPCChannel.h" #include <grpc/grpc_security.h> +#ifdef GRPC_COMPILE_WITH_CRONET +#include <grpc/grpc_cronet.h> +#endif #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> +#ifdef GRPC_COMPILE_WITH_CRONET +#import <Cronet/Cronet.h> +#import <GRPCClient/GRPCCall+Cronet.h> +#endif #import "GRPCCompletionQueue.h" void freeChannelArgs(grpc_channel_args *channel_args) { @@ -99,6 +106,24 @@ grpc_channel_args * buildChannelArgs(NSDictionary *dictionary) { grpc_channel_args *_channelArgs; } +#ifdef GRPC_COMPILE_WITH_CRONET +- (instancetype)initWithHost:(NSString *)host + cronetEngine:(cronet_engine *)cronetEngine + channelArgs:(NSDictionary *)channelArgs { + if (!host) { + [NSException raise:NSInvalidArgumentException format:@"host argument missing"]; + } + + if (self = [super init]) { + _channelArgs = buildChannelArgs(channelArgs); + _host = [host copy]; + _unmanagedChannel = grpc_cronet_secure_channel_create(cronetEngine, _host.UTF8String, _channelArgs, + NULL); + } + + return self; +} +#endif - (instancetype)initWithHost:(NSString *)host secure:(BOOL)secure @@ -133,6 +158,19 @@ grpc_channel_args * buildChannelArgs(NSDictionary *dictionary) { freeChannelArgs(_channelArgs); } +#ifdef GRPC_COMPILE_WITH_CRONET ++ (GRPCChannel *)secureCronetChannelWithHost:(NSString *)host + channelArgs:(NSDictionary *)channelArgs { + cronet_engine *engine = [GRPCCall cronetEngine]; + if (!engine) { + [NSException raise:NSInvalidArgumentException + format:@"cronet_engine is NULL. Set it first."]; + return nil; + } + return [[GRPCChannel alloc] initWithHost:host cronetEngine:engine channelArgs:channelArgs]; +} +#endif + + (GRPCChannel *)secureChannelWithHost:(NSString *)host { return [[GRPCChannel alloc] initWithHost:host secure:YES credentials:NULL channelArgs:NULL]; } diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 0358cc6236..08c699f99e 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -36,7 +36,10 @@ #include <grpc/grpc.h> #include <grpc/grpc_security.h> #import <GRPCClient/GRPCCall.h> +#ifdef GRPC_COMPILE_WITH_CRONET #import <GRPCClient/GRPCCall+ChannelArg.h> +#import <GRPCClient/GRPCCall+Cronet.h> +#endif #import "GRPCChannel.h" #import "GRPCCompletionQueue.h" @@ -211,15 +214,26 @@ static NSMutableDictionary *kHostCache; - (GRPCChannel *)newChannel { NSDictionary *args = [self channelArgs]; +#ifdef GRPC_COMPILE_WITH_CRONET + BOOL useCronet = [GRPCCall isUsingCronet]; +#endif if (_secure) { GRPCChannel *channel; @synchronized(self) { if (_channelCreds == nil) { [self setTLSPEMRootCerts:nil withPrivateKey:nil withCertChain:nil error:nil]; } - channel = [GRPCChannel secureChannelWithHost:_address - credentials:_channelCreds - channelArgs:args]; +#ifdef GRPC_COMPILE_WITH_CRONET + if (useCronet) { + channel = [GRPCChannel secureCronetChannelWithHost:_address + channelArgs:args]; + } else +#endif + { + channel = [GRPCChannel secureChannelWithHost:_address + credentials:_channelCreds + channelArgs:args]; + } } return channel; } else { diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 16e5bff7ff..a3fa5938cd 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -72,6 +72,8 @@ _op.op = GRPC_OP_SEND_INITIAL_METADATA; _op.data.send_initial_metadata.count = metadata.count; _op.data.send_initial_metadata.metadata = metadata.grpc_metadataArray; + _op.data.send_initial_metadata.maybe_compression_level.is_set = false; + _op.data.send_initial_metadata.maybe_compression_level.level = 0; _handler = handler; } return self; |