Update to version 1.0 of PHP for XML-RPC, inclusing ssl mods

This commit is contained in:
Miles Lott 2001-08-30 00:29:55 +00:00
parent 9bd1f18cd4
commit 8353d7e678
6 changed files with 251 additions and 106 deletions

View File

@ -161,17 +161,16 @@
{ {
$ele[$key] = CreateObject('phpgwapi.xmlrpcval',$val, 'string'); $ele[$key] = CreateObject('phpgwapi.xmlrpcval',$val, 'string');
} }
$arr[] = CreateObject('phpgwapi.xmlrpcval',$ele,'struct');
$f = CreateObject('phpgwapi.xmlrpcmsg', $method_name, $arr,'struct');
} }
$arr[] = CreateObject('phpgwapi.xmlrpcval',$ele,'struct');
$f = CreateObject('phpgwapi.xmlrpcmsg', $method_name, $arr,'struct');
} }
$this->debug("<pre>" . htmlentities($f->serialize()) . "</pre>\n",$debug); $this->debug("<pre>" . htmlentities($f->serialize()) . "</pre>\n",$debug);
$c = CreateObject('phpgwapi.xmlrpc_client',$this->urlparts['xmlrpc'], $hostpart, 80); $c = CreateObject('phpgwapi.xmlrpc_client',$this->urlparts['xmlrpc'], $hostpart, 443);
$c->username = $this->sessionid; $c->setCredentials($this->sessionid,$this->kp3);
$c->password = $this->kp3;
$c->setDebug(0); $c->setDebug(0);
$r = $c->send($f,0,True); $r = $c->send($f,0,'https');
if (!$r) if (!$r)
{ {
$this->debug('send failed'); $this->debug('send failed');
@ -223,8 +222,7 @@
$this->debug('<pre>' . htmlentities($f->serialize()) . '</pre>' . "\n",$debug); $this->debug('<pre>' . htmlentities($f->serialize()) . '</pre>' . "\n",$debug);
$c = CreateObject('phpgwapi.xmlrpc_client',$this->urlparts['xmlrpc'], $hostpart, 80); $c = CreateObject('phpgwapi.xmlrpc_client',$this->urlparts['xmlrpc'], $hostpart, 80);
$c->username = $this->sessionid; $c->setCredentials($this->sessionid,$this->kp3);
$c->password = $this->kp3;
// _debug_array($c); // _debug_array($c);
$c->setDebug(0); $c->setDebug(0);
$r = $c->send($f); $r = $c->send($f);
@ -295,10 +293,12 @@
function _send_soap_($method_name, $args, $url, $debug=True) function _send_soap_($method_name, $args, $url, $debug=True)
{ {
$method_name = str_replace('.','_',$method_name); // $method_name = str_replace('.','_',$method_name);
list($uri,$hostpart) = $this->_split_url($url . $this->urlparts['soap']); list($uri,$hostpart) = $this->_split_url($url . $this->urlparts['soap']);
$hostpart = ereg_replace('https://','',$hostpart); $hostpart = ereg_replace('https://','',$hostpart);
$hostpart = ereg_replace('http://','',$hostpart); $hostpart = ereg_replace('http://','',$hostpart);
$this->build_request($args);
/*
if(gettype($args) != 'array') if(gettype($args) != 'array')
{ {
$arr[] = CreateObject('phpgwapi.soapval','','string',$args); $arr[] = CreateObject('phpgwapi.soapval','','string',$args);
@ -313,15 +313,22 @@
{ {
$tmp[] = CreateObject('phpgwapi.soapval',$x,'string',$y); $tmp[] = CreateObject('phpgwapi.soapval',$x,'string',$y);
} }
$arr[] = CreateObject('phpgwapi.soapval',$key, 'array',$tmp); $ele[] = CreateObject('phpgwapi.soapval',$key, 'array',$tmp);
$complex = True;
} }
else else
{ {
$arr[] = CreateObject('phpgwapi.soapval',$key, 'string',$val); $ele[] = CreateObject('phpgwapi.soapval',$key, 'string',$val);
} }
} }
if($complex)
{
$arr[] = CreateObject('phpgwapi.soapval','','struct',$ele);
$ele = $arr;
}
} }
$soap_message = CreateObject('phpgwapi.soapmsg',$method_name,$arr); */
$soap_message = CreateObject('phpgwapi.soapmsg',$method_name,$this->request);
$soap = CreateObject('phpgwapi.soap_client',$uri,$hostpart); $soap = CreateObject('phpgwapi.soap_client',$uri,$hostpart);
$soap->username = $this->sessionid; $soap->username = $this->sessionid;
$soap->password = $this->kp3; $soap->password = $this->kp3;
@ -329,6 +336,7 @@
if($r = $soap->send($soap_message,$method_name)) if($r = $soap->send($soap_message,$method_name))
{ {
_debug_array(htmlentities($soap->outgoing_payload)); _debug_array(htmlentities($soap->outgoing_payload));
_debug_array(htmlentities($soap->incoming_payload));
$this->debug('<hr>I got this value back<br><pre>' . htmlentities($r->serialize()) . '</pre><hr>',$debug); $this->debug('<hr>I got this value back<br><pre>' . htmlentities($r->serialize()) . '</pre><hr>',$debug);
$this->result = $r->decode(); $this->result = $r->decode();
return $this->result; return $this->result;
@ -340,6 +348,33 @@
} }
} }
function build_request($_req,$recursed=False,$ext='')
{
if(is_array($_req))
{
$ele = array();
@reset($_req);
while(list($key,$val) = @each($_req))
{
$ele[$key] = $this->build_request($val,True,$key);
}
$this->request[] = CreateObject('phpgwapi.soapval',$ext,'struct',$ele);
$ext = '';
}
else
{
$_type = (is_long($_req)?'int':gettype($_req));
if($recursed)
{
return CreateObject('phpgwapi.soapval',$ext,$_type,$_req);
}
else
{
$this->request[$ext] = CreateObject('phpgwapi.soapval',$ext,$_type,$_req);
}
}
}
/* Following are for server list management and query */ /* Following are for server list management and query */
function read_repository($serverid='') function read_repository($serverid='')
{ {

View File

@ -1,22 +1,35 @@
<?php <?php
// by Edd Dumbill (C) 1999-2001 // Copyright (c) 1999,2000,2001 Edd Dumbill.
// <edd@usefulinc.com> // All rights reserved.
// xmlrpc.inc,v 1.18 2001/07/06 18:23:57 edmundd //
// Redistribution and use in source and binary forms, with or without
// License is granted to use or modify this software ("XML-RPC for PHP") // modification, are permitted provided that the following conditions
// for commercial or non-commercial use provided the copyright of the author // are met:
// is preserved in any distributed or derivative work. //
// * Redistributions of source code must retain the above copyright
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR // notice, this list of conditions and the following disclaimer.
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES //
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // * Redistributions in binary form must reproduce the above
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, // copyright notice, this list of conditions and the following
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT // disclaimer in the documentation and/or other materials provided
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // with the distribution.
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY //
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // * Neither the name of the "XML-RPC for PHP" nor the names of its
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // contributors may be used to endorse or promote products derived
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
class xmlrpc_client class xmlrpc_client
{ {
@ -25,11 +38,13 @@
var $port; var $port;
var $errno; var $errno;
var $errstring; var $errstring;
var $debug=0; var $debug = 0;
var $username = ''; var $username = '';
var $password = ''; var $password = '';
var $cert = '';
var $certpass = '';
function xmlrpc_client($path='', $server='', $port=80) function xmlrpc_client($path='', $server='', $port=0)
{ {
$this->port = $port; $this->port = $port;
$this->server = $server; $this->server = $server;
@ -54,61 +69,82 @@
$this->password = $p; $this->password = $p;
} }
function send($msg, $timeout=0, $ssl=False) function setCertificate($cert, $certpass)
{ {
// where msg is an xmlrpcmsg $this->cert = $cert;
$msg->debug = $this->debug; $this->certpass = $certpass;
}
if($ssl) function send($msg, $timeout=0, $method='http')
{
/* where msg is an xmlrpcmsg */
$msg->debug = $this->debug;
if ($method == 'https')
{ {
return $this->ssl_sendPayloadHTTP10( return $this->sendPayloadHTTPS(
$msg, $msg,
$this->server, $this->port, $this->server,
$timeout, $this->username, $this->port,
$this->password $timeout,
$this->username,
$this->password,
$this->cert,
$this->certpass
); );
} }
else else
{ {
return $this->sendPayloadHTTP10( return $this->sendPayloadHTTP10(
$msg, $msg,
$this->server, $this->port, $this->server,
$timeout, $this->username, $this->port,
$timeout,
$this->username,
$this->password $this->password
); );
} }
} }
function sendPayloadHTTP10($msg, $server, $port, $timeout=0,$username="", $password="") function sendPayloadHTTP10($msg, $server, $port, $timeout=0,$username='', $password='')
{ {
if($port == 0)
{
$port = 80;
}
if($timeout>0) if($timeout>0)
{ {
$fp=fsockopen($server, $port,&$this->errno, &$this->errstr, $timeout); $fp = fsockopen($server, $port,&$this->errno, &$this->errstr, $timeout);
} }
else else
{ {
$fp=fsockopen($server, $port,&$this->errno, &$this->errstr); $fp = fsockopen($server, $port,&$this->errno, &$this->errstr);
} }
if (!$fp) if (!$fp)
{ {
return 0; return CreateObject(
'phpgwapi.xmlrpcresp',
0,
$GLOBALS['xmlrpcerr']['http_error'],
$GLOBALS['xmlrpcstr']['http_error']
);
} }
// Only create the payload if it was not created previously // Only create the payload if it was not created previously
if(empty($msg->payload)) if(empty($msg->payload))
{ {
$msg->createPayload(); $msg->createPayload();
} }
// thanks to Grant Rauscher <grant7@firstworld.net> // thanks to Grant Rauscher <grant7@firstworld.net>
// for this // for this
$credentials = ''; $credentials = '';
if ($username!="") if ($username && $password)
{ {
$credentials = "Authorization: Basic " . base64_encode($username . ":" . $password) . "\r\n"; $credentials = 'Authorization: Basic ' . base64_encode($username . ':' . $password) . "\r\n";
} }
$op = "POST " . $this->path . " HTTP/1.0\r\nUser-Agent: PHP XMLRPC 1.0\r\n" $op = 'POST ' . $this->path . " HTTP/1.0\r\nUser-Agent: PHP XMLRPC 1.0\r\n"
. "Host: ". $this->server . "\r\n" . 'Host: '. $this->server . "\r\n"
. 'X-PHPGW-Server: ' . $this->server . ' ' . "\r\n" . 'X-PHPGW-Server: ' . $this->server . ' ' . "\r\n"
. 'X-PHPGW-Version: ' . $GLOBALS['phpgw_info']['server']['versions']['phpgwapi'] . "\r\n" . 'X-PHPGW-Version: ' . $GLOBALS['phpgw_info']['server']['versions']['phpgwapi'] . "\r\n"
. $credentials . $credentials
@ -118,59 +154,100 @@
if (!fputs($fp, $op, strlen($op))) if (!fputs($fp, $op, strlen($op)))
{ {
$this->errstr="Write error"; $this->errstr = 'Write error';
return 0; return CreateObject(
'phpgwapi.xmlrpcresp',
0,
$GLOBALS['xmlrpcerr']['http_error'],
$GLOBALS['xmlrpcstr']['http_error']
);
} }
$resp = $msg->parseResponseFile($fp); $resp = $msg->parseResponseFile($fp);
fclose($fp); fclose($fp);
return $resp; return $resp;
} }
function ssl_sendPayloadHTTP10($msg, $server, $port, $timeout=0,$username='', $password='') /* contributed by Justin Miller <justin@voxel.net> - requires curl to be built into PHP */
function sendPayloadHTTPS($msg, $server, $port, $timeout=0,$username='', $password='', $cert='',$certpass='')
{ {
if(!function_exists(curl_init)) if (!function_exists('curl_init'))
{ {
$this->errstr = 'No curl functions available - use of ssl is invalid'; return CreateObject(
return False; 'phpgwapi.xmlrpcresp',
0,
$GLOBALS['xmlrpcerr']['no_ssl'],
$GLOBALS['xmlrpcstr']['no_ssl']
);
} }
/* curl Method borrowed from:
http://sourceforge.net/tracker/index.php?func=detail&aid=427359&group_id=23199&atid=377731
*/
// Only create the payload if it was not created previously if ($port == 0)
{
$port = 443;
}
/* Only create the payload if it was not created previously */
if(empty($msg->payload)) if(empty($msg->payload))
{ {
$msg->createPayload(); $msg->createPayload();
} }
// thanks to Grant Rauscher <grant7@firstworld.net> $curl = curl_init('https://' . $server . ':' . $port . $this->path);
// for this
$credentials = ''; curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
if ($username!='') // results into variable
if ($this->debug)
{ {
$credentials = "Authorization: Basic " . base64_encode($username . ':' . $password) . "\r\n"; curl_setopt($curl, CURLOPT_VERBOSE, 1);
} }
curl_setopt($curl, CURLOPT_USERAGENT, 'PHP XMLRPC 1.0');
// required for XMLRPC
curl_setopt($curl, CURLOPT_POST, 1);
// post the data
curl_setopt($curl, CURLOPT_POSTFIELDS, $msg->payload);
// the data
curl_setopt($curl, CURLOPT_HEADER, 1);
// return the header too
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'X-PHPGW-Server: ' . $this->server,
'X-PHPGW-Version: ' . $GLOBALS['phpgw_info']['server']['versions']['phpgwapi'],
'Content-Type: text/xml'
));
if ($timeout)
{
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout == 1 ? 1 : $timeout - 1);
}
if ($username && $password)
{
curl_setopt($curl, CURLOPT_USERPWD, "$username:$password");
}
if ($cert)
{
curl_setopt($curl, CURLOPT_SSLCERT, $cert);
}
if ($certpass)
{
curl_setopt($curl, CURLOPT_SSLCERTPASSWD,$certpass);
}
// set cert password
$op = "POST " . $this->path . " HTTP/1.0\r\nUser-Agent: PHP XMLRPC 1.0\r\n" $result = curl_exec($curl);
. "Host: ". $this->server . "\r\n"
. 'X-PHPGW-Server: ' . $this->server . ' ' . "\r\n"
. 'X-PHPGW-Version: ' . $GLOBALS['phpgw_info']['server']['versions']['phpgwapi'] . "\r\n"
. $credentials
. "Content-Type: text/xml\r\nContent-Length: "
. strlen($msg->payload) . "\r\n\r\n"
. $msg->payload;
$ch = curl_init(); if (!$result)
curl_setopt($ch, CURLOPT_URL,$this->server); {
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $this->errstr = 'Write error';
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $op); $resp = CreateObject(
curl_setopt($ch, CURLOPT_HEADER, 0); 'phpgwapi.xmlrpcresp',
$response_buf = curl_exec($ch); 0,
curl_close($ch); $GLOBALS['xmlrpcerr']['curl_fail'],
$GLOBALS['xmlrpcstr']['curl_fail'] . ': ' . curl_error($curl)
);
}
else
{
$resp = $msg->parseResponse($result);
}
curl_close($curl);
$resp = $msg->parseResponse($response_buf);
return $resp; return $resp;
} }
} }
?> ?>

