Sending Request with iOS - Express answers with 304 HTTPCode - ios

i am developing a App for iPad.
I'm using express and a restful approach as a backend.
Express on the route GET /baumkontrollen should respond as the following:
exports.getAll = function(req, res) {
if(req.cookies.email) {
pq.getBaumkontrollen(function(rows) {
res.send(rows);
});
}
else {
res.send(400, 'Sie sind nicht eingelogt.');
}
};
but on the console i get: GET /baumkontrollen 304 23ms
I'm using an iPad for Requests. There i do it like this:
NSMutableString *serverString = [[NSMutableString alloc] initWithString:BKServerURL];
[serverString appendString:#"baumkontrollen"];
serverNSURL = [[NSURL alloc] initWithString:serverString];
req = [[NSMutableURLRequest alloc] initWithURL:serverNSURL];
[req setHTTPMethod:#"GET"];
[req addValue:cookies forHTTPHeaderField:#"Cookie"];
serverConnection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES];
The variable cookies is of type NSArray.
Why do i get an 304 HTTP Status Code?
This is the Request from an iPad.
This is from my Browser, it just works i get a 200 :/

I fixed it by adding this line to the request:
[req setValue:#"no-store, no-cache, must-revalidate" forHTTPHeaderField:#"Cache-Control"];

Related

Unable to add a header to NSMutableRequest

NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:tempURL]] autorelease];
[request setValue:encryptedValue forHTTPHeaderField:#"EncString"];
I could spot all other headers in the request but this specific header is missing, can any one let me know what could be the reasons.
I have tried the following code:
NSString *tempURL = #"https://stackoverflow.com/questions/50701101/unable-to-add-a-header-to-nsmutablerequest";
NSString *encryptedValue = #"whatever_that_has_no_special_characters_or_values_that_would_make_you_think_it_is_relevant_to_reproduce_this_issue";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:tempURL]];
[request setValue:encryptedValue forHTTPHeaderField:#"EncString"];
NSLog(#"%#", request.allHTTPHeaderFields);
The output is:
{
EncString = "whatever_that_has_no_special_characters_or_values_that_would_make_you_think_it_is_relevant_to_reproduce_this_issue";
}
which looks good. There is no reason to suspect the code you provided is responsible for the issue. Maybe you should check one of the following:
Is encryptedValue truly a valid object to be placed into header (is string, not too long, no very special characters)
Is the object you are printing really this specific request (printing NSLog(#"%p", request); returns same result)
In no place in this object a herder is being removed (if nothing else subclass NSMutableURLRequest and override relevant methods to track what is going on)
If none of these work create a post with additional details on what you have done, where are you checking these headers and "could spot all other headers".

iOS Tumblr Integration using oauth

Trying to understand how this all works. New to oauth and api integrations.
Not looking for a better way. Looking to understand and expand on what this is doing.
I followed this tutorial and have it working
through part 3.
I kind of understand, but having a hard time connecting the code to the Tumblr API documentation.
The tutorial leaves off with having the user's Access Token.
How do I use the Access Token to get the users info with api.tumblr.com/v2/user/info in xcode?
With this information I might be able to put together an understanding in my head.
Code example would be much appreciated!
#Ir100,
use the same acess_token and secret_key you generated via OAuth Library and just change your request url(API) because every time you have to send other parameter for API call.
_consumer = [[OAConsumer alloc] initWithKey: _consumerKey secret: _secretKey];
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL: url consumer: _consumer token:token realm:nil signatureProvider: nil] ;
if (!request) return;
if (self.pin.length)
token.verifier = _pin;
[request setHTTPMethod: #"POST"];
if (_api)
[request setHTTPMethod: #"GET"];
NSMutableArray *params = [[NSMutableArray alloc] initWithArray:request.oa_parameters];
request.oa_parameters = params;
OADataFetcher *fetcher = [[OADataFetcher alloc] init] ;
[fetcher fetchDataWithRequest: request delegate: self didFinishSelector: success didFailSelector: fail];

Asynchronous NSURLConnection receives null-bytes in between every byte

I'm trying to fetch an XML-document from a server, but the response I'm getting in clear text is just ÿþ<.
I found out, by reading the HEX-data of the NSData that what follows after those first three bytes is the whole response I wanted, but with a nullbyte in between every byte. Now, I could just strip the data from those bytes, but if I get the same data with Netcat, there are no nullbytes there, so I figured there is something wrong with my code.
I've sent the exact same headers that the iPad-simulator has sent, but everything seems normal from there. This is the code I'm using to fetch the XML-data:
NSString *postData = #"SomePostData";
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSString *URLString = [NSString stringWithFormat:#"https://www.example.com/xmlexport?sessionid=%#", sessionID];
[request setURL:[NSURL URLWithString:URLString]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:[postData dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
And these are the delegate methods I'm using.
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
myData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[myData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *myString = [[NSString alloc] initWithData:myData encoding:NSWindowsCP1252StringEncoding];
NSLog(#"%#", myString);
}
This is the response I'm getting from the server:
{ URL: https://www5.whentowork.com/cgi-bin/w2wE.dll/mgrexportemplist?SID=2835115254228 } { status code: 200, headers {
"Access-Control-Allow-Origin" = "*";
"Content-Disposition" = "attachment;filename=empdata.xml";
"Content-Encoding" = gzip;
"Content-Type" = "application/x-msdownload";
Date = "Mon, 14 Apr 2014 19:37:54 GMT";
Server = "Microsoft-IIS/6.0";
"Transfer-Encoding" = Identity;
Vary = "Accept-Encoding";
} }
This is the first part of the XML:
<?xml version="1.0" encoding="windows-1252" standalone="yes"?>
<!-- Generated by Exmaple.com -->
<!DOCTYPE tutorial [
<!ENTITY auml "&auml;">
<!ENTITY ouml "&ouml;">
<!ENTITY uuml "&uuml;">
<!ENTITY Auml "&Auml;">
<!ENTITY Ouml "&Ouml;">
<!ENTITY Uuml "&Uuml;">
I'm running the latest Xcode and running the code in the iOS simulator (Version 7.1 (463.9.41)) for iPad.
I really don't get this. I spent so much time trying to figure out why I only got three bytes, then later figured out I got everything, but with nullbytes in between everywhere. I do not have control over the server, so I can not change it's configuration.
EDIT: An NSLog of the data return this: (just the first couple of lines)
fffe3c00 3f007800 6d006c00 20007600 65007200 73006900 6f006e00 3d002200 31002e00 30002200
20006500 6e006300 6f006400 69006e00 67003d00 22007700 69006e00 64006f00 77007300 2d003100
32003500 32002200 20007300 74006100 6e006400 61006c00 6f006e00 65003d00 22007900 65007300
22003f00 3e000d00 0a003c00 21002d00 2d002000 47006500 6e006500 72006100 74006500 64002000
62007900 20005700 68006500 6e005400 6f005700 6f007200 6b002d00 2d003e00 0d000a00 3c002100
44004f00 43005400 59005000 45002000 74007500 74006f00 72006900 61006c00 20005b00 0d000a00
20002000 20002000 3c002100 45004e00 54004900 54005900 20006100 75006d00 6c002000 22002600
61006d00 70003b00 61007500 6d006c00 3b002200 3e000d00 0a002000 20002000 20003c00 21004500
4e005400 49005400 59002000 6f007500 6d006c00 20002200 26006100 6d007000 3b006f00 75006d00
6c003b00 22003e00 0d000a00 20002000 20002000 3c002100 45004e00 54004900 54005900 20007500
75006d00 6c002000 22002600 61006d00 70003b00 75007500 6d006c00 3b002200 3e000d00 0a002000
20002000 20003c00 21004500 4e005400 49005400 59002000 41007500 6d006c00 20002200
The fffe at the start is a byte order mark that indicates that the response is is little endian UTF-16. (See this byte order mark table.) This is further confirmed if you look at the rest of your data, where 3c00 is the little endian UTF-16 representation of <, 3f00 is ?, 7800 is x, etc.
Thus:
fffe3c00 3f007800 6d006c00 20007600 65007200 73006900 6f006e00 3d002200
31002e00 30002200 20006500 6e006300 6f006400 69006e00 67003d00 22007700
69006e00 64006f00 77007300 2d003100 32003500 32002200 20007300 74006100
6e006400 61006c00 6f006e00 65003d00 22007900 65007300 22003f00 3e00
is
<?xml version="1.0" encoding="windows-1252" standalone="yes"?>
You should therefore convert it to a string using:
NSString *myString = [[NSString alloc] initWithData:myData encoding:NSUTF16LittleEndianStringEncoding];
This will automatically handle the byte order mark, as well (eliminating that curious ÿþ at the start).
By the way, if you're ever unclear about the representation, you can always try saving the NSData to a file and then using stringWithContentsOfFile:usedEncoding:error:. Personally, I'd always first look for a the byte order mark or for obvious UTF-16 or UTF-32 data (which is generally pretty easy to identify in western languages), as we did above, but this can be useful sometimes:
NSStringEncoding encoding;
NSError *error;
NSString *string = [NSString stringWithContentsOfFile:path usedEncoding:&encoding error:&error];
if (string) {
NSLog(#"string = %#", string);
NSLog(#"encoding = %d", encoding);
} else {
NSLog(#"stringWithContentsOfFile error: %#", error);
}
It doesn't always work, but sometimes it provides interesting clues.

AFNetworking 2 Upload Plist Data to Apache Server

I am writing a sample app to test how AFNetworking can be used as a replacement for ASIHTTPLib.. The old library made it simple to upload a file to an Apache server (provided the user has write access to a URL/directory). No other server side support is used..
This code has some problem, but I have not pinpointed it: executing the method reports an upload success, but the plist file on the cloud side does not change…
-(void)uploadReminders:(NSArray*)reminders
{
NSLog(#"AppDelegate Synch Reminders to cloud");
//NSLog(#"Data: %#", reminders);
[self persistReminders:reminders atCustomPath:nil];
NSString *cacheDirectoryPath = [self cachesDirectoryPath];
NSString *urlString = [NSString stringWithFormat:#"%#/%#",kStandardCloudAreaAccessURL,kStandardLocalCachePlistFile];
//NSLog(#"URL: %#", urlString);
NSString *remindersPlistFile = [NSString stringWithFormat:#"%#/%#",cacheDirectoryPath,kStandardLocalCachePlistFile];
//NSLog(#"Filepath: %#",remindersPlistFile);
NSURLCredential *defaultCredential = [NSURLCredential credentialWithUser:kStandardCloudAreaAccessUsername password:kStandardCloudAreaAccessUserPW persistence:NSURLCredentialPersistenceNone];
/**/
NSURL *url = [NSURL URLWithString:urlString];
NSString *host = [url host];
NSInteger port = [[url port] integerValue];
NSString *protocol = [url scheme];
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc] initWithHost:host port:port protocol:protocol realm:nil authenticationMethod:NSURLAuthenticationMethodHTTPBasic];
NSURLCredentialStorage *credentials = [NSURLCredentialStorage sharedCredentialStorage];
[credentials setDefaultCredential:defaultCredential forProtectionSpace:protectionSpace];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
[configuration setURLCredentialStorage:credentials];
[configuration setHTTPAdditionalHeaders: #{#"Accept": #"text/plain"}];
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:configuration];
[manager.securityPolicy setAllowInvalidCertificates:YES];
manager.responseSerializer = [AFPropertyListResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"text/plain"];
NSURL *URL = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURL *filePath = [NSURL fileURLWithPath:remindersPlistFile];
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(#"Upload Error: %#", error);
} else {
//NSLog(#"Upload Success");
NSLog(#"Upload Success: %# %#", response, responseObject);
}
}];
[uploadTask resume];
}
The console shows this:
Upload Success: <NSHTTPURLResponse: 0x8d4ec50> { URL: https://[.....]/CodeTests/Reminders/Reminders.plist } { status code: 200, headers {
"Accept-Ranges" = bytes;
Connection = "Keep-Alive";
"Content-Length" = 1324;
"Content-Type" = "text/plain";
Date = "Mon, 10 Mar 2014 14:48:13 GMT";
Etag = "\"3f06e5-52c-4f430180dae80\"";
"Keep-Alive" = "timeout=5, max=100";
"Last-Modified" = "Sun, 09 Mar 2014 17:48:26 GMT";
Server = "Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.7l DAV/2";
} } {
reminders = (
{
completed = 1;
created = "2014-03-09 17:47:41 +0000";
description = "";
title = Reminder;
updated = "2014-03-09 17:47:41 +0000";
},
{
completed = 1;
created = "2014-03-08 09:47:58 +0000";
description = "Orza!!! Ma orza in fretta... Ah: funziona? Ebbene, s\U00ec! O no?\n";
title = "Reminder Orza";
updated = "2014-03-08 11:39:43 +0000";
},
{
completed = 0;
created = "2014-03-07 11:09:59 +0000";
description = "Whatever you like; and of course you can even make it quite long.\n\nYeooww..\nReally long!\n\n\n\n";
title = "Reminder A";
updated = "2014-03-08 11:34:24 +0000";
}
);
version = "1.0";
}
The only catch is that when I reopen the app, it jumps back to the test reminders I did manually put on the server: the Reminders.plist gets never changed.
Thanks!
I'm assuming your NSLog of the responseObject is confirming that the plist was successfully received by the server. If so, then that may eliminate the above "upload" code as the source of the problem. You may want to inspect the data on your server (not through the app, but manually inspect it yourself) and see whether your new list of reminders is there or not. It seems that there a couple of possible logical possibilities:
If the updated data is not there, then look at your server's "save" logic, as it would appear to be failing.
If it is there, then you should look at your client's "retrieve" logic. I wonder, for example, if your app is caching the responses to its requests, and thus when you attempt to download again, perhaps you're getting the cached original response. I'd try turning off caching.
In these cases, a tool like Charles can be useful, where you can inspect the requests and responses that you're getting. That can be helpful in narrowing down precisely where the problem is occurring.
Taking a closer look at your request, I notice that you're not specifying the request type. I would have thought that your request would be a POST:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
[request setHTTPMethod:#"POST"];
[request setValue:#"text/plain" forHTTPHeaderField:#"Accept"]; // I'd also personally set the `Accept` here at the request, not at the `NSURLSessionConfiguration`
Having said that, given that your web service is successfully reporting your plist data back at you, I would have inferred that it successfully received it on the basis of the evidence you shared with us thus far. But maybe the failure to make the request a POST request means that the web service concluded it didn't need to save anything.
Generally, when interfacing with a web service, rather than tweaking the request, like I have above, I'd encourage you to post data using one of the standard AFHTTPSessionManager variations of the POST method (one is for multipart/form-data requests, the other is for other requests). But I can't figure out what your server is doing on the basis of what you've provided thus far (e.g. it makes no sense that the server is sending the body of your request back to you at all; it makes no sense that the server would appear to have received your request, but doesn't do anything with it and doesn't report some error; etc.). So maybe try making the request a POST request and see if that fixes it. If not, run Charles on your old ASIHTTP source code, and you'll see precisely what the old request looks like and you should be able to reproduce it with AFNetworking.

HTTP post w/ JSON to rails server from iOS

I have succeeded in making a post using a HTTP Client by setting the content type as application/json and this json code:
{
"order": {
"name": "Tia Carter",
"location": "Corams",
"phone_number": "707",
"food": "Bobcat Burger"
}
}
The code works perfect and the order is registered in the database. I am trying to work this into my iOS app but keep getting syntax errors regarding the colons in the json. This is the objective-c code:
NSURL *nsURL = [[NSURL alloc] initWithString:#"http://0.0.0.0:3000/orders.json"];
NSMutableURLRequest *nsMutableURLRequest = [[NSMutableURLRequest alloc] initWithURL:nsURL];
// Set the request's content type to application/x-www-form-urlencoded
[nsMutableURLRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
// Set HTTP method to POST
[nsMutableURLRequest setHTTPMethod:#"POST"];
// Set up the parameters to send.
NSString *paramDataString = [NSString stringWithFormat:#
"{ "order": {"%#:" ="%#","%#:"="%#","%#:"="%#","%#:"="%#"}}", #"name", _name.text, #"location", _location.text, #"phone_number", _phoneNumber.text, #"food", _order.text];
// Encode the parameters to default for NSMutableURLRequest.
NSData *paramData = [paramDataString dataUsingEncoding:NSUTF8StringEncoding];
// Set the NSMutableURLRequest body data.
[nsMutableURLRequest setHTTPBody: paramData];
// Create NSURLConnection and start the request.
NSURLConnection *nsUrlConnection=[[NSURLConnection alloc]initWithRequest:nsMutableURLRequest delegate:self];
I'd appreciate any ideas or guidance. Thanks.
I believe you have two problems:
You didn't escape quotas (put \ before all of them)
You don't need to put text "name", "location" and etc in parameters (it's not a problem per se, just a style thing)
Also, I would recommend to work with NSDictionary and convert it to JSON when you need to (it will save you a lot of nerves for unescaped quotas, missing bracket and so on).
Look this question how to convert NSDictionary to JSON:
Generate JSON string from NSDictionary in iOS

Resources