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