[RESOLVED - Yay] I can't get a super basic HTTP POST network request to work

@budershank, thank you for letting me know. So it works with python but not with php? And you are using HTTP POST method (not HTTPS) – I know you said you are able to do this, but just to make tripple sure. I’ve been smashing my head on the wall way too long.

I’d so appreciate it if you can see any problem with the LUA/Corona portion of the code here? I know it’s a lot of trouble, but if you could help me out, I’d so appreciate it. I just can’t see what’s wrong with it. Is there something wrong with my lua code? Would this lua code work with python? Is it that Corona implementation of HTTP POST method is incompatible with PHP? What could it be so wrong with what I’m doing here?

--LUA (corona side - plug & play except for the URL):  
local URL = ... -- please include valid http url here  
local function networkListener( event )  
 if ( event.isError ) then  
 print( "Network error!")  
 else  
 print ( "RESPONSE: " .. event.response )  
 end  
end  
  
local function sendRequest(set\_email, set\_user)  
 local postdata = {}  
 local headers = {}  
 headers["Content-Type"] = "application/json"  
 headers["Accept-Language"] = "en-US"  
 postdata.headers = headers  
 local param = {}  
 param.username = set\_user  
 param.email = set\_email  
 postdata.body = json.encode(param)  
 network.request( URL, "POST", networkListener, postdata)  
end  
  
sendRequest("myemail@myweb.com", "mynickname")  
  
-- PHP (just responding back with the data dump to see if anything is getting there)  
<?php <br> echo var\_dump($\_REQUEST);  
?\>  
  
-- terminal output shows blank array  
RESPONSE: array(0) {  
}  

Naomi [import]uid: 67217 topic_id: 29545 reply_id: 118787[/import]

Well, looks like you are caught up where I got stuck(and got fed up). Though after playing with it I am thinking it seems like you are doing everything right so I am wondering if there is something on your webserver(presumably apache) or in your php.ini that is causing the post data to not be received. A quick google search shows that people do have that issue and there are some settings that can be tweaked. [import]uid: 147305 topic_id: 29545 reply_id: 118792[/import]

@budershank, thank you for looking into this. It sounds like I have a lot more to sort out – and honestly, tweaking server side setting is totally not my kind of thing. I’d rather have some super techie genius to get it done for me. But then, coding wasn’t my kind of thing when I started a year ago, so maybe (just maybe) I could get lucky and somehow manage this… with lots more help from all over the web somehow. ** deep sigh **

Thanks again.

Naomi

Edit: But wait. The webserver is able to receive post data from the web form I created. I mean, I set up something like form.php and process.php on the same domain, and when I directly enter email address and username to the input box on form.php, process.php recognizes the post data and process it (and it even inserts these data to MySQL database I set up.) Is receiving post data from client app like Corona different from receiving post data from its own web form?? And do I need to change the server setting when I want php to receive post data from a client app? It seems odd to me, though.

Edit 2 And the thing is, the webserver responds perfectly fine when I use GET method (using it in both Corona app side and PHP side). So it seems too strange to think that HTTP POST method trouble (when used in conjunction with PHP) is a server side issue. [import]uid: 67217 topic_id: 29545 reply_id: 118793[/import]

Hey there,

I’ve spent way to much time on this also. The POST method works as it is used during my IAP receipt verifications to my server and it handles the tables.

network.request(link,"POST",localListener,{body=postData})  

Here params is replaced by {body=postData}, what I need are both and I’d like to include body in the params.

Nail [import]uid: 106779 topic_id: 29545 reply_id: 118797[/import]

Nail @xnailbender, thank you for your post. I’d like to know how I may break you code snippet you posted down to basic mechanics so that I may use it to plug & play.

So… what do you have for postData? How is postData defined in your code that works? Once I can get the basics working, I know I can expand from there… but I can’t see the content of the postData as it is, and therefore, I can’t replicate the process that worked for you. Could you possibly show me what postData holds inside, please?

Naomi [import]uid: 67217 topic_id: 29545 reply_id: 118800[/import]

Hey there, I’ll break it out. Going to take me some time though.

I haven’t tried adding params to the line, maybe it would accept it, along with the body table.

Nail [import]uid: 106779 topic_id: 29545 reply_id: 118801[/import]

Hey there, here’s the code.
This is from Satheesh’s validate IAP receipt and PHP…

lua

