Saturday, November 20, 2010

 

HttpHelper for all, redux

Yeah, I know I said I wouldn't be posting much, but I've cleaned up and updated my HttpHelper class for one of my paid projects so that it supports cookies, form/multipart file uploads, non-ASCII characters, etc., so I thought I'd release it into the wild for y'all.

Apache License 2.0, as before.

The interface should be pretty self-evident from the .h file:


//
// HttpHelper.h
//
// Created by Jon Evans on 04/09/09.
// Copyright 2009 Jon Evans. Apache 2.0 license.
//

#import <Foundation/Foundation.h>

@interface HttpHelper : NSObject {
}

//Convenience methods
+(NSURLRequestCachePolicy)getCachePolicyFor:(NSString *)urlString;

//Cookie handling
+(void) useCookies:(BOOL)use;
+(NSArray*) latestCookies;
+(void) getCookiesFrom:(NSHTTPURLResponse*)response forURL:(NSURL*)url;

//HTTP Posts
+(NSURLRequest*) buildPostRequestForURL:(NSString *)urlString withData:(NSDictionary*) data;
+(NSURLRequest *) buildRequestWithPostKeys:(NSArray *) postKeys postValues:(NSArray *) postValues urlString:(NSString *)urlString;
+(BOOL) doPost:(NSURLRequest *)request forCaller:(id)caller onSuccess:(SEL)successSelector onFailure:(SEL)failSelector;

//HTTP Gets
+(NSURLRequest *)getURLRequestFor:(NSString *)urlString;
+(BOOL) doGet:(NSString *)urlString forCaller:(id)caller onSuccess:(SEL)successSelector onFailure:(SEL)failSelector;

//Synchronized accessors
+(NSString *) doSynchronizedGet:(NSString *)urlString;
+(NSData *) doSynchronizedDataGet:(NSString *)urlString;
+(NSString *) doSynchronizedPostTo:(NSString *)urlString withRequest:(NSURLRequest*)request;
+(NSString *) doSynchronizedPostTo:(NSString *)urlString withData:(NSDictionary*)data;
+(NSString *) doSynchronizedPostTo:(NSString *)urlString withKeys:(NSArray*)postKeys andValues:(NSArray*)postValues;

//Form/multipart (for file upload)
+(NSString *) doSynchronizedMultipartPostTo:(NSString*)urlString withData:(NSDictionary*)data fileKeys:(NSArray*)fileKeys;
+(NSString *) doSynchronizedMultipartPostTo:(NSString*)urlString withKeys:(NSArray*)keys andValues:(NSArray*)values fileKeys:(NSArray*)fileKeys;

@end


...and here's where the magic happens:


//
// HttpHelper.m
//
// Created by Jon Evans on 04/09/09.
// Copyright 2009 Jon Evans. Apache 2.0 license.
//

#import "HttpHelper.h"


@implementation HttpHelper

static HttpHelper *singleton=nil;
static NSArray *latestCookies=nil;
static BOOL useCookies=NO;


#pragma mark -
#pragma mark Singleton methods

+(HttpHelper *) getInstance {
if (singleton==nil)
singleton = [[[HttpHelper alloc] init] autorelease];
return singleton;
}

+(id)allocWithZone:(NSZone *)zone {
if (singleton == nil) {
singleton = [super allocWithZone:zone];
return singleton;
}
return nil;
}

-(id)copyWithZone:(NSZone *)zone {
return self;
}

-(id)retain {
return self;
}

-(NSUInteger)retainCount {
return UINT_MAX;
}

-(void)release {
//pass
}

-(id)autorelease {
return self;
}

- (void)dealloc {
[super dealloc];
}


#pragma mark -
#pragma mark Convenience methods

+(NSURLRequestCachePolicy)getCachePolicyFor:(NSString *)urlString {
//Hived out to a separate method because we might fine-tune this later.
return NSURLRequestUseProtocolCachePolicy;
// return NSURLRequestReloadIgnoringCacheData;
}


#pragma mark -
#pragma mark Cookie handling

+(void) useCookies:(BOOL)use
{
useCookies=use;
}

+(void) getCookiesFrom:(NSHTTPURLResponse*)response forURL:(NSURL*)url {
if ([response class]==[NSHTTPURLResponse class])
latestCookies = [NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:url];
}

+(NSArray*) latestCookies {
return latestCookies;
}



#pragma mark -
#pragma mark HTTP Posts

