Closed mtx-z closed 9 months ago
Hello @mtx-z,
At the moment, there is indeed no support for requests / responses in XOP format like e.g. MTOM services. It's something I surely want to support at some point in time.
There is an open discussion for this here: (which originates in 2017 or so ... to give you an idea) https://github.com/phpro/soap-client/discussions/357
About your comments:
I tried to manipulate the response using a custom middleware or response body manipulation, without success. I don't know what I should do. Should I try again to edit the XML response to remove the special character? Or is there any "do not throw" parameter so I can get the complete response and parse it?
If done the right way, this should be a valid (and suggested) workaround.
In your guzzle middleware, you are not removing the multi-part boundaries. It's not a matter of encoding url characters of doing utf8 conversions, but a matter of removing those --uuid:xxxxx
lines and only keeping the XML.
Of course, this will not solve the underlying problem of us not being able to support XOP payloads at the moment. I'm thinking more in line of solutions that can keep track of the "attachments" while only keeping the SOAP XML as an actual response. Maybe even with inline replacement of the xop:includes with the binary data directly.
Note that I was using wsdl2phpgenerator before, and I could get a response from the same Soap server. I just tried with wsdl2phpgenerator classes, and I'm able to get the response object without an error being thrown).
I don't know how wsdl2phpgenerator deals with this, but it's interesting to hear they supported this. If I find some more time, I can take a look at the codebase if I can figure out how they are doing it.
Going forward
Ad mentioned before: adding support for these kind of things would be very nice indeed! Currently I don't have any access nor experience with MTOM / XOP. It could help a lot if we could do an integration to gain some knowledge in this field.
Therefore I kindly link you to: https://github.com/php-soap/.github/blob/main/HELPING_OUT.md#let-us-do-your-implementation
If you want us to support this out of the box in our packages, we can always help you out with your implementation and transform those learnings to something that can generally be used by anyone who is facing the same issues as you are. If you just want to get around this issue in your project, that is fine as well of course :)
Hello @veewee,
thank you a lot for all those explanations and details. Unfortunately, I'm not sure that I have the required experience to create a PR for your package to support this.
But I could try to set up a middleware to strip the response from non-xml lines.
I tested a simple regex that should do the work $pattern = "/<s:Envelope(.*)<\/s:Envelope>/s";
.
I was able to edit the response to only keep the XML datas:
class SoapMiddleware implements Plugin
{
public function handleRequest(RequestInterface $request, callable $next, callable $first): Promise
{
return $next($request)
->then(function (ResponseInterface $response): ResponseInterface {
//extract content between <s:Envelope and </s:Envelope> including those tags
$pattern = "/<s:Envelope(.*)<\/s:Envelope>/s";
$body = $response->getBody()->getContents();
preg_match($pattern, $body, $matches);
$newBody = utf8_encode(urldecode($matches[0]));
$streamBody = fopen('data://text/plain,' . $newBody,'r');//new resource from string
$response = $response
->withBody(new \GuzzleHttp\Psr7\Stream($streamBody));
return (new XmlMessageManipulator)(
$response,
fn (Document $document) => $document->manipulate(
function($document) {
//dd('manipulate2', $document);
}
)
);
});
}
}
But I'm getting a new error Cannot assign string to property App\Services\Sld\PhpRoSoap\Type\GETLIEUResult::$schema of type App\Services\Sld\PhpRoSoap\Type\Schema
from ExtSoapDecoder
.
But at least it seems the data is now readable until a certain point. Any idea?
Thanks!
Hello,
Unfortunately, I'm not sure that I have the required experience to create a PR for your package to support this. But I could try to set up a middleware to strip the response from non-xml lines. I tested a simple regex that should do the work $pattern = "/<s:Envelope(.*)<\/s:Envelope>/s";.
That could work for you, but won't be sufficient to ship : MTOM is about adding multi-part binary files to the request / response in combination with a SOAP message. So we'll need some more advanced things to work with. But of course, it could work for your case.
But I'm getting a new error Cannot assign string to property App\Services\Sld\PhpRoSoap\Type\GETLIEUResult::$schema of type App\Services\Sld\PhpRoSoap\Type\Schema from ExtSoapDecoder . But at least it seems the data is now readable until a certain point. Any idea?
It's hard to tell from the given information about your service. But this might break/alter some namespaces making the decoder to not being able to map into the correct structure.
$newBody = utf8_encode(urldecode($matches[0]));
Closing this one : feedback was provided.
Bug Report
| Version | 3.1.0 x Laravel 10 x PHP 8.2
Summary
Hello, I'm consuming a remote SOAP (SOAP_1_1) endpoint serving some e-commerce data. I cannot share the WDSL URL, and cannot edit the SOAP server configuration. The server correctly sends back the response, but some extra character around the XML envelope seems to prevent the decoding.
Current behavior
I'm sure that the response contains the result object I need. I edited the vendor
vendor/php-soap/ext-soap-engine/src/ExtSoapDecoder.php
to debug the$response->getPayload()
. It gives me:So the object I need is in the HTTP received response. Authentication, method mapping etc... are OK. Issue is when decoding the response.
Error
What I tried
I tried to manipulate the response using a custom middleware or response body manipulation, without success.
I don't know what I should do. Should I try again to edit the XML response to remove the special character? Or is there any "do not throw" parameter so I can get the complete response and parse it?
Note that I was using wsdl2phpgenerator before, and I could get a response from the same Soap server. I just tried with wsdl2phpgenerator classes, and I'm able to get the response object without an error being thrown).
Thank you for your help; and for the awesome package.