Why, after setting an NSHTTPCookie, is it not appended to the NSURLRequest? - objective-c

I am setting (or attempting to set) an NSHTTPCookie as follows:
+ (void)setCookie {
NSString* cookieName = #"MyCookieName";
NSString* cookieValue = #"MyCookieValue";
NSString* cookieOriginURL = #"www.mycompany.com";
NSString* cookiePath = #"/";
NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:cookieName forKey:NSHTTPCookieName];
[cookieProperties setObject:cookieValue forKey:NSHTTPCookieValue];
[cookieProperties setObject:cookieOriginURL forKey:NSHTTPCookieOriginURL];
[cookieProperties setObject:cookiePath forKey:NSHTTPCookiePath];
[cookieProperties setObject:[[NSDate date] dateByAddingTimeInterval:3600] forKey:NSHTTPCookieExpires];
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
}
After this method is called, I create an NSURLRequest:
NSString *urlAddress = #"http//:www.mycompany.com/mobile/home";
//Create a URL object.
NSURL *url = [NSURL URLWithString:urlAddress];
//URL Request Object
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
NSLog(#"Here's the request: %#", [requestObj description]);
//Load the request in the UIWebView.
[self.webView loadRequest:requestObj];
But the output is:
Here's the request: <NSURLRequest: 0xa33a4d0> { URL: http:www.mycompany.com/mobile/home
I expected to see the cookie info appended to the request, but it is not.
I don't know much about cookies, so I don't know if my code is missing something, or if I'm just miss interpreting what the output means.
Thanks for any help.

I doubt that the description of the NSURLRequest will provide the cookie information.
The domains are a match (cookie and the URL), so the cookie must be appended to the request. Execute the following code before firing the request to see which cookies are sent along with your request.
NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for(NSHTTPCookie *cookie in [cookieJar cookiesForURL:url]) {
NSLog(#"Cookies attached: %#", cookie.description);
}

Related

IOS Application to send data to a REST API service content-type definition error

I managed to make an application to send data to a rest api service. The content type must be text/html. But whenever i run my app i get a 415 http code response which means not supported type of content. Here is my code:
NSURL *url = [NSURL new];
NSData *body = nil;
NSString *contentType = #"text/html";
NSURL *finalURL = [NSURL URLWithString:[NSString stringWithFormat:#"http://telesto.zapto.org:81/SMART_EdgeNode/EdgeNode/DataFeeds/3/addMeasurement"]];
NSString *yourString = #"geoX#35#geoY#65";
contentType = #"application/x-www-form-urlencoded; charset=utf-8";
body = [[NSString stringWithFormat:#"%#", yourString] dataUsingEncoding:NSUTF8StringEncoding];
NSString *putLength = [NSString stringWithFormat:#"%d",[body length]];
if (nil==finalURL) {
finalURL = url;
}
NSMutableDictionary* headers = [[[NSMutableDictionary alloc] init] autorelease];
[headers setValue:contentType forKey:#"Content-Type"];
[headers setValue:#"mimeType" forKey:#"Accept"];
[headers setValue:#"no-cache" forKey:#"Cache-Control"];
[headers setValue:#"no-cache" forKey:#"Pragma"];
[headers setValue:#"close" forKey:#"Connection"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:finalURL
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[request setHTTPMethod:#"PUT"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:body];
[request setValue:putLength forHTTPHeaderField:#"Content-Length"];
self.conn = [NSURLConnection connectionWithRequest:request delegate:self];
I guess atm there is something wrong with defining the content-type . Any help??
Thanks in advance
Ok i found it at last. It was this specific line that was causing the problem and had to do something with the content-type :
contentType = #"application/x-www-form-urlencoded; charset=utf-8";
After removing that i was able to send properly my string to the server.
I think the server's complaining that it doesn't know how to generate a response with the content type "mimeType".
Your Accept header should be "text/html" or whatever the content type you expect in the response, not "mimeType".
Update
After reading this again, I notice that you are setting the contentType to #"text/html", then to #"application/x-www-form-urlencoded; charset=utf-8". Which do you need? From the description, you want to sent text/html, but that is not what your sending. When you set contentType to #"application/x-www-form-urlencoded; charset=utf-8", text/html is lost.

Objective C HTML Request

I am just starting out in Xcode and wanted to try and make a simple app where you press a button and it creates a html post request and returns the html in a string i can't then fiddle with. I realise i would be better server using path or soap or xml, but this is step 1 for me.
The problem i am having is that I can't understand why i get null data returned after my request. I think it might be something to do with me trying to convert the NSData variable into a string?
below is the code for the button press, and below that is the NSLog Details of what is coming out.
Could anyone please suggest what i am doing wrong with this?
Cheers,
John
-(IBAction)buttonTouchedSignIn{
NSString *userName = #"mymadeupuser";
NSLog (#"NSString userName = %#\n\n", userName);
NSString *password = #"1234";
NSLog (#"NSString password = %#\n\n", password);
NSString *url = #"http%3A%2F%2Fmyotherwebsite.com%3A80%2Fsomthing%2Fweb%2Faction%2Flogin.do%3FtargetURL%3Dhttp%3A%2F%2Fsomwherelse.com%2Fsite3%2Fweb3%2Faction%2FmyAccountMenu.do%3Fdscnt%3D0%26vid%3DBSU";
NSLog (#"NSString url = %#\n\n", url);
// Create the username and password string.
// username and password are the username and password to login with
NSString *postString = [[NSString alloc] initWithFormat:#"bor_id=%#&bor_verification=%#&url=%#",userName, password, url];
NSLog (#"NSString postString = %#\n\n", postString);
// Create the URL request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString:#"https://mywebsite.com/somthing/"]];
NSLog (#"NSString NSMutableURLRequest = %#\n\n", request);
NSData *requestData = [postString dataUsingEncoding:NSASCIIStringEncoding];
[request setHTTPBody: requestData]; // apply the post data to be sent
NSLog (#"NSData requestData = %#\n\n", requestData);
// Call the URL
NSURLResponse *response; // holds the response from the server
NSLog (#"NSURLResponse response = %#\n\n", response);
NSError *error; // holds any errors
NSLog (#"NSError error = %#\n\n", error);
NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse:&response error:&error]; // call the URL
NSLog (#"NSData returnedData = %#\n\n", returnData);
//If the response from the server is a web page, dataReturned will hold the string of the HTML returned.
NSString *dataReturned = [[NSString alloc] initWithData:returnData encoding:NSASCIIStringEncoding];
NSLog(#"returned htmlASCII is: %#\n\n", dataReturned);
NSString *dataReturned2 = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(#"returned htmlUTF8 is: %#\n\n", dataReturned2);
}
Here is the NSLog output for all the variables
2012-03-29 12:10:04.306 MyApp[2635:f803] NSString userName = mymadeupusername
Current language: auto; currently objective-c
2012-03-29 12:10:16.520 MyApp[2635:f803] NSString password = 1234
2012-03-29 12:10:16.520 MyApp[2635:f803] NSString url = http%3A%2F%2Fsomewebpage.com%3A80%2Fweb2%2Fweb3%2Faction%2Fsigin.go%3FtargetURL%3Dhttp%3A%2F%2Fsomewebpage.com%2Fweb2%2Fweb3%2Faction%2Fyouraccounts.go%3Fdscnt%3D0%26vid%3DBSU
2012-03-29 12:10:16.521 MyApp[2635:f803] NSString postString = bor_id=joeliot&bor_verification=1234&url=http%3A%2F%2Fsomewebpage.com%3A80%2Fweb2%2Fweb3%2Faction%2Fsigin.go%3FtargetURL%3Dhttp%3A%2F%2Fsomewebpage.com%2Fweb2%2Fweb3%2Faction%2Fyouraccounts.go%3Fdscnt%3D0%26vid%3DBSU
2012-03-29 12:10:16.522 MyApp[2635:f803] NSString NSMutableURLRequest = https://somewebpage.com/pds?func=login&calling_system=blah&term1=short&company=BSU>
2012-03-29 12:10:16.522 MyApp[2635:f803] NSData requestData =
2012-03-29 12:10:16.650 MyApp[2635:f803] NSURLResponse response = (null)
2012-03-29 12:10:16.651 MyApp[2635:f803] NSError error = (null)
2012-03-29 12:10:17.422 MyApp[2635:f803] NSData returnedData = (null)
2012-03-29 12:10:17.422 MyApp[2635:f803] returned htmlASCII is:
2012-03-29 12:10:17.422 MyApp[2635:f803] returned htmlUTF8 is:
A few things I see:
1) You need to set the method as POST. Use setHTTPMethod on your request.
2) You need a content lenght Do something like: [request setValue:length forHTTPHeaderField:#"Content-Length"]; where length is a string representation of the number of bytes you are posting.
3) You probably need to set the host to the hostname of the server. This depends a bit per server, but they tend to reject things not for their hostname(s). Use setValue again.
4) You should probably have a content-type. Again, depends on the server, but most certainly good practice to have.
5) UTF8 string encoding is nicer than ascii, most of the web plays better with it.
I hope at least one of those helps. Good luck.

Basic authorization in NSMutableURLRequest isn't working

I'm trying to add basic authorization to my request header. The code below compiles and I dont get any runtime errors. However, on the server side I do not see the "Authorization" in the header at all.
I was able to implement the didReceiveAuthenticationChallenge method and that works, but I dont understand why I have to do it this way. I simply want to always add basic auth to every request.
I'm not interested in using ASIHTTPRequest.
Thanks for the help!
This is my code below:
NSURL *url = [[NSURL alloc] initWithString:#"http://localhost:8000/MyWebService"];
self.userName = #"myusername";
self.password = #"mypassword";
NSMutableString *credentials = [[NSMutableString alloc] initWithFormat:#"%#:%#", userName, password];
NSString *encodedCredentials = [[credentials dataUsingEncoding:NSUTF8StringEncoding] base64EncodedString];
NSString *authHeader = [NSString stringWithFormat:#"Basic %#", encodedCredentials];
NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5];
[req addValue:authHeader forHTTPHeaderField:#"Authorization"];
self.urlConnection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES];
if (self.urlConnection) {
self.receivedData = [NSMutableData data];
}
else {
errorLabel.text = #"Error connecting to the server";
}
The didReceiveAuthenticationChallenge is the way it works in iOS and the easiest way to do it. It will be submitted with every request (with the challenge). Guess that's not what you want to hear=)
I guess you have tried using different tutorials. I've used this one to authenticate before:
Basic access Auth, iOS

How to access secured url from ios

I'm trying to access a secure url from ios. Basically url will prompt the user with Username and Password. How can I send username and Password from ios?
My Code
Here is the Methods that I'm using to access JSON Parser
- (NSString *)stringWithUrl:(NSURL *)url{
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:30];
// Fetch the JSON response
NSData *urlData;
NSURLResponse *response;
NSError *error;
// Make synchronous request
urlData = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
// Construct a String around the Data from the response
return [[[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding] autorelease];}
- (id) objectWithUrl:(NSURL *)url{
SBJsonParser *jsonParser = [[[SBJsonParser alloc]init] autorelease];
NSString *jsonString = [self stringWithUrl:url];
// Parse the JSON into an Object
return [jsonParser objectWithString:jsonString error:nil]; }
Here is the piece of code that I'm retrieving json keys to my dictionary.
- (NSDictionary *) downloadFeed {
id response = [self objectWithUrl:[NSURL URLWithString:#"http://mysite.com/Services/Secure.svc/GetList?id=2127"]];
NSDictionary *feed = (NSDictionary *)response;
return feed; }
Can someone let me know where can I pass the Username and Password to this url?
Either switch to ASIHTTPRequest, which handles Basic authentication simply, or use a NSMutableRequest and set the Authorization header correctly, with a base64 encoded user:password pair.

Creating a POST/GET request using Objective -C [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Tutorials for using HTTP POST and GET on the iPhone in Objective-C
Is there away to create an NSArray with the correct information like id = 1, name = #"John", score = 100 then send it and receive a response from the server?
Maybe display it inside an NSLog();
Can anyone help answer this question by linking me to a good tutorial, I don't want to use ASIHTTPRequest either. I know it would be much simpler but if there is away to do something without using a load of prewritten code id rather learn how to make something using the functionality the the foundation framework offers before going off using someone elses classes.
What you're looking for is NSMutableURLRequest and the addValue:forHTTPHeaderField method.
Create the request with the URL you wish to communicate with. Load the values you wish to transmit into the header or into the HTTPBody, set your HTTPMethod and then use a NSURLConnection method to send and receive the response.
As for an array with the information you could simply enumerate through the array and add the values to the HTTPHeaderFields. It really depends on what the server is setup to receive.
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html#//apple_ref/doc/uid/10000165i
Has more information.
NSString *urlString = #"http://yoururl.com";
NSURL *url = [NSUL URLWithString:urlString];
NSMutalbeURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSDictionary *headerInformation = [NSDictionary dictionaryWithObjectsAndKeys:#"1",#"id",#"John",#"name",#"100",#"score", nil];
for (NSString *key in [headerInformation allKeys])
{
[request addValue:[dict valueForKey:key] forHTTPHeaderField:key];
}
NSHTTPURLResponse *response = nil;
NSError *error = nil;
// this will perform a synchronous GET operation passing the values you specified in the header (typically you want asynchrounous, but for simplicity of answering the question it works)
NSData *responseData = [NSURLConnection sendSynchronousRequest:request reuturningResponse:&response error:&error];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"Response: %#", responseString);
[responseString release];
It might be easier to just use NSData to send a url request and store the response then to reinvent the wheel. Here is some code similar to something in my production project:
+ (NSData *)getProfiles {
NSString *token = [[NSUserDefaults standardUserDefaults] objectForKey:#"token"];
// Create string of the URL
NSString *serviceURL = [NSString stringWithFormat:#"http://www.myurlhere.com/getProfiles.php?token=%#", token];
NSLog(#"Service URL : %#", serviceURL);
// Create a NSURL out of the string created earlier. Use NSASCIIStringEncoding to make it properly URL encoded (replaces " " with "+", etc)
NSURL *URL = [NSURL URLWithString:[serviceURL stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
// Request the url and store the response into NSData
NSData *data = [NSData dataWithContentsOfURL:URL];
if (!data) {
return nil;
}
// Since I know the response will be 100% strings, convert the NSData to NSString
NSString *response = [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease];
// Test response and return a string that an XML Parser can parse
if (![response isEqualToString:#"UNAUTHORIZED"]) {
response = [response stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
data = [response dataUsingEncoding:NSASCIIStringEncoding];
return data;
} else {
return nil;
}
}
NSLog output:
[Line: 476] +[WebSupport getProfiles]: Service URL : http://www.myurlhere.com/getProfiles.php?token=abcdef0123456789abcdef0123456789