Jump to content

File Upload Via XML RPC


riverdude

Recommended Posts

Hi All,

 

PHP newbie here.  I am working on a web service, whereby a desktop application will load large data files (5-50 MB) to a web server.  After some research, I decided to look into doing it using XML RPC.  So, I have a few questions:

 

--I am not sure that XML RPC is the right way to go.  Are there any other 'simple' ways to achieve this?

 

--Right now, I am using a PHP script on the client side to test the uploads.  I tried loading a 2.5 MB file and it took ten minutes...so I am hoping someone can take a look at my code and suggest some alternatives for loading large files.  BTW, I also use the XML RPC call to insert some info into a MYSQL DB.  My code for server and client is provided below.

 

MANY THANKS IN ADVANCE!

 

SERVER PHP SCRIPT:

*****************************************************************

<?php

 

//Main Function

function gxLoadFile($method_name, $params) {

 

header('Content-Type: text/xml');

 

  //Validate Agains the DB for Username and Password

$luser = $params[0];

$pword = $params[1];

 

//Mitigate SQL Injection through addslashes if magic quotes are off...

if (!get_magic_quotes_gpc()){

addslashes($luser);

addslashes($pword);

}

 

//Get user info from USERS table...

$db = dlDBConn();

$lsql = "SELECT * FROM ".$cfg['mysql']['prefix']."USERS where GUSER = '$luser'";

$lquery = mysql_query($lsql,$db) or die("<servmsg type=\"message\">Cannot query the database.<br>" . mysql_error()) ."</servmsg>";

$lrow = mysql_fetch_row($lquery);

 

$gusertype = $lrow[0];

$gid = $lrow[1];

$guser = $lrow[2];

$gpass = $lrow[4];

$gdir = $lrow[5];

$gkey = rand(1000000000,9999999999);

 

//Check $gusertype against ACL on GXUSER_TYPES

$usql = "SELECT * FROM ".$cfg['mysql']['prefix']."USERTYPES where USER_TYPE = '$gusertype'";

$uquery = mysql_query($usql,$db) or die("<servmsg type=\"message\">Cannot query the database.<br>" . mysql_error()) ."</servmsg>";

$urow = mysql_fetch_row($uquery);

 

$sizelimit = $urow[1];

$countlimit = $urow[2];

 

//Check to make sure that the user and pword are valid.  To prevent malicious hackers, we do not let them know which of the parameters is incorrect.

if ($guser != $luser || $gpass != $pword) {

$msg = "<servmsg type=\"message\">Sorry.  Either the user name or password are incorrect. </servmsg>";

die($msg);

}

 

//Allow the process to complete if the user and password are valid

//START PROCESSING BASED ON AUTHENTICATION *******************************************************************

if ($guser == $luser && $gpass == $pword) {

$msg = "<servmsg type=\"message\">Processing your request.</servmsg>";

 

//Get the subdirectory from the DB query

$userDir = "../userdirs/".$gdir;

 

//Check to see if file exists.  If so, prompt the user to see if they want to overvwrite...

if (file_exists($userDir."/".$params[2]) && ($params[6] == "false")) {

$msg = "<servmsg type=\"question\">Sorry, the file you are trying to upload (".$params[2].") already exists.  Do you want to overwrite it?</servmsg>";

die($msg);

}

 

//Create the directory (if it does not exist)

if (!is_dir($userDir) ) {

mkdir ($userDir, 0744);

}

 

//This array holds the filenames and file contents

$fArray = array($params[2]);

$cArray = array($params[3]);

for ($i=0;$i<count($fArray);$i++) {

 

//The new file name

$file = $userDir."/".$fArray[$i];

 

//The string stored from the files on the client side

$file_data = $cArray[$i];

 

//Check to make sure that the file size is less than the user's allotted file size limit (based on USER_TYPES > GFILESIZE_LIMIT)

$filelength = strlen($file_data);

if ($filelength > $sizelimit) {

$msg = "<servmsg type=\"message\">Sorry, the file you are trying to upload is too large for your account type.</servmsg>";

die($msg);

}

 

//Check to make sur ethat the number of maps is less than the user allotted number of maps

$filecount = count(glob($userDir . '/*.*'));

if ($filecount > $countlimit) {

$msg = "<servmsg type=\"message\">Sorry, you have reached the maximum number of files that you can load.</servmsg>";

die($msg);

}

 

//Check to make sure that the GKEY is valid (i.e., not a duplicate, as this is the primary key)...try 20 times...

for ($i=0;$i<20;$i++) {

$ksql = "SELECT GKEY FROM ".$cfg['mysql']['prefix']."FILES where GKEY = '$gkey'";

$kquery = mysql_query($ksql,$db) or die("<servmsg type=\"message\">Cannot query the database.<br>" . mysql_error()) . "</servmsg>";

$krow = mysql_fetch_row($kquery);

 

if (mysql_num_rows($kquery) > 0) {

$gkey = rand(1000000000,9999999999);

}

else {

//Stop the for loop; $gkey is unique

break;

}

}

 

$fh = @fopen($file, "wb");

if ($fh) {

  if (@fwrite($fh, $file_data)) {

  $msg = "<servmsg type=\"message\">Files were uploaded successfully.  ";

  $msg .= "You can view your document online at: http://www.mysite.com/test.php?q=".$gid."&i=".$gkey."</servmsg>";

  } else {

  $msg = "<servmsg type=\"message\">Could not write to file.</servmsg>";

  die($msg);

  }

  fclose($fh);

}

else {

  $msg = "<servmsg type=\"message\">Could not open file: ".$file."</servmsg>";

  die($msg);  

}

 

//Get the total file size of the new files combined

$filesize = $filesize+(round(filesize($file)/1000,1));

}

 

//The 5th array parameter is the title...use this to insert into the DB

$title = $params[4];

 

//The 6th array parameter is the style (right or left side panel)...use this to insert into the DB

$style = $params[5];

 

//Log the transaction to the DB

$fsql = "INSERT INTO ".$cfg['mysql']['prefix']."FILES (GID, GKEY, GXML, GHTM, GDATE, GTITLE, GSTYLE, GFILESIZE_KB)

VALUES ('$gid','$gkey','$fArray[0]','$fArray[2]',NOW(),'$title','$style','$filesize')";

$fquery = mysql_query($fsql,$db) or die("<servmsg type=\"message\">Cannot query the database.<br>" . mysql_error()) . "</servmsg>";

 

//END PROCESSING BASED ON AUTHENTICATION *******************************************************************

}

 

//Let the user know that it was successul

print $msg;

}

 

 

