[dev] Horde_RPC_soap tweaks
John Morrissey
jwm at horde.net
Mon Dec 17 18:34:38 UTC 2007
On Wed, Nov 28, 2007 at 11:24:18PM -0500, Chuck Hagenbuch wrote:
> Quoting John Morrissey <jwm at horde.net>:
>
> > > Did you try setting the available methods explicitly in the 'provides'
> > > settings in registry.php instead?
> >
> > Yup. However, Horde_RPC_soap calls Registry::listMethods() with no
> > arguments, so all methods are listed.
>
> Seems like a bug - if there are explicit provides entries, we
> shouldn't return other methods, right?
Sorry, I wasn't clear. Registry::listMethods() honors provides entries, but
since it's called with no arguments in Horde_RPC_soap, the provided methods
for all applications are listed. This makes complete sense for the main
Horde WSDL, since you want to emit all possible provided methods.
> > > Yeah. I guess after thinking about this, I'd rather you passed an
> > > explicit array of allowed methods in the RPC constructor params
> > > instead of using a regex. The regex just feels hackish to me, but
> > > creating a limited server doesn't. How does that sound?
> >
> > That sounds decent, unless we decide on a straightforward way of
> > specifying API method visibility in api.php (above).
>
> I think instantiating a limited server is still a useful feature.
I've made the suggestions to date; attached are the updated patches, for
HEAD and FRAMEWORK_3. Any final thoughts before I commit them?
> > > And is there any reason why you use global vars instead of object
> > > properties?
> >
> > I tried object properties initially, but it seems that something was
> > operating on a copy of the Horde_RPC_soap instance, so the data set in
> > Horde_RPC_soap::_dispatcher() never made it to
> > Horde_RPC_soap::getResponse() for logging. I suspect something in the
> > PEAR SOAP code, but wasn't able to find where.
>
> Are you using PHP 4? It's possible we're missing a reference
> somewhere, or that PEAR SOAP is, but with PHP 5 that shouldn't be an
> issue.
nod, this is running on PHP 4. I'm fairly sure the missing reference is in
PEAR SOAP, since Horde's RPC implementation looks like it's handling this
properly AFAICT.
john
--
John Morrissey _o /\ ---- __o
jwm at horde.net _-< \_ / \ ---- < \,
www.horde.net/ __(_)/_(_)________/ \_______(_) /_(_)__
-------------- next part --------------
Index: soap.php
===================================================================
RCS file: /repository/framework/RPC/RPC/soap.php,v
retrieving revision 1.24
diff -u -u -r1.24 soap.php
--- soap.php 2 Jan 2007 12:47:23 -0000 1.24
+++ soap.php 17 Dec 2007 18:11:50 -0000
@@ -24,6 +24,27 @@
var $_server;
/**
+ * List of types to emit in the WSDL.
+ *
+ * @var array
+ */
+ var $_restrictTypes = array();
+
+ /**
+ * List of method names to allow.
+ *
+ * @var array
+ */
+ var $_restrictCalls = array();
+
+ /**
+ * Name of the SOAP service to use in the WSDL.
+ *
+ * @var string
+ */
+ var $_serviceName = null;
+
+ /**
* Hash holding all methods' signatures.
*
* @var array
@@ -39,6 +60,16 @@
{
parent::Horde_RPC($params);
+ if (!empty($params['restrictTypes'])) {
+ $this->_restrictTypes = $params['restrictTypes'];
+ }
+ if (!empty($params['restrictCalls'])) {
+ $this->_restrictCalls = $params['restrictCalls'];
+ }
+ if (!empty($params['serviceName'])) {
+ $this->_serviceName = $params['serviceName'];
+ }
+
require_once 'SOAP/Server.php';
$this->_server = new SOAP_Server();
$this->_server->_auto_translation = true;
@@ -58,6 +89,10 @@
if (!is_array($signature)) {
continue;
}
+ if (!empty($this->_restrictCalls) &&
+ !in_array($method, $this->_restrictCalls)) {
+ continue;
+ }
$method = str_replace('/', '.', $method);
$this->__dispatch_map[$method] = array(
'in' => $signature[0],
@@ -65,7 +100,15 @@
);
}
- $this->__typedef = $registry->listTypes();
+ $this->__typedef = array();
+ foreach ($registry->listTypes() as $type => $params) {
+ if (!empty($this->_restrictTypes) &&
+ !in_array($type, $this->_restrictTypes)) {
+ continue;
+ }
+
+ $this->__typedef[$type] = $params;
+ }
}
/**
@@ -107,6 +150,15 @@
global $registry;
$method = str_replace('.', '/', $method);
+ if (!empty($this->_params['restrictCalls']) &&
+ !in_array($method, $this->_params['restrictCalls'])) {
+ return sprintf(_("Method \"%s\" is not defined"), $method);
+ }
+
+ $GLOBALS['__horde_rpc_soap']['lastMethodCalled'] = $method;
+ $GLOBALS['__horde_rpc_soap']['lastMethodParams'] =
+ !empty($params) ? $params : array();
+
if (!$registry->hasMethod($method)) {
return sprintf(_("Method \"%s\" is not defined"), $method);
}
@@ -128,7 +180,8 @@
if ($request == 'disco' || $request == 'wsdl') {
require_once 'SOAP/Disco.php';
- $disco = new SOAP_DISCO_Server($this->_server, 'horde');
+ $disco = new SOAP_DISCO_Server($this->_server,
+ !empty($this->_serviceName) ? $this->_serviceName : 'horde');
if ($request == 'wsdl') {
$this->_setupDispatchMap();
return $disco->getWSDL();
@@ -140,8 +193,19 @@
$this->_server->setCallHandler(array($this, '_dispatcher'));
/* We can't use Util::bufferOutput() here for some reason. */
+ $beginTime = time();
ob_start();
$this->_server->service($request);
+ Horde::logMessage(
+ sprintf(_("SOAP call: %s(%s) by %s serviced in %d seconds, sent %d bytes in response"),
+ $GLOBALS['__horde_rpc_soap']['lastMethodCalled'],
+ join(', ', array_map(
+ create_function('$a', 'return is_array($a) ? "Array" : $a;'),
+ $GLOBALS['__horde_rpc_soap']['lastMethodParams']
+ )),
+ Auth::getAuth(), time() - $beginTime, strlen($output)
+ ), __FILE__, __LINE__, PEAR_LOG_INFO
+ );
return ob_get_clean();
}
-------------- next part --------------
Index: soap.php
===================================================================
RCS file: /repository/framework/RPC/RPC/soap.php,v
retrieving revision 1.13.10.10
diff -u -u -r1.13.10.10 soap.php
--- soap.php 2 Jan 2007 13:54:36 -0000 1.13.10.10
+++ soap.php 17 Dec 2007 18:11:45 -0000
@@ -24,6 +24,27 @@
var $_server;
/**
+ * List of types to emit in the WSDL.
+ *
+ * @var array
+ */
+ var $_restrictTypes = array();
+
+ /**
+ * List of method names to allow.
+ *
+ * @var array
+ */
+ var $_restrictCalls = array();
+
+ /**
+ * Name of the SOAP service to use in the WSDL.
+ *
+ * @var string
+ */
+ var $_serviceName = null;
+
+ /**
* Hash holding all methods' signatures.
*
* @var array
@@ -48,6 +69,15 @@
if (!empty($params['wsdl']) || !empty($params['disco'])) {
$this->_authorize = false;
}
+ if (!empty($params['restrictTypes'])) {
+ $this->_restrictTypes = $params['restrictTypes'];
+ }
+ if (!empty($params['restrictCalls'])) {
+ $this->_restrictCalls = $params['restrictCalls'];
+ }
+ if (!empty($params['serviceName'])) {
+ $this->_serviceName = $params['serviceName'];
+ }
}
}
@@ -72,6 +102,10 @@
if (!is_array($signature)) {
continue;
}
+ if (!empty($this->_restrictCalls) &&
+ !in_array($method, $this->_restrictCalls)) {
+ continue;
+ }
$method = str_replace('/', '.', $method);
$this->__dispatch_map[$method] = array(
'in' => $signature[0],
@@ -79,7 +113,15 @@
);
}
- $this->__typedef = $registry->listTypes();
+ $this->__typedef = array();
+ foreach ($registry->listTypes() as $type => $params) {
+ if (!empty($this->_restrictTypes) &&
+ !in_array($type, $this->_restrictTypes)) {
+ continue;
+ }
+
+ $this->__typedef[$type] = $params;
+ }
}
/**
@@ -121,6 +163,15 @@
global $registry;
$method = str_replace('.', '/', $method);
+ if (!empty($this->_params['restrictCalls']) &&
+ !in_array($method, $this->_params['restrictCalls'])) {
+ return sprintf(_("Method \"%s\" is not defined"), $method);
+ }
+
+ $GLOBALS['__horde_rpc_soap']['lastMethodCalled'] = $method;
+ $GLOBALS['__horde_rpc_soap']['lastMethodParams'] =
+ !empty($params) ? $params : array();
+
if (!$registry->hasMethod($method)) {
return sprintf(_("Method \"%s\" is not defined"), $method);
}
@@ -143,16 +194,30 @@
{
$this->_server->addObjectMap($this, 'urn:horde');
- if (!$params) {
+ if (!$params ||
+ (is_array($params) &&
+ empty($params['disco']) && empty($params['wsdl']))) {
$this->_server->setCallHandler(array($this, '_dispatcher'));
/* We can't use Util::bufferOutput() here for some reason. */
+ $beginTime = time();
ob_start();
$this->_server->service($request);
$output = ob_get_contents();
+ Horde::logMessage(
+ sprintf(_("SOAP call: %s(%s) by %s serviced in %d seconds, sent %d bytes in response"),
+ $GLOBALS['__horde_rpc_soap']['lastMethodCalled'],
+ join(', ', array_map(
+ create_function('$a', 'return is_array($a) ? "Array" : $a;'),
+ $GLOBALS['__horde_rpc_soap']['lastMethodParams']
+ )),
+ Auth::getAuth(), time() - $beginTime, strlen($output)
+ ), __FILE__, __LINE__, PEAR_LOG_INFO
+ );
ob_end_clean();
} else {
require_once 'SOAP/Disco.php';
- $disco = new SOAP_DISCO_Server($this->_server, 'horde');
+ $disco = new SOAP_DISCO_Server($this->_server,
+ !empty($this->_serviceName) ? $this->_serviceName : 'horde');
// BC: $params should be an array, but until 3.1.4 $params
// required a string here.
if ((is_string($params) && $params == 'wsdl') ||
More information about the dev
mailing list