diff --git a/Source/TDRouter+Handlers.m b/Source/TDRouter+Handlers.m index 604c2af..6ab868b 100644 --- a/Source/TDRouter+Handlers.m +++ b/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) diff --git a/Source/TDRouter.m b/Source/TDRouter.m index aa29e47..c4962fd 100644 --- a/Source/TDRouter.m +++ b/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]; } } diff --git a/Source/TDView.m b/Source/TDView.m index 9112bf8..03dc1a3 100644 --- a/Source/TDView.m +++ b/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];