Closed pszalko closed 10 years ago
I have similar requirement how did you do it?
I have changed NXOAuth2Connection.m file, here is my applyParameters:onRequest: method:
- (void)applyParameters:(NSDictionary *)parameters onRequest:(NSMutableURLRequest *)aRequest;
{
if (!parameters) return;
NSString *httpMethod = [aRequest HTTPMethod];
if ([httpMethod caseInsensitiveCompare:@"POST"] != NSOrderedSame
&& [httpMethod caseInsensitiveCompare:@"PUT"] != NSOrderedSame) {
aRequest.URL = [aRequest.URL nxoauth2_URLByAddingParameters:parameters];
} else {
// original code: HTTP multipart/form-data
// NSInputStream *postBodyStream = [[NXOAuth2PostBodyStream alloc] initWithParameters:parameters];
// NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", [(NXOAuth2PostBodyStream *)postBodyStream boundary]];
// NSString *contentLength = [NSString stringWithFormat:@"%lld", [(NXOAuth2PostBodyStream *)postBodyStream length]];
// [aRequest setValue:contentType forHTTPHeaderField:@"Content-Type"];
// [aRequest setValue:contentLength forHTTPHeaderField:@"Content-Length"];
//
// [aRequest setHTTPBodyStream:postBodyStream];
// fix for oAuth Token request: Changed HTTP Content-Type to application/x-www-form-urlencoded
// by (Przemek Szalko <przemek@mobtitude.com>)
NSData *httpBody = [[parameters urlEncode] dataUsingEncoding:NSUTF8StringEncoding];
NSString *contentType = [NSString stringWithFormat:@"application/x-www-form-urlencoded"];
NSString *contentLength = [NSString stringWithFormat:@"%d", [httpBody length]];
[aRequest setValue:contentType forHTTPHeaderField:@"Content-Type"];
[aRequest setValue:contentLength forHTTPHeaderField:@"Content-Length"];
[aRequest setHTTPBody:httpBody];
}
}
It uses my custom NSDictionary category which encodes all entries from dictionary to HTTP Body string: [parameters urlEncode]
.
You need to encode all types of possible values in dictionary, for NSString the implementation is as follow:
// Encode a string to embed in an URL.
- (NSString*)urlEncode
{
return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef) self,
NULL,
(CFStringRef) @"!*'();:@&=+$,/?%# ",
kCFStringEncodingUTF8));
}
For NSArray and embedded NSDictionary I just iterate recursively through each item in dictionary or array and use the above code to escape NSStrings.
Implementation of urlEncode
in NSDictionary:
- (NSString*)urlEncode
{
return [[self encodeHttpBodyParamsWithParentKey:nil] componentsJoinedByString:@"&"];
}
- (NSArray*)encodeHttpBodyParamsWithParentKey:(NSString*)parentKey
{
NSMutableArray *encodedParams = [NSMutableArray arrayWithCapacity:[self count]];
for(NSString *dictKey in [self allKeys]) {
id value = [self objectForKey:dictKey];
NSString *key = dictKey;
NSString *encodedValue;
if([parentKey length] > 0) {
key = [parentKey stringByAppendingFormat:@"[%@]", key];
}
// NSDictionary
if([value isKindOfClass:[NSDictionary class]]) {
NSArray *temp = [(NSDictionary*)value encodeHttpBodyParamsWithParentKey:dictKey];
[encodedParams addObjectsFromArray:temp];
// NSArray
} else if([value isKindOfClass:[NSArray class]]) {
NSArray *arrayValue = (NSArray*)value;
NSArray *temp = [arrayValue encodeHttpBodyParamsWithKey:key];
[encodedParams addObjectsFromArray:temp];
// NSSet
} else if([value isKindOfClass:[NSSet class]]) {
NSArray *temp = [[value allObjects] encodeHttpBodyParamsWithKey:key];
[encodedParams addObjectsFromArray:temp];
// NSNull
} else if([value isKindOfClass:[NSNull class]]) {
[encodedParams addObject:[NSString stringWithFormat:@"%@=NULL", key]];
// NSString & Others
} else {
encodedValue = [[value description] urlEncode];
[encodedParams addObject:[NSString stringWithFormat:@"%@=%@", key, encodedValue]];
}
}
return encodedParams;
}
Implementations of method urlEncode
in NSArray and NSSet are almost identical.
Seems like this is supported now. can this issue be closed?
You are right :-)
Currently NXOAuth2Connection always sends POST requests as multipart/form-data.
We had use case where OAuth2 server didn't accept multipart/form-data but required Content-Type set to application/x-www-form-urlencoded.
In current OAuth2Client implementation there is no easy way to change how POST requests are send to server.
It would be very helpful to allow developers to change Content-Type of POST requests to application/x-www-form-urlencoded.