summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarl 'vollmerk' Vollmer <vollmer@ampache.org>2008-04-15 03:14:42 +0000
committerKarl 'vollmerk' Vollmer <vollmer@ampache.org>2008-04-15 03:14:42 +0000
commit669753d59d3b7acfb248e46daad174ed7414eb4a (patch)
tree1cb4505aa1bf878b470680ec85ab57f4e15c6955
parent9504931c64a67156cde61c597ab4b111e3dc478f (diff)
downloadampache-669753d59d3b7acfb248e46daad174ed7414eb4a.tar.gz
ampache-669753d59d3b7acfb248e46daad174ed7414eb4a.tar.bz2
ampache-669753d59d3b7acfb248e46daad174ed7414eb4a.zip
first steps of a fix for the xml-rpc streaming and cataloging
-rwxr-xr-xdocs/CHANGELOG5
-rw-r--r--lib/class/access.class.php2
-rw-r--r--lib/class/catalog.class.php69
-rw-r--r--lib/class/song.class.php2
-rw-r--r--lib/class/stream.class.php2
-rw-r--r--lib/class/vauth.class.php2
-rw-r--r--lib/class/xmlrpcclient.class.php130
-rw-r--r--lib/class/xmlrpcserver.class.php35
-rw-r--r--play/index.php56
-rw-r--r--templates/sidebar_localplay.inc.php11
10 files changed, 240 insertions, 74 deletions
diff --git a/docs/CHANGELOG b/docs/CHANGELOG
index 92824d90..833f8e33 100755
--- a/docs/CHANGELOG
+++ b/docs/CHANGELOG
@@ -4,6 +4,11 @@
--------------------------------------------------------------------------
v.3.4-Beta3
+ - Fixed seeking on random track, giving you a new track every
+ seek
+ - Added additional error reporting if localplay access / config
+ fails
+ - Give Admins Full Localplay Regardless
- Fixed incorrect reference to ellipsis thresholds
- Fixed page point not being remembered by the back button
- Fixed naming restrictions on database name during install
diff --git a/lib/class/access.class.php b/lib/class/access.class.php
index 08736cfc..734c7d76 100644
--- a/lib/class/access.class.php
+++ b/lib/class/access.class.php
@@ -238,7 +238,7 @@ class Access {
switch ($type) {
case 'localplay':
// Check their localplay_level
- if (Config::get('localplay_level') >= $level) {
+ if (Config::get('localplay_level') >= $level OR $GLOBALS['user']->access >= '100') {
return true;
}
else {
diff --git a/lib/class/catalog.class.php b/lib/class/catalog.class.php
index 3fb50cd6..2ec23dea 100644
--- a/lib/class/catalog.class.php
+++ b/lib/class/catalog.class.php
@@ -1211,45 +1211,27 @@ class Catalog {
return false;
} // end check for class
- // first, glean out the information from the path about the server and remote path
- // this can't contain the http
- preg_match("/http:\/\/([^\/]+)\/*(.*)/", $this->path, $match);
- $server = $match[1];
- $path = $match[2];
-
- if ( ! $path ) {
- $client = new xmlrpc_client("/server/xmlrpc.server.php", $server, 80);
- }
- else {
- $client = new xmlrpc_client("/$path/server/xmlrpc.server.php", $server, 80);
- }
+ // Handshake and get our token for this little conversation
+ $token = xmlRpcClient::ampache_handshake($this->path,$this->key);
- // 6 that's right, the secret level because if you do have debug on most likely you're
- // going to just crash your browser... sorry folks
- if (Config::get('debug') AND Config::get('debug_level') == '6') { $client->setDebug(1); }
+ if (!$token) {
+ debug_event('XMLCLIENT','Error No Token returned');
+ Error::display('general');
+ return;
+ }
- // Before we do anything else we need to do a handshake with the remote server
- $timestamp = time();
- $handshake_key = md5($timestamp . $this->key);
+ // Figure out the host etc
+ preg_match("/http:\/\/([^\/\:]+):?(\d*)\/*(.*)/", $this->path, $match);
+ $server = $match['1'];
+ $port = $match['2'] ? intval($match['2']) : '80';
+ $path = $match['3'];
- $encoded_key = new xmlrpcval($handshake_key,"string");
- $timestamp = new xmlrpcval($timestamp,"int");
- $xmlrpc_message = new xmlrpcmsg('xmlrpcserver.handshake',array($encoded_key,$timestamp));
+ $full_url = ltrim("/$path/server/xmlrpc.server.php",'/');
+ $client = new xmlrpc_client($full_url,$server,$port);
- // Send it off
- $response = $client->send($xmlrpc_message,10);
- if ($response->faultCode()) {
- $error_msg = _("Error connecting to") . " " . $server . " " . _("Code") . ": " . $response->faultCode() . " " . _("Reason") . ": " . $response->faultString();
- debug_event('XMLCLIENT',$error_msg,'1');
- echo "<p class=\"error\">$error_msg</p>";
- return;
- }
-
- $token = php_xmlrpc_decode($response->value());
-
/* encode the variables we need to send over */
- $encoded_key = new xmlrpcval($token,"string");
- $encoded_path = new xmlrpcval(Config::get('web_path'),"string");
+ $encoded_key = new xmlrpcval($token,'string');
+ $encoded_path = new xmlrpcval(Config::get('web_path'),'string');
$xmlrpc_message = new xmlrpcmsg('xmlrpcserver.get_catalogs', array($encoded_key,$encoded_path));
$response = $client->send($xmlrpc_message,30);
@@ -1287,6 +1269,9 @@ class Catalog {
echo "<p>" . _('Completed updating remote catalog(s)') . ".</p><hr />\n";
flush();
+ // Update the last update value
+ $this->update_last_update();
+
return true;
} // get_remote_catalog
@@ -1298,9 +1283,9 @@ class Catalog {
*/
public function get_remote_song($client,$token,$start,$end) {
- $encoded_start = new xmlrpcval($start,"int");
- $encoded_end = new xmlrpcval($end,"int");
- $encoded_key = new xmlrpcval($token,"string");
+ $encoded_start = new xmlrpcval($start,'int');
+ $encoded_end = new xmlrpcval($end,'int');
+ $encoded_key = new xmlrpcval($token,'string');
$query_array = array($encoded_key,$encoded_start,$encoded_end);
@@ -1329,14 +1314,11 @@ class Catalog {
} // get_remote_song
-
/**
* update_remote_catalog
* actually updates from the remote data, takes an array of songs that are base64 encoded and parses them
* @package XMLRPC
* @catagory Client
- * @todo This should be based off of seralize
- * @todo some kind of cleanup of dead songs?
*/
function update_remote_catalog($data,$root_path) {
@@ -1353,8 +1335,11 @@ class Catalog {
$song->artist = self::check_artist($song->artist);
$song->album = self::check_album($song->album,$song->year);
$song->genre = self::check_genre($song->genre);
- $song->file = $root_path . "/play/index.php?song=" . $data[12];
+ $song->file = $root_path . "/play/index.php?song=" . $song->id;
$song->catalog = $this->id;
+
+ // Clear out the song id
+ unset($song->id);
if (!$this->check_remote_song($song->file)) {
$this->insert_remote_song($song);
@@ -2158,8 +2143,6 @@ class Catalog {
} //check_local_mp3
-
-
/*!
@function import_m3u
@discussion this takes m3u filename and then attempts
diff --git a/lib/class/song.class.php b/lib/class/song.class.php
index 23a3b658..e6caa24d 100644
--- a/lib/class/song.class.php
+++ b/lib/class/song.class.php
@@ -1,7 +1,7 @@
<?php
/*
- Copyright (c) 2001 - 2007 Ampache.org
+ Copyright (c) Ampache.org
All rights reserved.
This program is free software; you can redistribute it and/or
diff --git a/lib/class/stream.class.php b/lib/class/stream.class.php
index 87d34d2d..7582b9e2 100644
--- a/lib/class/stream.class.php
+++ b/lib/class/stream.class.php
@@ -1,7 +1,7 @@
<?php
/*
- Copyright (c) 2001 - 2007 Ampache.org
+ Copyright (c) Ampache.org
All rights reserved.
This program is free software; you can redistribute it and/or
diff --git a/lib/class/vauth.class.php b/lib/class/vauth.class.php
index 14f8b40d..b3892872 100644
--- a/lib/class/vauth.class.php
+++ b/lib/class/vauth.class.php
@@ -1,7 +1,7 @@
<?php
/*
- Copyright (c) 2001 - 2007 Ampache.org
+ Copyright (c) Ampache.org
All Rights Reserved
This program is free software; you can redistribute it and/or
diff --git a/lib/class/xmlrpcclient.class.php b/lib/class/xmlrpcclient.class.php
new file mode 100644
index 00000000..88174880
--- /dev/null
+++ b/lib/class/xmlrpcclient.class.php
@@ -0,0 +1,130 @@
+<?php
+/*
+
+ Copyright (c) Ampache.org
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License v2
+ as published by the Free Software Foundation.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+/**
+ * xmlRpcClient
+ * This is the other half of the xmlrpcserver class, it Holds the different calls that Ampache might
+ * make that are xmlrpc'ie this does not include the API responses.
+ */
+
+class xmlRpcClient {
+
+ /**
+ * construtor
+ * not used
+ */
+ private function __construct() {
+
+ // Rien a faire
+
+ } // constructor
+
+ /**
+ * ampache_handshake
+ * This handshakes with ampache servers, this is used by the internal xml-rpc mojo
+ */
+ public static function ampache_handshake($target_url,$key) {
+
+ // Generate the client
+ $client = self::create_client($target_url);
+
+ // 6 that's right, the secret level because if you do have debug on most likely you're
+ // going to just crash your browser... sorry folks
+ if (Config::get('debug') AND Config::get('debug_level') == '6') { $client->setDebug(1); }
+
+ // Build our key
+ $timestamp = time();
+ $handshake_key = md5($timestamp . $key);
+
+ $encoded_key = new xmlrpcval($handshake_key,'string');
+ $timestamp = new xmlrpcval($timestamp,'int');
+ $xmlrpc_message = new xmlrpcmsg('xmlrpcserver.handshake',array($encoded_key,$timestamp));
+
+ // Send it off
+ $response = $client->send($xmlrpc_message,10);
+ if ($response->faultCode()) {
+ $error_msg = _('Error connecting to') . " " . $server . " " . _("Code") . ": " . $response->faultCode() . " " . _("Reason") . ": " . $response->faultString();
+ debug_event('XMLCLIENT',$error_msg,'1');
+ Error::add('general',$error_msg);
+ return;
+ }
+
+ $token = php_xmlrpc_decode($response->value());
+
+ debug_event('XML-RPC',$token . ' returned from ' . $server,'3');
+
+ return $token;
+
+ } // ampache_handshake
+
+ /**
+ * ampache_create_stream_session
+ * This generates a new stream session, it takes a target_url and a token as generated by
+ * a ampache_handshake action
+ */
+ public static function ampache_create_stream_session($target_url,$token) {
+
+ $client = self::create_client($target_url);
+
+ // 6 that's right, the secret level because if you do have debug on most likely you're
+ // going to just crash your browser... sorry folks
+ if (Config::get('debug') AND Config::get('debug_level') == '6') { $client->setDebug(1); }
+
+ $encoded_key = new xmlrpcval($token,'string');
+ $xmlrpc_message = new xmlrpcmsg('xmlrpcserver.create_stream_session',array($encoded_key));
+
+ $response = $client->send($xmlrpc_message,4);
+
+ if ($response->faultCode() ) {
+ $error_msg = _("Error connecting to") . " " . $server . " " . _("Code") . ": " . $response->faultCode() . " " .
+ debug_event('XMLCLIENT',$error_msg,'1');
+ return false;
+ }
+
+ $sid = php_xmlrpc_decode($response->value());
+
+ debug_event('XML-RPC',$sid . ' stream session ID returned from ' . $server,'3');
+
+ return $sid;
+
+ } // ampache_create_stream_session
+
+ /**
+ * create_client
+ * This creates the xmlrpc client object from a URL
+ */
+ public static function create_client($target_url) {
+
+ // Figure out the host etc
+ preg_match("/http:\/\/([^\/\:]+):?(\d*)\/*(.*)/", $target_url, $match);
+ $server = $match['1'];
+ $port = $match['2'] ? intval($match['2']) : '80';
+ $path = $match['3'];
+
+ $full_url = ltrim("/$path/server/xmlrpc.server.php",'/');
+ $client = new xmlrpc_client($full_url,$server,$port);
+
+ return $client;
+
+ } // create_client
+
+} // xmlRpcServer
+?>
diff --git a/lib/class/xmlrpcserver.class.php b/lib/class/xmlrpcserver.class.php
index 5b6b3892..fc903aaf 100644
--- a/lib/class/xmlrpcserver.class.php
+++ b/lib/class/xmlrpcserver.class.php
@@ -1,7 +1,7 @@
<?php
/*
- Copyright (c) 2001 - 2007 Ampache.org
+ Copyright (c) Ampache.org
All rights reserved.
This program is free software; you can redistribute it and/or
@@ -124,6 +124,36 @@ class xmlRpcServer {
return new xmlrpcresp($encoded_array);
} // get_songs
+
+ /**
+ * create_stream_session
+ * This creates a new stream session and returns the SID in question, this requires a TOKEN as generated by the handshake
+ */
+ public static function create_stream_session($xmlrpc_object) {
+
+ // Pull out the key
+ $variable = $xmlrpc_object->getParam(0);
+ $key = $variable->scalarval();
+
+ // Check it and make sure we're super green
+ if (!vauth::session_exists('xml-rpc',$key)) {
+ debug_event('XMLSERVER','Error ' . $_SERVER['REMOTE_ADDR'] . ' with key ' . $key . ' does not match any ACLs','1');
+ return new xmlrpcresp(0,'503','Key/IP Mis-match Access Denied');
+ }
+
+ $stream = new Stream();
+ $stream->user_id = '-1';
+
+ if (!$stream->insert_session($key)) {
+ debug_event('XMLSERVER','Failed to create stream session','1');
+ return new xmlrpcresp(0,'503','Failed to Create Stream Session','1');
+ }
+
+ $encoded_array = php_xmlrpc_encode($key);
+
+ return new xmlrpcresp($encoded_array);
+
+ } // create_stream_session
/**
* handshake
@@ -156,7 +186,6 @@ class xmlRpcServer {
// Build our encoded passphrase
$md5pass = md5($timestamp . $row['key']);
-
if ($md5pass == $encoded_key) {
$data['type'] = 'xml-rpc';
$data['username'] = 'System';
@@ -167,7 +196,7 @@ class xmlRpcServer {
} // end while rows
- return new xmlrpcresp(0,'503','Handshaek failure, Key/IP Incorrect');
+ return new xmlrpcresp(0,'503','Handshake failure, Key/IP Incorrect');
} // handshake
diff --git a/play/index.php b/play/index.php
index 87d09fb5..e3df5584 100644
--- a/play/index.php
+++ b/play/index.php
@@ -1,7 +1,7 @@
<?php
/*
- Copyright (c) 2001 - 2008 Ampache.org
+ Copyright (c) Ampache.org
All rights reserved.
This program is free software; you can redistribute it and/or
@@ -34,17 +34,26 @@ ob_end_clean();
$uid = scrub_in($_REQUEST['uid']);
$song_id = scrub_in($_REQUEST['song']);
$sid = scrub_in($_REQUEST['sid']);
+$xml_rpc = scrub_in($_REQUEST['xml_rpc']);
/* This is specifically for tmp playlist requests */
$demo_id = scrub_in($_REQUEST['demo_id']);
$random = scrub_in($_REQUEST['random']);
+// Parse byte range request
+$n = sscanf($_SERVER['HTTP_RANGE'], "bytes=%d-%d",$start,$end);
+
/* First things first, if we don't have a uid/song_id stop here */
if (empty($song_id) && empty($demo_id) && empty($random)) {
debug_event('no_song',"Error: No Song UID Specified, nothing to play",'2');
exit;
}
+// If we're XML-RPC and it's enabled, use system user
+if (isset($xml_rpc) AND Config::get('xml_rpc') AND !isset($uid)) {
+ $uid = '-1';
+}
+
if (!isset($uid)) {
debug_event('no_user','Error: No User specified','2');
exit;
@@ -77,7 +86,7 @@ if (Config::get('require_session')) {
$user->update_last_seen();
/* If we are in demo mode.. die here */
-if (Config::get('demo_mode') || !Access::check('interface','25')) {
+if (Config::get('demo_mode') || (!Access::check('interface','25') AND !isset($xml_rpc))) {
debug_event('access_denied',"Streaming Access Denied:" .Config::get('demo_mode') . "is the value of demo_mode. Current user level is " . $GLOBALS['user']->access,'3');
access_denied();
exit;
@@ -127,8 +136,15 @@ if ($demo_id) {
* if we are doing random let's pull the random object
*/
if ($random) {
- $song_id = Random::get_single_song($_REQUEST['type']);
-}
+ if (!isset($start)) {
+ $song_id = Random::get_single_song($_REQUEST['type']);
+ // Save this one incase we do a seek
+ $_SESSION['random']['last'] = $song_id;
+ }
+ else {
+ $song_id = $_SESSION['random']['last'];
+ }
+} // if random
/* Base Checks passed create the song object */
$song = new Song($song_id);
@@ -166,25 +182,25 @@ if (Config::get('lock_songs')) {
/* Check to see if this is a 'remote' catalog */
if ($catalog->catalog_type == 'remote') {
- // redirect to the remote host's play path
- /* Break Up the Web Path */
- preg_match("/http:\/\/([^\/]+)\/*(.*)/", Config::get('web_path'), $match);
- $server = rawurlencode($match[1]);
- $path = rawurlencode($match[2]);
- $port = $_SERVER['SERVER_PORT'];
- $ssl = ($_SERVER['HTTPS'] == 'on') ? '1' : '0';
- $catalog = $catalog->id;
-
- //Fixme: We should do a handshake here so we can pass a valid SID
-
- $extra_info = "&xml_rpc=1&xml_path=$path&xml_server=$server&xml_port=$port&ssl=$ssl&catalog=$catalog&sid=$sid";
+
+ preg_match("/(.+)\/play\/index.+/",$song->file,$match);
+
+ $token = xmlRpcClient::ampache_handshake($match['1'],$catalog->key);
+
+ // If we don't get anything back we failed and should bail now
+ if (!$token) {
+ debug_event('xmlrpc-stream','Error Unable to get Token from ' . $match['1'] . ' check target servers logs','1');
+ exit;
+ }
+
+ $sid = xmlRpcClient::ampache_create_stream_session($match['1'],$token);
+
+ $extra_info = "&xml_rpc=1&sid=$sid";
header("Location: " . $song->file . $extra_info);
debug_event('xmlrpc-stream',"Start XML-RPC Stream - " . $song->file . $extra_info,'5');
exit;
} // end if remote catalog
-
-
// make fread binary safe
set_magic_quotes_runtime(0);
@@ -239,10 +255,6 @@ if ($_GET['action'] == 'download' AND Config::get('download')) {
} // if they are trying to download and they can
-
-// Parse byte range request
-$n = sscanf($_SERVER['HTTP_RANGE'], "bytes=%d-%d",$start,$end);
-
// Generate browser class for sending headers
$browser = new Browser();
header("Accept-Ranges: bytes" );
diff --git a/templates/sidebar_localplay.inc.php b/templates/sidebar_localplay.inc.php
index 5e2e79ff..95313f4e 100644
--- a/templates/sidebar_localplay.inc.php
+++ b/templates/sidebar_localplay.inc.php
@@ -1,7 +1,7 @@
<?php
/*
- Copyright (c) 2001 - 2007 Ampache.org
+ Copyright (c) Ampache.org
All rights reserved.
This program is free software; you can redistribute it and/or
@@ -21,7 +21,7 @@
?>
<ul class="sb2" id="sb_localplay">
-<?php if (Config::get('allow_localplay_playback') AND Config::get('localplay_controller') AND Access::check('localplay','5')) { ?>
+<?php if ($server_allow = Config::get('allow_localplay_playback') AND $controller = Config::get('localplay_controller') AND $access_check = Access::check('localplay','5')) { ?>
<?php
// Little bit of work to be done here
$localplay = new Localplay(Config::get('localplay_controller'));
@@ -58,5 +58,12 @@
</li>
<?php } else { ?>
<li><h4><?php echo _('Localplay Disabled'); ?></h4></li>
+ <?php if (!$server_allow) { ?>
+ <li><?php echo _('Allow Localplay set to False'); ?></li>
+ <?php } elseif (!$controller) { ?>
+ <li><?php echo _('Localplay Controller Not Defined'); ?></li>
+ <?php } elseif (!$access_check) { ?>
+ <li><?php echo _('Access Denied'); ?></li>
+ <?php } ?>
<?php } ?>
</ul>