by date
An interesting question....
An interesting question....
| Name: | Harold "LabRat" Brown | ![]() |
|---|---|---|
| Date Posted: | Apr 06, 2006 | |
| Rating: | 4.8 out of 5 | |
| Public: | YES | |
| Comments: | YES | |
| RSS Feed: | or Subscribe with . | |
| Profile Page: | View profile page for Harold "LabRat" Brown |
Blog post
Recently (well within the last week or so) I received an E-Mail asking me for help with TCPObject and using it to send information to a webserver via an HTTP POST command. Many of you might be saying right now "But TorqueScript has the HTTPObject for that". Well yes it does.. and I've never really liked it for various reasons... perhapse because I like to have a bit more control....
Pulling out some of my old code (The origional Marble Blast score logging mod) I double checked some code and HTTP references. And came to the conclusion that it just wasn't up to snuff (BTW samples of this code can be found in the forums for TGE owners)
The biggest issue being... well I had no URLEncode function other then a couple String Replaces that did not meet the HTTP spec. So I did some searching and found a URL encoding function for Visual Basic.. did some re-writing and voila.. I had a torquescript based URL encoder.... well almost as it was missing a couple functions. The first being... TorqueScript has no function to return the ASCII value of a character. The second being.. there is no decimal to HEX conversion.
Code for the Decimal to Hex was quite easy to come by...
Getting the ASCII value of a character was a bit trickier as I wanted this to remain compleatly TorqueScript based solution.
Remembering that TorqueScript is string based I threw out the first 32 digits and start the lookup table with the SPACE character.
Finding our character position in the table, we then add 32 to get our ASCII value. Works quite well for the purpose needed.
I later added a hack to put \t, \n and \r (escape codes do count as one character in TorqueScript) at the 127->129 ASCII positions.
After this we were ready to put in our URLEncode function:
Then we just needed a test script to send data to the webserver. I opted to go with a "File Upload" script.
And of course on the server side I had the following small php file:
Overall this was a fun excercise for me... something I should probably have done 3 years ago. Yes I am aware that I should have used POST VARS in my PHP.. but as it was a simple test I didn't spend alot of time on the PHP code to make it pretty.
NOTE: I will not guarantee the code I have posted is 100% correct. I worked on this in several locations and errors may have crept into the code that I pasted here (missing semi-colons, quites, etc... or extras of any of the above)
Pulling out some of my old code (The origional Marble Blast score logging mod) I double checked some code and HTTP references. And came to the conclusion that it just wasn't up to snuff (BTW samples of this code can be found in the forums for TGE owners)
The biggest issue being... well I had no URLEncode function other then a couple String Replaces that did not meet the HTTP spec. So I did some searching and found a URL encoding function for Visual Basic.. did some re-writing and voila.. I had a torquescript based URL encoder.... well almost as it was missing a couple functions. The first being... TorqueScript has no function to return the ASCII value of a character. The second being.. there is no decimal to HEX conversion.
Code for the Decimal to Hex was quite easy to come by...
function dec2hex(%val)
{
// Converts a decimal number into a 2 digit HEX number
%digits ="0123456789ABCDEF"; //HEX digit table
// To get the first number we divide by 16 and then round down, using
// that number as a lookup into our HEX table.
%firstDigit = getSubStr(%digits,mFloor(%val/16),1);
// To get the second number we do a MOD 16 and using that number as a
// lookup into our HEX table.
%secDigit = getSubStr(%digits,%val % 16,1);
// return our two digit HEX number
return %firstDigit @ %secDigit;
}
Getting the ASCII value of a character was a bit trickier as I wanted this to remain compleatly TorqueScript based solution.
Remembering that TorqueScript is string based I threw out the first 32 digits and start the lookup table with the SPACE character.
Finding our character position in the table, we then add 32 to get our ASCII value. Works quite well for the purpose needed.
I later added a hack to put \t, \n and \r (escape codes do count as one character in TorqueScript) at the 127->129 ASCII positions.
function chrValue(%chr)
{
// So we don't have to do any C++ changes we approximate the function
// to return ASCII Values for a character. This ignores the first 31
// characters and the last 128.
// Setup our Character Table. Starting with ASCII character 32 (SPACE)
%charTable = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_'abcdefghijklmnopqrstuvwxyz{|}~\t\n\r";
//Find the position in the string for the Character we are looking for the value of
%value = strpos(%charTable,%chr);
// Add 32 to the value to get the true ASCII value
%value = %value + 32;
//HACK: Encode TAB, New Line and Carriage Return
if (%value >= 127)
{
if(%value == 127)
%value = 9;
if(%value == 128)
%value = 10;
if(%value == 129)
%value = 13;
}
//return the value of the character
return %value;
}
After this we were ready to put in our URLEncode function:
function URLEncode(%rawString)
{
// Encode strings to be HTTP safe for URL use
// Table of characters that are valid in an HTTP URL
%validChars = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz:/.?=_-$(){}~&";
// If the string we are encoding has text... start encoding
if (strlen(%rawString) > 0)
{
// Loop through each character in the string
for(%i=0;%i<strlen(%rawString);%i++)
{
// Grab the character at our current index location
%chrTemp = getSubStr(%rawString,%i,1);
// If the character is not valid for an HTTP URL... Encode it
if (strstr(%validChars,%chrTemp) == -1)
{
//Get the HEX value for the character
%chrTemp = dec2hex(chrValue(%chrTemp));
// Is it a space? Change it to a "+" symbol
if (%chrTemp $= "20")
{
%chrTemp = "+";
}
else
{
// It's not a space, prepend the HEX value with a %
%chrTemp = "%" @ %chrTemp;
}
}
// Build our encoded string
%encodeString = %encodeString @ %chrTemp;
}
}
// Return the encoded string value
return %encodeString;
}
Then we just needed a test script to send data to the webserver. I opted to go with a "File Upload" script.
function sendData(%file)
{
%obj = new TCPObject(TCPObj);
%obj.filename = %file;
%obj.connect("www.domain.com:80");
}
function TCPObj::onDNSResolved(%this)
{
}
function TCPObj::onDNSFailed(%this)
{
}
function TCPObj::onConnected(%this)
{
%filename= %this.filename;
%file = new FileObject();
if(%file.openForRead(%filename))
{
%text = %file.readLine();
while(!%file.isEOF())
{
%text = %text @ "\r\n" @ %file.readLine();
}
}
%file.delete();
%data="filename=" @ filename(%filename) @ "&fileContent=" @ %text;
%data = URLEncode(%data);
%httpCmd="POST /gg/upload.php HTTP/1.1\nHost: www.domain.com:80\nUser-Agent: Torque/1.0 \nAccept: */*\nContent-Length: "@ strlen(%data) @"\nContent-Type: application/x-www-form-urlencoded; charset=UTF-8\n\n" @ %data;
echo(%httpCmd);
%this.send(%httpCmd @ " \r\n");
}
function TCPObj::onConnectFailed(%this)
{
}
function TCPObj::onDisconnect(%this)
{
%this.delete();
}
function TCPObj::onLine(%this, %line)
{
if(firstword(%line) $= "RETURN:")
{
echo(restwords(%line));
%this.disconnect();
}
}
And of course on the server side I had the following small php file:
<HTML>
<HEAD>
</HEAD>
<BODY>
<?
$filename=stripslashes($filename);
$fileContent=stripslashes($fileContent);
$fd = fopen($filename, 'w');
fwrite($fd,stripslashes($fileContent)."\r\n");
fclose ($fd);
echo("RETURN: Upload Successful\r\n");
?>
</BODY></HTML>
Overall this was a fun excercise for me... something I should probably have done 3 years ago. Yes I am aware that I should have used POST VARS in my PHP.. but as it was a simple test I didn't spend alot of time on the PHP code to make it pretty.
NOTE: I will not guarantee the code I have posted is 100% correct. I worked on this in several locations and errors may have crept into the code that I pasted here (missing semi-colons, quites, etc... or extras of any of the above)
Recent Blog Posts
| List: | 09/14/07 - It's been over a year already.... 04/06/06 - An interesting question.... 09/28/05 - Plan for Harold "LabRat" Brown 06/21/05 - Plan for Harold "LabRat" Brown 09/05/04 - Plan for Harold "LabRat" Brown 04/26/04 - Plan for Harold "LabRat" Brown 04/09/04 - Plan for Harold "LabRat" Brown 01/30/04 - Plan for Harold "LabRat" Brown |
|---|
Submit your own resources!| Brandon Maness (Apr 06, 2006 at 09:17 GMT) Resource Rating: 5 |
| Vashner (Apr 06, 2006 at 23:56 GMT) |
| Rodney Rindels - Torqued (Jun 17, 2006 at 21:03 GMT) |
| Wolfgang Kurz (Dec 04, 2006 at 14:29 GMT) |
thank you for this ressource!
I implemented this and used a linux server but since i am a total beginner with linux i switched back to a windows server and thats when i started to have problems with his code.
Do you know which extensions i need to implement in the php install to make this work again? It keeps telling me function not implemented when i send variables to the page
would be cool if you had any hints for me:-)
thx a lot
| Saurabh Torne (Apr 27, 2007 at 11:24 GMT) |
| Howard Dortch (Jun 14, 2007 at 13:29 GMT) |
I have a modified version that is just supposed to send one piece of data but can't confirm it works.
On the php side how do I extract the data?
%data = "mydata=somename"; < this is what I send
in the php file
fd = fopen(torque.txt, 'w');
fwrite($fd,$mydata);
fclose ($fd);
torque.txt file on the web is blank
any hints?
| Arunas Ivanauskas (Nov 19, 2007 at 02:56 GMT) Resource Rating: 5 |
thanks!
@Howard Dortch:
try to use $_POST["fileContent"]
Edited on Nov 19, 2007 03:42 GMT
| gamer (Feb 29, 2008 at 22:48 GMT) |
thanks
Edited on Feb 29, 2008 22:49 GMT
| Conor O Kane (Mar 04, 2008 at 10:54 GMT) Resource Rating: 5 |
Here's what I changed:
function TCPSubmitScore(%name, %score)
{
%obj = new TCPObject(TCPScoreSender);
%obj.name = %name;
%obj.score = %score;
%obj.connect("www.domain.com:80");
}
function TCPScoreSender::onConnected(%this)
{
// add the correct tags for the php to read the name and score correctly
%data = "name=" @ %this.name @ "&score=" @ %this.score;
%data = URLEncode(%data);
%httpCmd="POST /db_test/submitscore.php HTTP/1.1\nHost: www.domain.com:80\nUser-Agent: Torque/1.0 \nAccept: */*\nContent-Length: "@ strlen(%data) @"\nContent-Type: application/x-www-form-urlencoded; charset=UTF-8\n\n" @ %data;
echo(%httpCmd);
%this.send(%httpCmd @ " \r\n");
}
In the php file I have
$name = $_POST['name'];
$score = $_POST['score'];
to catch the name and score variables sent, and I then stick these in a database. I found the tutorial on how to use php to store scores in a database here: www.clickteam.com/eng/resources/online_score/onlinescoreboards.html
| Gonzo T. Clown (Mar 25, 2008 at 09:47 GMT) Resource Rating: 4 |
Thank You
| gamer (Apr 17, 2008 at 21:25 GMT) |
function TCPObj::onConnected(%this)
{
//preprocessing
%this.send(%httpCmd @ " \r\n");
}
if preprocessing take too long(~10 secs), %this.send fails silently, disconnect is not called, but the data simply does not reaches the server. has anyone had this issue?
thanks
You must be a member and be logged in to either append comments or rate this resource.



4.8 out of 5


