Skip to content
Binary file added .DS_Store
Binary file not shown.
9 changes: 8 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,12 @@ if (major >= 5) {
base = './src/';
}

module.exports = require(base + 'soap');
module.exports = {
'soap': require(base + 'soap'),
'http': require(base + 'http'),
'QName': require(base + 'parser/qname'),
'WSDL': require(base + 'parser/wsdl'),
'WSSecurity': require(base + 'security/WSSecurity')
};


10 changes: 8 additions & 2 deletions src/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,17 @@ class Base extends EventEmitter {
this.bodyAttributes = [];
}

addSoapHeader(value, qname, options) {
var header = new SOAPElement(value, qname, options);
addSoapHeader(name, value, qname, options) {
var header = new SOAPElement(name, value, qname, options);
return this.soapHeaders.push(header) - 1;
}

changeSoapHeader(index, name, value, qname, options) {
var header = new SOAPElement(name, value, qname, options);
this.soapHeaders[index] = header;
}


getSoapHeaders() {
return this.soapHeaders;
}
Expand Down
23 changes: 12 additions & 11 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,16 @@ class Client extends Base {
var soapHeaderElement = envelope.header;
var soapBodyElement = envelope.body;

for (let i = 0, n = self.soapHeaders.length; i < n; i++) {
let soapHeader = self.soapHeaders[i];
let element = self.findElement(soapHeader.nsURI, soapHeader.name);
for (let i = 0, n = this.soapHeaders.length; i < n; i++) {
let soapHeader = this.soapHeaders[i];
if (soapHeader.qname.nsURI === null || soapHeader.qname.nsURI === undefined) {
continue;
}
let element = this.findElement(soapHeader.qname.nsURI, soapHeader.name);
let elementDescriptor =
element && element.describe(self.wsdl.definitions);
element && element.describe(this.wsdl.definitions);
xmlHandler.jsonToXml(soapHeaderElement, nsContext, elementDescriptor,
soapHeader.name, soapHeader.value);
soapHeader.value);
}

if (self.security && self.security.addSoapHeaders) {
Expand All @@ -185,8 +188,7 @@ class Client extends Base {
}
}

xmlHandler.jsonToXml(soapBodyElement, nsContext, inputBodyDescriptor,
null, args);
xmlHandler.jsonToXml(soapBodyElement, nsContext, inputBodyDescriptor, args);

if (self.security && self.security.postProcess) {
self.security.postProcess(envelope.header, envelope.body);
Expand Down Expand Up @@ -225,13 +227,13 @@ class Client extends Base {
callback(err);
} else {

var outputDescriptor = operationDescriptor.outputEnvelope;
var outputEnvDescriptor = operationDescriptor.outputEnvelope;
try {
obj = xmlHandler.xmlToJson(nsContext, body, outputDescriptor);
obj = xmlHandler.xmlToJson(nsContext, body, outputBodyDescriptor);
} catch (error) {
// When the output element cannot be looked up in the wsdl and the body is JSON
// instead of sending the error, we pass the body in the response.
if (!output || !output.$lookupTypes) {
if (!output) {
debug('Response element is not present. Unable to convert response xml to json.');
// If the response is JSON then return it as-is.
var json = _.isObject(body) ? body : tryJSONparse(body);
Expand All @@ -249,7 +251,6 @@ class Client extends Base {
// one-way, no output expected
return callback(null, null, body, obj.Header);
}

if (typeof obj.Body !== 'object') {
var error = new Error('Cannot parse response');
error.response = response;
Expand Down
48 changes: 29 additions & 19 deletions src/parser/xmlHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ var xmlBuilder = require('xmlbuilder');
var sax = require('sax');
var stream = require('stream');
var assert = require('assert');
var selectn = require('selectn');
var debug = require('debug')('node-soap:wsdl:xml');
var descriptor = require('./xsd/descriptor');
var ElementDescriptor = descriptor.ElementDescriptor;
Expand All @@ -12,6 +13,7 @@ var helper = require('./helper');
var NamespaceContext = require('./nscontext');
var Set = helper.Set;


class XMLHandler {
constructor(options) {
this.options = options || {};
Expand Down Expand Up @@ -97,7 +99,7 @@ class XMLHandler {
return node;
}

if (descriptor == null || descriptor instanceof TypeDescriptor) {
if (descriptor == null || descriptor === undefined || descriptor instanceof TypeDescriptor) {
this.mapObject(node, nsContext, descriptor, val);
return node;
}
Expand All @@ -121,16 +123,20 @@ class XMLHandler {
}

var elements = {}, attributes = {};
for (let i = 0, n = descriptor.elements.length; i < n; i++) {
let elementDescriptor = descriptor.elements[i];
let elementName = elementDescriptor.qname.name;
elements[elementName] = elementDescriptor;
if (descriptor !== undefined) {
for (let i = 0, n = descriptor.elements.length; i < n; i++) {
let elementDescriptor = descriptor.elements[i];
let elementName = elementDescriptor.qname.name;
elements[elementName] = elementDescriptor;
}
}

for (let a in descriptor.attributes) {
let attributeDescriptor = descriptor.attributes[a];
let attributeName = attributeDescriptor.qname.name;
attributes[attributeName] = attributeDescriptor;
if (descriptor !== undefined) {
for (let a in descriptor.attributes) {
let attributeDescriptor = descriptor.attributes[a];
let attributeName = attributeDescriptor.qname.name;
attributes[attributeName] = attributeDescriptor;
}
}

for (let p in val) {
Expand Down Expand Up @@ -158,6 +164,7 @@ class XMLHandler {
let prefix = mapping ? mapping.prefix : xsiType.prefix;
node.attribute('xsi:type', prefix ? prefix + ':' + xsiType.name :
xsiType.name);
continue;
}
let childDescriptor = attributes[p];
if (childDescriptor == null) {
Expand Down Expand Up @@ -485,16 +492,18 @@ class XMLHandler {

if (root.Envelope) {
var body = root.Envelope.Body;
if (body.Fault) {
var code = selectn('faultcode.$value', body.Fault) ||
selectn('faultcode', body.Fault);
var string = selectn('faultstring.$value', body.Fault) ||
selectn('faultstring', body.Fault);
var detail = selectn('detail.$value', body.Fault) ||
selectn('detail.message', body.Fault);
var error = new Error(code + ': ' + string + (detail ? ': ' + detail : ''));
error.root = root;
throw error;
if (root.Envelope.Body !== undefined && root.Envelope.Body !== null) {
if (body.Fault !== undefined && body.Fault !== null) {
var code = selectn('faultcode.$value', body.Fault) ||
selectn('faultcode', body.Fault);
var string = selectn('faultstring.$value', body.Fault) ||
selectn('faultstring', body.Fault);
var detail = selectn('detail.$value', body.Fault) ||
selectn('detail', body.Fault);
var error = new Error(code + ': ' + string + (detail ? ': ' + detail : ''));
error.root = root;
throw error;
}
}
return root.Envelope;
}
Expand All @@ -508,6 +517,7 @@ function declareNamespace(nsContext, node, prefix, nsURI) {
return false;
} else if (node) {
node.attribute('xmlns:' + mapping.prefix, mapping.uri);
return mapping;
}
}

Expand Down
57 changes: 47 additions & 10 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,15 +208,27 @@ class Server extends Base {
Object.keys(body)[1] : Object.keys(body)[0]);
var pair = binding.topElements[messageElemName];

self.emit('request', obj, pair.operationName);
var operationName, outputName;

var operations = binding.operations;
for (var name in operations) {
if(operations[name].input.message.parts.body.element.$name === messageElemName) {
operationName = operations[name].$name;
outputName = operations[name].output.message.parts.body.element.$name;
break;
}
}

console.log(operationName);
self.emit('request', obj, operationName);
if (headers)
self.emit('headers', headers, pair.operationName);
self.emit('headers', headers, operationName);

self._executeMethod({
serviceName: serviceName,
portName: portName,
operationName: pair.operationName,
outputName: pair.outputName,
operationName: operationName,
outputName: outputName,
args: body[messageElemName],
headers: headers,
style: 'document',
Expand Down Expand Up @@ -264,16 +276,41 @@ class Server extends Base {
result = error;
}

var env = XMLHandler.createSOAPEnvelope();

if (style === 'rpc') {
//[rashmi] this needs a fix, calling non existent api
var env = XMLHandler.createSOAPEnvelope();
body = self.wsdl.objectToRpcXML(outputName, result, '', self.wsdl.definitions.$targetNamespace);
} else {
var element = self.wsdl.definitions.services[serviceName]
.ports[portName].binding.operations[operationName].output;
body = self.wsdl.objectToDocumentXML(outputName, result,
element.targetNSAlias, element.targetNamespace);

var operation = self.wsdl.definitions.services[serviceName]
.ports[portName].binding.operations[operationName];
var element = operation.output;
// self.wsdl.objectToDocumentXML(outputName, result, element.targetNSAlias, element.targetNamespace);

var operationDescriptor = operation.describe(self.wsdl.definitions);
var outputBodyDescriptor = operationDescriptor.output.body;

var soapNsURI = 'http://schemas.xmlsoap.org/soap/envelope/';
var soapNsPrefix = self.wsdl.options.envelopeKey || 'soap';

if (self.wsdl.options.forceSoap12Headers) {
headers['Content-Type'] = 'application/soap+xml; charset=utf-8';
soapNsURI = 'http://www.w3.org/2003/05/soap-envelope';
}

var nsContext = self.createNamespaceContext(soapNsPrefix, soapNsURI);
var envelope = XMLHandler.createSOAPEnvelope(soapNsPrefix, soapNsURI);

self.xmlHandler.jsonToXml(envelope.body, nsContext, outputBodyDescriptor, result);

var message = envelope.body.toString({pretty: true});
var xml = envelope.doc.end({pretty: true});

}
callback(self._envelope(body, includeTimestamp));
//callback(self._envelope(envelope, includeTimestamp));
callback(xml);

}

if (!self.wsdl.definitions.services[serviceName].ports[portName]
Expand Down
3 changes: 2 additions & 1 deletion src/soapModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ var QName = require('./parser/qname');
* Representation for soap elements
*/
class SOAPElement {
constructor(value, qname, options) {
constructor(name, value, qname, options) {
if (typeof value === 'string' && !qname) {
this.xml = value;
} else {
this.name = name;
this.value = value;
this.qname = qname;
this.options = options || {};
Expand Down
12 changes: 6 additions & 6 deletions test/client-customHttp-test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
'use strict';

var fs = require('fs'),
soap = require('..'),
soap = require('..').soap,
http = require('http'),
assert = require('assert'),
duplexer = require('duplexer'),
req = require('request'),
httpClient = require('../lib/http.js'),
httpClient = require('..').http,
// stream = require('stream'),
stream = require('readable-stream'),
util = require('util'),
Expand Down Expand Up @@ -52,7 +52,7 @@ describe('custom http client', function() {

//Custom httpClient
function MyHttpClient(options, socket) {
httpClient.call(this, options);
this.httpCl = new httpClient(options);
this.agent = new CustomAgent(options, socket);
}

Expand All @@ -64,7 +64,7 @@ describe('custom http client', function() {
//Specify agent to use
options.agent = this.agent;
var headers = options.headers;
var req = self._request(options, function(err, res, body) {
var req = this.httpCl._request(options, function(err, res, body) {
if (err) {
return callback(err);
}
Expand Down Expand Up @@ -99,7 +99,7 @@ describe('custom http client', function() {

//Custom httpClient
function MyHttpClient(options, socket) {
httpClient.call(this, options);
this.httpCl = new httpClient(options);
this.agent = new CustomAgent(options, socket);
}

Expand All @@ -112,7 +112,7 @@ describe('custom http client', function() {
//Specify agent to use
options.agent = this.agent;
var headers = options.headers;
var req = self._request(options, function(err, res, body) {
var req = this.httpCl._request(options, function(err, res, body) {
if (err) {
return callback(err);
}
Expand Down
8 changes: 4 additions & 4 deletions test/client-customHttp-xsdinclude-test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
'use strict';

var soap = require('..'),
var soap = require('..').soap,
http = require('http'),
assert = require('assert'),
req = require('request'),
httpClient = require('../lib/http.js'),
httpClient = require('..').http,
util = require('util'),
events = require('events'),
createSocketStream = require('./_socketStream');
Expand Down Expand Up @@ -37,7 +37,7 @@ describe('custom http client', function() {

//Custom httpClient
function MyHttpClient(options, wsdlSocket, xsdSocket) {
httpClient.call(this, options);
this.httpCl = new httpClient(options);
this.agent = new CustomAgent(options, wsdlSocket, xsdSocket);
}

Expand All @@ -50,7 +50,7 @@ describe('custom http client', function() {
//Specify agent to use
options.agent = this.agent;
var headers = options.headers;
var req = self._request(options, function(err, res, body) {
var req = this.httpCl._request(options, function(err, res, body) {
if (err) {
return callback(err);
}
Expand Down
Loading