local function start(params)  
  
 local listener = params.listener or function(event) end   
 local testing = params.testing  
 local link = testing and "https://sandbox.itunes.apple.com/verifyReceipt"   
 or "https://buy.itunes.apple.com/verifyReceipt"  
  
 local receipt = params.receipt or "\<\>"  
 local password = params.password or nil  
 local serverValidation = params.serverValidation  
 local serverLink = params.serverLink  
  
 local postData  
  
 if serverValidation then   
 postData = preparePostData(receipt,{serverValidation = true})  
 postData = "receipt="..postData.."&testing="..(testing and 1 or 0)  
 link = serverLink  
 else   
 postData = preparePostData(receipt,{password = password})  
 end  
  
 local function localListener(event)  
 local response = event.response  
 local decoded = json.decode(response)  
 print("localListener FLAG after json.decode")  
 print("decoded == ", decoded )   
 print("after if decoded then FLAG1")  
 if type(decoded) == "table" then   
  
 event.iTunes\_StatusCode = decoded.status   
 print("decoded.status from validate.lua == ", decoded.status )  
 event.iTunes\_Response = decoded  
 event.iTunes\_StatusCodeDescription = errorMap[tostring(event.iTunes\_StatusCode)]  
 end   
  
 listener(event)  
 end   
  
 network.request(link,"POST",localListener,{body=postData})  
  
end   

PHP

<?php <br>  
$hex = $\_POST['receipt'];  
$testing = $\_POST['testing'];  
$password = "SecretPasswordHere";  
  
if ($testing == 1)  
 $url = 'https://sandbox.itunes.apple.com/verifyReceipt';  
else   
 $url = 'https://buy.itunes.apple.com/verifyReceipt';  
  
$postData = json\_encode  
(  
array(  
 'receipt-data' =\> $hex,  
 'password' =\> $password,  
 )  
);  
  
function do\_post\_request($url, $data, $optional\_headers = null)  
{  
 $params = array('http' =\> array(  
 'method' =\> 'POST',  
 'content' =\> $data  
 ));  
 if ($optional\_headers !== null) {  
 $params['http']['header'] = $optional\_headers;  
 }  
 $ctx = stream\_context\_create($params);  
 $fp = @fopen($url, 'rb', false, $ctx);  
 if (!$fp) {  
 throw new Exception("Problem with $url, $php\_errormsg");  
 }  
 $response = @stream\_get\_contents($fp);  
 if ($response === false) {  
 throw new Exception("Problem reading data from $url, $php\_errormsg");  
 }  
 return $response;  
}  
  
$response = do\_post\_request($url, $postData);  
echo $response;  
?\>  

It works. I should have studied it more today while fumbling around, but my App went LIVE in the App Store this afternoon. :slight_smile: Problem was the IAP did NOT work!!! OMG!!!

As this is my first app, I had no idea what was wrong. I figured it must the PHP above was using the Sandbox URL, so I commented out the “if” and Sandbox URL and it WORKED!!!

Do I have to learn something EVERY minute while doing this??!!??

GL
Nail [import]uid: 106779 topic_id: 29545 reply_id: 118803[/import]

@Naomi, I played around with it a bit this morning and figured some things out. Most likely the issue is that your data is making it to the web server but then the webserver/php/your webpage is having issues reading the body data properly. What ends up happening is your post data essentially gets dumped. Try this:

Your PHP File:
[php]

<?php
echo var\_dump(getallheaders()); echo var\_dump($\_REQUEST); //echo var\_dump($HTTP\_RAW\_POST\_DATA); echo "Thats all folks" ?\> [/php] Basically the first thing dumps out all the header information. This was key as i was able to see that the Content\_Length was actually correct so I knew my data was getting there. The HTTP\_RAW line is commented out. From here I could actually see the body data coming in even though PHP ended up dumping it. The reason why it is commented out is you would need to enable "always\_populate\_raw\_post\_data" in your php.ini. Since you are probably using a shared host I'm not sure how you do that. And here is the corona code, slightly different because I'm not bothering with JSON atm. [lua]local URL = "http://mywebsite.com/myphp.php" local function networkListener( event ) if ( event.isError ) then print( "Network error!") else print ( "RESPONSE: " .. event.response ) end end local function sendRequest(set\_email, set\_user) local postdata = {} local param = {} param.username = set\_user param.email = set\_email postdata.body = "email="..set\_email.."&user="..set\_user network.request( URL, "POST", networkListener, postdata) end sendRequest("myemail@myweb.com", "mynickname")[/lua] Main different as you can see is 1. I am not defining a header and 2. I'm not using json. Essentially those two things are the root cause of your issue. Somewhere along the line the PHP is trying to parse out your data from JSON format and it is unable to, hence no data being available. I figure at this point you can probably dig into it. I would compare the JSON data on the Corona side to a known working example of JSON php can handle properly. If you really can't find the solution you could forego using JSON and just building your body in the format I used, which is "email=bob@bob.com&user=bobby". Unfortunately I am currently on a windows machine and you apparently can't copy from the command window in Windows, so I can't give an example of the output without a bunch of typing that I am sure I would mess up. [import]uid: 147305 topic\_id: 29545 reply\_id: 118877[/import]

