HTTP request on 3G doesn't work - ios

I try to send HTTP request from my Iphone to local server that run on my local network (behind a router).
I forwarded the port on my router as follow:
HTTP request is :
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://213.57.x.x:8080/OurDogsServerV2/DoggizzMain"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setAllowsCellularAccess:YES];
Over Wifi everything is working fine but I want to test 3G network (for end user).
I set a break point on doPost at my server (Apachi) so I don't think its time interval problem because I don't even get to my BP.
(I disabled my firewall).
I tried to change the url to http://213.57.x.x:8080/localhost:8080/OurDogsServerV2/ and some other combinations.
Can somebody suggest what else can I try?

It was totally my fault. In the options of my router I did disable the WAN Blocking but I didn't notice the apply button in the bottom (I think I assumed that apply button for port forwarding will include that option).

Related

NSUrlConnection fails to hit host server sometimes when called to connect repeatedly

This is how I am using the NSUrlConnection
- (void) serverHttpRequest:(NSString*)data
forUrl:(NSString*)Url
withTag:(NSString*)tag
httpType:(NSString *)type
forThisTime:(int)tryTime
withTimeOutInterval:(float)interval
{
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#", Url]];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:interval];
[theRequest setHTTPMethod:type];
[theRequest setValue:#"application/x-www-form-urlencoded;charset=utf-8" forHTTPHeaderField:#"Content-Type"];
NSString *postData = data;
NSString *length = [NSString stringWithFormat:#"%d", [postData length]];
[theRequest setValue:length forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPBody:[postData dataUsingEncoding:NSASCIIStringEncoding]];
self.theConnection = [NSURLConnection connectionWithRequest:theRequest delegate:self];
[self.theConnection start];
}
But it fails to hit the server almost 50% time when called repeatedly. Why this is happening. The call frequency is per second.
The url is not same for all requests and the client is required to fetch data from multiple servlets on java server with Http POST request. May be something wrong configured on server side.
Possibly the problem is not on client side because when i Ran the same code on two different devices they both received error response at the same time. Also the devices are connected to internet via a proxy server. The error code is HTTP 503 . I know this error is shown when the server is overloaded or refused to respond, but it was working fine as it was receiving requests from other clients. I have implemented basic JAVA servlets and connecting it to MySql database using JDBC driver. If anyone could tell me how what configuration changes should i do on the server or client. THankyou
The only way I know of to determine why a server is sending back a 503 response is to check in the server's logs and see what went wrong. Either that or check the proxy server's logs.

Random latency between headers and body of POST

We're using NSUrlConnection sendAsynchronousRequest to send simple POST requests to our Node JS server. Through analyzing tcpdumps, we've noticed that sometimes the request headers and request body are split into 2 separate TCP packets.
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:url]];
[request setTimeoutInterval:3];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-type"];
[request setHTTPBody:postData];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler: ^(NSURLResponse *response, NSData *POSTReply, NSError *error) { }];
The problem is that occasionally the headers are sent to the server, which opens a connection to our API, and then multiple seconds later the body packet is sent. We're seeing a > 1 second delay between headers and body, randomly every hundred requests on the server side. It's the single largest source of latency on our API.
For the majority of requests, headers and body are about the same size (200 bytes each).
Has anyone seen this before?
I don't have concrete insights on the swift APIs (NSUrlConnection etc.) but in general, while the HTTP data is sent in chunks of large size (which can accommodate the 200 bytes in one packet), more granular decisions are taken at the underlying TCP level, which may decide to split these into chunks of lesser sizes.
I have observed this in node (sending side as well as receiving side) on specific platforms (such as AIX) where the packets are split at illogical boundaries by TCP. By TCP specification, applications should not rely on specific order or size of the low level data transport, it guarantees the data integrity at the final stage.
One suspect would be the presence of Nagile's algorithm in the TCP.
I would also recommend to change the client to another platform (such as Linux) and compare the behavior, if it is easy to port the code.
Hope this helps.

Authentication Issue with REST call for iOS