+(NSURLRequest*) buildPostRequestForURL:(NSString *)urlString withData:(NSDictionary*) data
{
NSArray *keys = [data allKeys];
NSMutableArray *values = [NSMutableArray arrayWithCapacity:[keys count]];
for (NSString *key in keys) {
NSString *value = [data objectForKey:key];
[values addObject:(value ? [NSString stringWithFormat:@"%@",value] : @"")];
}
return [self buildRequestWithPostKeys:keys postValues:values urlString:urlString];
}

+(NSURLRequest*) buildRequestWithPostKeys:(NSArray *) postKeys postValues:(NSArray *) postValues urlString:(NSString *)urlString {
NSURL * url = [NSURL URLWithString:urlString];
NSURLRequestCachePolicy policy = NSURLRequestReloadIgnoringCacheData; // we never want a cache of a post response
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:policy timeoutInterval:30.0];
[request setHTTPMethod:@"POST"];

if (useCookies && latestCookies!=nil && [latestCookies count]>0) {
NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies:latestCookies];
[request setAllHTTPHeaderFields:headers];
}

NSMutableData *paramData = [NSMutableData dataWithCapacity:8192];

NSMutableString *params=[[NSMutableString alloc] initWithCapacity:1024];
for (int i=0; i<[postValues count]; i++) {
NSString *param = i>0 ? @"&" : @"";
param = [param stringByAppendingFormat:@"%@=",[postKeys objectAtIndex:i]];
[paramData appendData:[param dataUsingEncoding:NSUTF8StringEncoding]];

NSObject* valueToPost = [postValues objectAtIndex:i];
NSString *stringToPost = [valueToPost class]==[NSString class] ? (NSString*)valueToPost : [NSString stringWithFormat:@"%@",valueToPost];
stringToPost = [stringToPost stringByReplacingOccurrencesOfString:@"&" withString:@"%26"];
[paramData appendData:[stringToPost dataUsingEncoding:NSUTF8StringEncoding]];
}

NSString *msgLength = [NSString stringWithFormat:@"%d", [paramData length]];
[request addValue: msgLength forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody: paramData];
[params release];

return request;
}

+(BOOL) doPost:(NSURLRequest *)request forCaller:(id)caller onSuccess:(SEL)onSuccess onFailure:(SEL)onFailure {

NSArray *keys = [NSArray arrayWithObjects:@"request", @"caller", @"onSuccess", @"onFailure", nil];
NSArray *values = [NSArray arrayWithObjects:request, caller,
[NSValue valueWithBytes:&onSuccess objCType:@encode(SEL)],
[NSValue valueWithBytes:&onFailure objCType:@encode(SEL)],
nil];
NSDictionary *args = [NSDictionary dictionaryWithObjects:values forKeys: keys];
[NSThread detachNewThreadSelector:@selector(doHttp:) toTarget:[self getInstance] withObject:args];
return TRUE;
}


#pragma mark -
#pragma mark HTTP Gets

+(NSURLRequest *)getURLRequestFor:(NSString *)urlString {
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequestCachePolicy policy = [self getCachePolicyFor:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:policy timeoutInterval:30.0];
[request setHTTPMethod:@"GET"];

if (useCookies && latestCookies!=nil && [latestCookies count]>0) {
NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies:latestCookies];
[request setAllHTTPHeaderFields:headers];
}
return request;
}

+(BOOL) doGet:(NSString *)urlString forCaller:(id)caller onSuccess:(SEL)onSuccess onFailure:(SEL)onFailure {
NSURLRequest *request = [self getURLRequestFor:urlString];
NSArray *keys = [NSArray arrayWithObjects:@"request", @"caller", @"onSuccess", @"onFailure", nil];
NSArray *values = [NSArray arrayWithObjects:request, caller,
[NSValue valueWithBytes:&onSuccess objCType:@encode(SEL)],
[NSValue valueWithBytes:&onFailure objCType:@encode(SEL)],
nil];
NSDictionary *args = [NSDictionary dictionaryWithObjects:values forKeys: keys];
NSThread* uploadThread = [[NSThread alloc] initWithTarget:[self getInstance] selector:@selector(doHttp:) object:args];
[uploadThread start];
[uploadThread release];
return TRUE;
}


#pragma mark -
#pragma mark Internals

