ASIHTTPRequest and NSURLRequest different result - objective-c

I send request to some url with ASIHTTPRequest, and always get strange response with different HTML body. If i make same request from browser or from NSURLRequest class, i get correct response with correct HTML body.
//Here is code of NSURLRequest. I'm getting correct response;
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *resp = nil;
NSError *err = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest: request returningResponse: &resp error: &err];
NSString *theString = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding];
NSLog(#"%#",theString);
//Here is code of ASIHTTPRequest. I'm getting different response. The html body is shorter than original and different;
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setCompletionBlock:^{
NSString *responseString = [request responseString];
}];
[request startAsynchronous];
I also tryed to send simple synchronous request with ASIHTTPRequest, but result the same. What it could be?

may be server have different logic for different request header

Related

Http request with method type patch using objective c

I am trying to send a http url request of method type 'PATCH' below is my sample code .
NSString *urlString=#"http://0.0.0.0:8000/v1/APvk";
para=[para stringByAppendingFormat:#"/%#?accessToken=",#"SOMEID"];
para= [para stringByAppendingString:#"SOMEACCESSTOKEN"];
NSURL *url = [NSURL URLWithString:para];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
if (!request) NSLog(#"Error creating the URL Request");
[request setHTTPMethod:#"PATCH"];
[request setHTTPBody:data];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
// Send a synchronous request
NSURLResponse * response = nil;
NSError * NSURLRequestError = nil;
NSData * responseData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&NSURLRequestError];
NSLog(#"%#",responseData);
NSDictionary *Replyfromserver=[NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];
NSLog(#"%#",Replyfromserver);
I don't know how to send a PATCH request I am just doing the same way we send a POST request ,here I am getting a message from server that is "Invalid Payload" Help me out of this.

Objective C Update RESTful Webservice

I have a web service that allows me to update records on in our database.
The columns in the table are as follows:
allowsActions
assetID
inventoryObjectID
objectDescription
quantity
retired
serialNumber
action
I'm using the following to GET data from the webservice.
NSString *urlString = [NSString stringWithFormat:#"%#", inventoryAndActionsWebservice];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"GET"];
Then shoving into a dictionary like so:
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
if (data.length > 0 && connectionError == nil)
{
NSLog(#"WE HAS THE DATAS");
NSDictionary *inventory = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
// Then storing the values in CoreData here
}
}
What would be the syntax for updating the webservice? It expects an object in the body of the service call (POST).
NSMutableURLRequest let's you setHTTPBody: and setHTTPMethod:.#"POST"is the way to do a post. Most services need to know the body length and encoding set in headers. (seeaddValue:forHTTPHeaderField:`) for that.
The only reason this topic is tricky is because the developer is forced to grapple with two problems at once: what constitutes a valid request for my server, and (2) how do I form that request with iOS? Part (2) is actually pretty easy once you get a valid request.
The best way to proceed is to get an example working using curl (or something equivalent). Then move on to producing that request in iOS. If you have trouble, ask a question here of the form: "I know my server needs X, here's my code to produce X, but I'm getting this error Y".
So the syntax that I was looking for was ultimately this:
NSString *jSONString = [NSString stringWithFormat:#"{\"MediaInventoryObjectsId\":%d,\"AssetId\":%d,\"Quantity\":%d,\"SerialNumber\":\"%#\",\"Description\":\"%#\",\"AllowActions\":%d,\"Retired\":%d}",inventoryObjectId, assetID, quantity, serialNumber, description, allowActions, retired];
// Convert jSON string to data
NSData *putData = [jSONString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
// Instantiate a url request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
// Set the request url format
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#/%d", inventoryAndActionsWebservice, inventoryObjectId]]];
[request setHTTPMethod:#"PUT"];
[request setHTTPBody:putData];
[request setValue:#"application/json" forHTTPHeaderField:#"content-type"];
// Send data to the webservice
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

Obj-C NSURLConnection not working

So i am trying to send data to a webservice via url with a parameter. the code i have is below but it never hits the server. the request and responses are null. What am i doing wrong?
-(void) postData:(NSString *)data{
NSURLResponse* response;
NSError* error = nil;
NSString *urlString = [NSString stringWithFormat:#"http://someaddress.com/api?data=%#", data];
NSURL *lookupURL = [NSURL URLWithString:urlString];
//Create the request.
NSURLRequest *theRequest=[NSURLRequest requestWithURL:lookupURL];
NSData *request = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&error];
NSString *dataString = [[NSString alloc] initWithData:request encoding:NSUTF8StringEncoding];
NSLog(#"-----------------------------");
NSLog(#"Request: %#", theRequest);
NSLog(#"req response: %#", request);
NSLog(#"response: %#", dataString);}
you want to POST some binary data but you do a GET request and try to put the binary into the url. (without encoding it)
sample post:
NSURL *url = [NSURL URLWithString:#"http://server.com"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = #"POST";
request.HTTPBody = postData;
NSData *respData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
also, note that the synchronous get is bad as it blocks :) use async networking!

NSURLConnection closes early on GET

I'm working on a method to centralize my URL connections for sending and receiving JSON data from a server. It works with POST, but not GET. I'm using a Google App Engine server and on my computer it'll handle the POST requests and return proper results (and log appropriately), but I get the following error when I try the request with a GET method:
Error Domain=kCFErrorDomainCFNetwork Code=303 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error 303.)" UserInfo=0xd57e400 {NSErrorFailingURLKey=http://localhost:8080/api/login, NSErrorFailingURLStringKey=http://localhost:8080/api/login}
In addition, the GAE dev server shows a "broken pipe" error, indicating that the client closed the connection before the server was finished sending all data.
Here's the method:
/* Connects to a given URL and sends JSON data via HTTP request and returns the result of the request as a dict */
- (id) sendRequestToModule:(NSString*) module ofType:(NSString*) type function:(NSString*) func params:(NSDictionary*) params {
NSString *str_params = [NSDictionary dictionaryWithObjectsAndKeys:func, #"function", params, #"params", nil];
NSString *str_url = [NSString stringWithFormat:#"%#%#", lds_url, module];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:str_url]];
NSData *data = [[NSString stringWithFormat:#"action=%#", [str_params JSONString]] dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPMethod:type];
[request setHTTPBody:data];
[request setValue:[NSString stringWithFormat:#"%d", [data length]] forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSError *error = nil;
NSURLResponse *response = nil;
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"Error: %#", error);
NSLog(#"Result: %#", [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding]);
return [result objectFromJSONData];
}
A sample call would be:
NSDictionary *response = [fetcher sendRequestToModule:#"login" ofType:#"GET" function:#"validate_email" params:dict];
Again, this works with a POST but not a GET. How can I fix this?
In my case i was not calling [request setHTTPMethod: #"POST" ]
I think the root cause is you have an invalid URL.
JSON encoding will include things like '{', '}', '[' and ']'. All of these need to be URL encoded before being added to a URL.
NSString *query = [NSString stringWithFormat:#"?action=%#", [str_params JSONString]];
query = [query stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#", str_url, query]];
To directly answer your question:
According to CFNetwork Error Codes Reference the error is kCFErrorHTTPParseFailure. This means the client failed to correctly parse the HTTP response.
The reason why is that a GET doesn't include a body. Why would you want to submit JSON in a GET anyways?
If the target api returns data only you pass it in the url params.
If you want to send data and "get" a response use a post and examine the body on return.
Sample Post:
NSError *error;
NSString *urlString = [[NSString alloc] initWithFormat:#"http://%#:%#/XXXX/MVC Controller Method/%#",self.ServerName, self.Port, sessionId ];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding ]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
// hydrate the remote object
NSString *returnString = [rdc JSONRepresentation];
NSData *s10 = [returnString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:s10];
NSURLResponse *theResponse = [[NSURLResponse alloc] init];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&theResponse error:&error];
NSString *message = [[NSString alloc] initWithFormat: #"nothing"];
if (error) {
message = [[NSString alloc] initWithFormat:#"Error: %#", error];
} else {
message = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
NSLog(#"%#", message);
return message;

I'm getting a 500 response code from Tumblr's API v2 on video post

I'm able to successfully submit text posts (with 201 responses) but when I change my type parameter to "video" and add appropriate embed and caption parameters, I get a 500 response from Tubmlr.
Their documentation is pretty light on the details of what I need to give for an embed value, but I've tried linking directly to the file, <iframe>, <embed>, with URL escaping using both methods at the W3Schools, and I always get a 500 response.
From what I've seen on other message boards, this is not uncommon, but no one has an answer. The code I'm using is below.
NSString *apiCallURL = [NSString stringWithFormat:#"http://api.tumblr.com/v2/blog/%#/post", self.baseURL];
NSLog(#"API Call URL: %#", apiCallURL);
NSURL *url = [NSURL URLWithString:apiCallURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"utf-8" forHTTPHeaderField:#"charset"];
NSMutableString *body = [[NSMutableString alloc] init]; //Using NSMutableString instead of stringWithFormat to avoid problems with % encoding
[body appendFormat:#"type=video&caption=%#", caption];
[body appendString:#"&embed=EMBED CODE HERE"];
[request setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]];
[body release], body = nil;
[self.authentication authorizeRequest:request];
NSError *error = nil;
NSHTTPURLResponse *response = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error)
{
NSLog(#"Error! \n%#", error);
return;
}
if (data) {
// API fetch succeeded
NSString *str = [[[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding] autorelease];
NSLog(#"Sharing response (%d): %#", [response statusCode], str);
}
The output I get is
Sharing response (500):
The embed code I've been trying to use works through tumblr's web interface and is the URL encoded version of the following:
<embed width="480" height="360" src="http://www.keek.com/embed/decaaab" frameborder="0" allowfullscreen />
You'll likely see an answer from the Tumblr devs on the mailing list here:
https://groups.google.com/forum/#!topic/tumblr-api/id_pKWwPcro
It seems to be a problem on tumblr's end.