mirror of https://github.com/grpc/grpc.git
Merge pull request #2754 from jcanizales/support-test-certificates
Support test certificates and SSL name override in Obj-Cpull/2776/merge
commit
a3428f3b4f
14 changed files with 410 additions and 101 deletions
@ -0,0 +1,45 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, 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.h" |
||||
|
||||
@interface GRPCCall (Tests) |
||||
|
||||
// Establish all SSL connections to the provided host using the passed SSL target name and the root
|
||||
// certificates found in the file at |certsPath|.
|
||||
// Must be called before any gRPC call to that host is made.
|
||||
+ (void)useTestCertsPath:(NSString *)certsPath |
||||
testName:(NSString *)testName |
||||
forHost:(NSString *)host; |
||||
|
||||
@end |
@ -0,0 +1,47 @@ |
||||
/* |
||||
* |
||||
* Copyright 2015, 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+Tests.h" |
||||
|
||||
#import "private/GRPCHost.h" |
||||
|
||||
@implementation GRPCCall (Tests) |
||||
+ (void)useTestCertsPath:(NSString *)certsPath |
||||
testName:(NSString *)testName |
||||
forHost:(NSString *)host { |
||||
GRPCHost *hostConfig = [GRPCHost hostWithAddress:host]; |
||||
hostConfig.secure = YES; |
||||
hostConfig.pathToCertificates = certsPath; |
||||
hostConfig.hostNameOverride = testName; |
||||
} |
||||
@end |
@ -0,0 +1,58 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, 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 <Foundation/Foundation.h> |
||||
|
||||
@class GRPCCompletionQueue; |
||||
struct grpc_call; |
||||
|
||||
@interface GRPCHost : NSObject |
||||
|
||||
@property(nonatomic, readonly) NSString *address; |
||||
|
||||
// The following properties should only be modified for testing:
|
||||
|
||||
@property(nonatomic, getter=isSecure) BOOL secure; |
||||
|
||||
@property(nonatomic, copy) NSString *pathToCertificates; |
||||
@property(nonatomic, copy) NSString *hostNameOverride; |
||||
|
||||
// Host objects initialized with the same address are the same.
|
||||
+ (instancetype)hostWithAddress:(NSString *)address; |
||||
- (instancetype)initWithAddress:(NSString *)address NS_DESIGNATED_INITIALIZER; |
||||
|
||||
// Create a grpc_call object to the provided path on this host.
|
||||
- (struct grpc_call *)unmanagedCallWithPath:(NSString *)path |
||||
completionQueue:(GRPCCompletionQueue *)queue; |
||||
|
||||
@end |
@ -0,0 +1,134 @@ |
||||
/* |
||||
* |
||||
* Copyright 2015, 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 "GRPCHost.h" |
||||
|
||||
#include <grpc/grpc.h> |
||||
|
||||
#import "GRPCChannel.h" |
||||
#import "GRPCCompletionQueue.h" |
||||
#import "GRPCSecureChannel.h" |
||||
#import "GRPCUnsecuredChannel.h" |
||||
|
||||
@interface GRPCHost () |
||||
// TODO(mlumish): Investigate whether caching channels with strong links is a good idea. |
||||
@property(nonatomic, strong) GRPCChannel *channel; |
||||
@end |
||||
|
||||
@implementation GRPCHost |
||||
|
||||
+ (instancetype)hostWithAddress:(NSString *)address { |
||||
return [[self alloc] initWithAddress:address]; |
||||
} |
||||
|
||||
- (instancetype)init { |
||||
return [self initWithAddress:nil]; |
||||
} |
||||
|
||||
// Default initializer. |
||||
- (instancetype)initWithAddress:(NSString *)address { |
||||
|
||||
// Verify and normalize the address, and decide whether to use SSL. |
||||
if (![address rangeOfString:@"://"].length) { |
||||
// No scheme provided; assume https. |
||||
address = [@"https://" stringByAppendingString:address]; |
||||
} |
||||
NSURL *hostURL = [NSURL URLWithString:address]; |
||||
if (!hostURL) { |
||||
[NSException raise:NSInvalidArgumentException format:@"Invalid URL: %@", address]; |
||||
} |
||||
NSString *scheme = hostURL.scheme; |
||||
if (![scheme isEqualToString:@"https"] && ![scheme isEqualToString:@"http"]) { |
||||
[NSException raise:NSInvalidArgumentException format:@"URL scheme %@ isn't supported.", scheme]; |
||||
} |
||||
// If the user didn't specify a port (hostURL.port is nil), provide a default one. |
||||
NSNumber *port = hostURL.port ?: [scheme isEqualToString:@"https"] ? @443 : @80; |
||||
address = [@[hostURL.host, port] componentsJoinedByString:@":"]; |
||||
|
||||
// Look up the GRPCHost in the cache. |
||||
static NSMutableDictionary *hostCache; |
||||
static dispatch_once_t cacheInitialization; |
||||
dispatch_once(&cacheInitialization, ^{ |
||||
hostCache = [NSMutableDictionary dictionary]; |
||||
}); |
||||
@synchronized(hostCache) { |
||||
GRPCHost *cachedHost = hostCache[address]; |
||||
if (cachedHost) { |
||||
// We could verify here that the cached host uses the same protocol that we're expecting. But |
||||
// creating non-SSL channels by adding "http://" to the address is going away (to make the use |
||||
// of insecure channels less subtle), so it's not worth it now. |
||||
return cachedHost; |
||||
} |
||||
|
||||
if ((self = [super init])) { |
||||
_address = address; |
||||
_secure = [scheme isEqualToString:@"https"]; |
||||
hostCache[address] = self; |
||||
} |
||||
return self; |
||||
} |
||||
} |
||||
|
||||
- (grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue { |
||||
if (!queue || !path || !self.channel) { |
||||
return NULL; |
||||
} |
||||
return grpc_channel_create_call(self.channel.unmanagedChannel, |
||||
NULL, GRPC_PROPAGATE_DEFAULTS, |
||||
queue.unmanagedQueue, |
||||
path.UTF8String, |
||||
self.hostName.UTF8String, |
||||
gpr_inf_future(GPR_CLOCK_REALTIME)); |
||||
} |
||||
|
||||
- (GRPCChannel *)channel { |
||||
// Create it lazily, because we don't want to open a connection just because someone is |
||||
// configuring a host. |
||||
if (!_channel) { |
||||
if (_secure) { |
||||
_channel = [[GRPCSecureChannel alloc] initWithHost:_address |
||||
pathToCertificates:_pathToCertificates |
||||
hostNameOverride:_hostNameOverride]; |
||||
} else { |
||||
_channel = [[GRPCUnsecuredChannel alloc] initWithHost:_address]; |
||||
} |
||||
} |
||||
return _channel; |
||||
} |
||||
|
||||
- (NSString *)hostName { |
||||
// TODO(jcanizales): Default to nil instead of _address when Issue #2635 is clarified. |
||||
return _hostNameOverride ?: _address; |
||||
} |
||||
|
||||
@end |
Loading…
Reference in new issue