HTTP PUT support rewritten to PHP.

This commit is contained in:
tomas 2005-01-19 05:09:41 +00:00
parent 62371a5ab0
commit 807c8cec6c
3 changed files with 198 additions and 434 deletions

View File

@ -23,7 +23,7 @@
Author : $Author: tomas $
Version : $Revision: 1.2 $
Version : $Revision: 1.3 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/archiveServer/var/Archive.php,v $
------------------------------------------------------------------------------*/
@ -34,189 +34,19 @@ require_once "../../../storageServer/var/LocStor.php";
*/
class Archive extends LocStor{
/**
* Constructor
*/
function Archive(&$dbc, $config)
{
parent::LocStor(&$dbc, $config);
$this->transDir = $config['transDir'];
}
/* ======================================================= upload methods */
/**
* Open file upload
*
* @param sessid string - session id
* @param trid string - transport id
* @param type string - media|metadata|search
* @return array(url string) or error
*/
function uploadOpen($sessid, $trid, $type)
{
$file = "{$this->transDir}/$trid";
if(!$fp = fopen($file, 'w')) return PEAR::raiseError(
"Archive::uploadOpen: unable to create blank file"
);
fclose($fp);
$host = $this->config['archiveUrlHost'];
$port = $this->config['archiveUrlPort'];
$path = $this->config['archiveUrlPath'];
$url = "http://$host:$port$path/trans/".basename($file);
return array('url'=>$url);
}
/**
* Check uploaded file
*
* @param sessid string - session id
* @param url string
* @param token string
* @return array(md5h string, size int, url string)
*/
function uploadCheck($sessid, $url)
function uploadCheck($token)
{
$file = "{$this->transDir}/".basename($url);
$md5h = $this->_md5sum($file);
$size = filesize($file);
return array('md5h'=>$md5h, 'size'=>$size, 'url'=>$url);
return $this->bsCheckPut($token);
}
/**
* Close file upload
*
* @param sessid string - session id
* @param url string
* @param type string - media|metadata|search
* @param gunid string - global unique id
* @return boolean or error
*/
function uploadClose($sessid, $url, $type, $gunid)
{
$file = "{$this->transDir}/".basename($url);
$res = $this->processUploaded($sessid, $file, $type, $gunid);
return $res;
}
/**
* Process uploaded file - insert to the storage
*
* @param sessid string - session id
* @param file string - absolute local pathname
* @param type string - media|metadata|search
* @param gunid string - global unique id
* @return boolean or error
*/
function processUploaded($sessid, $file, $type, $gunid='X')
{
switch($type){
case 'media':
if(!file_exists($file)) break;
$res = $this->storeAudioClip($sessid, $gunid,
$file, '');
if(PEAR::isError($res)) return $res;
@unlink($file);
break;
case 'metadata':
case 'mdata':
if(!file_exists($file)) break;
$res = $this->updateAudioClipMetadata($sessid, $gunid,
$file);
if(PEAR::isError($res)){
// catch valid exception
if($res->getCode() == GBERR_FOBJNEX){
$res2 = $this->storeAudioClip($sessid, $gunid,
'', $file);
if(PEAR::isError($res2)) return $res2;
}else return $res;
}
@unlink($file);
break;
case 'search':
return PEAR::raiseError("Archive::processUploaded: search not implemented");
/*
rename($file, $file."_");
$criteria = unserialize(file_get_contents($file_));
$res = $this->searchMetadata($sessid, $criteria);
$fh = fopen($file, "w");
fwrite($fh, serialize($res));
fclose($fh);
@unlink($file."_");
*/
break;
default:
return PEAR::raiseError("Archive::processUploaded: unknown type ($type)");
break;
}
return TRUE;
}
/* ===================================================== download methods */
/**
* Open file download
*
* @param sessid string - session id
* @param type string media|metadata|search
* @param par string - depends on type
*/
function downloadOpen($sessid, $type, $par)
{
switch($type){
case 'media':
case 'metadata':
$gunid = $par;
$res = $this->prepareForTransport('', $gunid, $sessid);
if(PEAR::isError($res)) return $res;
list($mediaFile, $mdataFile, $gunid) = $res;
default:
}
switch($type){
case 'media':
$fname = $mediaFile;
break;
case 'metadata':
$fname = $mdataFile;
break;
default:
}
$file = "{$this->transDir}/$fname";
$host = $this->config['archiveUrlHost'];
$port = $this->config['archiveUrlPort'];
$path = $this->config['archiveUrlPath'];
$url = "http://$host:$port$path/trans/$fname";
$md5h = $this->_md5sum($file);
return array('url'=>$url, 'md5h'=>$md5h, 'fname'=>$fname);
}
/**
* Close file download
*
* @param sessid string - session id
* @param url string
* @return boolean
*/
function downloadClose($sessid, $url)
{
$file = "{$this->transDir}/".basename($url);
@unlink($file);
return TRUE;
}
/* ==================================================== auxiliary methods */
/**
* Returns md5 hash of external file
*
* @param fpath string - local path to file
* @return string
*/
function _md5sum($fpath)
{
$md5h = `md5sum $fpath`;
$arr = split(' ', $md5h);
return $arr[0];
}
}
?>