-(BOOL) doHttp:(NSDictionary *)args
{
@synchronized (self) {
//autorelease pool
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSURLRequest *request = [args objectForKey:@"request"];
NSObject *caller = [args objectForKey:@"caller"];

SEL onSuccess;
[[args objectForKey:@"onSuccess"] getValue:&onSuccess];
SEL onFailure;
[[args objectForKey:@"onFailure"] getValue:&onFailure];

NSError *error=nil;
NSHTTPURLResponse *response=nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: &response error: &error ];
NSString * responseString = [[[NSString alloc] initWithData: returnData encoding: NSUTF8StringEncoding] autorelease];

NSString *errorString=nil;

if (error)
errorString = [NSString stringWithFormat:@"Error %@ '%@': %@",NSLocalizedString(@"loading page",nil), [request URL], [error localizedDescription]];
else if (response==nil || returnData==nil)
errorString = [NSString stringWithFormat:@"Error - %@ %@",NSLocalizedString(@"No response from URL",nil), [request URL]];
else if (response.statusCode!=200)
errorString = [NSString stringWithFormat:@"Error - %@ %i %@ %@",NSLocalizedString(@"HTTP Error",nil), response.statusCode, NSLocalizedString(@"from URL",nil), [request URL]];

if (errorString && [errorString length]>0) {
NSLog(@"iTravel Error ",errorString);
[caller performSelectorOnMainThread: onFailure withObject:errorString waitUntilDone:NO];
}
else {
if (useCookies)
[HttpHelper getCookiesFrom:response forURL:[request URL]];
[caller performSelectorOnMainThread: onSuccess withObject:responseString waitUntilDone:YES];
}
[pool release];
}
return TRUE;
}


#pragma mark -
#pragma mark Synchronized methods

+(NSString *) doSynchronizedGet:(NSString *)urlString {
NSData *returnData = [HttpHelper doSynchronizedDataGet:urlString];
if (!returnData)
return [NSString stringWithFormat:@"Error: %@ %@",NSLocalizedString(@"No data received from server",nil), urlString];

NSString * responseString = [[[NSString alloc] initWithData: returnData encoding: NSUTF8StringEncoding] autorelease];
return responseString;
}

+(NSData *) doSynchronizedDataGet:(NSString *)urlString {
NSURLRequest *request = [self getURLRequestFor:urlString];
NSHTTPURLResponse *response=nil;
NSError *error=nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

NSString *errorString=@"";
if (error)
errorString = [NSString stringWithFormat:@"Error %@ '%@': %@",NSLocalizedString(@"loading page",nil), urlString, [error localizedDescription]];
else if (response==nil || returnData==nil)
errorString = [NSString stringWithFormat:@"Error - %@ %@",NSLocalizedString(@"No response from URL",nil), urlString];
else if (response.statusCode!=200)
errorString = [NSString stringWithFormat:@"Error - %@ %i %@ %@",NSLocalizedString(@"HTTP Error",nil), response.statusCode, NSLocalizedString(@"from URL",nil), urlString];

if ([errorString length]>0)
return [errorString dataUsingEncoding:NSUTF8StringEncoding];;

if (useCookies)
[HttpHelper getCookiesFrom:response forURL:[request URL]];

return returnData;
}

+(NSString *) doSynchronizedPostTo:(NSString *)urlString withData:(NSDictionary*)data {
NSURLRequest *request = [self buildPostRequestForURL:urlString withData:data];
return [self doSynchronizedPostTo:urlString withRequest:request];
}
+(NSString *) doSynchronizedPostTo:(NSString *)urlString withKeys:(NSArray*)postKeys andValues:(NSArray*)postValues {
NSURLRequest *request = [self buildRequestWithPostKeys:postKeys postValues:postValues urlString:urlString];
return [self doSynchronizedPostTo:urlString withRequest:request];
}
+(NSString *) doSynchronizedPostTo:(NSString *)urlString withRequest:(NSURLRequest*)request {
NSHTTPURLResponse *response=nil;
NSError *error=nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

NSString *errorString=@"";
if (error)
errorString = [NSString stringWithFormat:@"Error - %@ '%@': %@",NSLocalizedString(@"HTTP Error posting to URL",nil), urlString, [error localizedDescription]];
else if (response==nil || returnData==nil)
errorString = [NSString stringWithFormat:@"Error - %@ %@",NSLocalizedString(@"No response from URL",nil), urlString];
else if (response.statusCode!=200)
errorString = [NSString stringWithFormat:@"Error - %@ %i %@ %@",NSLocalizedString(@"HTTP Error",nil), response.statusCode, NSLocalizedString(@"from URL",nil), urlString];

if ([errorString length]>0)
return errorString;

if (useCookies)
[HttpHelper getCookiesFrom:response forURL:[request URL]];

NSString * responseString = [[[NSString alloc] initWithData: returnData encoding: NSUTF8StringEncoding] autorelease];

if ([[responseString lowercaseString] hasPrefix:@"error"])
errorString = [NSString stringWithFormat:@"Error %@ %@ %@ %@",NSLocalizedString(@"message",nil), responseString, NSLocalizedString(@"from URL",nil), urlString];
else if ([[responseString lowercaseString] hasPrefix:@"fail"])
errorString = [NSString stringWithFormat:@"Error - %@ '%@' %@ %@",NSLocalizedString(@"Failure message",nil), responseString, NSLocalizedString(@"when posting to URL",nil), urlString];

if ([errorString length]>0)
return errorString;

return responseString;
}

