Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Support custom headers to send in replication requests.

Added property .headers to CouchReplication & CouchPersistentReplication.
Removed properties .source and .target from CouchPersistentReplication; these are problematic because they're directly mapped
to the replication document, where their values can be either strings or dictionaries.
Instead, use properties .remoteURL and .localDatabase to find the endpoints.

Change-Id: I0cff66b8c0505e484787e3b19b2c8d7a3f11419d
  • Loading branch information...
commit 71199c9a8082bbd13b6e9c8e198831e5a60bb35c 1 parent 6838c8d
@snej snej authored
View
7 Couch/CouchInternal.h
@@ -76,6 +76,13 @@ typedef void (^OnDatabaseChangeBlock)(CouchDocument*, BOOL externalChange);
@end
+@interface CouchPersistentReplication ()
+@property (readonly) NSString* sourceURLStr;
+@property (readonly) NSString* targetURLStr;
+@end
+
+
+
@interface CouchServer ()
@property (readonly) BOOL isEmbeddedServer;
- (CouchPersistentReplication*) replicationWithSource: (NSString*)source
View
17 Couch/CouchPersistentReplication.h
@@ -32,16 +32,15 @@ typedef enum {
CouchReplicationMode _mode;
}
-/** The source URL for the replication.
- This will be either a complete HTTP(s) URL or the name of a database on this server. */
-@property (readonly, copy) NSString* source;
-
-/** The destination URL for the replication.
- This will be either a complete HTTP(s) URL or the name of a database on this server. */
-@property (readonly, copy) NSString* target;
+/** The local database being replicated to/from. */
+@property (readonly) CouchDatabase* localDatabase;
+/** The remote database being replicated to/from. */
@property (readonly) NSURL* remoteURL;
+/** Does the replication pull from (as opposed to push to) the target? */
+@property (nonatomic, readonly) bool pull;
+
/** Should the target database be created if it doesn't already exist? (Defaults to NO). */
@property bool create_target;
@@ -60,6 +59,10 @@ typedef enum {
/** Sets the documents to specify as part of the replication. */
@property (copy) NSArray *doc_ids;
+/** Extra HTTP headers to send in all requests to the remote server.
+ Should map strings (header names) to strings. */
+@property (copy) NSDictionary* headers;
+
/** Sets the "user_ctx" property of the replication, which identifies what privileges it will run with when accessing the local server. To replicate design documents, this should be set to a value with "_admin" in the list of roles.
The server will not let you specify privileges you don't have, so the request to create the replication must be made with credentials that match what you're setting here, unless the server is in no-authentication "admin party" mode.
See <https://gist.github.com/832610>, section 8, for details.
View
72 Couch/CouchPersistentReplication.m
@@ -18,6 +18,8 @@
@interface CouchPersistentReplication ()
+@property (copy) id source;
+@property (copy) id target;
@property (readwrite) CouchReplicationState state;
@property (nonatomic, readwrite, retain) NSError* error;
@property (nonatomic, readwrite) CouchReplicationMode mode;
@@ -38,8 +40,8 @@ + (CouchPersistentReplication*) createWithReplicatorDatabase: (CouchDatabase*)re
{
CouchPersistentReplication* rep = [[self alloc] initWithNewDocumentInDatabase: replicatorDB];
rep.autosaves = YES;
- [rep setValue: source ofProperty: @"source"];
- [rep setValue: target ofProperty: @"target"];
+ rep.source = source;
+ rep.target = target;
return [rep autorelease];
}
@@ -75,14 +77,74 @@ - (void) actAsAdmin {
}
+static inline BOOL isLocalDBName(NSString* url) {
+ return [url rangeOfString: @":"].length == 0;
+}
+
+
+- (NSString*) sourceURLStr {
+ id source = self.source;
+ if ([source isKindOfClass: [NSDictionary class]])
+ source = [source objectForKey: @"url"];
+ return $castIf(NSString, source);
+}
+
+
+- (NSString*) targetURLStr {
+ id target = self.target;
+ if ([target isKindOfClass: [NSDictionary class]])
+ target = [target objectForKey: @"url"];
+ return $castIf(NSString, target);
+}
+
+
+- (bool) pull {
+ return isLocalDBName(self.targetURLStr);
+}
+
+
+- (CouchDatabase*) localDatabase {
+ NSString* name = self.sourceURLStr;
+ if (!isLocalDBName(name))
+ name = self.targetURLStr;
+ return [self.database.server databaseNamed: name];
+}
+
+
- (NSURL*) remoteURL {
- NSString* urlStr = self.source;
- if ([urlStr rangeOfString: @":"].length == 0)
- urlStr = self.target;
+ NSString* urlStr = self.sourceURLStr;
+ if (isLocalDBName(urlStr))
+ urlStr = self.targetURLStr;
return [NSURL URLWithString: urlStr];
}
+- (NSDictionary*) headers {
+ id source = self.source;
+ if ([source isKindOfClass: [NSDictionary class]]
+ && !isLocalDBName([source objectForKey: @"url"]))
+ return [source objectForKey: @"headers"];
+ id target = self.target;
+ if ([target isKindOfClass: [NSDictionary class]]
+ && !isLocalDBName([target objectForKey: @"url"]))
+ return [target objectForKey: @"headers"];
+ return nil;
+}
+
+
+- (void) setHeaders: (NSDictionary*)headers {
+ BOOL isPull = self.pull;
+ id remote = isPull ? self.source : self.target;
+ if ([remote isKindOfClass: [NSString class]])
+ remote = [NSMutableDictionary dictionaryWithObject: remote forKey: @"url"];
+ [remote setValue: headers forKey: @"headers"];
+ if (isPull)
+ self.source = remote;
+ else
+ self.target = remote;
+}
+
+
- (CouchReplicationState) state {
return _state;
}
View
19 Couch/CouchReplication.h
@@ -35,6 +35,7 @@ typedef enum {
NSString* _filter;
NSDictionary* _filterParams;
NSDictionary* _options;
+ NSDictionary* _headers;
BOOL _running;
NSString* _taskID;
NSString* _status;
@@ -43,6 +44,15 @@ typedef enum {
NSError* _error;
}
+/** The local database being replicated to/from. */
+@property (nonatomic, readonly) CouchDatabase* localDatabase;
+
+/** The URL of the remote database. */
+@property (nonatomic, readonly) NSURL* remoteURL;
+
+/** Does the replication pull from (as opposed to push to) the target? */
+@property (nonatomic, readonly) bool pull;
+
/** Should the target database be created if it doesn't already exist? (Defaults to NO). */
@property (nonatomic) bool createTarget;
@@ -58,6 +68,10 @@ typedef enum {
Should be a JSON-compatible dictionary. */
@property (nonatomic, copy) NSDictionary* filterParams;
+/** Extra HTTP headers to send in all requests to the remote server.
+ Should map strings (header names) to strings. */
+@property (nonatomic, copy) NSDictionary* headers;
+
/** Other options to be provided to the replicator.
These will be added to the JSON body of the POST to /_replicate. */
@property (nonatomic, copy) NSDictionary* options;
@@ -70,11 +84,6 @@ typedef enum {
/** Stops replication, asynchronously. */
- (void) stop;
-@property (nonatomic, readonly) NSURL* remoteURL;
-
-/** Does the replication pull from (as opposed to push to) the target? */
-@property (nonatomic, readonly) bool pull;
-
@property (nonatomic, readonly) BOOL running;
/** The current status string from the server, if active, else nil (observable).
View
16 Couch/CouchReplication.m
@@ -62,6 +62,7 @@ - (void)dealloc {
[_filter release];
[_filterParams release];
[_options release];
+ [_headers release];
[super dealloc];
}
@@ -73,12 +74,21 @@ - (NSString*) description {
@synthesize pull=_pull, createTarget=_createTarget, continuous=_continuous,
- filter=_filter, filterParams=_filterParams, options=_options;
+ filter=_filter, filterParams=_filterParams, options=_options, headers=_headers,
+ localDatabase=_database;
- (RESTOperation*) operationToStart: (BOOL)start {
- NSString* source = _pull ? _remote.absoluteString : _database.relativePath;
- NSString* target = _pull ? _database.relativePath : _remote.absoluteString;
+ id source = _pull ? _remote.absoluteString : _database.relativePath;
+ id target = _pull ? _database.relativePath : _remote.absoluteString;
+ if (_headers.count > 0) {
+ // Convert 'source' or 'target' to a dictionary so we can add 'headers' to it:
+ id *param = _pull ? &source : &target;
+ *param = [NSDictionary dictionaryWithObjectsAndKeys:
+ *param, @"url",
+ _headers, @"headers",
+ nil];
+ }
NSMutableDictionary* body = [NSMutableDictionary dictionaryWithObjectsAndKeys:
source, @"source",
target, @"target",
View
2  Couch/CouchServer.m
@@ -151,7 +151,7 @@ - (CouchPersistentReplication*) replicationWithSource: (NSString*)source
target: (NSString*)target
{
for (CouchPersistentReplication* repl in self.replications) {
- if ($equal(repl.source, source) && $equal(repl.target, target))
+ if ($equal(repl.sourceURLStr, source) && $equal(repl.targetURLStr, target))
return repl;
}
return [CouchPersistentReplication createWithReplicatorDatabase: self.replicatorDatabase
Please sign in to comment.
Something went wrong with that request. Please try again.