Skip to content
Browse files

PUT's previous revision ID can come from If-Match header.

Now passes "etags_head.js" tests.

In other news, fixed a potential crash querying a view with grouping enabled but no reduce block defined.
  • Loading branch information...
1 parent 10ceb2e commit ea0a5349e44ea42ef9d776b1d52d666cd2e28465 @snej snej committed Jan 5, 2012
Showing with 29 additions and 19 deletions.
  1. +18 −12 Source/TDRouter+Handlers.m
  2. +6 −3 Source/TDRouter.m
  3. +5 −4 Source/TDView.m
View
30 Source/TDRouter+Handlers.m
@@ -472,6 +472,18 @@ - (TDStatus) do_GET: (TDDatabase*)db docID: (NSString*)docID attachment: (NSStri
}
+- (NSString*) revIDFromIfMatchHeader {
+ NSString* ifMatch = [_request valueForHTTPHeaderField: @"If-Match"];
+ if (!ifMatch)
+ return nil;
+ // Value of If-Match is an ETag, so have to trim the quotes around it:
+ if (ifMatch.length > 2 && [ifMatch hasPrefix: @"\""] && [ifMatch hasSuffix: @"\""])
+ return [ifMatch substringWithRange: NSMakeRange(1, ifMatch.length-2)];
+ else
+ return nil;
+}
+
+
- (TDStatus) update: (TDDatabase*)db
docID: (NSString*)docID
body: (TDBody*)body
@@ -495,20 +507,14 @@ - (TDStatus) update: (TDDatabase*)db
// PUT's revision ID comes from the JSON body.
prevRevID = [body propertyForKey: @"_rev"];
} else {
- // DELETE's revision ID can come either from the ?rev= query param or an If-Match header.
+ // DELETE's revision ID comes from the ?rev= query param
prevRevID = [self query: @"rev"];
- if (!prevRevID) {
- NSString* ifMatch = [_request valueForHTTPHeaderField: @"If-Match"];
- if (ifMatch) {
- // Value of If-Match is an ETag, so have to trim the quotes around it:
- if (ifMatch.length > 2 && [ifMatch hasPrefix: @"\""] && [ifMatch hasSuffix: @"\""])
- prevRevID = [ifMatch substringWithRange: NSMakeRange(1, ifMatch.length-2)];
- else
- return 400;
- }
- }
}
-
+
+ // A backup source of revision ID is an If-Match header:
+ if (!prevRevID)
+ prevRevID = [self revIDFromIfMatchHeader];
+
TDRevision* rev = [[[TDRevision alloc] initWithDocID: docID revID: nil deleted: deleting]
autorelease];
if (!rev)
View
9 Source/TDRouter.m
@@ -93,7 +93,8 @@ - (int) intQuery: (NSString*)param defaultValue: (int)defaultValue {
}
- (id) jsonQuery: (NSString*)param error: (NSError**)outError {
- *outError = nil;
+ if (outError)
+ *outError = nil;
NSString* value = [self query: param];
if (!value)
return nil;
@@ -168,8 +169,10 @@ - (TDStatus) openDB {
for (NSString* comp in [pathString componentsSeparatedByString: @"/"]) {
if ([comp length] > 0) {
comp = [comp stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
- if (!comp)
- return nil; // bad URL
+ if (!comp) {
+ path = nil; // bad URL
+ break;
+ }
[path addObject: comp];
}
}
View
9 Source/TDView.m
@@ -373,9 +373,9 @@ - (NSArray*) queryWithOptions: (const TDQueryOptions*)options
// Reduced or grouped query:
if (group && !groupTogether(key, lastKey, groupLevel) && lastKey) {
// This pair starts a new group, so reduce & record the last one:
- id reduced = _reduceBlock(keysToReduce, valuesToReduce, NO) ?: $null;
+ id reduced = _reduceBlock ? _reduceBlock(keysToReduce, valuesToReduce,NO) : nil;
[rows addObject: $dict({@"key", groupKey(lastKey, groupLevel)},
- {@"value", reduced})];
+ {@"value", (reduced ?: $null)})];
[keysToReduce removeAllObjects];
[valuesToReduce removeAllObjects];
}
@@ -406,8 +406,9 @@ - (NSArray*) queryWithOptions: (const TDQueryOptions*)options
if (keysToReduce.count > 0) {
// Finish the last group (or the entire list, if no grouping):
id key = group ? groupKey(lastKey, groupLevel) : $null;
- id reduced = _reduceBlock(keysToReduce, valuesToReduce, NO) ?: $null;
- [rows addObject: $dict({@"key", key}, {@"value", reduced})];
+ id reduced = _reduceBlock ? _reduceBlock(keysToReduce, valuesToReduce,NO) : nil;
+ [rows addObject: $dict({@"key", key},
+ {@"value", (reduced ?: $null)})];
}
[keysToReduce release];
[valuesToReduce release];

0 comments on commit ea0a534

Please sign in to comment.
Something went wrong with that request. Please try again.