From 8bf9068a9fdd3d7e58121cecc2fc307290568d99 Mon Sep 17 00:00:00 2001 From: KUANG Qi Date: Thu, 25 Apr 2019 22:49:18 +0800 Subject: [PATCH] client.addSoapHeader() dynamic SOAP header --- src/client.ts | 52 +++++++++++++++++++++++++++++++++++---------- test/client-test.js | 25 ++++++++++++++++++++++ 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/src/client.ts b/src/client.ts index 56fb4749b..e5356994f 100644 --- a/src/client.ts +++ b/src/client.ts @@ -58,7 +58,7 @@ export class Client extends EventEmitter { private wsdl: WSDL; private httpClient: HttpClient; - private soapHeaders: string[]; + private soapHeaders: any[]; private httpHeaders: IHeaders; private bodyAttributes: string[]; private endpoint: string; @@ -82,23 +82,19 @@ export class Client extends EventEmitter { } /** add soapHeader to soap:Header node */ - public addSoapHeader(soapHeader: any, name?: string, namespace?: string, xmlns?: string): number { + public addSoapHeader(soapHeader: any, name?: string, namespace?: any, xmlns?: string): number { if (!this.soapHeaders) { this.soapHeaders = []; } - if (typeof soapHeader === 'object') { - soapHeader = this.wsdl.objectToXML(soapHeader, name, namespace, xmlns, true); - } + soapHeader = this._processSoapHeader(soapHeader, name, namespace, xmlns); return this.soapHeaders.push(soapHeader) - 1; } - public changeSoapHeader(index: number, soapHeader: any, name?: string, namespace?: string, xmlns?: string): void { + public changeSoapHeader(index: any, soapHeader: any, name?: any, namespace?: any, xmlns?: any): void { if (!this.soapHeaders) { this.soapHeaders = []; } - if (typeof soapHeader === 'object') { - soapHeader = this.wsdl.objectToXML(soapHeader, name, namespace, xmlns, true); - } + soapHeader = this._processSoapHeader(soapHeader, name, namespace, xmlns); this.soapHeaders[index] = soapHeader; } @@ -246,6 +242,28 @@ export class Client extends EventEmitter { }; } + private _processSoapHeader(soapHeader, name, namespace, xmlns) { + switch (typeof soapHeader) { + case 'object': + return this.wsdl.objectToXML(soapHeader, name, namespace, xmlns, true); + case 'function': + const _this = this; + // arrow function does not support arguments variable + // tslint:disable-next-line + return function() { + const result = soapHeader.apply(null, arguments); + + if (typeof result === 'object') { + return _this.wsdl.objectToXML(result, name, namespace, xmlns, true); + } else { + return result; + } + }; + default: + return soapHeader; + } + } + private _invoke(method: OperationElement, args, location: string, callback, options, extraHeaders) { const name = method.$name; const input = method.input; @@ -373,16 +391,28 @@ export class Client extends EventEmitter { // pass `input.$lookupType` if `input.$type` could not be found message = this.wsdl.objectToDocumentXML(input.$name, args, input.targetNSAlias, input.targetNamespace, (input.$type || input.$lookupType)); } + + let decodedHeaders; + if (this.soapHeaders) { + decodedHeaders = this.soapHeaders.map((header) => { + if (typeof header === 'function') { + return header(method, location, soapAction, args); + } else { + return header; + } + }).join('\n'); + } + xml = '' + '<' + envelopeKey + ':Envelope ' + xmlnsSoap + ' ' + 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' + encoding + this.wsdl.xmlnsInEnvelope + '>' + - ((this.soapHeaders || this.security) ? + ((decodedHeaders || this.security) ? ( '<' + envelopeKey + ':Header>' + - (this.soapHeaders ? this.soapHeaders.join('\n') : '') + + (decodedHeaders ? decodedHeaders : '') + (this.security && !this.security.postProcess ? this.security.toXML() : '') + '' ) diff --git a/test/client-test.js b/test/client-test.js index c1c1bfda2..44352482e 100644 --- a/test/client-test.js +++ b/test/client-test.js @@ -521,6 +521,31 @@ var fs = require('fs'), }); }); + it('should add dynamic soap headers', function (done) { + soap.createClient(__dirname + '/wsdl/default_namespace.wsdl', meta.options, function (err, client) { + assert.ok(client); + assert.ok(!client.getSoapHeaders()); + let random; + function dynamicHeader(method, location, soapAction, args) { + random = Math.floor(Math.random() * 65536); + return { + TeSt_location: location, + TeSt_action: soapAction, + TeSt_random: random + }; + } + + client.addSoapHeader(dynamicHeader); + assert.ok(typeof client.getSoapHeaders()[0] === 'function'); + client.MyOperation({}, function (err, result) { + assert.notEqual(client.lastRequest.indexOf('http://www.example.com/v1'), -1); + assert.notEqual(client.lastRequest.indexOf('MyOperation'), -1); + assert.notEqual(client.lastRequest.indexOf(`${random}`), -1); + done(); + }); + }); + }); + it('should add soap headers with a namespace', function (done) { soap.createClient(__dirname + '/wsdl/default_namespace.wsdl', meta.options, function (err, client) { assert.ok(client);