I am currently trying to make a REST call from an iOS device. My code is below
NSString *restCallString = [NSString stringWithFormat:#"MyURL"];
NSURL *url = [NSURL URLWithString:restCallString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];
[request setHTTPMethod:#"GET"];
[request addValue:Value1 forHTTPHeaderField:#"Header1"];
[request addValue:Value2 forHTTPHeaderField:#"Header2"];
[request setURL:[NSURL URLWithString:restCallString]];
#try{
_currentConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
#catch(NSError *e){
NSLog(#"%#", e.description);
}
Whenever this is called, I get the following error: Authentication credentials were not provided. However, what confuses me is that if I send an identical GET request via a HTTP web console, it works perfectly. In other words, using the same URL and the same 2 header-value pairs, I get a valid response on a web console, and see no authentication errors. What could be causing this?
You are setting the HTTP headers. This won't work, because the HTTP header is not contained in $_GET or $_POST because they're are not content, but description of the content expected.
Try this instead:
NSURL *url = [NSURL URLWithString:[restCallString stringByAppendingFormat:#"?Header1=%#&Header2=%#", Value1, Value2]];
Of cause you have to be aware that the URL is RFC 1738 compliant.
if I send an identical GET request via a HTTP web console, it works perfectly
I suspect your web console is leveraging SessionAuthentication — i.e. If you're already logged in to your site in your browser the API will authenticate you based on your session cookie.
Django Rest Framework provides various authentication methods and there are third-party options too. The simplest to get going is probably the provided Token Auth method.
Make sure this is enabled. Create a token in the admin (or via the provided view) and make sure you've set the Authorization header. It needs to look like this:
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
So your Objective-C will go something like:
[request addValue:[NSString stringWithFormat:#"Token %#", yourToken]
forHTTPHeaderField:#"Authorization"];
Hopefully that gets you started.

Set the header in ASIHTTPRequest

I'm using ASIHTTPRequest to access a web based API and need to set a header for App authentication. Note that this is not a server level authentication it is at API level. I've tried every thing I could find and most of the answers on the web as well as the ones here at www.stackoverflow.com tell me to use something like:
[request addRequestHeader:#"username" value:#"asdf"];
This does not work for me. The guy who built the API I'm using told me that I need to set the header as:
Authorization: TRUEREST username=PersonName&password=pass&apikey=dfiu6aewruif3Bismillah4Rah3anArahimiImi22MyDad
So I tried the following:
NSURL *url = [NSURL URLWithString:#"http://ifish-uk.co.uk/rest_users/login.json"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request addRequestHeader:#"username" value:#"MyUser"];
[request addRequestHeader:#"password" value:#"MyPass"];
[request addRequestHeader:#"apikey" value:#"dfiu6aewruif3Bismillah4Rah3anArahimiImi22MyDad"];
But it didn't work... I even tried setting the Request type to GET because the developer told me I should do this:
[request setRequestMethod:#"GET"];
This didn't work... The API developer told me he is made this module as follow:
POST /rest_catches/add.json HTTP/1.1
Host: ifish-uk.co.uk
Authorization: TRUEREST username=MyUser&password=MyPass&apikey=dfiu6aewruif3Bismillah4Rah3anArahimiImi22MyDad
Cache-Control: no-cache
any help would be greatly appreciated.
You should add only one header is Authorization no need to add separate headers for each field (use, pass, etc).
Fill it with your specific values and send.
[request addRequestHeader:#"Authorization" value:#"TRUEREST username=PersonName&password=pass&apikey=dfiu6aewruif3Bismillah4Rah3anArahimiImi22MyDad"];
Did you try adding:
[request setRequestMethod:#"POST"];
?

iOS - REST Client works fine while NSURLRequest returns NULL

I'm trying to download a file from a cloud via a GET HTTP request, and in my REST Client (Postman for Chrome) I get the results as expected, but when I pass the request in iOS, I get a NULL response. What could be the problem?
In my REST Client, I pass the URL as http://myserver.com/api/download.json?filepath=/&fileid=document:1pLNAbof_dbXGn43GtMNafABMAr_peTToh6wEkXlab7U&filename=My Info.doc with a header field for a authorization key, and it works perfectly fine.
While in iOS, if I do such a thing:
[request setURL:[NSURL URLWithString:URLString]]; // I tried even to hardcode the
// URLString to be one of the
// working URLs from the Postman
// Client, doesn't work as well.
[request setHTTPMethod:#"GET"];
NSData* response = [NSURLConnection sendSynchronousRequest:request
returningResponse:&urlResponseList
error:&requestErrorList];
response is null, and I get a status code 500.
Anyone know how to make this work? Thanks.
it looks like your URL has a space in it, you'll need to escape that before sending the string to NSURL.
it would also be helpful to know what the full error from your server is if this doesn't work. what does requestErrorList contain?
but if the only problem is the non-escaped characters something like this should work.
NSString *encodedString = [URLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[request setURL:[NSURL URLWithString:encodedString];
An HTTP status code 500 occurs when the webservice is not able to handle your request. An internal error occured.
Try to add some more details to your request.
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];

Resources