Revert "Revert "Add OAuth2 protocol in GRPCClient""
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m
index 8723624..436c19e 100644
--- a/src/objective-c/GRPCClient/GRPCCall.m
+++ b/src/objective-c/GRPCClient/GRPCCall.m
@@ -18,6 +18,8 @@
#import "GRPCCall.h"
+#import "GRPCCall+OAuth2.h"
+
#include <grpc/grpc.h>
#include <grpc/support/time.h>
#import <RxLibrary/GRXConcurrentWriteable.h>
@@ -40,10 +42,14 @@
NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
static NSMutableDictionary *callFlags;
+static NSString * const kAuthorizationHeader = @"authorization";
+static NSString * const kBearerPrefix = @"Bearer ";
+
@interface GRPCCall () <GRXWriteable>
// Make them read-write.
@property(atomic, strong) NSDictionary *responseHeaders;
@property(atomic, strong) NSDictionary *responseTrailers;
+@property(atomic) BOOL isWaitingForToken;
@end
// The following methods of a C gRPC call object aren't reentrant, and thus
@@ -181,9 +187,6 @@
- (void)finishWithError:(NSError *)errorOrNil {
@synchronized(self) {
- if (_state == GRXWriterStateFinished) {
- return;
- }
_state = GRXWriterStateFinished;
}
@@ -211,7 +214,11 @@
[self finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
code:GRPCErrorCodeCancelled
userInfo:@{NSLocalizedDescriptionKey: @"Canceled by app"}]];
- [self cancelCall];
+ if (!self.isWaitingForToken) {
+ [self cancelCall];
+ } else {
+ self.isWaitingForToken = NO;
+ }
}
- (void)dealloc {
@@ -410,6 +417,36 @@
#pragma mark GRXWriter implementation
+- (void)startCallWithWriteable:(id<GRXWriteable>)writeable {
+ _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable
+ dispatchQueue:_responseQueue];
+
+ _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host
+ serverName:_serverName
+ path:_path];
+ NSAssert(_wrappedCall, @"Error allocating RPC objects. Low memory?");
+
+ [self sendHeaders:_requestHeaders];
+ [self invokeCall];
+
+ // TODO(jcanizales): Extract this logic somewhere common.
+ NSString *host = [NSURL URLWithString:[@"https://" stringByAppendingString:_host]].host;
+ if (!host) {
+ // TODO(jcanizales): Check this on init.
+ [NSException raise:NSInvalidArgumentException format:@"host of %@ is nil", _host];
+ }
+ _connectivityMonitor = [GRPCConnectivityMonitor monitorWithHost:host];
+ __weak typeof(self) weakSelf = self;
+ void (^handler)() = ^{
+ typeof(self) strongSelf = weakSelf;
+ [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
+ code:GRPCErrorCodeUnavailable
+ userInfo:@{ NSLocalizedDescriptionKey : @"Connectivity lost." }]];
+ };
+ [_connectivityMonitor handleLossWithHandler:handler
+ wifiStatusChangeHandler:nil];
+}
+
- (void)startWithWriteable:(id<GRXWriteable>)writeable {
@synchronized(self) {
_state = GRXWriterStateStarted;
@@ -422,33 +459,23 @@
// that the life of the instance is determined by this retain cycle.
_retainSelf = self;
- _responseWriteable = [[GRXConcurrentWriteable alloc] initWithWriteable:writeable
- dispatchQueue:_responseQueue];
-
- _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host serverName:_serverName path:_path];
- NSAssert(_wrappedCall, @"Error allocating RPC objects. Low memory?");
-
- [self sendHeaders:_requestHeaders];
- [self invokeCall];
-
- // TODO(jcanizales): Extract this logic somewhere common.
- NSString *host = [NSURL URLWithString:[@"https://" stringByAppendingString:_host]].host;
- if (!host) {
- // TODO(jcanizales): Check this on init.
- [NSException raise:NSInvalidArgumentException format:@"host of %@ is nil", _host];
+ if (self.tokenProvider != nil) {
+ self.isWaitingForToken = YES;
+ __weak typeof(self) weakSelf = self;
+ [self.tokenProvider getTokenWithHandler:^(NSString *token){
+ typeof(self) strongSelf = weakSelf;
+ if (strongSelf && strongSelf.isWaitingForToken) {
+ if (token) {
+ NSString *t = [kBearerPrefix stringByAppendingString:token];
+ strongSelf.requestHeaders[kAuthorizationHeader] = t;
+ }
+ [strongSelf startCallWithWriteable:writeable];
+ strongSelf.isWaitingForToken = NO;
+ }
+ }];
+ } else {
+ [self startCallWithWriteable:writeable];
}
- __weak typeof(self) weakSelf = self;
- _connectivityMonitor = [GRPCConnectivityMonitor monitorWithHost:host];
- void (^handler)() = ^{
- typeof(self) strongSelf = weakSelf;
- if (strongSelf) {
- [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
- code:GRPCErrorCodeUnavailable
- userInfo:@{ NSLocalizedDescriptionKey : @"Connectivity lost." }]];
- }
- };
- [_connectivityMonitor handleLossWithHandler:handler
- wifiStatusChangeHandler:nil];
}
- (void)setState:(GRXWriterState)newState {