Added support for application/x-www-form-urlencoded form posts in ASIFormDataRequest
Showing
4 changed files
with
69 additions
and
6 deletions
| @@ -9,6 +9,12 @@ | @@ -9,6 +9,12 @@ | ||
| 9 | #import <Foundation/Foundation.h> | 9 | #import <Foundation/Foundation.h> |
| 10 | #import "ASIHTTPRequest.h" | 10 | #import "ASIHTTPRequest.h" |
| 11 | 11 | ||
| 12 | +typedef enum _ASIPostFormat { | ||
| 13 | + ASIMultipartFormDataPostFormat = 0, | ||
| 14 | + ASIURLEncodedPostFormat = 1 | ||
| 15 | + | ||
| 16 | +} ASIPostFormat; | ||
| 17 | + | ||
| 12 | @interface ASIFormDataRequest : ASIHTTPRequest { | 18 | @interface ASIFormDataRequest : ASIHTTPRequest { |
| 13 | 19 | ||
| 14 | // Parameters that will be POSTed to the url | 20 | // Parameters that will be POSTed to the url |
| @@ -17,6 +23,7 @@ | @@ -17,6 +23,7 @@ | ||
| 17 | // Files that will be POSTed to the url | 23 | // Files that will be POSTed to the url |
| 18 | NSMutableDictionary *fileData; | 24 | NSMutableDictionary *fileData; |
| 19 | 25 | ||
| 26 | + ASIPostFormat postFormat; | ||
| 20 | } | 27 | } |
| 21 | 28 | ||
| 22 | #pragma mark setup request | 29 | #pragma mark setup request |
| @@ -36,4 +43,6 @@ | @@ -36,4 +43,6 @@ | ||
| 36 | // Same as above, but you can specify the content-type and file name | 43 | // Same as above, but you can specify the content-type and file name |
| 37 | - (void)setData:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key; | 44 | - (void)setData:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key; |
| 38 | 45 | ||
| 46 | + | ||
| 47 | +@property (assign) ASIPostFormat postFormat; | ||
| 39 | @end | 48 | @end |
| @@ -11,6 +11,8 @@ | @@ -11,6 +11,8 @@ | ||
| 11 | 11 | ||
| 12 | // Private stuff | 12 | // Private stuff |
| 13 | @interface ASIFormDataRequest () | 13 | @interface ASIFormDataRequest () |
| 14 | +- (void)buildMultipartFormDataPostBody; | ||
| 15 | +- (void)buildURLEncodedPostBody; | ||
| 14 | @property (retain) NSMutableDictionary *postData; | 16 | @property (retain) NSMutableDictionary *postData; |
| 15 | @property (retain) NSMutableDictionary *fileData; | 17 | @property (retain) NSMutableDictionary *fileData; |
| 16 | @end | 18 | @end |
| @@ -21,7 +23,9 @@ | @@ -21,7 +23,9 @@ | ||
| 21 | 23 | ||
| 22 | + (id)requestWithURL:(NSURL *)newURL | 24 | + (id)requestWithURL:(NSURL *)newURL |
| 23 | { | 25 | { |
| 24 | - return [[[self alloc] initWithURL:newURL] autorelease]; | 26 | + ASIFormDataRequest *request = [[[self alloc] initWithURL:newURL] autorelease]; |
| 27 | + [request setPostFormat:ASIMultipartFormDataPostFormat]; | ||
| 28 | + return request; | ||
| 25 | } | 29 | } |
| 26 | 30 | ||
| 27 | - (void)dealloc | 31 | - (void)dealloc |
| @@ -106,8 +110,19 @@ | @@ -106,8 +110,19 @@ | ||
| 106 | if ([[self fileData] count] > 0) { | 110 | if ([[self fileData] count] > 0) { |
| 107 | [self setShouldStreamPostDataFromDisk:YES]; | 111 | [self setShouldStreamPostDataFromDisk:YES]; |
| 108 | } | 112 | } |
| 109 | - | ||
| 110 | 113 | ||
| 114 | + if ([self postFormat] == ASIURLEncodedPostFormat) { | ||
| 115 | + [self buildURLEncodedPostBody]; | ||
| 116 | + } else { | ||
| 117 | + [self buildMultipartFormDataPostBody]; | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + [super buildPostBody]; | ||
| 121 | +} | ||
| 122 | + | ||
| 123 | + | ||
| 124 | +- (void)buildMultipartFormDataPostBody | ||
| 125 | +{ | ||
| 111 | // 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. | 126 | // 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. |
| 112 | NSString *stringBoundary = @"0xKhTmLbOuNdArY"; | 127 | NSString *stringBoundary = @"0xKhTmLbOuNdArY"; |
| 113 | 128 | ||
| @@ -137,10 +152,10 @@ | @@ -137,10 +152,10 @@ | ||
| 137 | id file = [fileInfo objectForKey:@"data"]; | 152 | id file = [fileInfo objectForKey:@"data"]; |
| 138 | NSString *contentType = [fileInfo objectForKey:@"contentType"]; | 153 | NSString *contentType = [fileInfo objectForKey:@"contentType"]; |
| 139 | NSString *fileName = [fileInfo objectForKey:@"fileName"]; | 154 | NSString *fileName = [fileInfo objectForKey:@"fileName"]; |
| 140 | - | 155 | + |
| 141 | [self appendPostData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", key, fileName] dataUsingEncoding:NSUTF8StringEncoding]]; | 156 | [self appendPostData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", key, fileName] dataUsingEncoding:NSUTF8StringEncoding]]; |
| 142 | [self appendPostData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", contentType] dataUsingEncoding:NSUTF8StringEncoding]]; | 157 | [self appendPostData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", contentType] dataUsingEncoding:NSUTF8StringEncoding]]; |
| 143 | - | 158 | + |
| 144 | if ([file isKindOfClass:[NSString class]]) { | 159 | if ([file isKindOfClass:[NSString class]]) { |
| 145 | [self appendPostDataFromFile:file]; | 160 | [self appendPostDataFromFile:file]; |
| 146 | } else { | 161 | } else { |
| @@ -155,11 +170,33 @@ | @@ -155,11 +170,33 @@ | ||
| 155 | 170 | ||
| 156 | [self appendPostData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; | 171 | [self appendPostData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; |
| 157 | 172 | ||
| 158 | - [super buildPostBody]; | ||
| 159 | } | 173 | } |
| 160 | 174 | ||
| 175 | +- (void)buildURLEncodedPostBody | ||
| 176 | +{ | ||
| 177 | + // We can't post binary data using application/x-www-form-urlencoded | ||
| 178 | + if ([[self fileData] count] > 0) { | ||
| 179 | + [self setPostFormat:ASIMultipartFormDataPostFormat]; | ||
| 180 | + [self buildMultipartFormDataPostBody]; | ||
| 181 | + return; | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + [self addRequestHeader:@"Content-Type" value:@"application/x-www-form-urlencoded"]; | ||
| 185 | + | ||
| 186 | + | ||
| 187 | + NSEnumerator *e = [[self postData] keyEnumerator]; | ||
| 188 | + NSString *key; | ||
| 189 | + int i=0; | ||
| 190 | + int count = [[self postData] count]-1; | ||
| 191 | + while (key = [e nextObject]) { | ||
| 192 | + NSString *data = [NSString stringWithFormat:@"%@=%@%@",[key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],[[[self postData] objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],(i<count ? @"&" : @"")]; | ||
| 193 | + [self appendPostData:[data dataUsingEncoding:NSUTF8StringEncoding]]; | ||
| 194 | + i++; | ||
| 195 | + } | ||
| 196 | +} | ||
| 161 | 197 | ||
| 162 | -@synthesize fileData; | ||
| 163 | @synthesize postData; | 198 | @synthesize postData; |
| 199 | +@synthesize fileData; | ||
| 200 | +@synthesize postFormat; | ||
| 164 | 201 | ||
| 165 | @end | 202 | @end |
| @@ -103,6 +103,22 @@ | @@ -103,6 +103,22 @@ | ||
| 103 | GHAssertTrue(success,@"Convenience constructor failed to return an instance of the correct class"); | 103 | GHAssertTrue(success,@"Convenience constructor failed to return an instance of the correct class"); |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | +- (void)testURLEncodedPost | ||
| 107 | +{ | ||
| 108 | + ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://asi/ASIHTTPRequest/tests/url-encoded-post"]]; | ||
| 109 | + [request setPostValue:@"value1" forKey:@"value1"]; | ||
| 110 | + [request setPostValue:@"(%20 ? =)" forKey:@"value2"]; | ||
| 111 | + [request setPostValue:@"£100.00" forKey:@"value3"]; | ||
| 112 | + [request setPostValue:@"" forKey:@"value4"]; | ||
| 113 | + [request setShouldStreamPostDataFromDisk:YES]; | ||
| 114 | + [request setPostFormat:ASIURLEncodedPostFormat]; | ||
| 115 | + [request start]; | ||
| 116 | + | ||
| 117 | + | ||
| 118 | + BOOL success = ([[request responseString] isEqualToString:@"value1: value1\r\nvalue2: (%20 ? =)\r\nvalue3: £100.00\r\nvalue4: "]); | ||
| 119 | + GHAssertTrue(success,@"Failed to send the correct post data"); | ||
| 120 | +} | ||
| 121 | + | ||
| 106 | 122 | ||
| 107 | 123 | ||
| 108 | @end | 124 | @end |
-
Please register or login to post a comment