From 8c5318a6d122e9b933abc43780c131838cebac80 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Wed, 5 Aug 2015 18:50:08 -0700 Subject: [PATCH] =?UTF-8?q?Return=20nil=20instead=20of=20assert=20when=20t?= =?UTF-8?q?he=20test=20certs=20can=E2=80=99t=20be=20read?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/objective-c/GRPCClient/GRPCCall.m | 3 ++ src/objective-c/GRPCClient/private/GRPCHost.m | 2 +- .../GRPCClient/private/GRPCSecureChannel.m | 38 +++++++++++++------ 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index b6d4d52c7e3..5f7d74bca81 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -103,6 +103,9 @@ NSString * const kGRPCStatusMetadataKey = @"io.grpc.StatusMetadataKey"; } if ((self = [super init])) { _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:host path:path]; + if (!_wrappedCall) { + return nil; + } // Serial queue to invoke the non-reentrant methods of the grpc_call object. _callQueue = dispatch_queue_create("org.grpc.call", NULL); diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 452283c76eb..781eab20c59 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -100,7 +100,7 @@ } - (grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue { - if (!queue || !path) { + if (!queue || !path || !self.channel) { return NULL; } return grpc_channel_create_call(self.channel.unmanagedChannel, diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannel.m b/src/objective-c/GRPCClient/private/GRPCSecureChannel.m index 310fdb67c2d..d3c4d41a139 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannel.m @@ -35,11 +35,18 @@ #include -static grpc_credentials *CertificatesAtPath(NSString *path) { - NSData *certsData = [NSData dataWithContentsOfFile:path]; - NSCAssert(certsData.length, @"No data read from %@", path); - NSString *certsString = [[NSString alloc] initWithData:certsData encoding:NSUTF8StringEncoding]; - return grpc_ssl_credentials_create(certsString.UTF8String, NULL); +// Returns NULL if the file at path couldn't be read. In that case, if errorPtr isn't NULL, +// *errorPtr will be an object describing what went wrong. +static grpc_credentials *CertificatesAtPath(NSString *path, NSError **errorPtr) { + NSString *certsContent = [NSString stringWithContentsOfFile:path + encoding:NSASCIIStringEncoding + error:errorPtr]; + if (!certsContent) { + // Passing NULL to grpc_ssl_credentials_create produces behavior we don't want, so return. + return NULL; + } + const char * asCString = [certsContent cStringUsingEncoding:NSASCIIStringEncoding]; + return grpc_ssl_credentials_create(asCString, NULL); } @implementation GRPCSecureChannel @@ -55,15 +62,24 @@ static grpc_credentials *CertificatesAtPath(NSString *path) { static grpc_credentials *kDefaultCertificates; static dispatch_once_t loading; dispatch_once(&loading, ^{ + NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem // Do not use NSBundle.mainBundle, as it's nil for tests of library projects. NSBundle *bundle = [NSBundle bundleForClass:self.class]; - NSString *certsPath = [bundle pathForResource:@"gRPCCertificates.bundle/roots" ofType:@"pem"]; - NSAssert(certsPath.length, - @"gRPCCertificates.bundle/roots.pem not found under %@. This file, with the root " - "certificates, is needed to establish TLS (HTTPS) connections.", bundle.bundlePath); - kDefaultCertificates = CertificatesAtPath(certsPath); + NSString *path = [bundle pathForResource:defaultPath ofType:@"pem"]; + NSError *error; + kDefaultCertificates = CertificatesAtPath(path, &error); + NSAssert(kDefaultCertificates, @"Could not read %@/%@.pem. This file, with the root " + "certificates, is needed to establish secure (TLS) connections. Because the file is " + "distributed with the gRPC library, this error is usually a sign that the library " + "wasn't configured correctly for your project. Error: %@", + bundle.bundlePath, defaultPath, error); }); - grpc_credentials *certificates = path ? CertificatesAtPath(path) : kDefaultCertificates; + + //TODO(jcanizales): Add NSError** parameter to the initializer. + grpc_credentials *certificates = path ? CertificatesAtPath(path, NULL) : kDefaultCertificates; + if (!certificates) { + return nil; + } // Ritual to pass the SSL host name override to the C library. grpc_channel_args channelArgs;