$server = xmlrpc_server_create();

 

/* register the 'external' name and then the 'internal' name */

xmlrpc_server_register_method($server, "gxload", "gxLoadFile");

 

$request = $HTTP_RAW_POST_DATA;

 

$response = xmlrpc_server_call_method($server, $request, null);

 

xmlrpc_server_destroy($server);

******************************************************************

 

 

 

 

CLIENT PHP SCRIPT

******************************************************************

<?php

 

set_time_limit(600);

 

function do_call($host, $port, $request) {

 

  $fp = fsockopen($host, $port, $errno, $errstr);

  $query = "POST /service/test_server.php HTTP/1.0\nUser_Agent: geoXtract\nHost: ".$host."\nContent-Type: text/xml\nContent-Length: ".strlen($request)."\n\n".$request."\n";

 

  if (!fputs($fp, $query, strlen($query))) {

      $errstr = "Write error";

      return 0;

  }

 

  $contents = '';

  while (!feof($fp)) {

      $contents .= fgets($fp);

  }

 

  fclose($fp);

  return $contents;

}

 

$host = 'www.mysite.com';

$port = 80;

 

 

//User name

$user = "[email protected]";

$password = "*********";

 

 

//The file(s) to upload

$filepath = "C:\\Documents and Settings\\riverdude\\My Documents\\testdata\\";

$file = $filepath."testdata.xml";

 

//Get the filename (will be used as filename on server)

$fnArray = explode ("\\", $file);

$filename = end($fnArray);

 

//The file converted to a string object

$contents = file_get_contents($file);

 

$request = xmlrpc_encode_request('gxload', array($user, $password, $filename, $contents, 'Test Title', 'Style1', 'false'));

$response = do_call($host, $port, $request);

print $response;

?>

*************************************************************

Link to comment
https://forums.phpfreaks.com/topic/36520-file-upload-via-xml-rpc/
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.