Skip to content

Commit 8dbf11d

Browse files
leachiM2kjsdevel
authored andcommitted
Added one-way response configuration options
1 parent bcc41e6 commit 8dbf11d

File tree

4 files changed

+90
-5
lines changed

4 files changed

+90
-5
lines changed

Readme.md

+11
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ This module lets you connect to web services using SOAP. It also provides a ser
2020
- [Options](#options)
2121
- [Server Logging](#server-logging)
2222
- [Server Events](#server-events)
23+
- [Server Response on one-way calls](#server-response-on-one-way-calls)
2324
- [SOAP Fault](#soap-fault)
2425
- [Server security example using PasswordDigest](#server-security-example-using-passworddigest)
2526
- [Server connection authorization](#server-connection-authorization)
@@ -258,6 +259,16 @@ Server instances emit the following events:
258259
The sequence order of the calls is `request`, `headers` and then the dedicated
259260
service method.
260261

262+
### Server Response on one-way calls
263+
264+
The so called one-way (or asynchronous) calls occur when an operation is called with no output defined in WSDL.
265+
The server sends a response (defaults to status code 200 with no body) to the client disregarding the result of the operation.
266+
267+
You can configure the response to match the appropriate client expectation to the SOAP standard implementation.
268+
Pass in `oneWay` object in server options. Use the following keys:
269+
`emptyBody`: if true, returns an empty body, otherwise no content at all (default is false)
270+
`responseCode`: default statusCode is 200, override it with this options (for example 202 for SAP standard compliant response)
271+
261272
### SOAP Fault
262273

263274
A service method can reply with a SOAP Fault to a client by `throw`ing an

lib/server.js

+11-5
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ var Server = function (server, path, services, wsdl, options) {
3939
this.wsdl = wsdl;
4040
this.suppressStack = options && options.suppressStack;
4141
this.returnFault = options && options.returnFault;
42+
this.onewayOptions = options && options.oneWay || {};
4243

4344
if (path[path.length - 1] !== '/')
4445
path += '/';
@@ -130,6 +131,8 @@ Server.prototype.clearSoapHeaders = function () {
130131

131132
Server.prototype._initializeOptions = function (options) {
132133
this.wsdl.options.attributesKey = options.attributesKey || 'attributes';
134+
this.onewayOptions.statusCode = this.onewayOptions.responseCode || 200;
135+
this.onewayOptions.emptyBody = !!this.onewayOptions.emptyBody;
133136
};
134137

135138
Server.prototype._processRequestXml = function (req, res, xml) {
@@ -387,7 +390,11 @@ Server.prototype._executeMethod = function (options, req, callback, includeTimes
387390
if (!self.wsdl.definitions.services[serviceName].ports[portName].binding.methods[methodName].output) {
388391
// no output defined = one-way operation so return empty response
389392
handled = true;
390-
callback('');
393+
body = '';
394+
if (this.onewayOptions.emptyBody) {
395+
body = self._envelope('', headers, includeTimestamp);
396+
}
397+
callback(body, this.onewayOptions.responseCode);
391398
}
392399

393400
var result = method(args, handleResult, options.headers, req);
@@ -432,10 +439,9 @@ Server.prototype._envelope = function (body, headers, includeTimestamp) {
432439
xml += "<soap:Header>" + headers + "</soap:Header>";
433440
}
434441

435-
xml += "<soap:Body>" +
436-
body +
437-
"</soap:Body>" +
438-
"</soap:Envelope>";
442+
xml += body ? "<soap:Body>" + body + "</soap:Body>" : "<soap:Body/>";
443+
444+
xml += "</soap:Envelope>";
439445
return xml;
440446
};
441447

lib/soap.d.ts

+6
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,18 @@ export interface IOptions extends IWsdlBaseOptions {
8585
[key: string]: any;
8686
}
8787

88+
export interface IOneWayOptions {
89+
responseCode?: number;
90+
emptyBody?: boolean;
91+
}
92+
8893
export interface IServerOptions extends IWsdlBaseOptions {
8994
path: string;
9095
services: IServices;
9196
xml?: string;
9297
uri?: string;
9398
suppressStack?: boolean;
99+
oneWay?: IOneWayOptions;
94100
[key: string]: any;
95101
}
96102

test/server-options-test.js

+62
Original file line numberDiff line numberDiff line change
@@ -398,4 +398,66 @@ describe('SOAP Server with Options', function() {
398398
});
399399
});
400400
});
401+
it('should return configured statusCode on one-way operations', function (done) {
402+
test.server.listen(15099, null, null, function() {
403+
test.soapServer = soap.listen(test.server, {
404+
path: '/stockquote',
405+
services: test.service,
406+
xml: test.wsdl,
407+
oneWay: {
408+
responseCode: 202
409+
}
410+
}, test.service, test.wsdl);
411+
test.baseUrl = 'http://' + test.server.address().address + ":" + test.server.address().port;
412+
413+
//windows return 0.0.0.0 as address and that is not
414+
//valid to use in a request
415+
if (test.server.address().address === '0.0.0.0' || test.server.address().address === '::') {
416+
test.baseUrl = 'http://127.0.0.1:' + test.server.address().port;
417+
}
418+
419+
soap.createClient(test.baseUrl + '/stockquote?wsdl', function(err, client) {
420+
assert.ifError(err);
421+
client.on('response', function (xml, response) {
422+
assert.equal(response.statusCode, 202);
423+
done();
424+
});
425+
426+
client.SetTradePrice({ tickerSymbol: 'GOOG' }, function(err, result, body) {
427+
assert.ifError(err);
428+
assert.equal(result,null);
429+
assert.equal(body,'');
430+
});
431+
});
432+
});
433+
});
434+
it('should return empty body on one-way operations if configured', function (done) {
435+
var responseData = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://example.com/stockquote.wsdl" xmlns:xsd1="http://example.com/stockquote.xsd"><soap:Body/></soap:Envelope>';
436+
test.server.listen(15099, null, null, function() {
437+
test.soapServer = soap.listen(test.server, {
438+
path: '/stockquote',
439+
services: test.service,
440+
xml: test.wsdl,
441+
oneWay: {
442+
emptyBody: true
443+
}
444+
}, test.service, test.wsdl);
445+
test.baseUrl = 'http://' + test.server.address().address + ":" + test.server.address().port;
446+
447+
//windows return 0.0.0.0 as address and that is not
448+
//valid to use in a request
449+
if (test.server.address().address === '0.0.0.0' || test.server.address().address === '::') {
450+
test.baseUrl = 'http://127.0.0.1:' + test.server.address().port;
451+
}
452+
453+
soap.createClient(test.baseUrl + '/stockquote?wsdl', function(err, client) {
454+
assert.ifError(err);
455+
client.SetTradePrice({ tickerSymbol: 'GOOG' }, function(err, result, body) {
456+
assert.ifError(err);
457+
assert.strictEqual(body, responseData);
458+
done();
459+
});
460+
});
461+
});
462+
});
401463
});

0 commit comments

Comments
 (0)