View File

@ -0,0 +1,109 @@
<?php
/*------------------------------------------------------------------------------
Copyright (c) 2004 Media Development Loan Fund
This file is part of the LiveSupport project.
http://livesupport.campware.org/
To report bugs, send an e-mail to bugs@campware.org
LiveSupport is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
LiveSupport is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LiveSupport; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Author : $Author: tomas $
Version : $Revision: 1.1 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/archiveServer/var/xmlrpc/put.php,v $
------------------------------------------------------------------------------*/
/**
* \file put.php
* Store PUT data as temporary file.
*
* put.php is remote callable script through HTTP PUT method.
* Requires token returned by appropriate storageServer XMLRPC call.
* Appropriate closing XMLRPC call should follow.
*
* This script accepts following HTTP GET parameter:
* <ul>
* <li>token : string, put token returned by appropriate
* XMLRPC call</li>
* </ul>
*
* On success, returns HTTP return code 200.
*
* On errors, returns HTTP return code &gt;200
* The possible error codes are:
* <ul>
* <li> 400 - Incorrect parameters passed to method</li>
* <li> 403 - Access denied</li>
* <li> 500 - Application error</li>
* </ul>
*
* @see XR_LocStor
*/
require_once '../conf.php';
require_once 'DB.php';
require_once '../Archive.php';
PEAR::setErrorHandling(PEAR_ERROR_RETURN);
$dbc = DB::connect($config['dsn'], TRUE);
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
$gb = &new Archive(&$dbc, $config);
function http_error($code, $err){
header("HTTP/1.1 $code");
header("Content-type: text/plain; charset=UTF-8");
echo "$err\r\n";
exit;
}
if(preg_match("|^[0-9a-fA-F]{16}$|", $_REQUEST['token'])){
$token = $_REQUEST['token'];
}else{
http_error(400, "Error on token parameter. ({$_REQUEST['token']})");
}
$tc = $gb->bsCheckToken($token, 'put');
if(PEAR::isError($tc)){ http_error(500, $ex->getMessage()); }
if(!$tc){ http_error(403, "Token not valid."); }
#var_dump($tc); exit;
header("Content-type: text/plain");
#var_dump($_SERVER); var_dump($_REQUEST); exit;
#$destfile = $_SERVER['PATH_TRANSLATED'];
$destfile = "{$config['accessDir']}/{$token}";
/* PUT data comes in on the input stream */
$putdata = @fopen("php://input", "r") or
http_error(500, "put.php: Can't read input");
/* Open a file for writing */
$fp = @fopen($destfile, "ab") or
http_error(500, "put.php: Can't write to destination file (token=$token)");
/* Read the data 1 KB at a time and write to the file */
while ($data = fread($putdata, 1024)){
fwrite($fp, $data);
}
/* Close the streams */
fclose($fp);
fclose($putdata);
header("HTTP/1.1 200");
?>