Nail@xnailbender, thank you for posting the content of postData. I do plan on learning how Satheesh’s validate IAP receipt work (and use it too) at some point. I really appreciate it.

And @budershank, OMG, it sounds like you figured this out! I will look into how I may enable “always_populate_raw_post_data” in the php.ini. And yes, I’m using a shared host. I’ll post back with result. Thank you so much for investigating this far. I really appreciate it!

Naomi [import]uid: 67217 topic_id: 29545 reply_id: 118883[/import]

Naomi wrote: I do plan on learning how Satheesh’s validate IAP receipt work (and use it too) at some point

When I first tried to use Satheesh’s IAP, it did not work. I didn’t even know what “echo” did at that time and was when I first explored PHP.

As I was debugging why it didn’t work, I concluded the problem must be in the PHP, and it was.

Towards the top of the IAP PHP code there is a line of PHP code that causes the glitch.

echo $hex , I believe is what it is. When I commented out the line, the PHP worked.

As I stated above, when my app went live yesterday, the IAP didn’t work. The code was still passing the testing URL. Haven’t figured out why yet, but when I removed it from the PHP, my IAP’s started working. I’m so happy I was able to fix, or at least, patch the problem by altering my PHP and didn’t require another app submission immediately. :slight_smile:

You’ll want to keep both these issues in mind when you integrate the IAP verification.

Regarding POST, I think budershank is right. Our PHP is not parsing the header and body correctly. I needed the header info in my other PHP scripts and didn’t need to parse the body. I would like to be able to include both the header and body in the param though. There is some tricky PHP that will be required to do this I’m afraid. It seems I can get either the header, or I can get the body out of the param, but not both yet.

Integrating PHP into the app has so many uses, I amazed how little it’s been discussed here at Corona.

Nail [import]uid: 106779 topic_id: 29545 reply_id: 118892[/import]

Nail @xnailbender, thank you for the heads up on what to look out for with the IAP validation code.

As per @budershank’s discovery (thank you so much for it), I’m working on getting PHP side to cooperate so that it can receive simple POST from Corona app. With my shared host, I need to create php.ini file before I can change the setting.

But, geez, how do people go about creating php.ini file? I looked for example php.ini, and this one frightens me (a pure fear of unknown & unfamiliar.) Also, it says here that:

To protect the php.ini file, you can add these lines to your .htaccess file:
< Files php.ini >
order allow,deny
deny from all
< /Files >

So, I looked for .htaccess file example and this one also frightens me. Ugh.

Does anyone have a very basic php.ini file and .htaccess file that I may tweak? I really don’t want to change anything except for enabling the “always_populate_raw_post_data” and making sure that the php.ini that I add to my site will be protected.

Naomi
[import]uid: 67217 topic_id: 29545 reply_id: 118898[/import]

You can probably just upload the php.ini without editing the htaccess(though im not 100 percent certain on that). Here is the ini i used. For the most part it’s default values except for the raw thing(and i think global variables are turned on). You could also just install the same version of PHP that your server uses. It will create an ini file that you can then edit and upload.

http://www.neverrecycle.com/share/php.zip
[import]uid: 147305 topic_id: 29545 reply_id: 118904[/import]

Thank you, @budershank! I’ll use the php.ini file you posted. (I’ve also asked my hosting provider if they could create one for me that duplicates their default setting.) I’m not sure about the htaccess file, so for now I won’t include it (but maybe down the road once I become a little more acquainted with it and feel a little more comfortable with it.)

Thanks again.

Naomi

Edit: @budershank, I uploaded the php.ini file, and did the very basic version you posted on #27 above, and I get an error like this on terminal (see below). Maybe the php.ini file you sent me isn’t compatible with my setup. Dunno. I’ll look into the error doc. (I’ll also post back if/when I get the hosting provider send me their default php.ini file.) Anyhow, at least it’s no longer a blank response – so I’m getting somewhere.

[text]
RESPONSE: br> “http://www.w3.org/TR/html4/strict.dtd”>
[html]

500 – Internal Server Error

500 – Internal Server Error

The page you requested is currently unavailable. Please try again later.

If you are the website owner, please see
Error: 500 Internal Server Error
documentation for more information and possible steps to resolve the problem.

[/html]
[/text] [import]uid: 67217 topic_id: 29545 reply_id: 118913[/import]

Do you know which version of PHP is being used? [import]uid: 147305 topic_id: 29545 reply_id: 118923[/import]

Hey @budershank, it’s using PHP 5.4 version. And the error log says:

[text]
[Wed Aug 08 19:20:11 2012] [warn] [client xx.xxx.xxx.x] Not GET request: 2.
[Wed Aug 08 19:20:11 2012] [warn] [client xx.xxx.xxx.x] Not GET request: 2.
[Wed Aug 08 19:20:11 2012] [error] [client xx.xxx.xxx.x] Premature end of script headers: php54.cgi
[/text]

