PackageGenerator
PackageGenerator copied to clipboard
Content-Type not being set
I'm consuming an API that requires content-type = application/soap+xml; charset=utf-8 on the request.
On my generated service class I've specified:
$this->setHttpHeader('Content-Type', 'application/soap+xml; charset=utf-8');
$this->setHttpHeader('Test', 'xxxxxxxxx');
$this->setHttpHeader('Test2', 'yyyyyyy');
Then I get this error from the api
Response Validation Exception: Cannot process the message because the content type 'text/xml; charset=utf-8' was not the expected type 'application/soap+xml; charset=utf-8'.
On the AbstractSoapClientBase class, method setHttpHeader I can see all these three headers being set properly using
var_dump(stream_context_get_options(static::getSoapClient()->_stream_context));
The request actually end up with my new headers but failed back to the default Content-Type:
User-Agent: Nei
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://v12finance.com/Services/ApplicationGateway/1.1/IApplicationGatewayWebService/GetRetailerFinanceProducts"
Content-Length: 567
Test: xxxxxxxxx
Test2: yyyyyyy
I have no idea about this since I've not found any reference for content-type on the code. Any clue how to set the content-type?
content-type is set by the SoapClient, the "only" solution is to "manually" send the request "yourself" using a curl request overridding the __doRequest method.
In order to override the __doRequest, you can take example at this project https://github.com/WsdlToPhp/PackageEws365
let me know if you need further information
any feedback is appreciated as I know that other users faced this issue and it would be good know the best way/practice to work around this, thx 😉
You don't need to extend the SoapClient class.
The content type is indeed defined by the SoapClient but is determined by the soap_version. The default is SOAP_1_1 which sets the content type as text/xml, but if you use SOAP_1_2 it is set to application/soap+xml.
You can do this by add 'wsdl_soap_version' to your constructors options.
For example, building on a generated tutorial.php
require_once __DIR__ . '/vendor/autoload.php';
$options = array(
\WsdlToPhp\PackageBase\AbstractSoapClientBase::WSDL_URL => 'http://..../MyWsdl.wsdl',
\WsdlToPhp\PackageBase\AbstractSoapClientBase::WSDL_CLASSMAP => ClassMap::get(),
'wsdl_soap_version' => SOAP_1_2,
);
$is = new \ServiceType\Is($options);
if ($is->MyCallBack(new \StructType\MyCallBack()) !== false) {
print_r($is->getResult());
} else {
print_r($is->getLastError());
}
Thanks for this precision!
Nonetheless, if the server requires a specific content-type, which is are, you can't unless you send the request with your own implementation using curl for example
Yes that is true. And yes, extend the SoapClient and __doRequest. I would like to see an example if you have one.
The override of the SoapClient class instance is demonstrated in the PackageEws365 project especially in the dedicated SoapClient class