Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 715
drodman Avatar asked Dec 21 '22 21:12

drodman


2 Answers

In my case i was not calling [request setHTTPMethod: @"POST" ]

like image 181
Atif Khan Avatar answered Jan 13 '23 15:01

Atif Khan


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.

like image 24
Jeffery Thomas Avatar answered Jan 13 '23 14:01

Jeffery Thomas