Does this mean anything to you? Also, does it also sound like as if PHP side really wants GET to you?

Naomi [import]uid: 67217 topic_id: 29545 reply_id: 118925[/import]

Ah, well my ini is from 5.1. I would disregard the errors for now as it most likely is an issue between ini files. If you can’t find a php.ini for 5.4 itself you can just install php on your own system real quick and then take that one. Seems like a round about way but it works. [import]uid: 147305 topic_id: 29545 reply_id: 118931[/import]

OMG! @budershank, out of desperation (since my hosting service hasn’t gotten back to me and I was feeling rather experimental), I did this (thinking it couldn’t hurt) and it worked!!!

  1. Open a new text file (just a plain simple text file with nothing in it.)

  2. Add this single line to the text file: always_populate_raw_post_data = 1

  3. Save this single line text file as php.ini

  4. Upload the file to root-level of my server account (where I would upload my php file)

After I did this simplest thing of all, it returned the following to my simulator terminal:
[text]
RESPONSE: array(2) {
[“email”]=>
string(17) “myemail@myweb.com
[“user”]=>
string(10) “mynickname”
}
[/text]

This is all it needed. Wowowow. (Spending hours on something so simple is what happens when I’ve got no basic knowledge of anything PHP or server setup.) Now I can forge ahead. A bit of struggling was a good thing. I feel less frightened and more in control. All is well.

Thank you all for all your help.

Cheers,
Naomi
[import]uid: 67217 topic_id: 29545 reply_id: 118956[/import]

And here’s the very simple version that works for me (see below). Cheers!

Naomi

[code]
– LUA side
local mime = require(“mime”)
local json = require(“json”)
local URL = “http://mywebsite.com/myphp.php
local function networkListener( event )
if ( event.isError ) then
print( “Network error!”)
else
print ( “RESPONSE: " … event.response )
end
end
local function sendRequest(set_email, set_user)
local postdata = {}
set_email = mime.b64(set_email)
set_user = mime.b64(set_user)
postdata.body = “email=”…set_email…”&user="…set_user
network.request( URL, “POST”, networkListener, postdata)
end
sendRequest(“myemail@myweb.com”, “mynickname”)

– PHP side

<?php
$email = base64\_decode($\_REQUEST['email']); $username = base64\_decode($\_REQUEST['username']); $result = array(); $result["result"] = 'Received'; $result["message"] = 'The email address we received is ' . $email . ' and username received is ' . $username; echo json\_encode($result); ?\> -- php.ini file with single line of text always\_populate\_raw\_post\_data = 1 -- terminal output: RESPONSE: {"result":"Received","message":"The email address we received is myemail@myweb.com and username received is mynickname"} [/code] [import]uid: 67217 topic\_id: 29545 reply\_id: 118963[/import]

I wish I had seen this post earlier.

The basic problem that you’re running into (which your solution works for) is that PHP is expecting a mime type to be set in the POST headers. Corona SDK does not set that variable and many webhosts end up returning empty data to $_POST[].

Basically you need to add a field to your headers that get sent that works out to be:

headers = {}  
  
headers["Content-Type"] = "application/x-www-form-urlencoded"  
headers["Accept-Language"] = "en-US"  
  
body = "Your Post data"  
  
local params = {}  
params.headers = headers  
params.body = body  
  
network.request( "https://yourwebsite.com/yourPHPscript.php", "POST", networkListener, params)  

And that should work without having to change your PHP.ini settings.
[import]uid: 19626 topic_id: 29545 reply_id: 118964[/import]

OMG, Rob @robmiracle, you are right. I have tried so many different headers, body and etc., etc., with no luck – and it turns out it was only because of the json-encoded params table bringing everything down, or so it seems.

This now works without php.ini file on root-level, with the exact same PHP script I posted on #37 above:

-- LUA side  
local mime = require("mime")  
local json = require("json")  
local URL = "http://mywebsite.com/myphp.php"  
local function networkListener( event )  
 if ( event.isError ) then  
 print( "Network error!")  
 else  
 print ( "RESPONSE: " .. event.response )  
 end  
end  
local function sendRequest(set\_email, set\_user)  
 local postdata = {}  
 set\_email = mime.b64(set\_email)  
 set\_user = mime.b64(set\_user)  
 local headers = {}  
 headers["Content-Type"] = "application/x-www-form-urlencoded"  
 headers["Accept-Language"] = "en-US"  
 local postdata = {}  
 postdata.headers = headers  
 postdata.body = "email="..set\_email.."&username="..set\_user  
 network.request(URL, "POST", networkListener, postdata)  
end  
sendRequest("myemail@myweb.com", "mynickname")  

[import]uid: 67217 topic_id: 29545 reply_id: 118970[/import]