View File

@ -1,23 +1,36 @@
<?php <?php
// by Edd Dumbill (C) 1999-2001 // Copyright (c) 1999,2000,2001 Edd Dumbill.
// <edd@usefulinc.com> // All rights reserved.
// $Id$ //
// Redistribution and use in source and binary forms, with or without
// License is granted to use or modify this software ("XML-RPC for PHP") // modification, are permitted provided that the following conditions
// for commercial or non-commercial use provided the copyright of the author // are met:
// is preserved in any distributed or derivative work. //
// * Redistributions of source code must retain the above copyright
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR // notice, this list of conditions and the following disclaimer.
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES //
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // * Redistributions in binary form must reproduce the above
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, // copyright notice, this list of conditions and the following
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT // disclaimer in the documentation and/or other materials provided
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // with the distribution.
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY //
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // * Neither the name of the "XML-RPC for PHP" nor the names of its
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // contributors may be used to endorse or promote products derived
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
// XML RPC Server class // XML RPC Server class
// requires: xmlrpc.inc // requires: xmlrpc.inc

View File

@ -25,7 +25,7 @@
var $payload; var $payload;
var $methodname; var $methodname;
var $params = array(); var $params = array();
var $debug = 1; var $debug = 0;
function xmlrpcmsg($meth, $pars=0) function xmlrpcmsg($meth, $pars=0)
{ {
@ -125,11 +125,24 @@
xml_set_default_handler($parser, 'xmlrpc_dh'); xml_set_default_handler($parser, 'xmlrpc_dh');
// $xmlrpc_value = CreateObject('phpgwapi.xmlrpcval'); // $xmlrpc_value = CreateObject('phpgwapi.xmlrpcval');
$hdrfnd=0; $hdrfnd = 0;
if ($this->debug) if ($this->debug)
{ {
print '<PRE>---GOT---' . "\n" . htmlspecialchars($data) . "\n" . '---END---' . "\n" . '</PRE>'; echo '<PRE>---GOT---' . "\n" . htmlspecialchars($data) . "\n" . '---END---' . "\n" . '</PRE>';
} }
if ($data == '')
{
error_log('No response received from server.');
$r = CreateObject(
'phpgwapi.xmlrpcresp',
0,
$GLOBALS['xmlrpcerr']['no_data'],
$GLOBALS['xmlrpcstr']['no_data']
);
xml_parser_free($parser);
return $r;
}
// see if we got an HTTP 200 OK, else bomb // see if we got an HTTP 200 OK, else bomb
// but only do this if we're using the HTTP protocol. // but only do this if we're using the HTTP protocol.
if (ereg("^HTTP",$data) && !ereg("^HTTP/[0-9\.]+ 200 ", $data)) if (ereg("^HTTP",$data) && !ereg("^HTTP/[0-9\.]+ 200 ", $data))

View File

@ -29,6 +29,7 @@
{ {
if ($fcode!=0) if ($fcode!=0)
{ {
$this->xv = 0;
$this->fn = $fcode; $this->fn = $fcode;
$this->fs = htmlspecialchars($fstr); $this->fs = htmlspecialchars($fstr);
} }

View File

@ -71,6 +71,12 @@
$GLOBALS['xmlrpcstr']['introspect_unknown'] = "Can't introspect: method unknown"; $GLOBALS['xmlrpcstr']['introspect_unknown'] = "Can't introspect: method unknown";
$GLOBALS['xmlrpcerr']['http_error'] = 5; $GLOBALS['xmlrpcerr']['http_error'] = 5;
$GLOBALS['xmlrpcstr']['http_error'] = "Didn't receive 200 OK from remote server."; $GLOBALS['xmlrpcstr']['http_error'] = "Didn't receive 200 OK from remote server.";
$GLOBALS['xmlrpcerr']['no_data'] = 6;
$GLOBALS['xmlrpcstr']['no_data'] = 'No data received from server.';
$GLOBALS['xmlrpcerr']['no_ssl'] = 7;
$GLOBALS['xmlrpcstr']['no_ssl'] = 'No SSL support compiled in.';
$GLOBALS['xmlrpcerr']['curl_fail'] = 8;
$GLOBALS['xmlrpcstr']['curl_fail'] = 'CURL error';
$GLOBALS['xmlrpc_defencoding'] = 'UTF-8'; $GLOBALS['xmlrpc_defencoding'] = 'UTF-8';