commit
6b9477e8dc
118 changed files with 10318 additions and 2855 deletions
@ -0,0 +1,43 @@ |
||||
/*
|
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPCXX_STUB_OPTIONS_H |
||||
#define GRPCXX_STUB_OPTIONS_H |
||||
|
||||
namespace grpc { |
||||
|
||||
class StubOptions {}; |
||||
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPCXX_STUB_OPTIONS_H
|
@ -0,0 +1,89 @@ |
||||
#region Copyright notice and license |
||||
|
||||
// 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. |
||||
|
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Threading; |
||||
|
||||
using Grpc.Core.Internal; |
||||
using Grpc.Core.Utils; |
||||
|
||||
namespace Grpc.Core |
||||
{ |
||||
/// <summary> |
||||
/// Options for calls made by client. |
||||
/// </summary> |
||||
public class CallOptions |
||||
{ |
||||
readonly Metadata headers; |
||||
readonly DateTime deadline; |
||||
readonly CancellationToken cancellationToken; |
||||
|
||||
/// <summary> |
||||
/// Creates a new instance of <c>CallOptions</c>. |
||||
/// </summary> |
||||
/// <param name="headers">Headers to be sent with the call.</param> |
||||
/// <param name="deadline">Deadline for the call to finish. null means no deadline.</param> |
||||
/// <param name="cancellationToken">Can be used to request cancellation of the call.</param> |
||||
public CallOptions(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) |
||||
{ |
||||
// TODO(jtattermusch): consider only creating metadata object once it's really needed. |
||||
this.headers = headers != null ? headers : new Metadata(); |
||||
this.deadline = deadline.HasValue ? deadline.Value : DateTime.MaxValue; |
||||
this.cancellationToken = cancellationToken; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Headers to send at the beginning of the call. |
||||
/// </summary> |
||||
public Metadata Headers |
||||
{ |
||||
get { return headers; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Call deadline. |
||||
/// </summary> |
||||
public DateTime Deadline |
||||
{ |
||||
get { return deadline; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Token that can be used for cancelling the call. |
||||
/// </summary> |
||||
public CancellationToken CancellationToken |
||||
{ |
||||
get { return cancellationToken; } |
||||
} |
||||
} |
||||
} |
@ -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 |
@ -0,0 +1,44 @@ |
||||
/*
|
||||
* |
||||
* 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 <XCTest/XCTest.h> |
||||
|
||||
// Implements tests as described here:
|
||||
// https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md
|
||||
|
||||
@interface InteropTests : XCTestCase |
||||
// Returns @"http://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; |
||||
@end |
@ -0,0 +1,62 @@ |
||||
/* |
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
// Repeat of the tests in InteropTests.m, but using SSL to communicate with the local server instead |
||||
// of cleartext. |
||||
|
||||
#import <GRPCClient/GRPCCall+Tests.h> |
||||
|
||||
#import "InteropTests.h" |
||||
|
||||
static NSString * const kLocalSSLHost = @"localhost:5051"; |
||||
|
||||
@interface InteropTestsLocalSSL : InteropTests |
||||
@end |
||||
|
||||
@implementation InteropTestsLocalSSL |
||||
|
||||
+ (NSString *)host { |
||||
return kLocalSSLHost; |
||||
} |
||||
|
||||
- (void)setUp { |
||||
// Register test server certificates and name. |
||||
NSBundle *bundle = [NSBundle bundleForClass:self.class]; |
||||
NSString *certsPath = [bundle pathForResource:@"TestCertificates.bundle/test-certificates" |
||||
ofType:@"pem"]; |
||||
[GRPCCall useTestCertsPath:certsPath testName:@"foo.test.google.fr" forHost:kLocalSSLHost]; |
||||
|
||||
[super setUp]; |
||||
} |
||||
|
||||
@end |
@ -0,0 +1,15 @@ |
||||
-----BEGIN CERTIFICATE----- |
||||
MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV |
||||
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX |
||||
aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla |
||||
Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 |
||||
YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT |
||||
BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 |
||||
+L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu |
||||
g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd |
||||
Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV |
||||
HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau |
||||
sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m |
||||
oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG |
||||
Dfcog5wrJytaQ6UA0wE= |
||||
-----END CERTIFICATE----- |
@ -0,0 +1,132 @@ |
||||
/*
|
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
#include "test/core/end2end/end2end_tests.h" |
||||
|
||||
#include <string.h> |
||||
|
||||
#include "src/core/channel/client_channel.h" |
||||
#include "src/core/channel/connected_channel.h" |
||||
#include "src/core/channel/http_server_filter.h" |
||||
#include "src/core/surface/channel.h" |
||||
#include "src/core/surface/server.h" |
||||
#include "src/core/transport/chttp2_transport.h" |
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/host_port.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/sync.h> |
||||
#include <grpc/support/thd.h> |
||||
#include <grpc/support/useful.h> |
||||
#include "test/core/end2end/fixtures/proxy.h" |
||||
#include "test/core/util/port.h" |
||||
#include "test/core/util/test_config.h" |
||||
|
||||
typedef struct fullstack_fixture_data { |
||||
grpc_end2end_proxy *proxy; |
||||
} fullstack_fixture_data; |
||||
|
||||
static grpc_server *create_proxy_server(const char *port) { |
||||
grpc_server *s = grpc_server_create(NULL); |
||||
GPR_ASSERT(grpc_server_add_insecure_http2_port(s, port)); |
||||
return s; |
||||
} |
||||
|
||||
static grpc_channel *create_proxy_client(const char *target) { |
||||
return grpc_insecure_channel_create(target, NULL); |
||||
} |
||||
|
||||
static const grpc_end2end_proxy_def proxy_def = {create_proxy_server, |
||||
create_proxy_client}; |
||||
|
||||
static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( |
||||
grpc_channel_args *client_args, grpc_channel_args *server_args) { |
||||
grpc_end2end_test_fixture f; |
||||
fullstack_fixture_data *ffd = gpr_malloc(sizeof(fullstack_fixture_data)); |
||||
memset(&f, 0, sizeof(f)); |
||||
|
||||
ffd->proxy = grpc_end2end_proxy_create(&proxy_def); |
||||
|
||||
f.fixture_data = ffd; |
||||
f.cq = grpc_completion_queue_create(); |
||||
|
||||
return f; |
||||
} |
||||
|
||||
void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f, |
||||
grpc_channel_args *client_args) { |
||||
fullstack_fixture_data *ffd = f->fixture_data; |
||||
f->client = grpc_insecure_channel_create( |
||||
grpc_end2end_proxy_get_client_target(ffd->proxy), client_args); |
||||
GPR_ASSERT(f->client); |
||||
} |
||||
|
||||
void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f, |
||||
grpc_channel_args *server_args) { |
||||
fullstack_fixture_data *ffd = f->fixture_data; |
||||
if (f->server) { |
||||
grpc_server_destroy(f->server); |
||||
} |
||||
f->server = grpc_server_create(server_args); |
||||
grpc_server_register_completion_queue(f->server, f->cq); |
||||
GPR_ASSERT(grpc_server_add_insecure_http2_port( |
||||
f->server, grpc_end2end_proxy_get_server_port(ffd->proxy))); |
||||
grpc_server_start(f->server); |
||||
} |
||||
|
||||
void chttp2_tear_down_fullstack(grpc_end2end_test_fixture *f) { |
||||
fullstack_fixture_data *ffd = f->fixture_data; |
||||
grpc_end2end_proxy_destroy(ffd->proxy); |
||||
gpr_free(ffd); |
||||
} |
||||
|
||||
/* All test configurations */ |
||||
static grpc_end2end_test_config configs[] = { |
||||
{"chttp2/fullstack+proxy", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION, |
||||
chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, |
||||
chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, |
||||
}; |
||||
|
||||
int main(int argc, char **argv) { |
||||
size_t i; |
||||
|
||||
grpc_test_init(argc, argv); |
||||
grpc_init(); |
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { |
||||
grpc_end2end_tests(configs[i]); |
||||
} |
||||
|
||||
grpc_shutdown(); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,193 @@ |
||||
/*
|
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
#include "test/core/end2end/end2end_tests.h" |
||||
|
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
|
||||
#include "src/core/channel/channel_args.h" |
||||
#include "src/core/security/credentials.h" |
||||
#include "src/core/support/env.h" |
||||
#include "src/core/support/file.h" |
||||
#include "src/core/support/string.h" |
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/host_port.h> |
||||
#include <grpc/support/log.h> |
||||
#include "test/core/end2end/data/ssl_test_data.h" |
||||
#include "test/core/end2end/fixtures/proxy.h" |
||||
#include "test/core/util/test_config.h" |
||||
#include "test/core/util/port.h" |
||||
|
||||
typedef struct fullstack_secure_fixture_data { |
||||
grpc_end2end_proxy *proxy; |
||||
} fullstack_secure_fixture_data; |
||||
|
||||
static grpc_server *create_proxy_server(const char *port) { |
||||
grpc_server *s = grpc_server_create(NULL); |
||||
grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, |
||||
test_server1_cert}; |
||||
grpc_server_credentials *ssl_creds = |
||||
grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0); |
||||
GPR_ASSERT(grpc_server_add_secure_http2_port(s, port, ssl_creds)); |
||||
grpc_server_credentials_release(ssl_creds); |
||||
return s; |
||||
} |
||||
|
||||
static grpc_channel *create_proxy_client(const char *target) { |
||||
grpc_channel *channel; |
||||
grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL); |
||||
grpc_arg ssl_name_override = {GRPC_ARG_STRING, |
||||
GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, |
||||
{"foo.test.google.fr"}}; |
||||
grpc_channel_args client_args; |
||||
client_args.num_args = 1; |
||||
client_args.args = &ssl_name_override; |
||||
channel = grpc_secure_channel_create(ssl_creds, target, &client_args); |
||||
grpc_credentials_release(ssl_creds); |
||||
return channel; |
||||
} |
||||
|
||||
static const grpc_end2end_proxy_def proxy_def = {create_proxy_server, |
||||
create_proxy_client}; |
||||
|
||||
static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( |
||||
grpc_channel_args *client_args, grpc_channel_args *server_args) { |
||||
grpc_end2end_test_fixture f; |
||||
fullstack_secure_fixture_data *ffd = |
||||
gpr_malloc(sizeof(fullstack_secure_fixture_data)); |
||||
memset(&f, 0, sizeof(f)); |
||||
|
||||
ffd->proxy = grpc_end2end_proxy_create(&proxy_def); |
||||
|
||||
f.fixture_data = ffd; |
||||
f.cq = grpc_completion_queue_create(); |
||||
|
||||
return f; |
||||
} |
||||
|
||||
static void chttp2_init_client_secure_fullstack(grpc_end2end_test_fixture *f, |
||||
grpc_channel_args *client_args, |
||||
grpc_credentials *creds) { |
||||
fullstack_secure_fixture_data *ffd = f->fixture_data; |
||||
f->client = grpc_secure_channel_create( |
||||
creds, grpc_end2end_proxy_get_client_target(ffd->proxy), client_args); |
||||
GPR_ASSERT(f->client != NULL); |
||||
grpc_credentials_release(creds); |
||||
} |
||||
|
||||
static void chttp2_init_server_secure_fullstack( |
||||
grpc_end2end_test_fixture *f, grpc_channel_args *server_args, |
||||
grpc_server_credentials *server_creds) { |
||||
fullstack_secure_fixture_data *ffd = f->fixture_data; |
||||
if (f->server) { |
||||
grpc_server_destroy(f->server); |
||||
} |
||||
f->server = grpc_server_create(server_args); |
||||
grpc_server_register_completion_queue(f->server, f->cq); |
||||
GPR_ASSERT(grpc_server_add_secure_http2_port( |
||||
f->server, grpc_end2end_proxy_get_server_port(ffd->proxy), server_creds)); |
||||
grpc_server_credentials_release(server_creds); |
||||
grpc_server_start(f->server); |
||||
} |
||||
|
||||
void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { |
||||
fullstack_secure_fixture_data *ffd = f->fixture_data; |
||||
grpc_end2end_proxy_destroy(ffd->proxy); |
||||
gpr_free(ffd); |
||||
} |
||||
|
||||
static void chttp2_init_client_simple_ssl_secure_fullstack( |
||||
grpc_end2end_test_fixture *f, grpc_channel_args *client_args) { |
||||
grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL); |
||||
grpc_arg ssl_name_override = {GRPC_ARG_STRING, |
||||
GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, |
||||
{"foo.test.google.fr"}}; |
||||
grpc_channel_args *new_client_args = |
||||
grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1); |
||||
chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds); |
||||
grpc_channel_args_destroy(new_client_args); |
||||
} |
||||
|
||||
static void chttp2_init_server_simple_ssl_secure_fullstack( |
||||
grpc_end2end_test_fixture *f, grpc_channel_args *server_args) { |
||||
grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, |
||||
test_server1_cert}; |
||||
grpc_server_credentials *ssl_creds = |
||||
grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0); |
||||
chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); |
||||
} |
||||
|
||||
/* All test configurations */ |
||||
|
||||
static grpc_end2end_test_config configs[] = { |
||||
{"chttp2/simple_ssl_fullstack", |
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | |
||||
FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION | |
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, |
||||
chttp2_create_fixture_secure_fullstack, |
||||
chttp2_init_client_simple_ssl_secure_fullstack, |
||||
chttp2_init_server_simple_ssl_secure_fullstack, |
||||
chttp2_tear_down_secure_fullstack}, |
||||
}; |
||||
|
||||
int main(int argc, char **argv) { |
||||
size_t i; |
||||
FILE *roots_file; |
||||
size_t roots_size = strlen(test_root_cert); |
||||
char *roots_filename; |
||||
|
||||
grpc_test_init(argc, argv); |
||||
|
||||
/* Set the SSL roots env var. */ |
||||
roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename); |
||||
GPR_ASSERT(roots_filename != NULL); |
||||
GPR_ASSERT(roots_file != NULL); |
||||
GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); |
||||
fclose(roots_file); |
||||
gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); |
||||
|
||||
grpc_init(); |
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { |
||||
grpc_end2end_tests(configs[i]); |
||||
} |
||||
|
||||
grpc_shutdown(); |
||||
|
||||
/* Cleanup. */ |
||||
remove(roots_filename); |
||||
gpr_free(roots_filename); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,430 @@ |
||||
/*
|
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
#include "test/core/end2end/fixtures/proxy.h" |
||||
|
||||
#include <string.h> |
||||
|
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/host_port.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/sync.h> |
||||
#include <grpc/support/thd.h> |
||||
#include <grpc/support/useful.h> |
||||
|
||||
#include "test/core/util/port.h" |
||||
|
||||
struct grpc_end2end_proxy { |
||||
gpr_thd_id thd; |
||||
char *proxy_port; |
||||
char *server_port; |
||||
grpc_completion_queue *cq; |
||||
grpc_server *server; |
||||
grpc_channel *client; |
||||
|
||||
int shutdown; |
||||
|
||||
/* requested call */ |
||||
grpc_call *new_call; |
||||
grpc_call_details new_call_details; |
||||
grpc_metadata_array new_call_metadata; |
||||
}; |
||||
|
||||
typedef struct { |
||||
void (*func)(void *arg, int success); |
||||
void *arg; |
||||
} closure; |
||||
|
||||
typedef struct { |
||||
gpr_refcount refs; |
||||
grpc_end2end_proxy *proxy; |
||||
|
||||
grpc_call *c2p; |
||||
grpc_call *p2s; |
||||
|
||||
grpc_metadata_array c2p_initial_metadata; |
||||
grpc_metadata_array p2s_initial_metadata; |
||||
|
||||
grpc_byte_buffer *c2p_msg; |
||||
grpc_byte_buffer *p2s_msg; |
||||
|
||||
grpc_metadata_array p2s_trailing_metadata; |
||||
grpc_status_code p2s_status; |
||||
char *p2s_status_details; |
||||
size_t p2s_status_details_capacity; |
||||
|
||||
int c2p_server_cancelled; |
||||
} proxy_call; |
||||
|
||||
static void thread_main(void *arg); |
||||
static void request_call(grpc_end2end_proxy *proxy); |
||||
|
||||
grpc_end2end_proxy *grpc_end2end_proxy_create( |
||||
const grpc_end2end_proxy_def *def) { |
||||
gpr_thd_options opt = gpr_thd_options_default(); |
||||
int proxy_port = grpc_pick_unused_port_or_die(); |
||||
int server_port = grpc_pick_unused_port_or_die(); |
||||
|
||||
grpc_end2end_proxy *proxy = gpr_malloc(sizeof(*proxy)); |
||||
memset(proxy, 0, sizeof(*proxy)); |
||||
|
||||
gpr_join_host_port(&proxy->proxy_port, "localhost", proxy_port); |
||||
gpr_join_host_port(&proxy->server_port, "localhost", server_port); |
||||
proxy->cq = grpc_completion_queue_create(); |
||||
proxy->server = def->create_server(proxy->proxy_port); |
||||
proxy->client = def->create_client(proxy->server_port); |
||||
|
||||
grpc_server_register_completion_queue(proxy->server, proxy->cq); |
||||
grpc_server_start(proxy->server); |
||||
|
||||
gpr_thd_options_set_joinable(&opt); |
||||
GPR_ASSERT(gpr_thd_new(&proxy->thd, thread_main, proxy, &opt)); |
||||
|
||||
request_call(proxy); |
||||
|
||||
return proxy; |
||||
} |
||||
|
||||
static closure *new_closure(void (*func)(void *arg, int success), void *arg) { |
||||
closure *cl = gpr_malloc(sizeof(*cl)); |
||||
cl->func = func; |
||||
cl->arg = arg; |
||||
return cl; |
||||
} |
||||
|
||||
static void shutdown_complete(void *arg, int success) { |
||||
grpc_end2end_proxy *proxy = arg; |
||||
proxy->shutdown = 1; |
||||
grpc_completion_queue_shutdown(proxy->cq); |
||||
} |
||||
|
||||
void grpc_end2end_proxy_destroy(grpc_end2end_proxy *proxy) { |
||||
grpc_server_shutdown_and_notify(proxy->server, proxy->cq, |
||||
new_closure(shutdown_complete, proxy)); |
||||
gpr_thd_join(proxy->thd); |
||||
gpr_free(proxy->proxy_port); |
||||
gpr_free(proxy->server_port); |
||||
grpc_server_destroy(proxy->server); |
||||
grpc_channel_destroy(proxy->client); |
||||
grpc_completion_queue_destroy(proxy->cq); |
||||
grpc_call_details_destroy(&proxy->new_call_details); |
||||
gpr_free(proxy); |
||||
} |
||||
|
||||
static void unrefpc(proxy_call *pc, const char *reason) { |
||||
gpr_log(GPR_DEBUG, "unref %p: %s %d -> %d", pc, reason, pc->refs.count, |
||||
pc->refs.count - 1); |
||||
if (gpr_unref(&pc->refs)) { |
||||
grpc_call_destroy(pc->c2p); |
||||
grpc_call_destroy(pc->p2s); |
||||
grpc_metadata_array_destroy(&pc->c2p_initial_metadata); |
||||
grpc_metadata_array_destroy(&pc->p2s_initial_metadata); |
||||
grpc_metadata_array_destroy(&pc->p2s_trailing_metadata); |
||||
gpr_free(pc->p2s_status_details); |
||||
gpr_free(pc); |
||||
} |
||||
} |
||||
|
||||
static void refpc(proxy_call *pc, const char *reason) { |
||||
gpr_log(GPR_DEBUG, "ref %p: %s %d -> %d", pc, reason, pc->refs.count, |
||||
pc->refs.count + 1); |
||||
gpr_ref(&pc->refs); |
||||
} |
||||
|
||||
static void on_c2p_sent_initial_metadata(void *arg, int success) { |
||||
proxy_call *pc = arg; |
||||
unrefpc(pc, "on_c2p_sent_initial_metadata"); |
||||
} |
||||
|
||||
static void on_p2s_recv_initial_metadata(void *arg, int success) { |
||||
proxy_call *pc = arg; |
||||
grpc_op op; |
||||
grpc_call_error err; |
||||
|
||||
if (!pc->proxy->shutdown) { |
||||
op.op = GRPC_OP_SEND_INITIAL_METADATA; |
||||
op.flags = 0; |
||||
op.data.send_initial_metadata.count = pc->p2s_initial_metadata.count; |
||||
op.data.send_initial_metadata.metadata = pc->p2s_initial_metadata.metadata; |
||||
refpc(pc, "on_c2p_sent_initial_metadata"); |
||||
err = grpc_call_start_batch(pc->c2p, &op, 1, |
||||
new_closure(on_c2p_sent_initial_metadata, pc)); |
||||
GPR_ASSERT(err == GRPC_CALL_OK); |
||||
} |
||||
|
||||
unrefpc(pc, "on_p2s_recv_initial_metadata"); |
||||
} |
||||
|
||||
static void on_p2s_sent_initial_metadata(void *arg, int success) { |
||||
proxy_call *pc = arg; |
||||
unrefpc(pc, "on_p2s_sent_initial_metadata"); |
||||
} |
||||
|
||||
static void on_c2p_recv_msg(void *arg, int success); |
||||
|
||||
static void on_p2s_sent_message(void *arg, int success) { |
||||
proxy_call *pc = arg; |
||||
grpc_op op; |
||||
grpc_call_error err; |
||||
|
||||
grpc_byte_buffer_destroy(pc->c2p_msg); |
||||
if (!pc->proxy->shutdown && success) { |
||||
op.op = GRPC_OP_RECV_MESSAGE; |
||||
op.flags = 0; |
||||
op.data.recv_message = &pc->c2p_msg; |
||||
refpc(pc, "on_c2p_recv_msg"); |
||||
err = grpc_call_start_batch(pc->c2p, &op, 1, |
||||
new_closure(on_c2p_recv_msg, pc)); |
||||
GPR_ASSERT(err == GRPC_CALL_OK); |
||||
} |
||||
|
||||
unrefpc(pc, "on_p2s_sent_message"); |
||||
} |
||||
|
||||
static void on_p2s_sent_close(void *arg, int success) { |
||||
proxy_call *pc = arg; |
||||
unrefpc(pc, "on_p2s_sent_close"); |
||||
} |
||||
|
||||
static void on_c2p_recv_msg(void *arg, int success) { |
||||
proxy_call *pc = arg; |
||||
grpc_op op; |
||||
grpc_call_error err; |
||||
|
||||
if (!pc->proxy->shutdown && success) { |
||||
if (pc->c2p_msg != NULL) { |
||||
op.op = GRPC_OP_SEND_MESSAGE; |
||||
op.flags = 0; |
||||
op.data.send_message = pc->c2p_msg; |
||||
refpc(pc, "on_p2s_sent_message"); |
||||
err = grpc_call_start_batch(pc->p2s, &op, 1, |
||||
new_closure(on_p2s_sent_message, pc)); |
||||
GPR_ASSERT(err == GRPC_CALL_OK); |
||||
} else { |
||||
op.op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; |
||||
op.flags = 0; |
||||
refpc(pc, "on_p2s_sent_close"); |
||||
err = grpc_call_start_batch(pc->p2s, &op, 1, |
||||
new_closure(on_p2s_sent_close, pc)); |
||||
GPR_ASSERT(err == GRPC_CALL_OK); |
||||
} |
||||
} |
||||
|
||||
unrefpc(pc, "on_c2p_recv_msg"); |
||||
} |
||||
|
||||
static void on_p2s_recv_msg(void *arg, int success); |
||||
|
||||
static void on_c2p_sent_message(void *arg, int success) { |
||||
proxy_call *pc = arg; |
||||
grpc_op op; |
||||
grpc_call_error err; |
||||
|
||||
grpc_byte_buffer_destroy(pc->p2s_msg); |
||||
if (!pc->proxy->shutdown && success) { |
||||
op.op = GRPC_OP_RECV_MESSAGE; |
||||
op.flags = 0; |
||||
op.data.recv_message = &pc->p2s_msg; |
||||
refpc(pc, "on_p2s_recv_msg"); |
||||
err = grpc_call_start_batch(pc->p2s, &op, 1, |
||||
new_closure(on_p2s_recv_msg, pc)); |
||||
GPR_ASSERT(err == GRPC_CALL_OK); |
||||
} |
||||
|
||||
unrefpc(pc, "on_c2p_sent_message"); |
||||
} |
||||
|
||||
static void on_p2s_recv_msg(void *arg, int success) { |
||||
proxy_call *pc = arg; |
||||
grpc_op op; |
||||
grpc_call_error err; |
||||
|
||||
if (!pc->proxy->shutdown && success && pc->p2s_msg) { |
||||
op.op = GRPC_OP_SEND_MESSAGE; |
||||
op.flags = 0; |
||||
op.data.send_message = pc->p2s_msg; |
||||
refpc(pc, "on_c2p_sent_message"); |
||||
err = grpc_call_start_batch(pc->c2p, &op, 1, |
||||
new_closure(on_c2p_sent_message, pc)); |
||||
GPR_ASSERT(err == GRPC_CALL_OK); |
||||
} |
||||
unrefpc(pc, "on_p2s_recv_msg"); |
||||
} |
||||
|
||||
static void on_c2p_sent_status(void *arg, int success) { |
||||
proxy_call *pc = arg; |
||||
unrefpc(pc, "on_c2p_sent_status"); |
||||
} |
||||
|
||||
static void on_p2s_status(void *arg, int success) { |
||||
proxy_call *pc = arg; |
||||
grpc_op op; |
||||
grpc_call_error err; |
||||
|
||||
if (!pc->proxy->shutdown) { |
||||
GPR_ASSERT(success); |
||||
op.op = GRPC_OP_SEND_STATUS_FROM_SERVER; |
||||
op.flags = 0; |
||||
op.data.send_status_from_server.trailing_metadata_count = |
||||
pc->p2s_trailing_metadata.count; |
||||
op.data.send_status_from_server.trailing_metadata = |
||||
pc->p2s_trailing_metadata.metadata; |
||||
op.data.send_status_from_server.status = pc->p2s_status; |
||||
op.data.send_status_from_server.status_details = pc->p2s_status_details; |
||||
refpc(pc, "on_c2p_sent_status"); |
||||
err = grpc_call_start_batch(pc->c2p, &op, 1, |
||||
new_closure(on_c2p_sent_status, pc)); |
||||
GPR_ASSERT(err == GRPC_CALL_OK); |
||||
} |
||||
|
||||
unrefpc(pc, "on_p2s_status"); |
||||
} |
||||
|
||||
static void on_c2p_closed(void *arg, int success) { |
||||
proxy_call *pc = arg; |
||||
unrefpc(pc, "on_c2p_closed"); |
||||
} |
||||
|
||||
static void on_new_call(void *arg, int success) { |
||||
grpc_end2end_proxy *proxy = arg; |
||||
grpc_call_error err; |
||||
|
||||
if (success) { |
||||
grpc_op op; |
||||
proxy_call *pc = gpr_malloc(sizeof(*pc)); |
||||
memset(pc, 0, sizeof(*pc)); |
||||
pc->proxy = proxy; |
||||
GPR_SWAP(grpc_metadata_array, pc->c2p_initial_metadata, |
||||
proxy->new_call_metadata); |
||||
pc->c2p = proxy->new_call; |
||||
pc->p2s = grpc_channel_create_call( |
||||
proxy->client, pc->c2p, GRPC_PROPAGATE_DEFAULTS, proxy->cq, |
||||
proxy->new_call_details.method, proxy->new_call_details.host, |
||||
proxy->new_call_details.deadline); |
||||
gpr_ref_init(&pc->refs, 1); |
||||
|
||||
op.flags = 0; |
||||
|
||||
op.op = GRPC_OP_RECV_INITIAL_METADATA; |
||||
op.data.recv_initial_metadata = &pc->p2s_initial_metadata; |
||||
refpc(pc, "on_p2s_recv_initial_metadata"); |
||||
err = grpc_call_start_batch(pc->p2s, &op, 1, |
||||
new_closure(on_p2s_recv_initial_metadata, pc)); |
||||
GPR_ASSERT(err == GRPC_CALL_OK); |
||||
|
||||
op.op = GRPC_OP_SEND_INITIAL_METADATA; |
||||
op.data.send_initial_metadata.count = pc->c2p_initial_metadata.count; |
||||
op.data.send_initial_metadata.metadata = pc->c2p_initial_metadata.metadata; |
||||
refpc(pc, "on_p2s_sent_initial_metadata"); |
||||
err = grpc_call_start_batch(pc->p2s, &op, 1, |
||||
new_closure(on_p2s_sent_initial_metadata, pc)); |
||||
GPR_ASSERT(err == GRPC_CALL_OK); |
||||
|
||||
op.op = GRPC_OP_RECV_MESSAGE; |
||||
op.data.recv_message = &pc->c2p_msg; |
||||
refpc(pc, "on_c2p_recv_msg"); |
||||
err = grpc_call_start_batch(pc->c2p, &op, 1, |
||||
new_closure(on_c2p_recv_msg, pc)); |
||||
GPR_ASSERT(err == GRPC_CALL_OK); |
||||
|
||||
op.op = GRPC_OP_RECV_MESSAGE; |
||||
op.data.recv_message = &pc->p2s_msg; |
||||
refpc(pc, "on_p2s_recv_msg"); |
||||
err = grpc_call_start_batch(pc->p2s, &op, 1, |
||||
new_closure(on_p2s_recv_msg, pc)); |
||||
GPR_ASSERT(err == GRPC_CALL_OK); |
||||
|
||||
op.op = GRPC_OP_RECV_STATUS_ON_CLIENT; |
||||
op.data.recv_status_on_client.trailing_metadata = |
||||
&pc->p2s_trailing_metadata; |
||||
op.data.recv_status_on_client.status = &pc->p2s_status; |
||||
op.data.recv_status_on_client.status_details = &pc->p2s_status_details; |
||||
op.data.recv_status_on_client.status_details_capacity = |
||||
&pc->p2s_status_details_capacity; |
||||
refpc(pc, "on_p2s_status"); |
||||
err = |
||||
grpc_call_start_batch(pc->p2s, &op, 1, new_closure(on_p2s_status, pc)); |
||||
GPR_ASSERT(err == GRPC_CALL_OK); |
||||
|
||||
op.op = GRPC_OP_RECV_CLOSE_ON_SERVER; |
||||
op.data.recv_close_on_server.cancelled = &pc->c2p_server_cancelled; |
||||
refpc(pc, "on_c2p_closed"); |
||||
err = |
||||
grpc_call_start_batch(pc->c2p, &op, 1, new_closure(on_c2p_closed, pc)); |
||||
GPR_ASSERT(err == GRPC_CALL_OK); |
||||
|
||||
request_call(proxy); |
||||
|
||||
unrefpc(pc, "init"); |
||||
} else { |
||||
GPR_ASSERT(proxy->new_call == NULL); |
||||
} |
||||
} |
||||
|
||||
static void request_call(grpc_end2end_proxy *proxy) { |
||||
proxy->new_call = NULL; |
||||
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( |
||||
proxy->server, &proxy->new_call, |
||||
&proxy->new_call_details, |
||||
&proxy->new_call_metadata, proxy->cq, |
||||
proxy->cq, new_closure(on_new_call, proxy))); |
||||
} |
||||
|
||||
static void thread_main(void *arg) { |
||||
grpc_end2end_proxy *proxy = arg; |
||||
closure *cl; |
||||
for (;;) { |
||||
grpc_event ev = grpc_completion_queue_next( |
||||
proxy->cq, gpr_inf_future(GPR_CLOCK_MONOTONIC)); |
||||
switch (ev.type) { |
||||
case GRPC_QUEUE_TIMEOUT: |
||||
gpr_log(GPR_ERROR, "Should never reach here"); |
||||
abort(); |
||||
case GRPC_QUEUE_SHUTDOWN: |
||||
return; |
||||
case GRPC_OP_COMPLETE: |
||||
cl = ev.tag; |
||||
cl->func(cl->arg, ev.success); |
||||
gpr_free(cl); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
const char *grpc_end2end_proxy_get_client_target(grpc_end2end_proxy *proxy) { |
||||
return proxy->proxy_port; |
||||
} |
||||
|
||||
const char *grpc_end2end_proxy_get_server_port(grpc_end2end_proxy *proxy) { |
||||
return proxy->server_port; |
||||
} |
@ -0,0 +1,55 @@ |
||||
/*
|
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_TEST_CORE_END2END_FIXTURES_PROXY_H |
||||
#define GRPC_TEST_CORE_END2END_FIXTURES_PROXY_H |
||||
|
||||
#include <grpc/grpc.h> |
||||
|
||||
/* proxy service for _with_proxy fixtures */ |
||||
|
||||
typedef struct grpc_end2end_proxy grpc_end2end_proxy; |
||||
|
||||
typedef struct grpc_end2end_proxy_def { |
||||
grpc_server *(*create_server)(const char *port); |
||||
grpc_channel *(*create_client)(const char *target); |
||||
} grpc_end2end_proxy_def; |
||||
|
||||
grpc_end2end_proxy *grpc_end2end_proxy_create( |
||||
const grpc_end2end_proxy_def *def); |
||||
void grpc_end2end_proxy_destroy(grpc_end2end_proxy *proxy); |
||||
|
||||
const char *grpc_end2end_proxy_get_client_target(grpc_end2end_proxy *proxy); |
||||
const char *grpc_end2end_proxy_get_server_port(grpc_end2end_proxy *proxy); |
||||
|
||||
#endif /* GRPC_TEST_CORE_END2END_FIXTURES_PROXY_H */ |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue