Мыльный клиент, как вызвать функцию через HTTPS с базовой HTTP-аутентификацией - PullRequest
4 голосов
/ 10 февраля 2011

Эта проблема убивала меня весь день.

У меня есть клиентский веб-сервис https://*.asmx?WSDL, с базовой HTTP-аутентификацией.

Если я использую SoapUI для подключения к веб-сервису, все работает отлично, без ошибок ..

Проблема в том, когда я переключаюсь на PHP ...

Мне удалось подключиться к нему, и я могу получить список функций с сервера, используя расширение soapclient для php (я использую PHP 5.3.0).

Когда я пытаюсь вызвать функцию с использованием расширения soapclient для PHP, я получаю следующую ошибку:

Неустранимая ошибка: исключение Uncaught SoapFault: [HTTP] Ошибка при получении заголовков http в C: \ www \ xpto_Atestes \ soapclient.php: 26 Трассировка стека: # 0 [внутренняя функция]:> SoapClient -> __ doRequest ('*** ...', 'http://****...', 1, 0 ) # 1> C: \ www \ xpto_Atestes \ soapclient.php (26): SoapClient -> __ soapCall ('login', Array) # 2 {main}>, брошенный в C: \ www \ xpto_Atestes \ soapclient.php в строке 26

Более четкая ошибка (когда я делаю print_r результата вызова):

[faultstring] => Ошибка при получении заголовков http
[код ошибки] => HTTP

С отправкой следующих заголовков:

POST /*.asmx HTTP / 1.1 Хост: * .pt Соединение: Keep-Alive User-Agent:> PHP-SOAP / 5.3.0 Content-Type: text / xml; charset = utf-8 SOAPAction: "http://**/Login"> Длина содержимого: 264 Авторизация: Basic AUTHSECRETPASS

Я называю это так:

$ soapParams = array ('login' => 'HTTP_LOGIN',
'password' => 'HTTP_PASS',
'аутентификация' => SOAP_AUTHENTICATION_BASIC,
'trace' => 1,
«исключения» => 0
);
$ client = new SoapClient ("https://****.asmx?WSDL", $ soapParams); echo "Connected
"; $ params = array ('account' => '', 'msisdn' => 'NUMBER', 'password' => 'PASSWORD'); $ result = $ client -> __ soapCall ("логин", $ params);

Через некоторое время погуглив и попытавшись выяснить, в чем может быть проблема, я переключился на nusoap .., который, к моему несчастью, тоже выдал ошибку:

Error

Ошибка HTTP: истекло время ожидания чтения сокетов

Запрос

POST /**.asmx HTTP / 1.0 Ведущий: * .pt Пользователь-агент: NuSOAP / 0.9.5 (1.123) Content-Type: text / xml; кодировка = ISO-8859-1 SOAPAction: "http://****/Login" Авторизация: Базовый AUTHSECRETPASS Длина контента: 481

NUMBERPASSWORD

Ответ

Я называю это так:

$ client = new nusoap_client ("https://**.asmx?WSDL", true);
$ Client-> SetCredentials ( 'HTTPUSER', 'HTTPPASS', 'основной');
$ params = array ( 'account' => '', 'MSISDN' => 'NUMBER', 'Пароль' => 'PASSWORD' );
$ result = $ client-> call ('Логин', $ params);

С помощью nusoap я также попытался включить включение расширения curl для совершения звонков:

$ client-> setUseCurl (истина);

Но не повезло, он продолжал выдавать ошибку:

Ошибка HTTP: ОШИБКА cURL: 56: Ошибка при получении данных от партнера URL: http://*********.asmx
content_type:
http_code: 0
header_size: 0
размер запроса: 750
время файла: -1
ssl_verify_result: 0
redirect_count: 0
итого: 21.015
namelookup_time: 0
connect_time: 0
pretransfer_time: 0
size_upload: 462
size_download: 0
speed_download: 0
speed_upload: 21
длина_загрузки_контента: -1
upload_content_length: -1
starttransfer_time: 0
redirect_time: 0

Я на 100% уверен, что с веб-сервисом все в порядке, если я могу без проблем вызвать его из SoapUI, я не понимаю, почему я не могу вызвать его из PHP.

Я не знаю, что еще я могу сделать .. Я думаю, что все перепробовал ...

Редактировать: я только что попробовал другой класс Soap для PHP, на этот раз от Zend ..

Результат:

Неустранимая ошибка: необработанное исключение SoapFault: [WSDL] SOAP-ERROR: синтаксический анализ WSDL: невозможно загрузить из 'https://**.asmx?WSDL': не удалось загрузить внешнюю сущность "https://*.asmx?WSDL" в C: \ www \ xpto_Atestes \ Zend \ Soap \ Client \ Common.php: 51 Трассировка стека:
# 0 C: \ www \ xpto_Atestes \ Zend \ Soap \ Client \ Common.php (51): SoapClient-> SoapClient ('https://**...', Array)
# 1 C: \ www **** _Atestes \ Zend \ Soap \ Client.php (1032): Zend_Soap_Client_Common -> __ construct (Array, 'https://**...', Array)
# 2 C: \ www **** _Atestes \ Zend \ Soap \ Client.php (1188): Zend_Soap_Client -> _ initSoapClientObject ()
# 3 C: \ www *** _Atestes \ Zend \Soap \ Client.php (1112): Zend_Soap_Client-> getSoapClient () # 4 [внутренняя функция]: Zend_Soap_Client -> __ call ('Login', Array)
# 5 C: \ www **** _Atestes \ zend.php (28): Zend_Soap_Client-> Login (Array)
# 6 {main} добавляется в

1 Ответ

2 голосов
/ 21 октября 2011

Просто чтобы ответить самому себе, на случай, если кто-то еще захочет узнать, как я это решил.

Проблема заключалась в следующем, запрос XML для одного из веб-сервисов должен был быть в таком формате:

<?xml version="1.0" encoding="utf-8" ?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
        <ns123:IsTokenValid xmlns:ns123="http://www.xxxxxxx.com">
            <ns123:token xsi:type="xsd:string">'.$this->loginToken.'</ns123:token>
        </ns123:IsTokenValid>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Когда я упоминаю префикс, я имею в виду часть ns123.Проблема в том, что ни одна из библиотек не создала правильный XML для отправки на сервер, они никогда не ставили префикс, поэтому запрос никогда не работал.

Сначала я решил его, перейдя непосредственно к классу NuSoap иизменил код в одном из классов, но потом я обнаружил, что могу сделать свой собственный XML-запрос с NuSoap, получив следующий код:

$nsValue = rand(1000, 9000);
$requestXml = '<?xml version="1.0" encoding="utf-8" ?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns'.$nsValue.':IsTokenValid xmlns:ns'.$nsValue.'="http://www.xxxxxxx.com">
<ns'.$nsValue.':token xsi:type="xsd:string">'.$this->loginToken.'</ns'.$nsValue.':token>
</ns'.$nsValue.':IsTokenValid>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
$result = WebService::CallWebService($this->endPoint, 'http://www.xxxxxxx.com/IsTokenValid', $requestXml, $this->httpUser, $this->httpPass);

WebService :: CallWebService - это просто оболочка для класса NuSoapкоторый делает что-то вроде этого (а также имеет обработку ошибок, HTTP-аутентификацию и т. д.):

$client = new nusoap_client($webServiceLink, false);
$result = $client->send($request, $soapAction, '', self::$timeout, self::$responseTimeout);

Iain и все остальные, надеюсь, это понятно.

...