Ben Copsey

Added support for application/x-www-form-urlencoded form posts in ASIFormDataRequest

... ... @@ -9,6 +9,12 @@
#import <Foundation/Foundation.h>
#import "ASIHTTPRequest.h"
typedef enum _ASIPostFormat {
ASIMultipartFormDataPostFormat = 0,
ASIURLEncodedPostFormat = 1
} ASIPostFormat;
@interface ASIFormDataRequest : ASIHTTPRequest {
// Parameters that will be POSTed to the url
... ... @@ -17,6 +23,7 @@
// Files that will be POSTed to the url
NSMutableDictionary *fileData;
ASIPostFormat postFormat;
}
#pragma mark setup request
... ... @@ -36,4 +43,6 @@
// Same as above, but you can specify the content-type and file name
- (void)setData:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key;
@property (assign) ASIPostFormat postFormat;
@end
... ...
... ... @@ -11,6 +11,8 @@
// Private stuff
@interface ASIFormDataRequest ()
- (void)buildMultipartFormDataPostBody;
- (void)buildURLEncodedPostBody;
@property (retain) NSMutableDictionary *postData;
@property (retain) NSMutableDictionary *fileData;
@end
... ... @@ -21,7 +23,9 @@
+ (id)requestWithURL:(NSURL *)newURL
{
return [[[self alloc] initWithURL:newURL] autorelease];
ASIFormDataRequest *request = [[[self alloc] initWithURL:newURL] autorelease];
[request setPostFormat:ASIMultipartFormDataPostFormat];
return request;
}
- (void)dealloc
... ... @@ -106,8 +110,19 @@
if ([[self fileData] count] > 0) {
[self setShouldStreamPostDataFromDisk:YES];
}
if ([self postFormat] == ASIURLEncodedPostFormat) {
[self buildURLEncodedPostBody];
} else {
[self buildMultipartFormDataPostBody];
}
[super buildPostBody];
}
- (void)buildMultipartFormDataPostBody
{
// Set your own boundary string only if really obsessive. We don't bother to check if post data contains the boundary, since it's pretty unlikely that it does.
NSString *stringBoundary = @"0xKhTmLbOuNdArY";
... ... @@ -137,10 +152,10 @@
id file = [fileInfo objectForKey:@"data"];
NSString *contentType = [fileInfo objectForKey:@"contentType"];
NSString *fileName = [fileInfo objectForKey:@"fileName"];
[self appendPostData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", key, fileName] dataUsingEncoding:NSUTF8StringEncoding]];
[self appendPostData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", contentType] dataUsingEncoding:NSUTF8StringEncoding]];
if ([file isKindOfClass:[NSString class]]) {
[self appendPostDataFromFile:file];
} else {
... ... @@ -155,11 +170,33 @@
[self appendPostData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
[super buildPostBody];
}
- (void)buildURLEncodedPostBody
{
// We can't post binary data using application/x-www-form-urlencoded
if ([[self fileData] count] > 0) {
[self setPostFormat:ASIMultipartFormDataPostFormat];
[self buildMultipartFormDataPostBody];
return;
}
[self addRequestHeader:@"Content-Type" value:@"application/x-www-form-urlencoded"];
NSEnumerator *e = [[self postData] keyEnumerator];
NSString *key;
int i=0;
int count = [[self postData] count]-1;
while (key = [e nextObject]) {
NSString *data = [NSString stringWithFormat:@"%@=%@%@",[key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],[[[self postData] objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],(i<count ? @"&" : @"")];
[self appendPostData:[data dataUsingEncoding:NSUTF8StringEncoding]];
i++;
}
}
@synthesize fileData;
@synthesize postData;
@synthesize fileData;
@synthesize postFormat;
@end
... ...
... ... @@ -15,4 +15,5 @@
- (void)testPostWithFileUpload;
- (void)testEmptyData;
- (void)testSubclass;
- (void)testURLEncodedPost;
@end
... ...
... ... @@ -103,6 +103,22 @@
GHAssertTrue(success,@"Convenience constructor failed to return an instance of the correct class");
}
- (void)testURLEncodedPost
{
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://asi/ASIHTTPRequest/tests/url-encoded-post"]];
[request setPostValue:@"value1" forKey:@"value1"];
[request setPostValue:@"(%20 ? =)" forKey:@"value2"];
[request setPostValue:@"£100.00" forKey:@"value3"];
[request setPostValue:@"" forKey:@"value4"];
[request setShouldStreamPostDataFromDisk:YES];
[request setPostFormat:ASIURLEncodedPostFormat];
[request start];
BOOL success = ([[request responseString] isEqualToString:@"value1: value1\r\nvalue2: (%20 ? =)\r\nvalue3: £100.00\r\nvalue4: "]);
GHAssertTrue(success,@"Failed to send the correct post data");
}
@end
... ...