Skip to content
Snippets Groups Projects
Commit 84fa531e authored by murgatroid99's avatar murgatroid99 Committed by Jorge Canizales
Browse files

Added class for setting request headers on a call

parent 18c975f9
No related branches found
No related tags found
No related merge requests found
......@@ -32,6 +32,7 @@
*/
#import "GRPCCall+OAuth2.h"
#import "private/GRPCRequestHeaders.h"
static NSString * const kAuthorizationHeader = @"authorization";
static NSString * const kBearerPrefix = @"Bearer ";
......
......@@ -48,6 +48,8 @@
#import <Foundation/Foundation.h>
#import <RxLibrary/GRXWriter.h>
@class GRPCRequestHeaders;
// Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by
// the server.
extern id const kGRPCHeadersKey;
......@@ -70,7 +72,7 @@ extern id const kGRPCTrailersKey;
//
// For convenience, the property is initialized to an empty NSMutableDictionary, and the setter
// accepts (and copies) both mutable and immutable dictionaries.
- (NSMutableDictionary *)requestHeaders; // nonatomic
- (GRPCRequestHeaders *)requestHeaders; // nonatomic
- (void)setRequestHeaders:(NSDictionary *)requestHeaders; // nonatomic, copy
// This dictionary is populated with the HTTP headers received from the server. This happens before
......
......@@ -41,6 +41,7 @@
#import "private/NSData+GRPC.h"
#import "private/NSDictionary+GRPC.h"
#import "private/NSError+GRPC.h"
#import "private/GRPCRequestHeaders.h"
NSString * const kGRPCHeadersKey = @"io.grpc.HeadersKey";
NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
......@@ -93,7 +94,7 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
// the response arrives.
GRPCCall *_retainSelf;
NSMutableDictionary *_requestHeaders;
GRPCRequestHeaders *_requestHeaders;
}
@synthesize state = _state;
......@@ -124,19 +125,23 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
_requestWriter = requestWriter;
_requestHeaders = [NSMutableDictionary dictionary];
_requestHeaders = [[GRPCRequestHeaders alloc] initWithCall:self];
}
return self;
}
#pragma mark Metadata
- (NSMutableDictionary *)requestHeaders {
- (GRPCRequestHeaders *)requestHeaders {
return _requestHeaders;
}
- (void)setRequestHeaders:(NSDictionary *)requestHeaders {
_requestHeaders = [NSMutableDictionary dictionaryWithDictionary:requestHeaders];
GRPCRequestHeaders *newHeaders = [[GRPCRequestHeaders alloc] initWithCall:self];
for (id key in requestHeaders) {
newHeaders[key] = requestHeaders[key];
}
_requestHeaders = newHeaders;
}
#pragma mark Finish
......@@ -230,10 +235,11 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey";
#pragma mark Send headers
- (void)sendHeaders:(NSDictionary *)headers {
- (void)sendHeaders:(GRPCRequestHeaders *)headers {
// TODO(jcanizales): Add error handlers for async failures
[_wrappedCall startBatchWithOperations:@[[[GRPCOpSendMetadata alloc]
initWithMetadata:headers ?: @{} handler:nil]]];
initWithMetadata:[headers asDictionary] ?: @{}
handler:nil]]];
}
#pragma mark GRXWriteable implementation
......
/*
*
* 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>
#include <grpc/grpc.h>
@class GRPCCall;
@interface GRPCRequestHeaders : NSObject
- (instancetype)initWithCall:(GRPCCall *)call;
- (id)objectForKeyedSubscript:(NSString *)key;
- (void)setObject:(id)obj forKeyedSubscript:(NSString *)key;
- (void)removeAllObjects;
- (void)removeObjectForKey:(NSString *)aKey;
- (NSDictionary *)asDictionary;
@end
\ No newline at end of file
/*
*
* 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>
#import "GRPCRequestHeaders.h"
#import "GRPCCall.h"
static NSString* normalizeKey(NSString* key) {
if ([key canBeConvertedToEncoding:NSASCIIStringEncoding]) {
return [key lowercaseString];
} else {
return nil;
}
}
static bool isKeyValuePairValid(NSString *key, id value) {
if ([key hasSuffix:@"-bin"]) {
if (![value isKindOfClass:[NSData class]]) {
return false;
}
} else {
if (![value isKindOfClass:[NSString class]]) {
return false;
}
}
return true;
}
@implementation GRPCRequestHeaders {
__weak GRPCCall *_call;
NSMutableDictionary *_proxy;
}
- (instancetype) initWithCall:(GRPCCall *)call {
self = [super init];
if (self) {
_call = call;
_proxy = [NSMutableDictionary dictionary];
}
return self;
}
- (id) objectForKeyedSubscript:(NSString *)key {
NSString *normalizedKey = normalizeKey(key);
if (normalizedKey) {
return _proxy[normalizedKey];
} else {
return [NSNull null];
}
}
- (void) setObject:(id)obj forKeyedSubscript:(NSString *)key {
if (_call.state == GRXWriterStateNotStarted) {
NSString *normalizedKey = normalizeKey(key);
if (normalizedKey) {
if (isKeyValuePairValid(key, obj)) {
_proxy[normalizedKey] = obj;
} else {
[NSException raise:@"Invalid key/value pair"
format:@"Key %@ could not be added with value %@", key, obj];
}
} else {
[NSException raise:@"Invalid key" format:@"Key %@ contains illegal characters", key];
}
} else {
[NSException raise:@"Invalid modification"
format:@"Cannot modify request metadata after call is started"];
}
}
- (void) removeObjectForKey:(NSString *)aKey {
if (_call.state == GRXWriterStateNotStarted) {
NSString *normalizedKey = normalizeKey(aKey);
if (normalizedKey) {
[_proxy removeObjectForKey:normalizedKey];
} else {
[NSException raise:@"Invalid key" format:@"Key %@ contains illegal characters", aKey];
}
} else {
[NSException raise:@"Invalid modification"
format:@"Cannot modify request metadata after call is started"];
}
}
- (void) removeAllObjects {
if (_call.state == GRXWriterStateNotStarted) {
[_proxy removeAllObjects];
} else {
[NSException raise:@"Invalid modification"
format:@"Cannot modify request metadata after call is started"];
}
}
- (NSDictionary *)asDictionary {
return [NSDictionary dictionaryWithDictionary:_proxy];
}
@end
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment