1

I used Wireshark to capture what my browser was sending to a printer and captured this:

https://pastebin.com/ZgpDVazX

I'm trying to duplicate that in PHP with the SOAP extension and am having some difficulty. Here's my PHP code:

<?php
$client = new SoapClient(dirname(__FILE__) . '/WebPackage/WSDPrinterService.wsdl', ['trace' => 1]);
$client->__setLocation('http://192.168.1.116/WebServices/PrinterService');

$temp = new stdClass();
$temp->DocumentId = 1;
$temp->Compression = 'none';
$temp->Format = 'unknown';

$params = new stdClass();
$params->JobId  = 1;
$params->DocumentDescription = $temp;
$params->LastDocument = true;
$params->DocumentData = file_get_contents('filename.pdf');

$client->SendDocument($params);

Here's the error I get:

[30-Dec-2021 12:57:15 America/Chicago] PHP Fatal error:  Uncaught SoapFault exception: []  in /home/neubert/test.php:16
Stack trace:
#0 /home/neubert/test.php(16): SoapClient->__call('SendDocument', Array)
#1 {main}
  thrown in /home/neubert/test.php on line 16

If I put $client->SendDocument($params) in a try / catch block and do $client->__getLastRequest() / $client->__getLastResponse() I can see the request (https://pastebin.com/9mTEBD2y) / response (https://pastebin.com/ue94kQUZ).

The faultcode part of the response says "SOAP-ENV:VersionMismatch" but the faultstring makes it sound like there could be something else wrong with the request other than just the version. None-the-less I tried to change the SOAP version by adding 'soap_version' => SOAP_1_2 (and SOAP_1_1) to the ['trace' => 1] array. With SOAP_1_2 the request (https://pastebin.com/cZGusCXa) / response (https://pastebin.com/PLfTV8qt) changes a bit as does the error (End of file or no input: Operation interrupted or timed out) but it's still not working and the error is still just as cryptic to me.

The only thing I can figure is that the DocumentData isn't being formatted correctly. Here's the DocumentData part of the good SOAP request:

<pri:DocumentData>
    <xop:Include href="cid:0@body"></xop:Include>
</pri:DocumentData>

Here's the DocumentData of hte bad SOAP request:

<ns1:DocumentData>...</ns1:DocumentData>

So maybe that's the issue? If so then it's not clear to me how to make PHP use xop:Include for the attachment.

The WSDL can be found at https://learn.microsoft.com/en-us/windows-hardware/drivers/print/ws-print-v1-1 (do Ctrl + F and find "Print Device Definition V1.0 for Web Services on Devices")

edit: I also tried converting the PDF to a PS as well but that didn't help. I thought that might make a difference because https://learn.microsoft.com/en-us/previous-versions/ff562064(v=vs.85) describes DocumentData as "Document PDL Data" and https://stackoverflow.com/a/39708917/569976 mentions PS and PCL as PDL's but not PDF.

neubert
  • 15,947
  • 24
  • 120
  • 212
  • I tried using WSDPrinterServiceV12.wsdl as well but that got me a `Uncaught SoapFault exception: [Sender] Function ("SendDocument") is not a valid method for this service` error – neubert Dec 30 '21 at 19:46
  • 1
    First, the SOAP mismatch is caused by using the wrong SOAP version for the call. There is SOAP 1.1 and SOAP 1.2. There are some differences on which I won't go into, but if the service expects a SOAP 1.2 message and you send a SOAP 1.1 message (or the other way arround) you get the first error. Some services allow you to use both versions, some just one of the versions, but you need to tell SoapClient what version you want to use before making calls (default is SOAP 1.1). – Bogdan Dec 30 '21 at 20:24
  • 1
    Second, you can't send binary content with SOAP. SOAP is XML. You either convert any binary as base64 text, dump it into the XML, and then convert it back in binary at the other end, or you use some other mechanism like XOP as I see in your samples, which basically extracts the binary as mime messages that travel next to your SOAP XML message with a reference placeholder (that include element you mention) inside the message to point to "the place" from where you can retrieve the binary. It seems that's what your service expects. – Bogdan Dec 30 '21 at 20:25
  • 1
    You might have a lot of work in front of you to make the call work with PHP (I don't remember the SoapClient's support for binary attachments) so I suggest you first try to get a succesful call with SoapUI and only when you are satisfied with the result to start to duplicate the same in PHP code. See here: https://en.m.wikipedia.org/wiki/XML-binary_Optimized_Packaging and here: https://www.soapui.org/docs/soap-and-wsdl/attachments/ – Bogdan Dec 30 '21 at 20:26

0 Answers0