NSMutableURLRequest and a Password with special Characters won't work - iphone

I'm writing a small program (using Cocoa Touch), which communicates with a webservice.
The code for calling the webservice, is the following:
- (IBAction)send:(id)sender
{
if ([number.text length] > 0)
{
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[activityIndicator startAnimating];
NSString *modded;
modded = [self computeNumber];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL: [NSURL URLWithString:#"https://tester:%=&=-Test2009#samurai.sipgate.net/RPC2"]];
[theRequest setHTTPMethod:#"POST"];
[theRequest addValue:#"text/xml" forHTTPHeaderField:#"content-type"];
[theRequest setCachePolicy:NSURLCacheStorageNotAllowed];
[theRequest setTimeoutInterval:5.0];
NSString* pStr = [[NSString alloc] initWithFormat:#"<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodCall><methodName>samurai.SessionInitiate</methodName><params><param><value><struct><member><name>LocalUri</name><value><string></string></value></member><member><name>RemoteUri</name><value><string>sip:%##sipgate.net</string></value></member><member><name>TOS</name><value><string>text</string></value></member><member><name>Content</name><value><string>%#</string></value></member><member><name>Schedule</name><value><string></string></value></member></struct></value></param></params></methodCall>", modded, TextView.text];
NSData* pBody = [pStr dataUsingEncoding:NSUTF8StringEncoding];
[theRequest setHTTPBody:pBody];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (!theConnection)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"A Connection could not be established!"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alert show];
[alert release];
sendButton.enabled = TRUE;
return;
}
[pStr release];
[pBody release];
}
}
The Username and Password have to be in the URL, and it works in most cases, but when the password consists of special characters like in the example "%=&=-Test2009", the Webservice does not respond. If it is something like "Test2009" it works fine. Does anyone have an idea why, and maybe a solution for that?

Special characters have to be URL encoded, the URL you requested,
https://tester:%=&=-Test2009#samurai.sipgate.net/RPC2
..is invalid, specifically the %= part (% is used for escaping characters, for example %20 is used to represent a space), so..
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:
[NSURL URLWithString:#"https://tester:%=&=-Test2009#samurai.sipgate.net/RPC2"]];
..should change to something like:
NSString *theAddress = [NSString stringWithFormat:#"https://%#:%##%#",
[#"tester" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[#"%=&=-Test2009" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
#"example.com"];
NSURL *theURL = [NSURL URLWithString:theAddress];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:theURL];
This requests the URL https://tester:%25=&=-Test2009#example.com

You must use URL safe characters in your string when making the URL, use this NSString method stringByAddingPercentEscapesUsingEncoding: which will do this for you.

Related

Sending post variables to iOS form

I am trying to send a username and password to a website which is normally done through a form. The server however is redirecting me to a login page, which usually occurs when the username and password is wrong. The username is in the form of an email address and the password is a string.
I do currently have access to the website as the developer is away to check that the values are being processed correctly. Can anyone see any obvious errors in the code I have created below?
Please note I have removed the URL from the example code for privacy reasons.
// Validate login
-(bool)validateLogin{
// Initialize URL to be fetched
NSURL *url = [NSURL URLWithString:#"removedurl"];
NSString *post = #"username=example1%40example.com&password=example2";
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
// Initalize a request from a URL
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[url standardizedURL]];
//set url
[request setURL:url];
//set http method
[request setHTTPMethod:#"POST"];
//set request length
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
//set request content type we MUST set this value.
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
//set post data of request
[request setHTTPBody:postData];
NSLog(#"%#", [request allHTTPHeaderFields]);
//initialize a connection from request
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
_connection = connection;
//start the connection
[connection start];
return YES;
}
This string is not correct NSString *post = #"username=example1%40example.com&example2";
After ampersand you have to provide key=value.
#"key1=value1&key2=value2";
Example of working code:
In .h file set delegate:
#interface Controller <NSURLConnectionDataDelegate>
In .m file:
- (void)login {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:kRequestTimeOut];
request.HTTPMethod = #"POST";
NSString *params = #"key1=value1&key2=value2";
request.HTTPBody = [params dataUsingEncoding:NSUTF8StringEncoding];
_data = [NSMutableData data];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[_data appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
//Parse your '_data' here.
}

NSURLConnection error not working

I am trying to detect if there is an error in my request using the if statement on theConnection. It enters the first part if successful fine but does not enter the else if there is an error. I am not sure why.
- (void)vehicleSearchRequest:(NSData *)postBodyData
{
NSString *address = [NSString stringWithFormat:#"http://%#", serverAddress];
//Set database address
NSMutableString *databaseURL = [[NSMutableString alloc] initWithFormat:#"%#", address];
NSURL *url = [NSURL URLWithString:databaseURL];
NSString *postLength = [NSString stringWithFormat:#"%d", [postBodyData length]];
//SynchronousRequest to grab the data, also setting up the cachePolicy
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //if request dose not finish happen within 60 second timeout.
// Set up request
[request setHTTPMethod: #"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/octet-stream" forHTTPHeaderField:#"content-type"];
[request setHTTPBody:postBodyData];
[request setTimeoutInterval:180];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
if (theConnection) {
// do animation thankyou here
NSLog(#"Sucsess!");
[self submitSuccessful];
} else {
// Inform the user that the connection failed from the connection:didFailWithError method
NSLog(#"Connectin ERROR!!!");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Connection error, Please try again" message:nil delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
Your code checks to see whether it was able to instantiate an NSURLConnection or not. This is a useful safety check, but will only fail in practice if you pass it a URL that the system does not support.
The connection itself is asynchronous, and so will take a little while to tell you if there was a problem or not. Implement its delegate methods to hear back from the server.

Sending JSON Request to server?

I have following JSON for sending request on server
{
"name":"Home",
"latitude":"45.5037078163837",
"longitude":"-122.622699737549",
"radius":"240"
}
and URL of for request is
URL: https://api.geoloqi.com/1/place/create
I am making request like this,
NSString *urlString= #"https://api.geoloqi.com/1/place/create ";
NSURL* url = [[NSURL alloc] initWithString:urlString];
NSString *jsonRequest = #"{\"name\":\"veer\",\"latitude\":\"45.5037078163837\",\"longitude\":\"-122.622699737549\,\"radius\":\"500\ }";
jsonRequest = [self JSONString:jsonRequest];
NSData* requestData = [jsonRequest dataUsingEncoding:NSUTF8StringEncoding];
NSString* requestDataLengthString = [[NSString alloc] initWithFormat:#"%d", [requestData length]];
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:requestData];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:requestDataLengthString forHTTPHeaderField:#"Content-Length"];
[request setTimeoutInterval:30.0];
[url release];
[requestData release];
[requestDataLengthString release];
NSURLConnection *m_URLConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[request release];
What is wrong with this request ?
Your JSON string seems to be missing 2 quotes after the longitude and radius values:
Change
NSString *jsonRequest = #"{\"name\":\"veer\",\"latitude\":\"45.5037078163837\",\"longitude\":\"-122.622699737549\,\"radius\":\"500\ }";
To this
NSString *jsonRequest = #"{\"name\":\"veer\",\"latitude\":\"45.5037078163837\",\"longitude\":\"-122.622699737549\",\"radius\":\"500\" }";
It is not clear from your question what is your issue with that.
Anyway, are you doing also:
[m_URLConnection start];
after creating the connection?
Alternatively, you could create the connection using
[– initWithRequest:delegate:startImmediately:][1]
which allows you to specify that the loading of data shall start immediately.
Also consider using [+sendAsynchronousRequest:queue:completionHandler:][2] as a convenience constructor for your connection.
The Webservice URL you are trying to hit is seem to be using SSL. You may need to put access token in request header in order to get the proper response from web service.
Please see the link for authentication:
https://developers.geoloqi.com/api/authentication

iPhone [request setTimeoutInterval:10] not working, app freezes

When I chnage to port number I'm connecting to to test the timout, my app freezes.
I am calling [request setTimeoutInterval:10];, which I assume should be 10 seconds. But, the app hangs. Could it have something to do with it being a local server?
Code:
// call this when program first starts
-(void) nSendMessage : (NSString *) name Password: (NSString *) password page: (NSString *) page
{
// set the url
NSString *address = #"http://localhost:1075/update";
address=[ address stringByAppendingString: page];
NSMutableURLRequest *request =
[[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString:address]];
// post or get
[request setHTTPMethod:#"POST"];
// data to send
NSString *postString = #"username=iusername&password=ipassword";
NSString *sendString=[postString stringByReplacingOccurrencesOfString:#"iusername" withString: name];
sendString=[sendString stringByReplacingOccurrencesOfString:#"ipassword" withString: password];
[request setValue:[NSString
stringWithFormat:#"%d", [sendString length]]
forHTTPHeaderField:#"Content-length"];
[request setHTTPBody:[sendString
dataUsingEncoding:NSUTF8StringEncoding]];
[request setTimeoutInterval:10];
[[NSURLConnection alloc]
initWithRequest:request delegate:self];
//
//THE PROGRAM FREEZES HERE
//
NSData *urlData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *response = [[NSString alloc] initWithData:urlData encoding:NSASCIIStringEncoding];
// Phrase repl
[self nUpdateDisplay:response];
}
Your question looks like a dupe of this one:
iPhone SDK: URL request not timing out
So to summarise: the timeout lower limit is at least four minutes, even if you pass in a smaller value.
And as detailed at the above link, using the asynchronous method is usually the best option. If you use synchronous, as you are doing above, and you're in the main runloop, you will block your UI completely, which will cause the 'hang' effect.

How to post a string to web server url in iphone sdk?

How can I post a string(i.e) a word to web server url in iphone sdk?
Some sample codes or tutorials would be appreciated.
Thanking you.
This may help you, although I havent tested it:
NSMutableString *httpBodyString;
NSURL *url;
NSMutableString *urlString;
httpBodyString=[[NSMutableString alloc] initWithString:#"Name=The Big Bopper&Subject=Hello Baby&MsgBody=...You knooow what I like...Chantilly lace..."];
urlString=[[NSMutableString alloc] initWithString:#"http://www.somedomain.com/contactform.php"];
url=[[NSURL alloc] initWithString:urlString];
[urlString release];
NSMutableURLRequest *urlRequest=[NSMutableURLRequest requestWithURL:url];
[url release];
[urlRequest setHTTPMethod:#"POST"];
[urlRequest setHTTPBody:[httpBodyString dataUsingEncoding:NSISOLatin1StringEncoding]];
[httpBodyString release];
NSURLConnection *connectionResponse = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
if (!connectionResponse)
{
NSLog(#"Failed to submit request");
}
else
{
NSLog(#"--------- Request submitted ---------");
NSLog(#"connection: %# method: %#, encoded body: %#, body: %a", connectionResponse, [urlRequest HTTPMethod], [urlRequest HTTPBody], httpBodyString);
NSLog(#"New connection retain count: %d", [connectionResponse retainCount]);
responseData=[[NSMutableData data] retain];
NSLog(#"response", responseData);
}
Source: http://www.iphonedevsdk.com/forum/iphone-sdk-development/6341-help-executing-http-url-post-variables.html
You can post the string to webservice in so many ways, In those one is
Using Rest protocol:
It has two sub types, HTTP GET, HTTP POST. The Http Get is simple.
You can add the value to the attribute and you can directly call the service.
Check the following code.
NSString *url = #"http://123.456.789.0?action=get_movies";
Here the I am passing the get_movies string to the server to the action attribute.
and then follow the code for requesting to server.
NSURL *reqUrl = [[NSURL alloc] initWithString:url];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:reqUrl];
NSError *error;
NSURLResponse *response;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSStringEncoding responseEncoding = NSUTF8StringEncoding;
if ([response textEncodingName]) {
CFStringEncoding cfStringEncoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)[response textEncodingName]);
if (cfStringEncoding != kCFStringEncodingInvalidId) {
responseEncoding = CFStringConvertEncodingToNSStringEncoding(cfStringEncoding);
}
}
[reqUrl release];
NSString *dataString = [[NSString alloc] initWithData:data encoding:responseEncoding];
the dataString is the responseString from the server. You can use that.
Regards,
Satya.