View File

@ -23,286 +23,111 @@
Author : $Author: tomas $
Version : $Revision: 1.2 $
Version : $Revision: 1.3 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/archiveServer/var/xmlrpc/xrArchive.php,v $
------------------------------------------------------------------------------*/
include_once "../../../storageServer/var/xmlrpc/xmlrpc.inc";
include_once "../../../storageServer/var/xmlrpc/xmlrpcs.inc";
require_once '../conf.php';
require_once 'DB.php';
require_once "../Archive.php";
/* ====================================================== specific PHP config */
//error_reporting(0);
ini_set("error_prepend_string", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<methodResponse>
<fault>
<value>
<struct>
<member>
<name>faultCode</name>
<value><int>804</int></value>
</member>
<member>
<name>faultString</name>
<value><string>");
ini_set("error_append_string", "</string></value>
</member>
</struct>
</value>
</fault>
</methodResponse>");
header("Content-type: text/xml");
/* ================================================================= includes */
require_once 'DB.php';
require_once "../../../storageServer/var/xmlrpc/XML/RPC/Server.php";
require_once '../conf.php';
require_once 'XR_Archive.php';
/* ============================================ setting default error handler */
function errHndl($errno, $errmsg, $filename, $linenum, $vars){
if($errno == 8 /*E_NOTICE*/) return;
$xr =& new XML_RPC_Response(0, 805,
"ERROR:xrLocStor: $errno $errmsg ($filename:$linenum)");
header("Content-type: text/xml");
echo $xr->serialize();
exit($errno);
}
$old_error_handler = set_error_handler("errHndl");
/* ============================================================= runable code */
PEAR::setErrorHandling(PEAR_ERROR_RETURN);
$dbc = DB::connect($config['dsn'], TRUE);
$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
/**
* XMLRPC layer for Archive module
*/
class XR_Archive extends Archive{
/**
* Call LocStor::authenticate
*
* @param input XMLRPC struct
*/
function xr_authenticate($input)
{
list($ok, $r) = $this->_xr_getPars($input);
if(!$ok) return $r;
$res = $this->authenticate($r['login'], $r['pass']);
return new xmlrpcresp(new xmlrpcval($res, "boolean"));
}
/**
* Call LocStor::existsAudioClip
*
* @param input XMLRPC struct
*/
function xr_existsAudioClip($input)
{
list($ok, $r) = $this->_xr_getPars($input);
if(!$ok) return $r;
#$this->debugLog(join(', ', $r));
$res = $this->existsAudioClip($r['sessid'], $r['gunid']);
#$this->debugLog($res);
if(PEAR::isError($res))
return new xmlrpcresp(0, 803,
"xr_existsAudioClip: ".$res->getMessage().
" ".$res->getUserInfo()
);
return new xmlrpcresp(new xmlrpcval($res, "boolean"));
}
/**
* Call LocStor::deleteAudioClip
*
* @param input XMLRPC struct
*/
function xr_deleteAudioClip($input)
{
list($ok, $r) = $this->_xr_getPars($input);
if(!$ok) return $r;
$res = $this->deleteAudioClip($r['sessid'], $r['gunid']);
if(!PEAR::isError($res))
return new xmlrpcresp(new xmlrpcval($res, "boolean"));
else
return new xmlrpcresp(0, 803,
"xr_deleteAudioClip: ".$res->getMessage().
" ".$res->getUserInfo()
);
}
/* ======================================================= upload methods */
/**
* Open general file upload
*
* @param input XMLRPC struct
*/
function xr_uploadOpen($input)
{
list($ok, $r) = $this->_xr_getPars($input);
if(!$ok) return $r;
$res = $this->uploadOpen($r['sessid'], $r['trid'], $r['type']);
if(PEAR::isError($res))
return new xmlrpcresp(0, 803,
"xr_uploadOpen: ".$res->getMessage().
" ".$res->getUserInfo()
);
return new xmlrpcresp(xmlrpc_encoder($res));
}
/**
* Check general file upload
*
* @param input XMLRPC struct
*/
function xr_uploadCheck($input)
{
list($ok, $r) = $this->_xr_getPars($input);
if(!$ok) return $r;
$res = $this->uploadCheck($r['sessid'], $r['url']);
if(PEAR::isError($res))
return new xmlrpcresp(0, 803,
"xr_uploadCheck: ".$res->getMessage().
" ".$res->getUserInfo()
);
return new xmlrpcresp(xmlrpc_encoder($res));
}
/**
* Close general file upload
*
* @param input XMLRPC struct
*/
function xr_uploadClose($input)
{
list($ok, $r) = $this->_xr_getPars($input);
if(!$ok) return $r;
$res = $this->uploadClose($r['sessid'], $r['url'], $r['type'], $r['gunid']);
if(PEAR::isError($res))
return new xmlrpcresp(0, 803,
"xr_uploadClose: ".$res->getMessage().
" ".$res->getUserInfo()
);
return new xmlrpcresp(xmlrpc_encoder($res));
}
/* ===================================================== download methods */
/**
* Open general file download
*
* @param input XMLRPC struct
*/
function xr_downloadOpen($input)
{
list($ok, $r) = $this->_xr_getPars($input);
if(!$ok) return $r;
$res = $this->downloadOpen($r['sessid'], $r['type'], $r['par']);
if(PEAR::isError($res))
return new xmlrpcresp(0, 803,
"xr_downloadOpen: ".$res->getMessage().
" ".$res->getUserInfo()
);
return new xmlrpcresp(xmlrpc_encoder($res));
}
/**
* Close general file download
*
* @param input XMLRPC struct
*/
function xr_downloadClose($input)
{
list($ok, $r) = $this->_xr_getPars($input);
if(!$ok) return $r;
$res = $this->downloadClose($r['sessid'], $r['url']);
if(PEAR::isError($res))
return new xmlrpcresp(0, 803,
"xr_downloadClose: ".$res->getMessage().
" ".$res->getUserInfo()
);
return new xmlrpcresp(xmlrpc_encoder($res));
}
/* =============================================== authentication methods */
/**
* Call Archive::login
*
* @param input XMLRPC struct
*/
function xr_login($input)
{
list($ok, $r) = $this->_xr_getPars($input);
if(!$ok) return $r;
if(!($res = $this->login($r['login'], $r['pass'])))
return new xmlrpcresp(0, 802,
"xr_login: login failed - incorrect username or password ({$r['login']}/{$r['pass']})."
);
else
return new xmlrpcresp($this->_v2xr($res, false));
}
/**
* Call Archive::logout
*
* @param input XMLRPC struct
*/
function xr_logout($input)
{
list($ok, $r) = $this->_xr_getPars($input);
if(!$ok) return $r;
$res = $this->logout($r['sessid']);
if(!PEAR::isError($res))
return new xmlrpcresp($this->_v2xr('Bye', false));
else
return new xmlrpcresp(0, 803,
"xr_logout: logout failed - not logged."
);
}
/* ==================================================== auxiliary methods */
/**
* Simple ping method - return strtouppered string
*
* @param input XMLRPC struct
*/
function xr_ping($input)
{
list($ok, $r) = $this->_xr_getPars($input);
if(!$ok) return $r;
return new xmlrpcresp(new xmlrpcval(strtoupper($r['par']), "string"));
}
/**
* Convert PHP variables to XMLRPC objects
*
* @param var mixed - PHP variable
* @param struct boolean - flag for using XMLRPC struct instead of array
* @return XMLRPC object
*/
function _v2xr($var, $struct=true){
if(is_array($var)){
$r = array();
foreach($var as $k=>$v){
if($struct) $r[$k]=$this->_v2xr($v);
else $r[]=$this->_v2xr($v);
}
return new xmlrpcval($r, ($struct ? "struct" : "array"));
}else if(is_int($var)){
return new xmlrpcval($var, "int");
}else if(is_bool($var)){
return new xmlrpcval($var, "boolean");
}else{
return new xmlrpcval($var, "string");
}
}
/**
* Convert XMLRPC struct to PHP array
*
* @param input XMLRPC struct
*/
function _xr_getPars($input)
{
$p = $input->getParam(0);
if(isset($p) && $p->scalartyp()=="struct"){
$p->structreset(); $r = array();
while(list($k,$v) = $p->structeach()){ $r[$k] = $v->scalarval(); }
return array(TRUE, $r);
}
else return array(FALSE, new xmlrpcresp(0, 801,
"xr_login: wrong 1st parameter, struct expected."
));
}
}
$archive = &new XR_Archive(&$dbc, $config);
$methods = array(
'test' => 'Tests toupper and checks sessid, params: '.
'teststring, sessid.',
'authenticate' => 'Checks authentication.',
'login' => 'Login to storage.',
'logout' => 'Logout from storage.',
'ping' =>'Echo request',
'existsAudioClip' => 'Checks if an Audio clip with the specified '.
'id is stored in local storage.',
'storeAudioClipOpen' => 'Open channel for store a new audio clip '.
'or replace an existing one.',
'storeAudioClipClose' => 'Close channel for store a new audio clip'.
' or replace an existing one.',
'downloadRawAudioDataOpen'=> 'Create and return downloadable URL'.
'for audio file',
'downloadRawAudioDataClose'=>'Discard downloadable URL for audio file',
'downloadMetadataOpen' => 'Create and return downloadable URL'.
'for metadata',
'downloadMetadataClose' => 'Discard downloadable URL for metadata',
'openPut' => 'openPut',
'closePut' => 'closePut',
'deleteAudioClip' => 'Delete an existing Audio clip.',
'updateAudioClipMetadata' => 'Update the metadata of an Audio clip '.
'stored in Local storage.',
'searchMetadata' => 'Search through the metadata of stored '.
'AudioClips, return all matching clip ids.',
'accessRawAudioData' => 'Get access to raw audio data.',
'releaseRawAudioData' => 'Release access to raw audio data.',
'getAudioClip' => 'Return the contents of an Audio clip.',
'resetStorage' => 'Reset storageServer for debugging.',
'createPlaylist' => 'Create a new Playlist metafile.',
'editPlaylist' => 'Open a Playlist metafile for editing.',
'savePlaylist' => 'Save a Playlist metafile.',
'deletePlaylist' => 'Delete a Playlist metafile.',
'accessPlaylist' => 'Open readable URL to a Playlist metafile.',
'releasePlaylist' => 'Release readable URL from accessPlaylist.',
'existsPlaylist' => 'Check whether a Playlist exists.',
'playlistIsAvailable' => 'Check whether a Playlist is available '.
'for editing.',
'uploadOpen' =>'Open file upload',
'uploadCheck' =>'Check size and md5 uploaded file',
'uploadClose' =>'Close file upload',
'downloadOpen' =>'Open file download',
'downloadClose' =>'Close file download',
'uploadCheck' => 'Check the checksum of uploaded file',
'ping' => 'Echo request',
);
$defs = array();
foreach($methods as $method=>$description){
$defs["archive.$method"] = array(
"function" => array(&$archive, "xr_$method"),
"signature" => array(array($xmlrpcStruct, $xmlrpcStruct)),
# "function" => array(&$archive, "xr_$method"),
"function" => "\$GLOBALS['archive']->xr_$method",
"signature" => array(
array($GLOBALS['XML_RPC_Struct'], $GLOBALS['XML_RPC_Struct'])
),
"docstring" => $description
);
}
$s=new xmlrpc_server( $defs );
$s = &new XML_RPC_Server( $defs );
?>