1

I'm trying to send a POST in Objective-C to a PHP script, but the $_POST winds up empty. Here is the Obj-C code:

// Create the JSON object that describes the request
NSError *error;
NSDictionary *requestContents = @{
                                  @"action": @"X",
                                  @"distributor": @"Y"
                                  };

NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
                                                      options:0
                                                        error:&error];

// Create a POST request with the receipt data.
NSURL *registryURL=[NSURL URLWithString:@"https://example.com/registry/"];
NSMutableURLRequest *registryRequest=[NSMutableURLRequest requestWithURL:registryURL];
[registryRequest setHTTPMethod:@"POST"];
[registryRequest setHTTPBody:requestData];

// Make a connection on a background queue.
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:registryRequest queue:queue
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
                           if (connectionError) {
                               /* ... Handle error ... */
                           } else {
                               NSError *error;
                               NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
                               if (!jsonResponse) { /* ... Handle error ...*/ }
                               /* ... Send a response back to the device ... */
                               NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
                           }
                       }];

Here is the .htaccess on the server. Of particular note is that I am forcing HTTP requests to HTTPS and therefore would lose the POST on the redirect, but the above code is requesting on HTTPS already.

<ifModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

#Redirect HTTP to HTTPS
RewriteCond %{HTTP_HOST} !^example.com$ [NC]
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301] 
RewriteCond %{HTTPS} !on
RewriteRule ^(.*)$ https://example.com/$1 [R,L]

#
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !index

RewriteRule ^([^/\.]+)/?$ /index.php?urlseg1=$1 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/?$ /index.php?urlseg1=$1&urlseg2=$2 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ /index.php?urlseg1=$1&urlseg2=$2&urlseg3=$3 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ /index.php?urlseg1=$1&urlseg2=$2&urlseg3=$3&urlseg4=$4 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ /index.php?urlseg1=$1&urlseg2=$2&urlseg3=$3&urlseg4=$4&urlseg5=$5 [L,QSA]

#RewriteRule (.*) index.php [L]
</ifModule>

Now in the PHP script, $_POST is blank. And no matter what method I use of printing the request headers, POST is simply MIA.

I'm thinking that either the Obj-C code isn't doing the request properly, or the .htaccess is killing it. I'm not an expert in mod_rewrite so perhaps someone knows.

Appreciate any help!

Edward
  • 518
  • 3
  • 13
  • @Cristik I'm not familiar with curl - what would be the command (I assume I'd be using Terminal.app)? – Edward Jan 24 '16 at 18:55
  • When you ran this code, what was returned by the `NSURLResponse`, the `NSData`, and `NSError` objects? You shouldn't try to guess what's wrong, but look at the result of making the request and see if there's anything illuminating there. Also, tools like [Charles](http://charlesproxy.com) are really useful for watching request and response. – Rob Jan 24 '16 at 19:31

1 Answers1

1

You say that you suspect .htaccess, but there is another problem here. Your code is building a POST request, but the body of the request is JSON. When you do that, $_POST will not be populated for you. If you want to use $_POST, then consider creating a application/x-www-form-urlrequest. In that case, you set the HTTPBody to look like:

key1=value1&key2=value2

For example:

action=X&distributor=Y

You may also want to set the Content-Type of the HTTP header to be application/x-www-form-urlrequest. (This isn't technically required, but it's good practice to specify the Content-Type header to correspond to the nature of the body of the request.)

Furthermore, if X and Y values might include characters other than alphanumeric characters (e.g. if it contains space, punctuation, or any non-ASCII characters), you'll want to percent-escape those values. See https://stackoverflow.com/a/25702239/1271826 for example of how you might do that in Objective-C.

Alternatively, if you really want to make JSON request (which is fine), you just can't use $_POST on server end, but rather manually receive the body of the request and then call json_decode. For example, see https://stackoverflow.com/a/27884399/1271826.

If you don't want to get lost in the weeds of the proper preparation of these sorts of requests, consider using a library like AFNetworking, which takes care of these details for you.

Community
  • 1
  • 1
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Going to try this. Very weird as the code is based on an Apple example: https://developer.apple.com/library/mac/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html#//apple_ref/doc/uid/TP40010573-CH104-SW1 – Edward Jan 25 '16 at 00:42
  • @Edward - Yeah, there's nothing wrong with writing code that issues a JSON request, but it only makes sense if you're doing that in conjunction with a web service that was expecting a JSON request. But if you wrote a server expecting to parse `$_POST`, that's a different beast. BTW, that code in that article is very old (e.g. we generally don't use `NSURLConnection` anymore, because that's now deprecated). – Rob Jan 25 '16 at 01:15
  • Wow I just sort of assumed the example was storing JSON text in a POST variable, but you're right it's just putting that in the body and not doing a single POST variable! That's what I get for not thinking:) Thanks @Rob! – Edward Jan 25 '16 at 04:20