0

I'm building a request that will be a simple http POST. Inside this post I need to add a few items and one of these is a large viewstate string that is pulled down during a previous request. What I've noticed is that the raw request needs to have all special chars escaped (like the below)

_EVENTTARGET=&_EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwUENTM4MQ9kFgJmD2QWAmYPZBYCZg9kFgJmD2QWAgIBEGRkFgQCAQ9kFgICBw9kFgJmD2QWCmYPFgIeA3NyYwUpL2Fzc2V0cy9pbWFnZXMvc2l0ZW1haW5uYXYtcmVudG9ubGluZS5wbmdkAgEPFgIfAAUlL2Fzc2V0cy9pbWFnZXMvc2l0ZW1haW5uYXYtc3BhY2VyLnBuZ2QCAg8WAh8ABSUvYXNzZXRzL2ltYWdlcy9zaXRlbWFpbm5hdi1tb3ZpZXMucG5nZAIDDxYCHwAFJS9hc3NldHMvaW1hZ2VzL3NpdGVtYWlubmF2LXNwYWNlci5wbmdkAgQPZBYCZg9kFgZmDxYCHwAFLi9hc3NldHMvaW1hZ2VzL3NpdGVtYWlubmF2LWtpb3Nrc2Fub255bW91cy5wbmdkAgEPFgIfAAUlL2Fzc2V0cy9pbWFnZXMvc2l0ZW1haW5uYXYtc3BhY2VyLnBuZ2QCAg8WAh8ABSgvYXNzZXRzL2ltYWdlcy9zaXRlbWFpbm5hdi1idXlPbmxpbmUucG5nZAICD2QWAgIBD2QWAgIGD2QWAgIBD2QWAmYPZBYCAgIPEA8WAh4EVGV4dAVTUmVjb2duaXplIG1lIGZvciAxNCBkYXlzIChEbyBub3QgY2hlY2sgdGhpcyBib3ggaWYgeW91IGFyZSB1c2luZyBhIHNoYXJlZCBjb21wdXRlcilkZGRkGAEFHl9fQ29udHJvbHNSZXF1aXJlUG9zdEJhY2tLZXlfXxYBBVVjdGwwMCRjdGwwMCRjdGwwMCRjdGwwMCRNYWluQ29udGVudCRNYWluQ29udGVudCRNYWluQ29udGVudCRiYnhsb2dpbl83JGNoa1JlY29nbml6ZU1lNZH1xfrz8glwi2XmQJFTCJ0dMNk%3D&

But I'm not certain that I've done this in objective-c. Currently when I NSLog out the viewstate string it is still showing / and = characters.

Can anyone verify I'm on the right path here? And if not how would I convert the special chars in viewstate (ie - instead of = I should get %3D)?

- (void)doHttpPostWithViewState:(NSString *)viewstate
{ 
  responseData = [[NSMutableData data] retain];

  NSURL *url = [NSURL URLWithString:@"https://localhost/Login"];
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];

  NSString* theBodyString = [[NSString alloc] initWithFormat:@"__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%@",viewstate];
  NSData *requestData = [theBodyString dataUsingEncoding:NSUTF8StringEncoding];

  NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];

  [request setHTTPMethod:@"POST"];
  [request setValue:@"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" forHTTPHeaderField:@"Accept"];
  [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
  [request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"];
  [request setHTTPBody: requestData];
  [request setAllHTTPHeaderFields:headers];

  [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

And finally, for local debugging purposes- how can I use NSLog to view the final (raw) string that will be sent to the client? Thank you in advance!

Update

Turns out this is a bug in the stringByAddingPercentEscapesUsingEncoding method

I've found the following to work from this blog post

NSString * cleanViewState = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                                                                                 NULL,
                                                                                 (CFStringRef)viewstate,
                                                                                 NULL,
                                                                                 (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                                                 kCFStringEncodingUTF8 );
Toran Billups
  • 27,111
  • 40
  • 155
  • 268
  • possible duplicate of [Objective-c iPhone percent encode a string?](http://stackoverflow.com/questions/3423545/objective-c-iphone-percent-encode-a-string) – Dave DeLong Jan 17 '11 at 03:11
  • 1
    Just a small point, it's not a bug. The documentation says that escapes are added to "convert the receiver into a legal URL string". Clearly for a legal URL string, you need to preserve `/`, `&` and `=` otherwise something like `http://www.google.co.uk/search?rls=en&q=nsstring` would get converted into something that is not a URL. – JeremyP Jan 17 '11 at 09:44

1 Answers1

5

You're probably looking for the stringByAddingPercentEscapesUsingEncoding: method on NSString to %-encode your POST request.


Update:

If the NSString method isn't getting all the special characters you need, the next step is to drop down to the Core Foundation level function (CFURLCreateStringByAddingPercentEscapes), which gives you better control. See http://simonwoodside.com/weblog/2009/4/22/how_to_really_url_encode/

David Gelhar
  • 27,873
  • 3
  • 67
  • 84
  • When I do the following the "cleanViewState" still has special chars NSString* cleanViewState = [viewstate stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; – Toran Billups Jan 17 '11 at 03:26