diff --git a/Marshmallows.xcodeproj/project.pbxproj b/Marshmallows.xcodeproj/project.pbxproj index 4ab6030..6547281 100644 --- a/Marshmallows.xcodeproj/project.pbxproj +++ b/Marshmallows.xcodeproj/project.pbxproj @@ -7,8 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 7BD1009D1413375B00A9921B /* RegexKitLite.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BD1009B1413375B00A9921B /* RegexKitLite.h */; }; - 7BD1009E1413375B00A9921B /* RegexKitLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BD1009C1413375B00A9921B /* RegexKitLite.m */; }; 7BD100A2141341EB00A9921B /* MMHTTPClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BD100A0141341EB00A9921B /* MMHTTPClient.h */; }; 7BD100A3141341EB00A9921B /* MMHTTPClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BD100A1141341EB00A9921B /* MMHTTPClient.m */; }; 7BD100A614134FBE00A9921B /* MMHTTPRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BD100A414134FBE00A9921B /* MMHTTPRequest.h */; }; @@ -21,8 +19,6 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 7BD1009B1413375B00A9921B /* RegexKitLite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegexKitLite.h; sourceTree = ""; }; - 7BD1009C1413375B00A9921B /* RegexKitLite.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RegexKitLite.m; sourceTree = ""; }; 7BD100A0141341EB00A9921B /* MMHTTPClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMHTTPClient.h; sourceTree = ""; }; 7BD100A1141341EB00A9921B /* MMHTTPClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMHTTPClient.m; sourceTree = ""; }; 7BD100A414134FBE00A9921B /* MMHTTPRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMHTTPRequest.h; sourceTree = ""; }; @@ -49,20 +45,10 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 7BD1009F1413396F00A9921B /* RegexKitLite */ = { - isa = PBXGroup; - children = ( - 7BD1009B1413375B00A9921B /* RegexKitLite.h */, - 7BD1009C1413375B00A9921B /* RegexKitLite.m */, - ); - name = RegexKitLite; - sourceTree = ""; - }; 7BE32CFB14132EE3008F2DEA = { isa = PBXGroup; children = ( 7BE32D0B14132EE4008F2DEA /* Marshmallows */, - 7BD1009F1413396F00A9921B /* RegexKitLite */, 7BE32D0814132EE4008F2DEA /* Frameworks */, 7BE32D0714132EE4008F2DEA /* Products */, ); @@ -117,7 +103,6 @@ buildActionMask = 2147483647; files = ( 7BE32D6A14133618008F2DEA /* NSString+sanity.h in Headers */, - 7BD1009D1413375B00A9921B /* RegexKitLite.h in Headers */, 7BD100A2141341EB00A9921B /* MMHTTPClient.h in Headers */, 7BD100A614134FBE00A9921B /* MMHTTPRequest.h in Headers */, 7BD100AA141353B700A9921B /* NSDate+relative.h in Headers */, @@ -175,7 +160,6 @@ buildActionMask = 2147483647; files = ( 7BE32D6B14133618008F2DEA /* NSString+sanity.m in Sources */, - 7BD1009E1413375B00A9921B /* RegexKitLite.m in Sources */, 7BD100A3141341EB00A9921B /* MMHTTPClient.m in Sources */, 7BD100A714134FBE00A9921B /* MMHTTPRequest.m in Sources */, 7BD100AB141353B700A9921B /* NSDate+relative.m in Sources */, diff --git a/Marshmallows/MMHTTPClient.h b/Marshmallows/MMHTTPClient.h index bee7446..90ea68d 100644 --- a/Marshmallows/MMHTTPClient.h +++ b/Marshmallows/MMHTTPClient.h @@ -7,22 +7,10 @@ // #import - -#define MMHTTPClientStatusError -1 -#define MMHTTPClientDefaultTimeout 120 - -typedef void (^MMHTTPClientCallback)(NSInteger status, id data); -typedef void (^MMHTTPClientTextCallback)(NSInteger status, NSString *text); -typedef void (^MMHTTPClientImageCallback)(NSInteger status, UIImage *image); +#import "MMHTTPRequest.h" @interface MMHTTPClient : NSObject { - NSMutableDictionary *_callbacks; - NSMutableDictionary *_connections; - NSMutableDictionary *_data; - NSMutableDictionary *_headers; - NSMutableDictionary *_statusCodes; - NSMutableDictionary *_types; NSString *_baseURL; NSUInteger _timeout; } @@ -35,14 +23,14 @@ typedef void (^MMHTTPClientImageCallback)(NSInteger status, UIImage *image); + (NSString *) pathFor: (NSString *)first, ... NS_REQUIRES_NIL_TERMINATION; + (NSString *) urlFor: (NSString *)first, ... NS_REQUIRES_NIL_TERMINATION; + (NSString *) urlWithPath: (NSString *)path; -+ (void) request: (NSDictionary *)options then: (MMHTTPClientCallback)callback; -+ (void) get: (NSString *)url then: (MMHTTPClientCallback)callback; -+ (void) getImage: (NSString *)url then: (MMHTTPClientImageCallback)callback; -+ (void) getText: (NSString *)url then: (MMHTTPClientTextCallback)callback; -+ (void) post: (NSString *)url then: (MMHTTPClientCallback)callback; -+ (void) post: (NSString *)url data: (NSData *)data then: (MMHTTPClientCallback)callback; -+ (void) put: (NSString *)url data: (NSData *)data then: (MMHTTPClientCallback)callback; -+ (void) delete: (NSString *)url then: (MMHTTPClientCallback)callback; ++ (MMHTTPRequest *) request: (NSDictionary *)options then: (MMHTTPCallback)callback; ++ (MMHTTPRequest *) get: (NSString *)url then: (MMHTTPCallback)callback; ++ (MMHTTPRequest *) getImage: (NSString *)url then: (MMHTTPImageCallback)callback; ++ (MMHTTPRequest *) getText: (NSString *)url then: (MMHTTPTextCallback)callback; ++ (MMHTTPRequest *) post: (NSString *)url then: (MMHTTPCallback)callback; ++ (MMHTTPRequest *) post: (NSString *)url data: (NSData *)data then: (MMHTTPCallback)callback; ++ (MMHTTPRequest *) put: (NSString *)url data: (NSData *)data then: (MMHTTPCallback)callback; ++ (MMHTTPRequest *) delete: (NSString *)url then: (MMHTTPCallback)callback; @property (nonatomic, retain) NSString *baseURL; @property NSUInteger timeout; @@ -52,13 +40,13 @@ typedef void (^MMHTTPClientImageCallback)(NSInteger status, UIImage *image); - (NSString *) pathFor: (NSString *)first, ... NS_REQUIRES_NIL_TERMINATION; - (NSString *) urlFor: (NSString *)first, ... NS_REQUIRES_NIL_TERMINATION; - (NSString *) urlWithPath: (NSString *)path; -- (void) request: (NSDictionary *)options then: (MMHTTPClientCallback)callback; -- (void) get: (NSString *)url then: (MMHTTPClientCallback)callback; -- (void) getImage: (NSString *)url then: (MMHTTPClientImageCallback)callback; -- (void) getText: (NSString *)url then: (MMHTTPClientTextCallback)callback; -- (void) post: (NSString *)url then: (MMHTTPClientCallback)callback; -- (void) post: (NSString *)url data: (NSData *)data then: (MMHTTPClientCallback)callback; -- (void) put: (NSString *)url data: (NSData *)data then: (MMHTTPClientCallback)callback; -- (void) delete: (NSString *)url then: (MMHTTPClientCallback)callback; +- (MMHTTPRequest *) request: (NSDictionary *)options then: (MMHTTPCallback)callback; +- (MMHTTPRequest *) get: (NSString *)url then: (MMHTTPCallback)callback; +- (MMHTTPRequest *) getImage: (NSString *)url then: (MMHTTPImageCallback)callback; +- (MMHTTPRequest *) getText: (NSString *)url then: (MMHTTPTextCallback)callback; +- (MMHTTPRequest *) post: (NSString *)url then: (MMHTTPCallback)callback; +- (MMHTTPRequest *) post: (NSString *)url data: (NSData *)data then: (MMHTTPCallback)callback; +- (MMHTTPRequest *) put: (NSString *)url data: (NSData *)data then: (MMHTTPCallback)callback; +- (MMHTTPRequest *) delete: (NSString *)url then: (MMHTTPCallback)callback; @end diff --git a/Marshmallows/MMHTTPClient.m b/Marshmallows/MMHTTPClient.m index 498b404..2451a3f 100644 --- a/Marshmallows/MMHTTPClient.m +++ b/Marshmallows/MMHTTPClient.m @@ -73,54 +73,54 @@ NSString *JoinURLComponents(NSString *first, va_list args) return [[[self sharedClient] baseURL] stringByAppendingPathComponent: path]; } -+ (void) request: (NSDictionary *)options then: (MMHTTPClientCallback)callback ++ (MMHTTPRequest *) request: (NSDictionary *)options then: (MMHTTPCallback)callback { - [[self sharedClient] request: options then: callback]; + return [[self sharedClient] request: options then: callback]; } -+ (void) get: (NSString *)url then: (MMHTTPClientCallback)callback ++ (MMHTTPRequest *) get: (NSString *)url then: (MMHTTPCallback)callback { - [[self sharedClient] get: url then: callback]; + return [[self sharedClient] get: url then: callback]; } -+ (void) getImage: (NSString *)url then: (MMHTTPClientImageCallback)callback ++ (MMHTTPRequest *) getImage: (NSString *)url then: (MMHTTPImageCallback)callback { - [[self sharedClient] getImage: url then: callback]; + return [[self sharedClient] getImage: url then: callback]; } -+ (void) getText: (NSString *)url then: (MMHTTPClientTextCallback)callback ++ (MMHTTPRequest *) getText: (NSString *)url then: (MMHTTPTextCallback)callback { - [[self sharedClient] getText: url then: callback]; + return [[self sharedClient] getText: url then: callback]; } -+ (void) post: (NSString *)url then: (MMHTTPClientCallback)callback ++ (MMHTTPRequest *) post: (NSString *)url then: (MMHTTPCallback)callback { - [[self sharedClient] post: url then: callback]; + return [[self sharedClient] post: url then: callback]; } -+ (void) post: (NSString *)url data: (NSData *)data then: (MMHTTPClientCallback)callback ++ (MMHTTPRequest *) post: (NSString *)url data: (NSData *)data then: (MMHTTPCallback)callback { - [[self sharedClient] post: url data: data then: callback]; + return [[self sharedClient] post: url data: data then: callback]; } -+ (void) put: (NSString *)url data: (NSData *)data then: (MMHTTPClientCallback)callback ++ (MMHTTPRequest *) put: (NSString *)url data: (NSData *)data then: (MMHTTPCallback)callback { - [[self sharedClient] put: url data: data then: callback]; + return [[self sharedClient] put: url data: data then: callback]; } -+ (void) delete: (NSString *)url then: (MMHTTPClientCallback)callback ++ (MMHTTPRequest *) delete: (NSString *)url then: (MMHTTPCallback)callback { - [[self sharedClient] delete: url then: callback]; + return [[self sharedClient] delete: url then: callback]; } - (id) init { - return [self initWithBaseURL: nil timeout: MMHTTPClientDefaultTimeout]; + return [self initWithBaseURL: nil timeout: MMHTTPRequestDefaultTimeout]; } - (id) initWithBaseURL: (NSString *)baseURL { - return [self initWithBaseURL: baseURL timeout: MMHTTPClientDefaultTimeout]; + return [self initWithBaseURL: baseURL timeout: MMHTTPRequestDefaultTimeout]; } - (id) initWithBaseURL: (NSString *)baseURL timeout: (NSUInteger)timeout @@ -129,12 +129,6 @@ NSString *JoinURLComponents(NSString *first, va_list args) if (self) { _baseURL = [baseURL copy]; _timeout = timeout; - _callbacks = [[NSMutableDictionary alloc] init]; - _connections = [[NSMutableDictionary alloc] init]; - _data = [[NSMutableDictionary alloc] init]; - _headers = [[NSMutableDictionary alloc] init]; - _statusCodes = [[NSMutableDictionary alloc] init]; - _types = [[NSMutableDictionary alloc] init]; } return self; } @@ -162,193 +156,85 @@ NSString *JoinURLComponents(NSString *first, va_list args) return [_baseURL stringByAppendingPathComponent: path]; } -- (void) getImage: (NSString *)url then: (MMHTTPClientImageCallback)callback +- (MMHTTPRequest *) getImage: (NSString *)url then: (MMHTTPImageCallback)callback { - [self request: [NSDictionary dictionary] then: (MMHTTPClientCallback)callback]; + return [self request: [NSDictionary dictionary] then: (MMHTTPCallback)callback]; } -- (void) getText: (NSString *)url then: (MMHTTPClientTextCallback)callback +- (MMHTTPRequest *) getText: (NSString *)url then: (MMHTTPTextCallback)callback { NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: url, @"url", @"text", @"type", nil]; - [self request: options then: (MMHTTPClientCallback)callback]; + return [self request: options then: (MMHTTPCallback)callback]; } -- (void) get: (NSString *)url then: (MMHTTPClientCallback)callback +- (MMHTTPRequest *) get: (NSString *)url then: (MMHTTPCallback)callback { NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: url, @"url", @"image", @"type", nil]; - [self request: options then: (MMHTTPClientCallback)callback]; + return [self request: options then: (MMHTTPCallback)callback]; } -- (void) post: (NSString *)url then: (MMHTTPClientCallback)callback +- (MMHTTPRequest *) post: (NSString *)url then: (MMHTTPCallback)callback { NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: @"POST", @"method", url, @"url", nil]; - [self request: options then: callback]; + return [self request: options then: callback]; } -- (void) post: (NSString *)url data: (NSData *)data then: (MMHTTPClientCallback)callback +- (MMHTTPRequest *) post: (NSString *)url data: (NSData *)data then: (MMHTTPCallback)callback { NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: @"POST", @"method", url, @"url", data, @"data", nil]; - [self request: options then: callback]; + return [self request: options then: callback]; } -- (void) put: (NSString *)url data: (NSData *)data then: (MMHTTPClientCallback)callback +- (MMHTTPRequest *) put: (NSString *)url data: (NSData *)data then: (MMHTTPCallback)callback { NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: @"PUT", @"method", url, @"url", data, @"data", nil]; - [self request: options then: callback]; + return [self request: options then: callback]; } -- (void) delete: (NSString *)url then: (MMHTTPClientCallback)callback +- (MMHTTPRequest *) delete: (NSString *)url then: (MMHTTPCallback)callback { NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: @"DELETE", @"method", url, @"url", nil]; - [self request: options then: callback]; + return [self request: options then: callback]; } -- (void) request: (NSDictionary *)options then: (MMHTTPClientCallback)callback +- (MMHTTPRequest *) request: (NSDictionary *)options then: (MMHTTPCallback)callback { - NSString *urlString = [options valueForKey: @"url"]; - NSString *method = [options valueForKey: @"method"]; - NSData *data = [options valueForKey: @"data"]; - NSDictionary *headers = [options valueForKey: @"headers"]; - NSString *type = [options valueForKey: @"type"]; - - if (!method) method = @"GET"; - - if (![[urlString substringToIndex: 5] isEqualToString: @"http:"] - && ![[urlString substringToIndex: 6] isEqualToString: @"https:"]) - { - urlString = [self urlWithPath: urlString]; + NSString *url = [options objectForKey: @"url"]; + if (_baseURL && !([url hasPrefix: @"http:"] || [url hasPrefix: @"https:"])) { + NSMutableDictionary *mutableOptions = [options mutableCopy]; + [mutableOptions setObject: [self urlWithPath: url] forKey: @"url"]; + options = [NSDictionary dictionaryWithDictionary: mutableOptions]; } - NSURL *url = [NSURL URLWithString: urlString]; - - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: url - cachePolicy: NSURLRequestUseProtocolCachePolicy - timeoutInterval: self.timeout]; - [request setHTTPMethod: method]; - - if (data && ([method isEqualToString: @"POST"] || [method isEqualToString: @"PUT"])) { - [request setHTTPBody: data]; + NSUInteger timeout = [[options objectForKey: @"timeout"] unsignedIntValue]; + if (timeout == 0) { + [options setValue: [NSNumber numberWithUnsignedInt: self.timeout] forKey: @"timeout"]; } - - if (headers) { - for (NSString *key in headers) { - [request setValue: [headers objectForKey: key] forHTTPHeaderField: key]; - } - } - - NSURLConnection *connection = [NSURLConnection connectionWithRequest: request delegate: self]; - NSString *key = [connection description]; - [_callbacks setObject: [[callback copy] autorelease] forKey: [connection description]]; - [_connections setObject: connection forKey: key]; - if (type) [_types setObject: type forKey: key]; -} - - -#pragma mark - NSURLConnection delegate methods - -- (void) connection: (NSURLConnection *)connection didReceiveResponse: (NSURLResponse *)response -{ - NSString *key = [connection description]; - NSNumber *status; - NSDictionary *headers; - - if ([response respondsToSelector :@selector(statusCode)]) - { - status = [NSNumber numberWithInt: [(NSHTTPURLResponse *)response statusCode]]; - headers = [(NSHTTPURLResponse *)response allHeaderFields]; - } - else { - NSLog(@"Not an HTTP response? connection: %@ response: %@", connection, response); - status = [NSNumber numberWithInt: 500]; - headers = [NSDictionary dictionary]; - } - - [_statusCodes setObject: status forKey: key]; - [_headers setObject: headers forKey: key]; - [_data setObject: [[[NSMutableData alloc] init] autorelease] forKey: key]; -} - -- (void) connection: (NSURLConnection *)connection didReceiveData: (NSData *)data -{ - [[_data objectForKey: [connection description]] appendData: data]; -} - -- (void) connection: (NSURLConnection *)connection didFailWithError: (NSError *)error -{ - NSString *key = [connection description]; - MMHTTPClientCallback callback = [_callbacks objectForKey: key]; - - callback(MMHTTPClientStatusError, nil); - - [_statusCodes removeObjectForKey: key]; - [_callbacks removeObjectForKey: key]; - [_data removeObjectForKey: key]; -} - -- (void) connectionDidFinishLoading: (NSURLConnection *)connection -{ - NSString *key = [connection description]; - MMHTTPClientCallback callback = [_callbacks objectForKey: key]; - int status = [[_statusCodes objectForKey: key] intValue]; - NSString *type = [_types objectForKey: key]; - id data = nil; - if (status == 200) { - if ([type isEqualToString: @"text"]) { - NSData *rawData = [_data objectForKey: key]; - data = [[[NSString alloc] initWithBytes: rawData.bytes - length: rawData.length - encoding: NSUTF8StringEncoding] autorelease]; - } - else if ([type isEqualToString: @"image"]) { - data = [UIImage imageWithData: [_data objectForKey: key]]; - } - else { - data = [_data objectForKey: key]; - } - } - - callback(status, data); - - [_callbacks removeObjectForKey: key]; - [_connections removeObjectForKey: key]; - [_data removeObjectForKey: key]; - [_headers removeObjectForKey: key]; - [_statusCodes removeObjectForKey: key]; - [_types removeObjectForKey: key]; + return [MMHTTPRequest requestWithOptions: options callback: callback]; } - (void) dealloc { - for (NSURLConnection *conn in _connections) { - [conn cancel]; - } - [_baseURL release]; - [_callbacks release]; - [_connections release]; - [_data release]; - [_headers release]; - [_statusCodes release]; - [_types release]; [super dealloc]; } diff --git a/Marshmallows/MMHTTPRequest.h b/Marshmallows/MMHTTPRequest.h new file mode 100644 index 0000000..e4de3e9 --- /dev/null +++ b/Marshmallows/MMHTTPRequest.h @@ -0,0 +1,43 @@ +// +// MMHTTPRequest.h +// Marshmallows +// +// Created by Sami Samhuri on 11-09-03. +// Copyright 2011 Guru Logic. All rights reserved. +// + +#import +#import + +#define MMHTTPRequestStatusError -1 +#define MMHTTPRequestDefaultTimeout 120 + +typedef void (^MMHTTPCallback)(NSInteger status, id data); +typedef void (^MMHTTPTextCallback)(NSInteger status, NSString *text); +typedef void (^MMHTTPImageCallback)(NSInteger status, UIImage *image); + +@interface MMHTTPRequest : NSObject +{ + NSMutableData *_responseData; +} + +@property (nonatomic, retain) NSURLConnection *connection; +@property (nonatomic, retain) NSMutableURLRequest *request; +@property (nonatomic, retain) NSString *method; +@property (nonatomic, retain) NSString *url; +@property (nonatomic, retain) NSMutableDictionary *headers; +@property (nonatomic, retain) NSData *data; +@property (nonatomic, retain) NSString *type; +@property (nonatomic, retain) MMHTTPCallback callback; +@property NSUInteger timeout; +@property (readonly) NSInteger statusCode; +@property (readonly) NSDictionary *responseHeaders; +@property (readonly) NSData *responseData; +@property (readonly) NSString *responseText; +@property (readonly) UIImage *responseImage; + ++ (id) requestWithOptions: (NSDictionary *)options callback: (MMHTTPCallback)callback; +- (id) initWithOptions: (NSDictionary *)options callback: (MMHTTPCallback)callback; +- (void) cancel; + +@end diff --git a/Marshmallows/MMHTTPRequest.m b/Marshmallows/MMHTTPRequest.m new file mode 100644 index 0000000..6072449 --- /dev/null +++ b/Marshmallows/MMHTTPRequest.m @@ -0,0 +1,158 @@ +// +// MMHTTPRequest.m +// Marshmallows +// +// Created by Sami Samhuri on 11-09-03. +// Copyright 2011 Guru Logic. All rights reserved. +// + +#import "MMHTTPRequest.h" + +@interface MMHTTPRequest () +- (void) _start; +@end + + +@implementation MMHTTPRequest + +@synthesize connection = _connection; +@synthesize request = _request; +@synthesize method = _method; +@synthesize url = _url; +@synthesize headers = _headers; +@synthesize data = _data; +@synthesize type = _type; +@synthesize callback = _callback; +@synthesize timeout = _timeout; +@synthesize statusCode = _statusCode; +@synthesize responseHeaders = _responseHeaders; + ++ (id) requestWithOptions: (NSDictionary *)options callback: (MMHTTPCallback)callback +{ + return [[[self alloc] initWithOptions: options callback: callback] autorelease]; +} + +- (id) initWithOptions: (NSDictionary *)options callback: (MMHTTPCallback)callback +{ + self = [super init]; + if (self) { + self.callback = [callback copy]; + self.timeout = MMHTTPRequestDefaultTimeout; + self.method = [options objectForKey: @"method"]; + self.url = [options objectForKey: @"url"]; + self.headers = [options objectForKey: @"headers"]; + self.data = [options objectForKey: @"data"]; + self.type = [options objectForKey: @"type"]; + if (!self.method) self.method = @"GET"; + [self _start]; + } + return self; +} + +- (void) cancel +{ + [_connection cancel]; +} + +- (NSData *) responseData +{ + return [NSData dataWithData: _responseData]; +} + +- (NSString *) responseText +{ + return [[[NSString alloc] initWithBytes: _responseData.bytes + length: _responseData.length + encoding: NSUTF8StringEncoding] autorelease]; +} + +- (UIImage *) responseImage +{ + return [UIImage imageWithData: _responseData]; +} + +- (void) _start +{ + self.request = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: self.url] + cachePolicy: NSURLRequestUseProtocolCachePolicy + timeoutInterval: self.timeout]; + [self.request setHTTPMethod: self.method]; + + if (self.data && ([self.method isEqualToString: @"POST"] || [self.method isEqualToString: @"PUT"])) { + [self.request setHTTPBody: self.data]; + } + + if (self.headers) { + for (NSString *key in self.headers) { + [self.request setValue: [self.headers objectForKey: key] forHTTPHeaderField: key]; + } + } + + self.connection = [NSURLConnection connectionWithRequest: self.request delegate: self]; +} + +#pragma mark - NSURLConnection delegate methods + +- (void) connection: (NSURLConnection *)connection didReceiveResponse: (NSURLResponse *)response +{ + if ([response respondsToSelector: @selector(statusCode)]) + { + _statusCode = [(NSHTTPURLResponse *)response statusCode]; + _responseHeaders = [[(NSHTTPURLResponse *)response allHeaderFields] retain]; + } + else { + NSLog(@"Not an HTTP response? connection: %@ response: %@", connection, response); + _statusCode = 500; + _responseHeaders = [[NSDictionary alloc] init]; + } + + _responseData = [[NSMutableData alloc] init]; +} + +- (void) connection: (NSURLConnection *)connection didReceiveData: (NSData *)data +{ + [_responseData appendData: data]; +} + +- (void) connection: (NSURLConnection *)connection didFailWithError: (NSError *)error +{ + [_responseData release]; + _responseData = nil; + _statusCode = MMHTTPRequestStatusError; + self.callback(self.statusCode, nil); +} + +- (void) connectionDidFinishLoading: (NSURLConnection *)connection +{ + id data = nil; + if (self.statusCode == 200) { + if ([self.type isEqualToString: @"text"]) { + data = self.responseText; + } + else if ([self.type isEqualToString: @"image"]) { + data = self.responseImage; + } + else { + data = self.responseData; + } + } + + self.callback(self.statusCode, data); +} + +- (void) dealloc +{ + [_connection release]; + [_request release]; + [_method release]; + [_url release]; + [_headers release]; + [_data release]; + [_type release]; + [_callback release]; + [_responseHeaders release]; + [_responseData release]; + [super dealloc]; +} + +@end