Ben Copsey

Tweak behaviour of ASIFormDataRequests various set/add value methods:

* If key is empty, don't add anything (value can be empty)
* All file/data methods now do through the long form addData:withFileName:andContentType:forKey: method, to cut down on a bit of duplication
Thanks to Bas Scheffers for suggesting changes here!
@@ -50,13 +50,13 @@ typedef enum _ASIPostFormat { @@ -50,13 +50,13 @@ typedef enum _ASIPostFormat {
50 - (void)addFile:(NSString *)filePath forKey:(NSString *)key; 50 - (void)addFile:(NSString *)filePath forKey:(NSString *)key;
51 51
52 // Same as above, but you can specify the content-type and file name 52 // Same as above, but you can specify the content-type and file name
53 -- (void)addFile:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key; 53 +- (void)addFile:(NSString *)filePath withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key;
54 54
55 // Add the contents of a local file to the request, clearing any others with the same key 55 // Add the contents of a local file to the request, clearing any others with the same key
56 - (void)setFile:(NSString *)filePath forKey:(NSString *)key; 56 - (void)setFile:(NSString *)filePath forKey:(NSString *)key;
57 57
58 // Same as above, but you can specify the content-type and file name 58 // Same as above, but you can specify the content-type and file name
59 -- (void)setFile:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key; 59 +- (void)setFile:(NSString *)filePath withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key;
60 60
61 // Add the contents of an NSData object to the request 61 // Add the contents of an NSData object to the request
62 - (void)addData:(NSData *)data forKey:(NSString *)key; 62 - (void)addData:(NSData *)data forKey:(NSString *)key;
@@ -67,10 +67,16 @@ @@ -67,10 +67,16 @@
67 67
68 - (void)addPostValue:(id <NSObject>)value forKey:(NSString *)key 68 - (void)addPostValue:(id <NSObject>)value forKey:(NSString *)key
69 { 69 {
  70 + if (!key) {
  71 + return;
  72 + }
70 if (![self postData]) { 73 if (![self postData]) {
71 [self setPostData:[NSMutableArray array]]; 74 [self setPostData:[NSMutableArray array]];
72 } 75 }
73 - [[self postData] addObject:[NSDictionary dictionaryWithObjectsAndKeys:[value description],@"value",key,@"key",nil]]; 76 + NSMutableDictionary *keyValuePair = [NSMutableDictionary dictionaryWithCapacity:2];
  77 + [keyValuePair setValue:key forKey:@"key"];
  78 + [keyValuePair setValue:[value description] forKey:@"value"];
  79 + [[self postData] addObject:keyValuePair];
74 } 80 }
75 81
76 - (void)setPostValue:(id <NSObject>)value forKey:(NSString *)key 82 - (void)setPostValue:(id <NSObject>)value forKey:(NSString *)key
@@ -93,36 +99,26 @@ @@ -93,36 +99,26 @@
93 [self addFile:filePath withFileName:nil andContentType:nil forKey:key]; 99 [self addFile:filePath withFileName:nil andContentType:nil forKey:key];
94 } 100 }
95 101
96 -- (void)addFile:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key 102 +- (void)addFile:(NSString *)filePath withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key
97 { 103 {
98 - if (![self fileData]) { 104 + BOOL isDirectory = NO;
99 - [self setFileData:[NSMutableArray array]]; 105 + BOOL fileExists = [[[[NSFileManager alloc] init] autorelease] fileExistsAtPath:filePath isDirectory:&isDirectory];
  106 + if (!fileExists || isDirectory) {
  107 + [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileBuildingRequestType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"No file exists at %@",filePath],NSLocalizedDescriptionKey,nil]]];
100 } 108 }
101 -  
102 - // If data is a path to a local file  
103 - if ([data isKindOfClass:[NSString class]]) {  
104 - BOOL isDirectory = NO;  
105 - BOOL fileExists = [[[[NSFileManager alloc] init] autorelease] fileExistsAtPath:(NSString *)data isDirectory:&isDirectory];  
106 - if (!fileExists || isDirectory) {  
107 - [self failWithError:[NSError errorWithDomain:NetworkRequestErrorDomain code:ASIInternalErrorWhileBuildingRequestType userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"No file exists at %@",data],NSLocalizedDescriptionKey,nil]]];  
108 - }  
109 109
110 - // If the caller didn't specify a custom file name, we'll use the file name of the file we were passed 110 + // If the caller didn't specify a custom file name, we'll use the file name of the file we were passed
111 - if (!fileName) { 111 + if (!fileName) {
112 - fileName = [(NSString *)data lastPathComponent]; 112 + fileName = [filePath lastPathComponent];
113 - } 113 + }
114 114
115 - // If we were given the path to a file, and the user didn't specify a mime type, we can detect it from the file extension 115 + // If we were given the path to a file, and the user didn't specify a mime type, we can detect it from the file extension
116 - if (!contentType) { 116 + if (!contentType) {
117 - contentType = [ASIHTTPRequest mimeTypeForFileAtPath:data]; 117 + contentType = [ASIHTTPRequest mimeTypeForFileAtPath:filePath];
118 - }  
119 } 118 }
120 - 119 + [self addData:filePath withFileName:fileName andContentType:contentType forKey:key];
121 - NSDictionary *fileInfo = [NSDictionary dictionaryWithObjectsAndKeys:data, @"data", contentType, @"contentType", fileName, @"fileName", key, @"key", nil];  
122 - [[self fileData] addObject:fileInfo];  
123 } 120 }
124 121
125 -  
126 - (void)setFile:(NSString *)filePath forKey:(NSString *)key 122 - (void)setFile:(NSString *)filePath forKey:(NSString *)key
127 { 123 {
128 [self setFile:filePath withFileName:nil andContentType:nil forKey:key]; 124 [self setFile:filePath withFileName:nil andContentType:nil forKey:key];
@@ -155,8 +151,13 @@ @@ -155,8 +151,13 @@
155 if (!contentType) { 151 if (!contentType) {
156 contentType = @"application/octet-stream"; 152 contentType = @"application/octet-stream";
157 } 153 }
158 - 154 +
159 - NSDictionary *fileInfo = [NSDictionary dictionaryWithObjectsAndKeys:data, @"data", contentType, @"contentType", fileName, @"fileName", key, @"key", nil]; 155 + NSMutableDictionary *fileInfo = [NSMutableDictionary dictionaryWithCapacity:4];
  156 + [fileInfo setValue:key forKey:@"key"];
  157 + [fileInfo setValue:fileName forKey:@"fileName"];
  158 + [fileInfo setValue:contentType forKey:@"contentType"];
  159 + [fileInfo setValue:data forKey:@"data"];
  160 +
160 [[self fileData] addObject:fileInfo]; 161 [[self fileData] addObject:fileInfo];
161 } 162 }
162 163
@@ -24,7 +24,7 @@ @@ -24,7 +24,7 @@
24 #import "ASIDataCompressor.h" 24 #import "ASIDataCompressor.h"
25 25
26 // Automatically set on build 26 // Automatically set on build
27 -NSString *ASIHTTPRequestVersion = @"v1.8-95 2011-05-28"; 27 +NSString *ASIHTTPRequestVersion = @"v1.8.1 2011-06-04";
28 28
29 static NSString *defaultUserAgent = nil; 29 static NSString *defaultUserAgent = nil;
30 30
@@ -17,6 +17,27 @@ @@ -17,6 +17,27 @@
17 17
18 @implementation ASIFormDataRequestTests 18 @implementation ASIFormDataRequestTests
19 19
  20 +- (void)testAddNilKeysAndValues
  21 +{
  22 + ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/empty-post-value"]];
  23 + [request setPostValue:nil forKey:@"key1"];
  24 + [request setPostValue:@"value2" forKey:@"key2"];
  25 + [request setData:nil forKey:@"file1"];
  26 + [request setData:[@"hello" dataUsingEncoding:NSUTF8StringEncoding] forKey:@"file2"];
  27 + [request startSynchronous];
  28 + BOOL success = ([[request responseString] isEqualToString:@"key1: \r\nkey2: value2\r\nfile1: \r\nfile2: hello"]);
  29 + GHAssertTrue(success, @"Sent wrong data");
  30 +
  31 + // Test nil key (no key or value should be sent to the server)
  32 + request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]];
  33 + [request addPostValue:@"value1" forKey:nil];
  34 + [request addPostValue:@"value2" forKey:@"key2"];
  35 + [request buildPostBody];
  36 + NSString *postBody = [[[NSString alloc] initWithData:[request postBody] encoding:NSUTF8StringEncoding] autorelease];
  37 + success = ([postBody isEqualToString:@"key2=value2"]);
  38 + GHAssertTrue(success, @"Sent wrong data");
  39 +}
  40 +
20 - (void)testPostWithFileUpload 41 - (void)testPostWithFileUpload
21 { 42 {
22 NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/post"]; 43 NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/post"];
This diff was suppressed by a .gitattributes entry.