且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

PHP NuSoap 中的 XML 请求 - “HTTP/1.1 400 Bad Request"

更新时间:2023-01-03 18:32:56

问题出在标题上.

开头 &结束标记导致 HTTP 错误 400错误请求"

$proxy->setHeaders('<soap:Header><AuthenticationSoapHeader xmlns="https://www.xxxxx.com/aspapi"><Token>xxxxx</Token><;/AuthenticationSoapHeader>');

应该

$proxy->setHeaders('<AuthenticationSoapHeader xmlns="https://www.xxxxx.com/aspapi"><Token>xxxxx</Token></AuthenticationSoapHeader>');

I'm using NuSoap within PHP to connect to an API.

At the minute, I'm just simple trying to send over an example XML string provided by the company who provides the API, however I'm receiving a HTTP/1.1 400 Bad Request error.

I've queried this directly with the company but they've said that when they use the XML they've provided, as well as other clients, they aren't having any problems.

The XML I'm trying to send is:

![CDATA[<?xml version="1.0" encoding="utf-8" ?>
<Service>
  <Name><![CDATA[Demo]]></Name>
  <Description><![CDATA[Demo Service]]></Description>
  <Version>1.0</Version>
  <Nodes>
    <Node NodeType="Start" NodeID="5" Description="">
      <!-- Comments can be included -->
      <MandatoryProperties>
        <Property Name="MaxLength" Value="0"/>
        <Property Name="EnableSpeedDial" Value="False"/>
      </MandatoryProperties>
     <OptionalSettings/>
      <Branches>
        <Branch Name="Continue" NodeID="20" Description=""/>
      </Branches>
      <DynamicBranches/>
      <DynamicProperties/>
    </Node>
    <Node NodeType="DeliverCall" NodeID="20" Description="Home Phone">
      <MandatoryProperties>
        <Property Name="DestinationNumber" Value="01132211444"/>
        <Property Name="RingDuration" Value="60"/>
      </MandatoryProperties>
      <OptionalSettings/>
      <Branches>
      </Branches>
      <DynamicBranches/>
      <DynamicProperties/>
    </Node>
  </Nodes>
</Service>]]

The response I'm getting is:

Response:
HTTP/1.1 100 Continue

HTTP/1.1 400 Bad Request
Date: Fri, 24 Jan 2014 15:47:16 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET 2.0
MicrosoftOfficeWebServer: 5.0_Pub
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
Cache-Control: private
Content-Type: text/xml; charset=utf-8
Content-Length: 2
Connection: close

I've used http://www.validome.org/xml/validate/ to validate the XML as I'm not experienced with XML and this is one of the few times I've had to use it, so I'm not going to be on the ball at picking up any syntax errors, but the error the validation tool is providing is:

I've checked that there's no whitespace leading or trailing on the XML.

Something I've noticed is that in the XML, it's setting the encoding to utf-8. However the encoding in my request seems to be ISO - although it doesn't look as though there are any special characters or anything in the XML string.

The request data:

POST /dev/aspapi/api.asmx HTTP/1.0
Host: www.xxxxx.com
User-Agent: NuSOAP/0.9.5 (1.123)
Content-Type: text/xml; charset=ISO-8859-1
SOAPAction: "https://www.xxxxx.com/ASPAPI/ValidateService"
Authorization: Basic bWVkaWFoYXdrOm1lZGlhaGF3aw==
Content-Length: 2127

I'd be grateful if anyone could spot anything wrong with this!

Full connection script:

<?php

require_once('./nusoap.php');

error_reporting(E_ALL);
ini_set("display_errors", true);

$client = new nusoap_client('http://xxx.xxx/api.asmx', 'wsdl');

$client->setCredentials('xxxxx', 'xxxxx'); 
$client->response_timeout = 120;

$err = $client->getError();

if($err) {
    echo 'ERROR<br /><pre>' . $err . '</pre><br />';
    exit;
} else {
    echo "<strong><em>Sucessfull connection</em></strong><br /><br />";
}

$proxy = $client->getProxy();

$proxy->setHeaders('<soap:Header><AuthenticationSoapHeader xmlns="https://www.xxxxx.com/aspapi"><Token>xxxxx</Token></AuthenticationSoapHeader></soap:Header>');

