Browse files

Merge branch 'gzip-compression-experimental' into experimental-gcd-pr…

…ocessing

Conflicts:
	AFNetworking/AFHTTPRequestOperation.m
	AFNetworking/AFImageRequestOperation.m
	AFNetworking/AFJSONRequestOperation.m
  • Loading branch information...
2 parents a2138c6 + 48be808 commit 390c51a30de398f57415136259746c0ec9c70536 @mattt mattt committed Aug 14, 2011
View
6 AFNetworking/AFHTTPRequestOperation.h
@@ -35,6 +35,7 @@ extern NSString * const AFHTTPOperationDidFinishNotification;
NSData *_responseBody;
NSMutableData *_dataAccumulator;
+ NSOutputStream *_outputStream;
}
@property (nonatomic, retain) NSURLConnection *connection;
@@ -50,7 +51,10 @@ extern NSString * const AFHTTPOperationDidFinishNotification;
+ (id)operationWithRequest:(NSURLRequest *)urlRequest
completion:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSData *data, NSError *error))completion;
-- (id)initWithRequest:(NSURLRequest *)urlRequest;
++ (id)operationWithRequest:(NSURLRequest *)urlRequest
+ inputStream:(NSInputStream *)inputStream
+ outputStream:(NSOutputStream *)outputStream
+ completion:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))completion;
- (void)setProgressBlock:(void (^)(NSUInteger totalBytesWritten, NSUInteger totalBytesExpectedToWrite))block;
View
69 AFNetworking/AFHTTPRequestOperation.m
@@ -80,9 +80,11 @@ @interface AFHTTPRequestOperation ()
@property (nonatomic, assign) AFHTTPOperationState state;
@property (nonatomic, assign) BOOL isCancelled;
@property (readwrite, nonatomic, retain) NSMutableData *dataAccumulator;
+@property (readwrite, nonatomic, retain) NSOutputStream *outputStream;
@property (readwrite, nonatomic, copy) AFHTTPRequestOperationProgressBlock progress;
@property (readwrite, nonatomic, copy) AFHTTPRequestOperationCompletionBlock completion;
+- (id)initWithRequest:(NSURLRequest *)urlRequest;
- (void)cleanup;
@end
@@ -96,6 +98,7 @@ @implementation AFHTTPRequestOperation
@synthesize error = _error;
@synthesize responseBody = _responseBody;
@synthesize dataAccumulator = _dataAccumulator;
+@synthesize outputStream = _outputStream;
@synthesize progress = _progress;
@synthesize completion = _completion;
@@ -108,6 +111,26 @@ + (id)operationWithRequest:(NSURLRequest *)urlRequest
return operation;
}
++ (id)operationWithRequest:(NSURLRequest *)urlRequest
+ inputStream:(NSInputStream *)inputStream
+ outputStream:(NSOutputStream *)outputStream
+ completion:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))completion
+{
+ NSMutableURLRequest *mutableURLRequest = [[urlRequest mutableCopy] autorelease];
+ [mutableURLRequest setHTTPBodyStream:inputStream];
+ if ([[mutableURLRequest HTTPMethod] isEqualToString:@"GET"]) {
+ [mutableURLRequest setHTTPMethod:@"POST"];
+ }
+
+ AFHTTPRequestOperation *operation = [self operationWithRequest:mutableURLRequest completion:^(NSURLRequest *request, NSHTTPURLResponse *response, NSData *data, NSError *error) {
+ if (completion) {
+ completion(request, response, error);
+ }
+ }];
+
+ return operation;
+}
+
- (id)initWithRequest:(NSURLRequest *)urlRequest {
self = [super init];
if (!self) {
@@ -130,17 +153,21 @@ - (void)dealloc {
[_response release];
[_responseBody release];
[_dataAccumulator release];
+ [_outputStream release]; _outputStream = nil;
- [_connection release];
+ [_connection release]; _connection = nil;
[_progress release];
[_completion release];
+ [_progress release];
[super dealloc];
}
- (void)cleanup {
+ [self.outputStream close];
for (NSString *runLoopMode in self.runLoopModes) {
[self.connection unscheduleFromRunLoop:[NSRunLoop currentRunLoop] forMode:runLoopMode];
+ [self.outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:runLoopMode];
}
CFRunLoopStop([[NSRunLoop currentRunLoop] getCFRunLoop]);
}
@@ -212,6 +239,7 @@ - (void)start {
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
for (NSString *runLoopMode in self.runLoopModes) {
[self.connection scheduleInRunLoop:runLoop forMode:runLoopMode];
+ [self.outputStream scheduleInRunLoop:runLoop forMode:runLoopMode];
}
[self.connection start];
@@ -241,27 +269,48 @@ - (void)finish {
#pragma mark - NSURLConnection
-- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
+- (void)connection:(NSURLConnection *)connection
+didReceiveResponse:(NSURLResponse *)response
+{
self.response = (NSHTTPURLResponse *)response;
- NSUInteger contentLength = MIN(MAX(abs(response.expectedContentLength), 1024), 1024 * 1024 * 8);
-
- self.dataAccumulator = [NSMutableData dataWithCapacity:contentLength];
+
+ if (self.outputStream) {
+ [self.outputStream open];
+ } else {
+ NSUInteger contentLength = MIN(MAX(abs(response.expectedContentLength), 1024), 1024 * 1024 * 8);
+ self.dataAccumulator = [NSMutableData dataWithCapacity:contentLength];
+ }
}
-- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
- [self.dataAccumulator appendData:data];
+- (void)connection:(NSURLConnection *)connection
+ didReceiveData:(NSData *)data
+{
+ if (self.outputStream) {
+ if ([self.outputStream hasSpaceAvailable]) {
+ const uint8_t *dataBuffer = [data bytes];
+ [self.outputStream write:&dataBuffer[0] maxLength:[data length]];
+ }
+ } else {
+ [self.dataAccumulator appendData:data];
+ }
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
self.state = AFHTTPOperationFinishedState;
- self.responseBody = [NSData dataWithData:self.dataAccumulator];
- self.dataAccumulator = nil;
+ if (self.outputStream) {
+ [self.outputStream close];
+ } else {
+ self.responseBody = [NSData dataWithData:self.dataAccumulator];
+ [_dataAccumulator release]; _dataAccumulator = nil;
+ }
[self performSelectorOnMainThread:@selector(finish) withObject:nil waitUntilDone:NO];
}
-- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
+- (void)connection:(NSURLConnection *)connection
+ didFailWithError:(NSError *)error
+{
self.state = AFHTTPOperationFinishedState;
self.error = error;
View
6 AFNetworking/AFImageRequestOperation.m
@@ -55,7 +55,7 @@ + (id)operationWithRequest:(NSURLRequest *)urlRequest
options:(AFImageRequestOptions)options
success:(void (^)(UIImage *image))success
{
- return [self operationWithRequest:urlRequest completion:^(NSURLRequest *request, NSHTTPURLResponse *response, NSData *data, NSError *error) {
+ AFImageRequestOperation *operation = [self operationWithRequest:urlRequest completion:^(NSURLRequest *request, NSHTTPURLResponse *response, NSData *data, NSError *error) {
dispatch_async(image_request_operation_processing_queue(), ^(void) {
UIImage *image = nil;
if ([[UIScreen mainScreen] scale] == 2.0) {
@@ -81,6 +81,10 @@ + (id)operationWithRequest:(NSURLRequest *)urlRequest
[[AFImageCache sharedImageCache] cacheImage:image forRequest:request imageSize:imageSize options:options];
});
}];
+
+ operation.runLoopModes = [NSSet setWithObject:NSRunLoopCommonModes];
+
+ return operation;
}
@end
View
4 AFNetworking/AFJSONRequestOperation.h
@@ -34,8 +34,8 @@
+ (id)operationWithRequest:(NSURLRequest *)urlRequest
acceptableStatusCodes:(NSIndexSet *)acceptableStatusCodes
acceptableContentTypes:(NSSet *)acceptableContentTypes
- success:(void (^)(id JSON))success
- failure:(void (^)(NSError *error))failure;
+ success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, id JSON))success
+ failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure;
+ (NSIndexSet *)defaultAcceptableStatusCodes;
+ (NSSet *)defaultAcceptableContentTypes;
View
20 AFNetworking/AFJSONRequestOperation.m
@@ -46,14 +46,22 @@ + (id)operationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(id JSON))success
failure:(void (^)(NSError *error))failure
{
- return [self operationWithRequest:urlRequest acceptableStatusCodes:[self defaultAcceptableStatusCodes] acceptableContentTypes:[self defaultAcceptableContentTypes] success:success failure:failure];
+ return [self operationWithRequest:urlRequest acceptableStatusCodes:[self defaultAcceptableStatusCodes] acceptableContentTypes:[self defaultAcceptableContentTypes] success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
+ if (success) {
+ success(JSON);
+ }
+ } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
+ if (failure) {
+ failure(error);
+ }
+ }];
}
+ (id)operationWithRequest:(NSURLRequest *)urlRequest
acceptableStatusCodes:(NSIndexSet *)acceptableStatusCodes
acceptableContentTypes:(NSSet *)acceptableContentTypes
- success:(void (^)(id JSON))success
- failure:(void (^)(NSError *error))failure
+ success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, id JSON))success
+ failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure
{
return [self operationWithRequest:urlRequest completion:^(NSURLRequest *request, NSHTTPURLResponse *response, NSData *data, NSError *error) {
BOOL statusCodeAcceptable = [acceptableStatusCodes containsIndex:[response statusCode]];
@@ -68,7 +76,7 @@ + (id)operationWithRequest:(NSURLRequest *)urlRequest
if (error) {
if (failure) {
- failure(error);
+ failure(request, response, error);
}
} else {
dispatch_async(json_request_operation_processing_queue(), ^(void) {
@@ -87,11 +95,11 @@ + (id)operationWithRequest:(NSURLRequest *)urlRequest
dispatch_sync(dispatch_get_main_queue(), ^(void) {
if (JSONError) {
if (failure) {
- failure(JSONError);
+ failure(request, response, JSONError);
}
} else {
if (success) {
- success(JSON);
+ success(request, response, JSON);
}
}
});
View
54 AFNetworking/AFRestClient.h
@@ -23,6 +23,9 @@
#import <Foundation/Foundation.h>
#import "AFHTTPRequestOperation.h"
+#import "NSMutableURLRequest+AFNetworking.h"
+#import "NSString+AFNetworking.h"
+
@protocol AFRestClient <NSObject>
+ (NSURL *)baseURL;
@end
@@ -38,25 +41,46 @@
- (void)setAuthorizationHeaderWithToken:(NSString *)token;
- (void)clearAuthorizationHeader;
-- (NSMutableURLRequest *)requestWithMethod:(NSString *)method path:(NSString *)path parameters:(NSDictionary *)parameters;
-- (void)enqueueHTTPOperationWithRequest:(NSURLRequest *)request success:(void (^)(id response))success failure:(void (^)(NSError *error))failure;
+- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
+ path:(NSString *)path parameters:(NSDictionary *)parameters;
-- (void)getPath:(NSString *)path parameters:(NSDictionary *)parameters success:(void (^)(id response))success;
-- (void)getPath:(NSString *)path parameters:(NSDictionary *)parameters success:(void (^)(id response))success failure:(void (^)(NSError *error))failure;
+- (void)enqueueHTTPOperationWithRequest:(NSURLRequest *)request
+ success:(void (^)(id response))success
+ failure:(void (^)(NSError *error))failure;
-- (void)postPath:(NSString *)path parameters:(NSDictionary *)parameters success:(void (^)(id response))success;
-- (void)postPath:(NSString *)path parameters:(NSDictionary *)parameters success:(void (^)(id response))success failure:(void (^)(NSError *error))failure;
+- (void)getPath:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ success:(void (^)(id response))success;
-- (void)putPath:(NSString *)path parameters:(NSDictionary *)parameters success:(void (^)(id response))success;
-- (void)putPath:(NSString *)path parameters:(NSDictionary *)parameters success:(void (^)(id response))success failure:(void (^)(NSError *error))failure;
+- (void)getPath:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ success:(void (^)(id response))success
+ failure:(void (^)(NSError *error))failure;
-- (void)deletePath:(NSString *)path parameters:(NSDictionary *)parameters success:(void (^)(id response))success;
-- (void)deletePath:(NSString *)path parameters:(NSDictionary *)parameters success:(void (^)(id response))success failure:(void (^)(NSError *error))failure;
-@end
+- (void)postPath:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ success:(void (^)(id response))success;
+
+- (void)postPath:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ success:(void (^)(id response))success
+ failure:(void (^)(NSError *error))failure;
+
+- (void)putPath:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ success:(void (^)(id response))success;
+
+- (void)putPath:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ success:(void (^)(id response))success
+ failure:(void (^)(NSError *error))failure;
-#pragma mark - NSString + AFRestClient
+- (void)deletePath:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ success:(void (^)(id response))success;
-@interface NSString (AFRestClient)
-- (NSString *)urlEncodedString;
-- (NSString *)urlEncodedStringWithEncoding:(NSStringEncoding)encoding;
+- (void)deletePath:(NSString *)path
+ parameters:(NSDictionary *)parameters
+ success:(void (^)(id response))success
+ failure:(void (^)(NSError *error))failure;
@end
View
23 AFNetworking/AFRestClient.m
@@ -28,8 +28,6 @@
@interface AFRestClient ()
@property (readwrite, nonatomic, retain) NSMutableDictionary *defaultHeaders;
@property (readwrite, nonatomic, retain) NSOperationQueue *operationQueue;
-
-- (void)enqueueHTTPOperationWithRequest:(NSURLRequest *)request success:(void (^)(id response))success failure:(void (^)(NSError *error))failure;
@end
@implementation AFRestClient
@@ -174,24 +172,3 @@ - (void)deletePath:(NSString *)path parameters:(NSDictionary *)parameters succes
}
@end
-
-#pragma mark - NSString + AFRestClient
-
-@implementation NSString (AFRestClient)
-
-// See http://github.com/pokeb/asi-http-request/raw/master/Classes/ASIFormDataRequest.m
-- (NSString*)urlEncodedString {
- return [self urlEncodedStringWithEncoding:NSUTF8StringEncoding];
-}
-
-- (NSString *)urlEncodedStringWithEncoding:(NSStringEncoding)encoding {
- NSString *newString = [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self, NULL, CFSTR(":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`"), CFStringConvertNSStringEncodingToEncoding(encoding)) autorelease];
-
- if (newString) {
- return newString;
- }
-
- return @"";
-}
-
-@end
View
32 AFNetworking/NSData+AFNetworking.h
@@ -0,0 +1,32 @@
+// NSData+AFNetworking.h
+//
+// Copyright (c) 2011 Gowalla (http://gowalla.com/)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import <Foundation/Foundation.h>
+
+extern NSString * const kAFZlibErrorDomain;
+
+@interface NSData (AFNetworking)
+
+- (NSData *)dataByGZipCompressingWithError:(NSError **)error;
+- (NSData *)dataByGZipDecompressingDataWithError:(NSError **)error;
+
+@end
View
99 AFNetworking/NSData+AFNetworking.m
@@ -0,0 +1,99 @@
+// NSData+AFNetworking.m
+//
+// Copyright (c) 2011 Gowalla (http://gowalla.com/)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import "NSData+AFNetworking.h"
+#import <zlib.h>
+
+NSString * const kAFZlibErrorDomain = @"com.alamofire.zlib.error";
+
+static inline NSUInteger NSDataEstimatedCompressedLength(NSData *data) {
+ return [data length] / 2;
+}
+
+typedef enum {
+ GzipDeflate = -1,
+ GzipInflate = 1,
+} GzipOperation;
+
+@interface NSData (_AFNetworking)
++ (NSData *)dataByTransformingData:(NSData *)data
+ usingGZipOperation:(GzipOperation)operation
+ error:(NSError **)error;
+@end
+
+@implementation NSData (_AFNetworking)
+
++ (NSData *)dataByTransformingData:(NSData *)data
+ usingGZipOperation:(GzipOperation)operation
+ error:(NSError **)error
+{
+ z_stream zStream;
+
+ NSUInteger estimatedLength = NSDataEstimatedCompressedLength(data);
+ NSMutableData *mutableData = [NSMutableData dataWithLength:estimatedLength];
+
+ int status;
+ zStream.next_in = (Bytef *)[data bytes];
+ zStream.avail_in = (unsigned int)[data length];
+ zStream.avail_out = 0;
+
+ NSInteger bytesProcessedAlready = zStream.total_out;
+ while (zStream.avail_out == 0) {
+ if (zStream.total_out - bytesProcessedAlready >= [mutableData length]) {
+ [mutableData increaseLengthBy:estimatedLength / 2];
+ }
+
+ zStream.next_out = [mutableData mutableBytes] + zStream.total_out-bytesProcessedAlready;
+ zStream.avail_out = (unsigned int)([mutableData length] - (zStream.total_out-bytesProcessedAlready));
+ status = deflate(&zStream, Z_FINISH);
+
+ if (status == Z_STREAM_END) {
+ break;
+ } else if (status != Z_OK) {
+ if (error) {
+ *error = [NSError errorWithDomain:kAFZlibErrorDomain code:status userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Compression of data failed with code %hi", status] forKey:NSLocalizedDescriptionKey]];
+ }
+
+ return nil;
+ }
+ }
+
+ [mutableData setLength:zStream.total_out - bytesProcessedAlready];
+
+ return mutableData;
+}
+
+@end
+
+#pragma mark -
+
+@implementation NSData (AFNetworking)
+
+- (NSData *)dataByGZipCompressingWithError:(NSError **)error {
+ return [NSData dataByTransformingData:self usingGZipOperation:GzipDeflate error:error];
+}
+
+- (NSData *)dataByGZipDecompressingDataWithError:(NSError **)error {
+ return [NSData dataByTransformingData:self usingGZipOperation:GzipInflate error:error];
+}
+
+@end
View
33 AFNetworking/NSMutableURLRequest+AFNetworking.h
@@ -0,0 +1,33 @@
+// NSMutableURLRequest+AFNetworking.h
+//
+// Copyright (c) 2011 Gowalla (http://gowalla.com/)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import <Foundation/Foundation.h>
+
+@interface NSMutableURLRequest (AFNetworking)
+
+- (void)setHTTPBodyWithData:(NSData *)data
+ mimeType:(NSString *)mimeType
+ forParameterNamed:(NSString *)parameterName
+ parameters:(NSDictionary *)parameters
+ useGzipCompression:(BOOL)useGzipCompression;
+
+@end
View
76 AFNetworking/NSMutableURLRequest+AFNetworking.m
@@ -0,0 +1,76 @@
+// NSMutableURLRequest+AFNetworking.m
+//
+// Copyright (c) 2011 Gowalla (http://gowalla.com/)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import "NSMutableURLRequest+AFNetworking.h"
+#import "NSData+AFNetworking.h"
+
+@implementation NSMutableURLRequest (AFNetworking)
+
+- (void)setHTTPBodyWithData:(NSData *)data
+ mimeType:(NSString *)mimeType
+ forParameterNamed:(NSString *)parameterName
+ parameters:(NSDictionary *)parameters
+ useGzipCompression:(BOOL)useGzipCompression
+{
+ if ([[self HTTPMethod] isEqualToString:@"GET"]) {
+ [self setHTTPMethod:@"POST"];
+ }
+
+ NSString *filename = [[NSString stringWithFormat:@"%d", [[NSDate date] hash]] stringByAppendingPathExtension:[mimeType lastPathComponent]];
+
+ static NSString * const boundary = @"----Boundary+0xAbCdEfGbOuNdArY";
+ [self setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary] forHTTPHeaderField:@"Content-Type"];
+
+ NSMutableData *mutableData = [NSMutableData data];
+ [mutableData appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
+
+ id key;
+ NSEnumerator *enumerator = [parameters keyEnumerator];
+ while ((key = [enumerator nextObject])) {
+ [mutableData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
+ [mutableData appendData:[[NSString stringWithFormat:@"%@", [parameters valueForKey:key]] dataUsingEncoding:NSUTF8StringEncoding]];
+ [mutableData appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
+ }
+
+ [mutableData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"", parameterName, filename, nil] dataUsingEncoding:NSUTF8StringEncoding]];
+ [mutableData appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
+ [mutableData appendData:[[NSString stringWithFormat:@"Content-Type: %@", mimeType] dataUsingEncoding:NSUTF8StringEncoding]];
+ [mutableData appendData:[@"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
+ [mutableData appendData:data];
+ [mutableData appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
+
+ if (useGzipCompression) {
+ NSError *error = nil;
+ NSData *compressedData = [mutableData dataByGZipCompressingWithError:&error];
+
+ if (!error && compressedData) {
+ [self setHTTPBody:compressedData];
+
+ // Content-Encoding HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11
+ [self setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"];
+ }
+ } else {
+ [self setHTTPBody:mutableData];
+ }
+}
+
+@end
View
30 AFNetworking/NSString+AFNetworking.h
@@ -0,0 +1,30 @@
+// NSString+AFNetworking.h
+//
+// Copyright (c) 2011 Gowalla (http://gowalla.com/)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import <Foundation/Foundation.h>
+
+@interface NSString (AFNetworking)
+
+- (NSString *)urlEncodedString;
+- (NSString *)urlEncodedStringWithEncoding:(NSStringEncoding)encoding;
+
+@end
View
38 AFNetworking/NSString+AFNetworking.m
@@ -0,0 +1,38 @@
+// NSString+AFNetworking.m
+//
+// Copyright (c) 2011 Gowalla (http://gowalla.com/)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import "NSString+AFNetworking.h"
+
+@implementation NSString (AFNetworking)
+
+- (NSString*)urlEncodedString {
+ return [self urlEncodedStringWithEncoding:NSUTF8StringEncoding];
+}
+
+// See http://github.com/pokeb/asi-http-request/raw/master/Classes/ASIFormDataRequest.m
+- (NSString *)urlEncodedStringWithEncoding:(NSStringEncoding)encoding {
+ NSString *urlEncodedString = [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self, NULL, (CFStringRef)@":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`", CFStringConvertNSStringEncodingToEncoding(encoding)) autorelease];
+
+ return urlEncodedString ? urlEncodedString : @"";
+}
+
+@end
View
38 Example/AFNetworking Example.xcodeproj/project.pbxproj
@@ -7,6 +7,10 @@
objects = {
/* Begin PBXBuildFile section */
+ F85CE2D413EC478F00BFAE01 /* NSString+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = F85CE2D313EC478F00BFAE01 /* NSString+AFNetworking.m */; };
+ F85CE2DC13EC4A4200BFAE01 /* NSMutableURLRequest+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = F85CE2DB13EC4A4200BFAE01 /* NSMutableURLRequest+AFNetworking.m */; };
+ F85CE55513EC759200BFAE01 /* NSData+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = F85CE55413EC759200BFAE01 /* NSData+AFNetworking.m */; };
+ F85CE55B13EC771100BFAE01 /* libz.1.2.5.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F85CE55A13EC771100BFAE01 /* libz.1.2.5.dylib */; settings = {ATTRIBUTES = (Weak, ); }; };
F874B5D913E0AA6500B28E3E /* AFHTTPRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F874B5C913E0AA6500B28E3E /* AFHTTPRequestOperation.m */; };
F874B5DA13E0AA6500B28E3E /* AFImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = F874B5CA13E0AA6500B28E3E /* AFImageCache.m */; };
F874B5DB13E0AA6500B28E3E /* AFImageRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F874B5CB13E0AA6500B28E3E /* AFImageRequestOperation.m */; };
@@ -32,6 +36,13 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
+ F85CE2D213EC478F00BFAE01 /* NSString+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSString+AFNetworking.h"; path = "../AFNetworking/NSString+AFNetworking.h"; sourceTree = "<group>"; };
+ F85CE2D313EC478F00BFAE01 /* NSString+AFNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSString+AFNetworking.m"; path = "../AFNetworking/NSString+AFNetworking.m"; sourceTree = "<group>"; };
+ F85CE2DA13EC4A4200BFAE01 /* NSMutableURLRequest+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSMutableURLRequest+AFNetworking.h"; path = "../AFNetworking/NSMutableURLRequest+AFNetworking.h"; sourceTree = "<group>"; };
+ F85CE2DB13EC4A4200BFAE01 /* NSMutableURLRequest+AFNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSMutableURLRequest+AFNetworking.m"; path = "../AFNetworking/NSMutableURLRequest+AFNetworking.m"; sourceTree = "<group>"; };
+ F85CE55313EC759100BFAE01 /* NSData+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSData+AFNetworking.h"; path = "../AFNetworking/NSData+AFNetworking.h"; sourceTree = "<group>"; };
+ F85CE55413EC759200BFAE01 /* NSData+AFNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSData+AFNetworking.m"; path = "../AFNetworking/NSData+AFNetworking.m"; sourceTree = "<group>"; };
+ F85CE55A13EC771100BFAE01 /* libz.1.2.5.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.1.2.5.dylib; path = usr/lib/libz.1.2.5.dylib; sourceTree = SDKROOT; };
F874B5C913E0AA6500B28E3E /* AFHTTPRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFHTTPRequestOperation.m; path = ../AFNetworking/AFHTTPRequestOperation.m; sourceTree = "<group>"; };
F874B5CA13E0AA6500B28E3E /* AFImageCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFImageCache.m; path = ../AFNetworking/AFImageCache.m; sourceTree = "<group>"; };
F874B5CB13E0AA6500B28E3E /* AFImageRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFImageRequestOperation.m; path = ../AFNetworking/AFImageRequestOperation.m; sourceTree = "<group>"; };
@@ -82,6 +93,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ F85CE55B13EC771100BFAE01 /* libz.1.2.5.dylib in Frameworks */,
F8E469651395739D00DB05C8 /* UIKit.framework in Frameworks */,
F8E469671395739D00DB05C8 /* Foundation.framework in Frameworks */,
F8E469691395739D00DB05C8 /* CoreGraphics.framework in Frameworks */,
@@ -92,6 +104,23 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ F85CE2D613EC47BC00BFAE01 /* Categories */ = {
+ isa = PBXGroup;
+ children = (
+ F85CE2DA13EC4A4200BFAE01 /* NSMutableURLRequest+AFNetworking.h */,
+ F85CE2DB13EC4A4200BFAE01 /* NSMutableURLRequest+AFNetworking.m */,
+ F85CE2D213EC478F00BFAE01 /* NSString+AFNetworking.h */,
+ F85CE2D313EC478F00BFAE01 /* NSString+AFNetworking.m */,
+ F874B5D713E0AA6500B28E3E /* UIImage+AFNetworking.h */,
+ F874B5CF13E0AA6500B28E3E /* UIImage+AFNetworking.m */,
+ F874B5D813E0AA6500B28E3E /* UIImageView+AFNetworking.h */,
+ F874B5D013E0AA6500B28E3E /* UIImageView+AFNetworking.m */,
+ F85CE55313EC759100BFAE01 /* NSData+AFNetworking.h */,
+ F85CE55413EC759200BFAE01 /* NSData+AFNetworking.m */,
+ );
+ name = Categories;
+ sourceTree = "<group>";
+ };
F8D25D0F1396A9C400CF3BD6 /* JSONKit */ = {
isa = PBXGroup;
children = (
@@ -165,6 +194,7 @@
F8E469631395739D00DB05C8 /* Frameworks */ = {
isa = PBXGroup;
children = (
+ F85CE55A13EC771100BFAE01 /* libz.1.2.5.dylib */,
F8E469E413957E0400DB05C8 /* SystemConfiguration.framework */,
F8E469E213957DF700DB05C8 /* SystemConfiguration.framework */,
F8E469E013957DF100DB05C8 /* Security.framework */,
@@ -223,12 +253,9 @@
F874B5CB13E0AA6500B28E3E /* AFImageRequestOperation.m */,
F874B5D213E0AA6500B28E3E /* AFImageCache.h */,
F874B5CA13E0AA6500B28E3E /* AFImageCache.m */,
- F874B5D713E0AA6500B28E3E /* UIImage+AFNetworking.h */,
- F874B5CF13E0AA6500B28E3E /* UIImage+AFNetworking.m */,
- F874B5D813E0AA6500B28E3E /* UIImageView+AFNetworking.h */,
- F874B5D013E0AA6500B28E3E /* UIImageView+AFNetworking.m */,
F874B5D513E0AA6500B28E3E /* AFNetworkActivityIndicatorManager.h */,
F874B5CD13E0AA6500B28E3E /* AFNetworkActivityIndicatorManager.m */,
+ F85CE2D613EC47BC00BFAE01 /* Categories */,
);
name = AFNetworking;
sourceTree = "<group>";
@@ -331,6 +358,9 @@
F874B5DE13E0AA6500B28E3E /* AFRestClient.m in Sources */,
F874B5DF13E0AA6500B28E3E /* UIImage+AFNetworking.m in Sources */,
F874B5E013E0AA6500B28E3E /* UIImageView+AFNetworking.m in Sources */,
+ F85CE2D413EC478F00BFAE01 /* NSString+AFNetworking.m in Sources */,
+ F85CE2DC13EC4A4200BFAE01 /* NSMutableURLRequest+AFNetworking.m in Sources */,
+ F85CE55513EC759200BFAE01 /* NSData+AFNetworking.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
7 Example/AFNetworking Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Workspace
- version = "1.0">
- <FileRef
- location = "self:AFNetworkingExample.xcodeproj">
- </FileRef>
-</Workspace>
View
17,655 ...xcodeproj/project.xcworkspace/xcuserdata/mattt.xcuserdatad/UserInterfaceState.xcuserstate
0 additions, 17,655 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
10 ...e.xcodeproj/project.xcworkspace/xcuserdata/mattt.xcuserdatad/WorkspaceSettings.xcsettings
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>IDEWorkspaceUserSettings_HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
- <true/>
- <key>IDEWorkspaceUserSettings_SnapshotAutomaticallyBeforeSignificantChanges</key>
- <false/>
-</dict>
-</plist>

0 comments on commit 390c51a

Please sign in to comment.