+(NSString*) doSynchronizedMultipartPostTo:(NSString*)urlString withData:(NSDictionary*)data fileKeys:(NSArray*)fileKeys
{
NSArray *keys = [data allKeys];
NSMutableArray *values = [NSMutableArray arrayWithCapacity:[keys count]];
for (NSString *key in keys) {
NSString *value = [data objectForKey:key];
[values addObject:(value ? value : @"")];
}
return [self doSynchronizedMultipartPostTo:urlString withKeys:keys andValues:values fileKeys:fileKeys];
}

+(NSString *) doSynchronizedMultipartPostTo:(NSString*)urlString withKeys:(NSArray*)keys andValues:(NSArray*)values fileKeys:(NSArray*)fileKeys
{
NSURL * url = [NSURL URLWithString:urlString];
NSURLRequestCachePolicy policy = NSURLRequestReloadIgnoringCacheData; // we never want a cache of a post response
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:policy timeoutInterval:30.0];
[request setHTTPMethod:@"POST"];

NSString *boundary = [[NSProcessInfo processInfo] globallyUniqueString];
[request setValue: [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary] forHTTPHeaderField:@"Content-Type"];

NSMutableData *postBody = [NSMutableData dataWithCapacity:65536];
for (int i=0; i<[keys count]; i++) {
NSString *key = [keys objectAtIndex:i];
NSObject *value = [values objectAtIndex:i];

if (value && fileKeys && [fileKeys containsObject:key]) {
[postBody appendData: [[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
if ([value isKindOfClass:[NSString class]]) {
NSString *valueString = (NSString*)value;
if ([valueString length]>0) {
NSRange slashRange = [valueString rangeOfString:@"/" options:NSBackwardsSearch];
NSString *fileName = slashRange.location!=NSNotFound && ![valueString hasSuffix:@"/"]
? [valueString substringFromIndex:slashRange.location+1]
: valueString;
[postBody appendData: [[NSString stringWithFormat: @"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", key, fileName] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData: [[NSString stringWithFormat: @"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData: [NSData dataWithContentsOfMappedFile:valueString]];
}
}
else if ([value isKindOfClass:[NSURL class]]) {
NSURL *fileURL = (NSURL*)value;
[postBody appendData: [[NSString stringWithFormat: @"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", key, [fileURL lastPathComponent]] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData: [[NSString stringWithFormat: @"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData: [NSData dataWithContentsOfURL:fileURL]];
}
else if ([value isKindOfClass:[NSData class]]) {
[postBody appendData: [[NSString stringWithFormat: @"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", key, key] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData: [[NSString stringWithFormat: @"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData: (NSData*)value];
}
}
else {
[postBody appendData:[[NSString stringWithFormat: @"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat: @"Content-Disposition: form-data; name=\"%@\"\r\n",key] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData: [[NSString stringWithFormat: @"Content-Type: text/plain;charset=utf-8\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
NSString *valueString = [NSString stringWithFormat: @"%@", value];
[postBody appendData:[valueString dataUsingEncoding:NSUTF8StringEncoding]];
}
[postBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
}
[postBody appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

NSString *msgLength = [NSString stringWithFormat:@"%d", [postBody length]];
[request addValue: msgLength forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody:postBody];

NSHTTPURLResponse *response=nil;
NSError *error=nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

NSString *errorString=@"";
if (error)
errorString = [NSString stringWithFormat:@"Error - %@ '%@': %@",NSLocalizedString(@"HTTP Error posting to URL",nil), urlString, [error localizedDescription]];
else if (response==nil || returnData==nil)
errorString = [NSString stringWithFormat:@"Error - %@ %@",NSLocalizedString(@"No response from URL",nil), urlString];
else if (response.statusCode!=200)
errorString = [NSString stringWithFormat:@"Error - %@ %i %@ %@",NSLocalizedString(@"HTTP Error",nil), response.statusCode, NSLocalizedString(@"from URL",nil), urlString];

if ([errorString length]>0)
return errorString;

NSString * responseString = [[[NSString alloc] initWithData: returnData encoding: NSUTF8StringEncoding] autorelease];

if ([[responseString lowercaseString] hasPrefix:@"error"])
errorString = [NSString stringWithFormat:@"Error %@ %@ %@ %@",NSLocalizedString(@"message",nil), responseString, NSLocalizedString(@"from URL",nil), urlString];
else if ([[responseString lowercaseString] hasPrefix:@"fail"])
errorString = [NSString stringWithFormat:@"Error - %@ '%@' %@ %@",NSLocalizedString(@"Failure message",nil), responseString, NSLocalizedString(@"when posting to URL",nil), urlString];

if ([errorString length]>0)
return errorString;

if (useCookies)
[HttpHelper getCookiesFrom:response forURL:[request URL]];
return responseString;
}


@end

Comments:
At first, you need to visit any trusted website where you will get the option to order assignment help. There you will be asked to submit a few details regarding the assignment and also some of your requirements as well. You can also give them a deadline if you are running short of time. Then, you have to make the payment as per the charges previously set on the website. After this, a programming expert will be assigned for your assignment that will complete the task before the given deadline. If you want to see the progress in between, then you can also ask for drafts from the assigned expert for your assignment. As soon as your programming assignment is completed, the assignment will be handed over to you. These were the split steps of programming assignment help offered online, which is fast and convenient for students.
 
192.168.1.1 is a private IP address used to login the admin panel of a router. 192.168.l.l is pre-specified by the router companies as the default gateway address and can be used to make different changes to the router’s settings. 192.168.15.1
 
Yeah I have studied about these Http & Https network protocols while I was looking to buy assignment online because I don't have a computer science background due to which it takes me time to understand these topics, so I take help from others on the Internet.
 
These kinda article which is related to computer programing and coding it is very useful for the computer science students and I truly appreciate you sharing these kinds of informations with us. Regards: Professional essay writers in UK
 
Nice to meet you. The information is there!Thank you for some information.You give me some idea's.Please post it.

카지노
메이저토토사이트
토토
토토사이트링크
스포츠토토
우리카지노탑

 
Oh, nice! I like it! Opera is excellent and should be better than fire fox for sure! But Google is chrome is also good! But you know what’s the best? This pretty service for essay and homework! Check this residency statements and be prepared for help! Excellent luck and have fun!
 
We have a team of certified academic professionals who are native https://expertpaperwriter.com/slader-review/ speakers with good command of the English language. Moreover, they hold diverse qualifications in numerous disciplines. Thus, you can never go wrong in choosing our services. We guarantee top-quality assignments.
 
I think you should try to customize these lines of code :

-(NSUInteger)retainCount {
return UINT_MAX;
}

-(void)release {
//pass
}

-(id)autorelease {
return self;
}

- (void)dealloc {
[super dealloc];
}

try and share if something improved
 
Here, we charge a nominal fee from students as we are aware of the financial constraints. When you wonder, “Can I pay someone to do my homework for me?”
 
i have found a lot of interesting topics in it while searching for Cheap Essay Writing Services Uk
 
Online english assignment help uk tutors from MyAssignmenthelp.com can help you write an A+ quality English assignment.
 
Professors prefer that the assignment help manchester be done at a specific time or with a device and presented automatically. So, you should always maintain the format or structure of the physics assignment and follow it without any confusion. You will get a detailed structure of how to write your physics assignment, word count, references, citation styles and presentation rules.
 
If you are looking for someone to provide you high-notch assignment solution, you may go for a customized writing service. We can provide you with the top and most outstanding assignment papers that will give an impressive impression on your professors. When it comes to securing better marks, Assignment Help is the one of most reliable options for students. Our Assignment Help services provide the best assignment solutions that can help students to secure top-rated scores in the exams. Providing students with more accurate assignment answers is the primary motto of our website. Getting assignment help is a better option for struggling with your college assignments on your own. If you do this without proper preparation, you will neither achieve anything nor produce a poorly written paper. Instead, the ideal solution is only a few clicks away.
 
Thank you for this wonderful blog! Nowadays companies employ Custom LMS Solutions to train their teams. Acadecraft is a leading LMS solution provider company.
Also Read: Skill Development Training
 

Post a Comment

Subscribe to Post Comments [Atom]





<< Home

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]