Require very explicit registration of non-SSL hosts.

pull/2758/head
Jorge Canizales 9 years ago
parent 82b68d8a97
commit b2bd06775e
  1. 4
      src/objective-c/GRPCClient/GRPCCall+Tests.h
  2. 8
      src/objective-c/GRPCClient/GRPCCall+Tests.m
  3. 37
      src/objective-c/GRPCClient/private/GRPCHost.m
  4. 7
      src/objective-c/tests/GRPCClientTests.m
  5. 2
      src/objective-c/tests/InteropTests.h
  6. 10
      src/objective-c/tests/InteropTests.m

@ -33,6 +33,8 @@
#import "GRPCCall.h"
// Methods to let tune down the security of gRPC connections for specific hosts. These shouldn't be
// used in releases, but are sometimes needed for testing.
@interface GRPCCall (Tests)
// Establish all SSL connections to the provided host using the passed SSL target name and the root
@ -42,4 +44,6 @@
testName:(NSString *)testName
forHost:(NSString *)host;
// Establish all connections to the provided host using cleartext instead of SSL.
+ (void)useInsecureConnectionsForHost:(NSString *)host;
@end

@ -36,12 +36,18 @@
#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;
}
+ (void)useInsecureConnectionsForHost:(NSString *)host {
GRPCHost *hostConfig = [GRPCHost hostWithAddress:host];
hostConfig.secure = NO;
}
@end

@ -58,22 +58,12 @@
// 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];
// To provide a default port, we try to interpret the address.
// TODO(jcanizales): Add unit tests for the types of addresses we want to let pass through.
NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:address]];
if (hostURL && !hostURL.port) {
address = [hostURL.host stringByAppendingString:@":443"];
}
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;
@ -84,19 +74,15 @@
@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;
if ((self = [super init])) {
_address = address;
_secure = YES;
hostCache[address] = self;
}
return self;
}
- (grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue {
@ -131,4 +117,7 @@
return _hostNameOverride ?: _address;
}
// TODO(jcanizales): Don't let set |secure| to |NO| if |pathToCertificates| or |hostNameOverride|
// have been set. Don't let set either of the latter if |secure| has been set to |NO|.
@end

@ -35,6 +35,7 @@
#import <XCTest/XCTest.h>
#import <GRPCClient/GRPCCall.h>
#import <GRPCClient/GRPCCall+Tests.h>
#import <ProtoRPC/ProtoMethod.h>
#import <RemoteTest/Messages.pbobjc.h>
#import <RxLibrary/GRXWriteable.h>
@ -43,8 +44,7 @@
// These are a few tests similar to InteropTests, but which use the generic gRPC client (GRPCCall)
// rather than a generated proto library on top of it.
// grpc-test.sandbox.google.com
static NSString * const kHostAddress = @"http://localhost:5050";
static NSString * const kHostAddress = @"localhost:5050";
static NSString * const kPackage = @"grpc.testing";
static NSString * const kService = @"TestService";
@ -58,6 +58,9 @@ static ProtoMethod *kUnaryCallMethod;
@implementation GRPCClientTests
- (void)setUp {
// Register test server as non-SSL.
[GRPCCall useInsecureConnectionsForHost:kHostAddress];
// This method isn't implemented by the remote server.
kInexistentMethod = [[ProtoMethod alloc] initWithPackage:kPackage
service:kService

@ -37,7 +37,7 @@
// https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md
@interface InteropTests : XCTestCase
// Returns @"http://localhost:5050".
// Returns @"localhost:5050".
// Override in a subclass to perform the same tests against a different address.
// For interop tests, use @"grpc-test.sandbox.google.com".
+ (NSString *)host;

@ -35,6 +35,7 @@
#include <grpc/status.h>
#import <GRPCClient/GRPCCall+Tests.h>
#import <ProtoRPC/ProtoRPC.h>
#import <RemoteTest/Empty.pbobjc.h>
#import <RemoteTest/Messages.pbobjc.h>
@ -75,15 +76,22 @@
}
@end
#pragma mark Tests
static NSString * const kLocalCleartextHost = @"localhost:5050";
@implementation InteropTests {
RMTTestService *_service;
}
+ (NSString *)host {
return @"http://localhost:5050";
return kLocalCleartextHost;
}
- (void)setUp {
// Register test server as non-SSL.
[GRPCCall useInsecureConnectionsForHost:kLocalCleartextHost];
_service = [[RMTTestService alloc] initWithHost:self.class.host];
}

Loading…
Cancel
Save