From c0c26cc0a962f9b32dae2fed000692231f55a4b6 Mon Sep 17 00:00:00 2001 From: Lukas Scharmer Date: Thu, 26 Sep 2024 11:20:44 +0200 Subject: [PATCH] Soap: Add Options to improve server to server requests --- .../SOAP/classes/class.ilSoapClient.php | 18 ++++++- ...ass.ilWebServicesConfigStoredObjective.php | 13 ++++- .../Setup/class.ilWebServicesSetupAgent.php | 6 +++ .../Setup/class.ilWebServicesSetupConfig.php | 44 ++++++++++++++++- docs/databay/patches/internal-soap-url.md | 47 +++++++++++++++++++ ...lass.ilNusoapUserAdministrationAdapter.php | 13 ++++- webservice/soap/lib/nusoap.php | 29 ++++++++++-- webservice/soap/server.php | 7 ++- 8 files changed, 165 insertions(+), 12 deletions(-) create mode 100644 docs/databay/patches/internal-soap-url.md diff --git a/Services/WebServices/SOAP/classes/class.ilSoapClient.php b/Services/WebServices/SOAP/classes/class.ilSoapClient.php index 34cc764f098d..0525b1c5eee9 100644 --- a/Services/WebServices/SOAP/classes/class.ilSoapClient.php +++ b/Services/WebServices/SOAP/classes/class.ilSoapClient.php @@ -79,8 +79,13 @@ public function enabledWSDL(): bool public function init(): bool { + // databay-patch: begin internal soap url + $internal_path = $this->settings->get('soap_internal_wsdl_path'); if (trim($this->getServer()) === '') { - if (trim($this->settings->get('soap_wsdl_path', '')) !== '') { + if ($internal_path) { + $this->uri = $internal_path; + } elseif (trim($this->settings->get('soap_wsdl_path', '')) !== '') { + // databay-patch: end internal soap url $this->uri = $this->settings->get('soap_wsdl_path', ''); } else { $this->uri = ilUtil::_getHttpPath() . '/webservice/soap/server.php?wsdl'; @@ -97,7 +102,16 @@ public function init(): bool array( 'exceptions' => true, 'trace' => 1, - 'connection_timeout' => $this->getTimeout() + // databay-patch: begin internal soap url + 'connection_timeout' => $this->getTimeout(), + 'stream_context' => $this->uri === $internal_path ? stream_context_create([ + 'ssl' => [ + 'verify_peer' => (bool) $this->settings->get('soap_internal_wsdl_verify_peer', '1'), + 'verify_peer_name' => (bool) $this->settings->get('soap_internal_wsdl_verify_peer_name', '1'), + 'allow_self_signed' => (bool) $this->settings->get('soap_internal_wsdl_allow_self_signed', ''), + ] + ]) : null + // databay-patch: end internal soap url ) ); return true; diff --git a/Services/WebServices/classes/Setup/class.ilWebServicesConfigStoredObjective.php b/Services/WebServices/classes/Setup/class.ilWebServicesConfigStoredObjective.php index ee24e640753e..0e1810f5d677 100644 --- a/Services/WebServices/classes/Setup/class.ilWebServicesConfigStoredObjective.php +++ b/Services/WebServices/classes/Setup/class.ilWebServicesConfigStoredObjective.php @@ -11,9 +11,11 @@ */ class ilWebServicesConfigStoredObjective implements Setup\Objective { - protected Setup\Config $config; + // databay-patch: begin internal soap url + protected ilWebServicesSetupConfig $config; - public function __construct(Setup\Config $config) + public function __construct(ilWebServicesSetupConfig $config) + // databay-patch: end internal soap url { $this->config = $config; } @@ -55,6 +57,13 @@ public function achieve(Setup\Environment $environment): Setup\Environment $settings->set("rpc_server_host", $this->config->getRPCServerHost()); $settings->set("rpc_server_port", (string) $this->config->getRPCServerPort()); + // databay-patch: begin internal soap url + $settings->set('soap_internal_wsdl_path', (string) $this->config->getSoapInternalWsdlPath()); + $settings->set('soap_internal_wsdl_verify_peer', (string) $this->config->getSoapInternalWsdlVerifyPeer()); + $settings->set('soap_internal_wsdl_verify_peer_name', (string) $this->config->getSoapInternalWsdlVerifyPeerName()); + $settings->set('soap_internal_wsdl_allow_self_signed', (string) $this->config->getSoapInternalWsdlAllowSelfSigned()); + // databay-patch: end internal soap url + return $environment; } diff --git a/Services/WebServices/classes/Setup/class.ilWebServicesSetupAgent.php b/Services/WebServices/classes/Setup/class.ilWebServicesSetupAgent.php index 4d9948fe484a..c65bcefee44d 100644 --- a/Services/WebServices/classes/Setup/class.ilWebServicesSetupAgent.php +++ b/Services/WebServices/classes/Setup/class.ilWebServicesSetupAgent.php @@ -62,6 +62,12 @@ public function getArrayToConfigTransformation(): Refinery\Transformation (int) ($data["soap_response_timeout"] ?? ilSoapClient::DEFAULT_RESPONSE_TIMEOUT), $data["rpc_server_host"] ?? "", (int) ($data["rpc_server_port"] ?? 0), + // databay-patch: begin internal soap url + (string) ($data['soap_internal_wsdl_path'] ?? ''), + (bool) ($data['soap_internal_wsdl_verify_peer'] ?? true), + (bool) ($data['soap_internal_wsdl_verify_peer_name'] ?? true), + (bool) ($data['soap_internal_wsdl_allow_self_signed'] ?? false), + // databay-patch: end internal soap url ); }); } diff --git a/Services/WebServices/classes/Setup/class.ilWebServicesSetupConfig.php b/Services/WebServices/classes/Setup/class.ilWebServicesSetupConfig.php index 97ba624454ca..b818471a1e02 100644 --- a/Services/WebServices/classes/Setup/class.ilWebServicesSetupConfig.php +++ b/Services/WebServices/classes/Setup/class.ilWebServicesSetupConfig.php @@ -14,6 +14,13 @@ class ilWebServicesSetupConfig implements Setup\Config protected string $rpc_server_host; protected int $rpc_server_port; + // databay-patch: begin internal soap url + protected string $soap_internal_wsdl_path; + protected bool $soap_internal_wsdl_verify_peer; + protected bool $soap_internal_wsdl_verify_peer_name; + protected bool $soap_internal_wsdl_allow_self_signed; + // databay-patch: end internal soap url + /** * @var int */ @@ -25,7 +32,13 @@ public function __construct( int $soap_connect_timeout, int $soap_response_timeout, string $rpc_server_host, - int $rpc_server_port + // databay-patch: begin internal soap url + int $rpc_server_port, + string $soap_internal_wsdl_path, + bool $soap_internal_wsdl_verify_peer, + bool $soap_internal_wsdl_verify_peer_name, + bool $soap_internal_wsdl_allow_self_signed, + // databay-patch: end internal soap url ) { $this->soap_user_administration = $soap_user_administration; $this->soap_wsdl_path = $soap_wsdl_path; @@ -33,6 +46,13 @@ public function __construct( $this->rpc_server_host = $rpc_server_host; $this->rpc_server_port = $rpc_server_port; $this->soap_response_timeout = $soap_response_timeout; + + // databay-patch: begin internal soap url + $this->soap_internal_wsdl_path = $soap_internal_wsdl_path; + $this->soap_internal_wsdl_verify_peer = $soap_internal_wsdl_verify_peer; + $this->soap_internal_wsdl_verify_peer_name = $soap_internal_wsdl_verify_peer_name; + $this->soap_internal_wsdl_allow_self_signed = $soap_internal_wsdl_allow_self_signed; + // databay-patch: end internal soap url } public function isSOAPUserAdministration(): bool @@ -64,4 +84,26 @@ public function getSoapResponseTimeout(): int { return $this->soap_response_timeout; } + + // databay-patch: begin internal soap url + public function getSoapInternalWsdlPath(): string + { + return $this->soap_internal_wsdl_path; + } + + public function getSoapInternalWsdlVerifyPeer(): bool + { + return $this->soap_internal_wsdl_verify_peer; + } + + public function getSoapInternalWsdlVerifyPeerName(): bool + { + return $this->soap_internal_wsdl_verify_peer_name; + } + + public function getSoapInternalWsdlAllowSelfSigned(): bool + { + return $this->soap_internal_wsdl_allow_self_signed; + } + // databay-patch: end internal soap url } diff --git a/docs/databay/patches/internal-soap-url.md b/docs/databay/patches/internal-soap-url.md new file mode 100644 index 000000000000..17decd52ed9f --- /dev/null +++ b/docs/databay/patches/internal-soap-url.md @@ -0,0 +1,47 @@ +# Performance-Optimierung für Soap Aufrufe vom Server zum Server. + +Dieser Patch fügt neue ILIAS-Setup-Optionen für die Webservices hinzu, um eine URL zu konfigurieren, die für SOAP-Aufrufe vom Server zum Server verwendet werden sollen. +Siehe: https://gitlab.databay.de/ilias-hosting/ilias/-/issues/8 + +## Patch-Markierungen + +Patches wurden mit `databay-patch: begin internal soap url` und `databay-patch: end internal soap url` markiert. + +## Änderungen + +Angepasst wurden im Rahmen der Funktionalität folgende Dateien: + +* Services/WebServices/SOAP/classes/class.ilSoapClient.php +* Services/WebServices/classes/Setup/class.ilWebServicesConfigStoredObjective.php +* Services/WebServices/classes/Setup/class.ilWebServicesSetupAgent.php +* Services/WebServices/classes/Setup/class.ilWebServicesSetupConfig.php +* webservice/soap/classes/class.ilNusoapUserAdministrationAdapter.php +* webservice/soap/lib/nusoap.php +* webservice/soap/server.php + +Folgende Optionen wurden für die config.json des ILIAS Setup hinzugefügt: + +```json +{ + ... + "webservices": { + ... + "soap_internal_wsdl_path": "https://foo", + "soap_internal_wsdl_verify_peer": true, + "soap_internal_wsdl_verify_peer_name": true, + "soap_internal_wsdl_allow_self_signed": false + } +} +``` + +Die Optionen: + +* `soap_internal_wsdl_verify_peer` +* `soap_internal_wsdl_verify_peer_name` +* `soap_internal_wsdl_allow_self_signed` + +setzen die entsprechenden SSL Optionen wenn `soap_internal_wsdl_path` gesetzt ist (Siehe: https://www.php.net/manual/en/function.stream-context-create.php). + +## Spezifikation + +Der Patch setzt folgenden FR um: https://docu.ilias.de/go/wiki/wpage_8363_1357 diff --git a/webservice/soap/classes/class.ilNusoapUserAdministrationAdapter.php b/webservice/soap/classes/class.ilNusoapUserAdministrationAdapter.php index 23e85400b2c6..b648cdf4cd41 100644 --- a/webservice/soap/classes/class.ilNusoapUserAdministrationAdapter.php +++ b/webservice/soap/classes/class.ilNusoapUserAdministrationAdapter.php @@ -56,7 +56,10 @@ public function __construct(bool $a_use_wsdl = true) $this->server->class = "ilSoapFunctions"; if ($a_use_wsdl) { - $this->enableWSDL(); + // databay-patch: begin internal soap url + global $DIC; + $this->enableWSDL($DIC->settings()); + // databay-patch: end internal soap url } $this->registerMethods(); @@ -69,10 +72,16 @@ public function start(): void exit(); } - private function enableWSDL(): void + // databay-patch: begin internal soap url + private function enableWSDL(ilSetting $setting): void { $this->server->configureWSDL(SERVICE_NAME, SERVICE_NAMESPACE); + $internal_path = $setting->get('soap_internal_wsdl_path', ''); + if ($internal_path) { + $this->server->addInternalPort(SERVICE_NAME, $internal_path); + } } + // databay-patch: end internal soap url private function registerMethods(): void { diff --git a/webservice/soap/lib/nusoap.php b/webservice/soap/lib/nusoap.php index 35da3a159557..d127f609c14b 100644 --- a/webservice/soap/lib/nusoap.php +++ b/webservice/soap/lib/nusoap.php @@ -4590,6 +4590,21 @@ public function configureWSDL($serviceName, $namespace = false, $endpoint = fals 'location'=>$endpoint, 'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/'); } + + // databay-patch: begin internal soap url + public function addInternalPort(string $serviceName, string $url): void + { + $port = $this->wsdl->ports[$serviceName . 'Port'] ?? [ + 'binding'=> $serviceName . 'Binding', + 'location'=> [], + 'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/' + ]; + + $port['location'] = is_array($port['location']) ? array_merge($port['location'], [$url]) : [$port['location'], $url]; + + $this->wsdl->ports[$serviceName . 'Port'] = $port; + } + // databay-patch: end internal soap url } /** @@ -5614,10 +5629,16 @@ public function serialize($debug = 0) if (count($this->ports) >= 1) { foreach ($this->ports as $pName => $attrs) { $xml .= "\n" . ' '; - $address = $attrs['location'] . ($debug || $has_client ? "?" : "") - . ($debug ? 'debug=1' : '') . ($debug && $has_client ? "&" : "") - . ($has_client ? 'client_id=' . $_GET['client_id'] : ''); - $xml .= "\n" . ' '; + // databay-patch: begin internal soap url + $locations = $attrs['location']; + $locations = is_array($locations) ? $locations : [$locations]; + foreach ($locations as $location) { + $address = $location . ($debug || $has_client ? "?" : "") + . ($debug ? 'debug=1' : '') . ($debug && $has_client ? "&" : "") + . ($has_client ? 'client_id=' . $_GET['client_id'] : ''); + $xml .= "\n" . ' '; + } + // databay-patch: end internal soap url $xml .= "\n" . ' '; } } diff --git a/webservice/soap/server.php b/webservice/soap/server.php index 98f7428e1078..30f5231a4d02 100755 --- a/webservice/soap/server.php +++ b/webservice/soap/server.php @@ -21,7 +21,9 @@ include_once "Services/Context/classes/class.ilContext.php"; ilContext::init(ilContext::CONTEXT_SOAP); -require_once("./Services/Init/classes/class.ilIniFile.php"); +// databay-patch: begin internal soap url +require_once("./libs/composer/vendor/autoload.php"); +// databay-patch: end internal soap url $ilIliasIniFile = new ilIniFile("./ilias.ini.php"); $ilIliasIniFile->read(); @@ -50,5 +52,8 @@ $soapServer->handle(); } else { // This is a request to display the available SOAP methods or WSDL... + // databay-patch: begin internal soap url + ilInitialisation::initILIAS(); + // databay-patch: end internal soap url include('webservice/soap/nusoapserver.php'); }