$xml = '
![CDATA[<?xml version="1.0" encoding="utf-8" ?>
<Service>
  <Name><![CDATA[Demo]]></Name>
  <Description><![CDATA[Demo Service]]></Description>
  <Version>1.0</Version>
  <Nodes>
    <Node NodeType="Start" NodeID="5" Description="">
      <!-- Comments can be included -->
      <MandatoryProperties>
        <Property Name="MaxLength" Value="0"/>
        <Property Name="EnableSpeedDial" Value="False"/>
      </MandatoryProperties>
     <OptionalSettings/>
      <Branches>
        <Branch Name="Continue" NodeID="20" Description=""/>
      </Branches>
      <DynamicBranches/>
      <DynamicProperties/>
    </Node>
    <Node NodeType="DeliverCall" NodeID="20" Description="Home Phone">
      <MandatoryProperties>
        <Property Name="DestinationNumber" Value="01132211444"/>
        <Property Name="RingDuration" Value="60"/>
      </MandatoryProperties>
      <OptionalSettings/>
      <Branches>
      </Branches>
      <DynamicBranches/>
      <DynamicProperties/>
    </Node>
  </Nodes>
</Service>]]';

$result = $proxy->call('ValidateService', array('serviceXML' => $xml));

$err = $proxy->getError();
if($err) {
    echo 'ERROR<br /><pre>' . $err . '</pre><br />';
    echo '<strong>Request:</strong>';
    echo '<pre>'; print_r($proxy->request); echo '</pre>';
    echo '<strong>Response:</strong>';
    echo '<pre>'; print_r($proxy->response); echo '</pre>';
    exit;
} else {
    echo "<strong><em>Sucessfull connection</em></strong><br /><br />";
}
?>

The output of the above script:

Sucessfull connection

ERROR
HTTP Error: Unsupported HTTP response status 400 Bad Request (soapclient->response has contents of the response)

Request:
POST /dev/aspapi/api.asmx HTTP/1.0
Host: www.xxxxx.com
User-Agent: NuSOAP/0.9.5 (1.123)
Content-Type: text/xml; charset=ISO-8859-1
SOAPAction: "https://www.xxxxx.com/ASPAPI/ValidateService"
Authorization: Basic bWVkaWFoYXdrOm1lZGlhaGF3aw==
Content-Length: 2127

<TOKEN IS HERE IN OUTPUT>
![CDATA[<?xml version="1.0" encoding="utf-8" ?>
<Service>
  <Name><![CDATA[Demo]]></Name>
  <Description><![CDATA[Demo Service]]></Description>
  <Version>1.0</Version>
  <Nodes>
    <Node NodeType="Start" NodeID="5" Description="">
      <!-- Comments can be included -->
      <MandatoryProperties>
        <Property Name="MaxLength" Value="0"/>
        <Property Name="EnableSpeedDial" Value="False"/>
      </MandatoryProperties>
     <OptionalSettings/>
      <Branches>
        <Branch Name="Continue" NodeID="20" Description=""/>
      </Branches>
      <DynamicBranches/>
      <DynamicProperties/>
    </Node>
    <Node NodeType="DeliverCall" NodeID="20" Description="Home Phone">
      <MandatoryProperties>
        <Property Name="DestinationNumber" Value="01132211444"/>
        <Property Name="RingDuration" Value="60"/>
      </MandatoryProperties>
      <OptionalSettings/>
      <Branches>
      </Branches>
      <DynamicBranches/>
      <DynamicProperties/>
    </Node>
  </Nodes>
</Service>]]

Response:

HTTP/1.1 100 Continue

HTTP/1.1 400 Bad Request
Date: Fri, 24 Jan 2014 16:28:39 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET 2.0
MicrosoftOfficeWebServer: 5.0_Pub
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
Cache-Control: private
Content-Type: text/xml; charset=utf-8
Content-Length: 2
Connection: close

Additional Info

Still no luck as of yet, the output of the debug string can be found at http://pastebin.com/hF3DYGWP

The problem lies in the headers.

The <soap:Header> opening & closing tags were causing the HTTP Error 400 "Bad Request"

$proxy->setHeaders('<soap:Header><AuthenticationSoapHeader xmlns="https://www.xxxxx.com/aspapi"><Token>xxxxx</Token></AuthenticationSoapHeader></soap:Header>');

Should be

$proxy->setHeaders('<AuthenticationSoapHeader xmlns="https://www.xxxxx.com/aspapi"><Token>xxxxx</Token></AuthenticationSoapHeader>');