1

Closed

HttpBatchResponse HttpResponses improperly extracted

description

It appears that beginning at: +(HttpBatchResponse ) CreateBatchResponse:(NSString )response untested code has been put in to extract information from the responses. The main problem being that the response is parsed using some "componentsSeparatedByString" calls with what appears to be regular expression parameters, which that method does not take. The end result is that instead of the proper number of responses, there are many because the response is basically split on any character included in the regex.
 
I'm by no means a regex expert and I've only done enough work to get me by at this point, but my fixes are:
 
 
First, get the correct changeset boundary (currently an empty string is returned):
+(NSString ) ExtractChangesetBoundary:(NSString )body
{
NSError *error = NULL;    
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?<=boundary=)changesetresponse_[^\\r\\n]+"                                  
                                                                       options:NSRegularExpressionCaseInsensitive                                  
                                                                         error:&error];

NSArray *matches = [regex matchesInString:body options:0 range:NSMakeRange(0, [body length])];
if ([matches count] == 0) {
    return @"";
}

NSTextCheckingResult *firstResult = [matches objectAtIndex:0];
NSString *boundary = [body substringWithRange:firstResult.range];
 
return boundary;
}
 
 
 
 
 
Then in Microsoft_Http_Response,
 
 
  • (NSInteger)extractCode:(NSString *)response_str
    {

    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?<=HTTP/[\\d\\.x]{3} )\d+"
                                                                       options:NSRegularExpressionCaseInsensitive                                  
                                                                         error:&error];
    
    NSArray *matches = [regex matchesInString:response_str options:0 range:NSMakeRange(0, [response_str length])];

    if ([matches count] < 1) {
    return 0;
    }

    NSTextCheckingResult *firstResult = [matches objectAtIndex:0];
    NSString *code = [response_str substringWithRange:firstResult.range];
     
    return [code intValue];
}
 
 
 
 
 
  • (NSMutableDictionary )extractHeaders:(NSString )response_str
    {

    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?:\r?\n){2}[\w\W]+?(?:\r?\n){2}"
                                                                       options:NSRegularExpressionCaseInsensitive                                  
                                                                         error:&error];
    
    NSArray *matches = [regex matchesInString:response_str options:0 range:NSMakeRange(0, [response_str length])];

    NSMutableDictionary *headers = [NSMutableDictionary dictionaryWithCapacity:1];

    for (int i = 0; i <[matches count]; i++) {
    NSTextCheckingResult *textCheck = [matches objectAtIndex:i];
    NSString *match = [response_str substringWithRange:textCheck.range];
    NSArray *lines = [[match stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsSeparatedByString:@"\r\n"];
    
    for(int j=0;j<[lines count];j++)
    {
        NSString *line = [lines objectAtIndex:j];
     
        if([line isEqualToString:@""])
            continue;            
    
        NSArray *keyValueArray = [line componentsSeparatedByString:@": "];
    
        if ([keyValueArray count] >= 2) {
            //coalesce all entries after 0
            NSString *value = [keyValueArray objectAtIndex:1];
    
            for (int k = 2; k < [keyValueArray count]; k++) {
                value = [value stringByAppendingString:[keyValueArray objectAtIndex:k]];
            }
    
            //add key value pair to headers dict
            [headers setObject:value forKey:[keyValueArray objectAtIndex:0]];
        }
    }        
    
    }

    return headers;
}
 
 
 
 
  • (NSString )extractBody:(NSString )response_str
    {
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?:\r?\n){2}[\w\W]+?(?:\r?\n){2}"
                                                                       options:NSRegularExpressionCaseInsensitive                                  
                                                                         error:&error];
    
    NSArray *matches = [regex matchesInString:response_str options:0 range:NSMakeRange(0, [response_str length])];

    if ([matches count] > 0) {
    NSTextCheckingResult *result = [matches objectAtIndex:0];
    
    //take the body after headers
    NSString *body = [response_str substringFromIndex:(result.range.location + result.range.length)];                
    return body;
    }

    return @"";
}
 
 
  • (NSString )extractVersion:(NSString )response_str
    {
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?<=HTTP/)[\\d\\.x]{3}(?= \d+)"
                                                                       options:NSRegularExpressionCaseInsensitive                                  
                                                                         error:&error];
    
    NSArray *matches = [regex matchesInString:response_str options:0 range:NSMakeRange(0, [response_str length])];

    if ([matches count] >= 1) {
    NSTextCheckingResult *firstResult = [matches objectAtIndex:0];
    NSString *version = [response_str substringWithRange:firstResult.range];
    
    return version;
    }

    return @"";
}
 
 
 
 
  • (NSString )extractMessage:(NSString )response_str
    {
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?<=HTTP/[\\d\\.x]{3} \d{3} )[^\r\n]+"
                                                                       options:NSRegularExpressionCaseInsensitive                                  
                                                                         error:&error];
    
    NSArray *matches = [regex matchesInString:response_str options:0 range:NSMakeRange(0, [response_str length])];

    if ([matches count] >= 1) {
    NSTextCheckingResult *firstResult = [matches objectAtIndex:0];
    NSString *message = [response_str substringWithRange:firstResult.range];
     
    return message;
    }

    return @"";
}
 
 
 
Hopefully this can help get proper information from batch responses.
Closed Sep 8, 2011 at 3:35 AM by abub
Fixed as part of V1.3

comments

abub wrote May 9, 2011 at 10:02 PM

Thanks for reporting this, we shall consider it for the next release