Skip to content

Commit

Permalink
Added support for attachmentin SOAP. SWA and MTOM
Browse files Browse the repository at this point in the history
  • Loading branch information
NicolaCorvo90 authored and f3l1x committed Oct 1, 2022
1 parent 3ec9caf commit e962aec
Showing 1 changed file with 81 additions and 0 deletions.
81 changes: 81 additions & 0 deletions src/nusoap.php
Original file line number Diff line number Diff line change
Expand Up @@ -3689,6 +3689,13 @@ class nusoap_server extends nusoap_base
* @access private
*/
var $responseSOAP = '';
/**
* SOAP attachments in response
*
* @var string
* @access private
*/
var $attachments= '';
/**
* method return value to place in response
*
Expand Down Expand Up @@ -6756,6 +6763,8 @@ class nusoap_parser extends nusoap_base
// toggle for auto-decoding element content
var $decode_utf8 = true;

var $attachments = array();

/**
* constructor that actually does the parsing
*
Expand All @@ -6772,6 +6781,7 @@ function __construct($xml, $encoding = 'UTF-8', $method = '', $decode_utf8 = tru
$this->xml_encoding = $encoding;
$this->method = $method;
$this->decode_utf8 = $decode_utf8;
$this->attachments = array();

// Check whether content has been read.
if (!empty($xml)) {
Expand Down Expand Up @@ -6822,6 +6832,75 @@ function __construct($xml, $encoding = 'UTF-8', $method = '', $decode_utf8 = tru
//Tell the script that is the end of the parsing (by setting is_final to TRUE)
xml_parse($this->parser, '', true);

// Check if there is any attachment
$this->attachments = array();
foreach(preg_split("/((\r?\n)|(\r\n?))/", $xml) as $line){
if(preg_match(("/^--(.*)/"), $line, $matches)) {
array_push($this->attachments, array());
$this->attachments[count($this->attachments)-1]['boundaryStr'] = $matches[1];
} elseif(preg_match(("/Content-Type:(.*)/"), $line, $matches)) {
$this->attachments[count($this->attachments)-1]['Content-Type'] = $matches[1];
} elseif(preg_match(("/Content-Id:(.*)/"), $line, $matches)) {
$this->attachments[count($this->attachments)-1]['Content-Id'] = $matches[1];
} elseif(preg_match(("/Content-Transfer-Encoding:(.*)/"), $line, $matches)) {
$this->attachments[count($this->attachments)-1]['Content-Transfer-Encoding'] = $matches[1];
}
}

if(!empty($this->attachments)) {
// Extract the content of each attachments
$substrXml = $xml;
foreach($this->attachments as $key => $attachment) {
$startPos = max(
stripos($substrXml, $attachment['boundaryStr']),
(array_key_exists('Content-Type', $attachment) ? stripos($substrXml, $attachment['Content-Type']) : 0),
(array_key_exists('Content-Id', $attachment) ? stripos($substrXml, $attachment['Content-Id']) : 0),
(array_key_exists('Content-Transfer-Encoding', $attachment) ? stripos($substrXml, $attachment['Content-Transfer-Encoding']) : 0)
);
$substrXml = substr($substrXml, $startPos);
$startPos = stripos($substrXml, PHP_EOL);
$substrXml = substr($substrXml, $startPos);
$substrXml = trim($substrXml);
$length = null;
if(array_key_exists($key+1, $this->attachments) && $this->attachments[$key+1] && !empty($this->attachments[$key+1]['boundaryStr'])) {
$length = stripos($substrXml, ('--' . $this->attachments[$key+1]['boundaryStr']))-1;
}
$content = substr($substrXml, 0, $length);
$this->attachments[$key]['content'] = $content;

$substrXml = substr($substrXml, $length);
}
}

if(!empty($parseErrors) && !empty($this->attachments)){
// Search the SOAP response message
foreach($this->attachments as $key => $attachment) {
// Settings for xml_parse
$this->parser = xml_parser_create($this->xml_encoding);
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
xml_set_object($this->parser, $this);
xml_set_element_handler($this->parser, 'start_element', 'end_element');
xml_set_character_data_handler($this->parser, 'character_data');

if(!empty($attachment['content'])) {
$content = $attachment['content'];
foreach(preg_split("/((\r?\n)|(\r\n?))/", $content) as $line){
if(preg_match(("/:Envelope/"), $line, $matches)) {
if(!xml_parse($this->parser, $content, true)) {
$parseErrors['lineNumber'] = xml_get_current_line_number($this->parser);
$parseErrors['errorString'] = xml_error_string(xml_get_error_code($this->parser));
} else {
$parseErrors = array();
unset($this->attachments[$key]);
break 2;
}
}
}
}
}
}

if(!empty($parseErrors)){
// Display an error message.
$err = sprintf('XML error parsing SOAP payload on line %d: %s',
Expand Down Expand Up @@ -7915,6 +7994,8 @@ function parseResponse($headers, $data)
$return = $parser->get_soapbody();
// add document for doclit support
$this->document = $parser->document;
// Add attachments
$this->attachments = $parser->attachments;
// destroy the parser object
unset($parser);
// return decode message
Expand Down

0 comments on commit e962aec

Please sign in to comment.