From b409fbb72591b43df7431e83e30d6c00ea633f21 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 5 Apr 2018 15:08:52 +0200 Subject: [locationinfo] Add exchange backend Closes #3170 --- .../jamesiarmes/PhpNtlm/SoapClient.php | 226 +++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 modules-available/locationinfo/exchange-includes/jamesiarmes/PhpNtlm/SoapClient.php (limited to 'modules-available/locationinfo/exchange-includes/jamesiarmes/PhpNtlm/SoapClient.php') diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpNtlm/SoapClient.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpNtlm/SoapClient.php new file mode 100644 index 00000000..21c77cbf --- /dev/null +++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpNtlm/SoapClient.php @@ -0,0 +1,226 @@ + null, + 'password' => null, + 'curlopts' => array(), + 'strip_bad_chars' => true, + 'warn_on_bad_chars' => false, + ); + $this->options = $options; + + // Verify that a user name and password were entered. + if (empty($options['user']) || empty($options['password'])) { + throw new \BadMethodCallException( + 'A username and password is required.' + ); + } + + parent::__construct($wsdl, $options); + } + + /** + * {@inheritdoc} + */ + public function __doRequest($request, $location, $action, $version, $one_way = 0) + { + $headers = $this->buildHeaders($action); + $this->__last_request = $request; + $this->__last_request_headers = $headers; + + // Only reinitialize curl handle if the location is different. + if (!$this->ch + || curl_getinfo($this->ch, CURLINFO_EFFECTIVE_URL) != $location) { + $this->ch = curl_init($location); + } + + curl_setopt_array($this->ch, $this->curlOptions($action, $request)); + $response = curl_exec($this->ch); + + // TODO: Add some real error handling. + // If the response if false than there was an error and we should throw + // an exception. + if ($response === false) { + $this->__last_response = $this->__last_response_headers = false; + throw new \RuntimeException( + 'Curl error: ' . curl_error($this->ch), + curl_errno($this->ch) + ); + } + + $this->parseResponse($response); + $this->cleanResponse(); + + return $this->__last_response; + } + + /** + * {@inheritdoc} + */ + public function __getLastRequestHeaders() + { + return implode("\n", $this->__last_request_headers) . "\n"; + } + + /** + * Returns the response code from the last request + * + * @return integer + * + * @throws \BadMethodCallException + * If no cURL resource has been initialized. + */ + public function getResponseCode() + { + if (empty($this->ch)) { + throw new \BadMethodCallException('No cURL resource has been ' + . 'initialized. This is probably because no request has not ' + . 'been made.'); + } + + return curl_getinfo($this->ch, CURLINFO_HTTP_CODE); + } + + /** + * Builds the headers for the request. + * + * @param string $action + * The SOAP action to be performed. + */ + protected function buildHeaders($action) + { + return array( + 'Method: POST', + 'Connection: Keep-Alive', + 'User-Agent: PHP-SOAP-CURL', + 'Content-Type: text/xml; charset=utf-8', + "SOAPAction: \"$action\"", + 'Expect: 100-continue', + ); + } + + /** + * Cleans the response body by stripping bad characters if instructed to. + */ + protected function cleanResponse() + { + // If the option to strip bad characters is not set, then we shouldn't + // do anything here. + if (!$this->options['strip_bad_chars']) { + return; + } + + // Strip invalid characters from the XML response body. + $count = 0; + $this->__last_response = preg_replace( + '/(?!�?(9|A|D))(&#x[0-1]?[0-9A-F];)/', + ' ', + $this->__last_response, + -1, + $count + ); + + // If the option to warn on bad characters is set, and some characters + // were stripped, then trigger a warning. + if ($this->options['warn_on_bad_chars'] && $count > 0) { + trigger_error( + 'Invalid characters were stripped from the XML SOAP response.', + E_USER_WARNING + ); + } + } + + /** + * Builds an array of curl options for the request + * + * @param string $action + * The SOAP action to be performed. + * @param string $request + * The XML SOAP request. + * @return array + * Array of curl options. + */ + protected function curlOptions($action, $request) + { + $options = $this->options['curlopts'] + array( + CURLOPT_SSL_VERIFYPEER => true, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HTTPHEADER => $this->buildHeaders($action), + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_HTTPAUTH => CURLAUTH_BASIC | CURLAUTH_NTLM, + CURLOPT_USERPWD => $this->options['user'] . ':' + . $this->options['password'], + ); + + // We shouldn't allow these options to be overridden. + $options[CURLOPT_HEADER] = true; + $options[CURLOPT_POST] = true; + $options[CURLOPT_POSTFIELDS] = $request; + + return $options; + } + + /** + * Pareses the response from a successful request. + * + * @param string $response + * The response from the cURL request, including headers and body. + */ + public function parseResponse($response) + { + // Parse the response and set the last response and headers. + $info = curl_getinfo($this->ch); + $this->__last_response_headers = substr( + $response, + 0, + $info['header_size'] + ); + $this->__last_response = substr($response, $info['header_size']); + } +} -- cgit v1.2.3-55-g7522