soap 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +585 -560
- package/eslint.config.mjs +15 -0
- package/lib/client.d.ts +1 -2
- package/lib/client.js +80 -49
- package/lib/client.js.map +1 -1
- package/lib/http.d.ts +2 -4
- package/lib/http.js +28 -15
- package/lib/http.js.map +1 -1
- package/lib/nscontext.js +5 -3
- package/lib/nscontext.js.map +1 -1
- package/lib/security/BasicAuthSecurity.js +18 -8
- package/lib/security/BasicAuthSecurity.js.map +1 -1
- package/lib/security/BearerSecurity.js +17 -7
- package/lib/security/BearerSecurity.js.map +1 -1
- package/lib/security/ClientSSLSecurity.d.ts +0 -1
- package/lib/security/ClientSSLSecurity.js +18 -8
- package/lib/security/ClientSSLSecurity.js.map +1 -1
- package/lib/security/ClientSSLSecurityPFX.d.ts +0 -1
- package/lib/security/ClientSSLSecurityPFX.js +17 -7
- package/lib/security/ClientSSLSecurityPFX.js.map +1 -1
- package/lib/security/NTLMSecurity.js +17 -7
- package/lib/security/NTLMSecurity.js.map +1 -1
- package/lib/security/WSSecurity.js +36 -24
- package/lib/security/WSSecurity.js.map +1 -1
- package/lib/security/WSSecurityCert.js +22 -23
- package/lib/security/WSSecurityCert.js.map +1 -1
- package/lib/security/WSSecurityCertWithToken.d.ts +0 -1
- package/lib/security/WSSecurityCertWithToken.js +26 -22
- package/lib/security/WSSecurityCertWithToken.js.map +1 -1
- package/lib/security/WSSecurityPlusCert.js.map +1 -1
- package/lib/security/index.js.map +1 -1
- package/lib/server.d.ts +0 -2
- package/lib/server.js +64 -63
- package/lib/server.js.map +1 -1
- package/lib/soap.js +21 -16
- package/lib/soap.js.map +1 -1
- package/lib/types.d.ts +2 -2
- package/lib/utils.d.ts +0 -1
- package/lib/utils.js +25 -20
- package/lib/utils.js.map +1 -1
- package/lib/wsdl/elements.d.ts +1 -0
- package/lib/wsdl/elements.js +88 -166
- package/lib/wsdl/elements.js.map +1 -1
- package/lib/wsdl/index.js +59 -69
- package/lib/wsdl/index.js.map +1 -1
- package/package.json +15 -12
- package/tsconfig.json +6 -8
- package/index.js +0 -3
- package/soap-stub.js +0 -146
- package/tslint.json +0 -24
package/Readme.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# SOAP client and server for node.js.
|
|
6
6
|
|
|
7
|
-
This module lets you connect to web services using SOAP.
|
|
7
|
+
This module lets you connect to web services using SOAP. It also provides a server that allows you to run your own SOAP services.
|
|
8
8
|
|
|
9
9
|
<!-- Run `npm run toc` to update below section -->
|
|
10
10
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
|
@@ -16,8 +16,8 @@ This module lets you connect to web services using SOAP. It also provides a ser
|
|
|
16
16
|
- [Module](#module)
|
|
17
17
|
- [soap.createClient(url[, options], callback) - create a new SOAP client from a WSDL url. Also supports a local filesystem path.](#soapcreateclienturl-options-callback---create-a-new-soap-client-from-a-wsdl-url-also-supports-a-local-filesystem-path)
|
|
18
18
|
- [soap.createClientAsync(url[, options]) - create a new SOAP client from a WSDL url. Also supports a local filesystem path.](#soapcreateclientasyncurl-options---create-a-new-soap-client-from-a-wsdl-url-also-supports-a-local-filesystem-path)
|
|
19
|
-
- [soap.listen(
|
|
20
|
-
- [soap.listen(
|
|
19
|
+
- [soap.listen(_server_, _path_, _services_, _wsdl_, _callback_) - create a new SOAP server that listens on _path_ and provides _services_.](#soaplistenserver-path-services-wsdl-callback---create-a-new-soap-server-that-listens-on-path-and-provides-services)
|
|
20
|
+
- [soap.listen(_server_, _options_) - create a new SOAP server that listens on _path_ and provides _services_.](#soaplistenserver-options---create-a-new-soap-server-that-listens-on-path-and-provides-services)
|
|
21
21
|
- [Server Logging](#server-logging)
|
|
22
22
|
- [Server Events](#server-events)
|
|
23
23
|
- [Server Response on one-way calls](#server-response-on-one-way-calls)
|
|
@@ -30,11 +30,11 @@ This module lets you connect to web services using SOAP. It also provides a ser
|
|
|
30
30
|
- [Client](#client)
|
|
31
31
|
- [Client.describe() - description of services, ports and methods as a JavaScript object](#clientdescribe---description-of-services-ports-and-methods-as-a-javascript-object)
|
|
32
32
|
- [Client.setSecurity(security) - use the specified security protocol](#clientsetsecuritysecurity---use-the-specified-security-protocol)
|
|
33
|
-
- [Client
|
|
34
|
-
- [Client.*method*Async(args, options) - call
|
|
35
|
-
- [Client
|
|
33
|
+
- [Client._method_(args, callback, options) - call _method_ on the SOAP service.](#clientmethodargs-callback-options---call-method-on-the-soap-service)
|
|
34
|
+
- [Client.*method*Async(args, options) - call _method_ on the SOAP service.](#clientmethodasyncargs-options---call-method-on-the-soap-service)
|
|
35
|
+
- [Client._service_._port_._method_(args, callback[, options[, extraHeaders]]) - call a _method_ using a specific _service_ and _port_](#clientserviceportmethodargs-callback-options-extraheaders---call-a-method-using-a-specific-service-and-port)
|
|
36
36
|
- [Overriding the namespace prefix](#overriding-the-namespace-prefix)
|
|
37
|
-
- [Client
|
|
37
|
+
- [Client._lastRequest_ - the property that contains last full soap request for client logging](#clientlastrequest---the-property-that-contains-last-full-soap-request-for-client-logging)
|
|
38
38
|
- [Client.setEndpoint(url) - overwrite the SOAP service endpoint address](#clientsetendpointurl---overwrite-the-soap-service-endpoint-address)
|
|
39
39
|
- [Client Events](#client-events)
|
|
40
40
|
- [_request_](#_request_)
|
|
@@ -67,20 +67,18 @@ This module lets you connect to web services using SOAP. It also provides a ser
|
|
|
67
67
|
- [Changing the tag formats to use self-closing (empty element) tags](#changing-the-tag-formats-to-use-self-closing-empty-element-tags)
|
|
68
68
|
- [Handling "ignored" namespaces](#handling-ignored-namespaces)
|
|
69
69
|
- [Handling "ignoreBaseNameSpaces" attribute](#handling-ignorebasenamespaces-attribute)
|
|
70
|
-
- [soap-stub](#soap-stub)
|
|
71
|
-
- [Example](#example)
|
|
72
70
|
- [Contributors](#contributors)
|
|
73
71
|
|
|
74
72
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
|
75
73
|
|
|
76
74
|
## Features
|
|
77
75
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
76
|
+
- Very simple API
|
|
77
|
+
- Handles both RPC and Document schema types
|
|
78
|
+
- Supports multiRef SOAP messages (thanks to [@kaven276](https://github.com/kaven276))
|
|
79
|
+
- Support for both synchronous and asynchronous method handlers
|
|
80
|
+
- WS-Security UsernameToken Profile 1.0
|
|
81
|
+
- Supports [Express](http://expressjs.com/) based web server (body parser middleware can be used)
|
|
84
82
|
|
|
85
83
|
## Install
|
|
86
84
|
|
|
@@ -97,52 +95,55 @@ Paid support can be provided as well, please contact one of the active maintaine
|
|
|
97
95
|
|
|
98
96
|
### soap.createClient(url[, options], callback) - create a new SOAP client from a WSDL url. Also supports a local filesystem path.
|
|
99
97
|
|
|
100
|
-
- `url` (
|
|
101
|
-
- `options` (
|
|
102
|
-
- `endpoint` (
|
|
103
|
-
- `envelopeKey` (
|
|
104
|
-
- `preserveWhitespace` (
|
|
105
|
-
- `escapeXML` (
|
|
106
|
-
- `suppressStack` (
|
|
107
|
-
- `returnFault` (
|
|
108
|
-
- `forceSoap12Headers` (
|
|
109
|
-
- `httpClient` (
|
|
110
|
-
- `request` (
|
|
111
|
-
- `wsdl_headers` (
|
|
112
|
-
- `wsdl_options` (
|
|
113
|
-
- `disableCache` (
|
|
114
|
-
- `wsdlCache` (
|
|
115
|
-
- `overridePromiseSuffix` (
|
|
116
|
-
- `normalizeNames` (
|
|
117
|
-
- `namespaceArrayElements` (
|
|
118
|
-
- `stream` (
|
|
119
|
-
- `returnSaxStream` (
|
|
120
|
-
- `parseReponseAttachments` (
|
|
121
|
-
- `encoding` (_string_):
|
|
122
|
-
- `
|
|
123
|
-
|
|
124
|
-
- `
|
|
98
|
+
- `url` (_string_): A HTTP/HTTPS URL, XML or a local filesystem path.
|
|
99
|
+
- `options` (_Object_):
|
|
100
|
+
- `endpoint` (_string_): Override the host specified by the SOAP service in the WSDL file.
|
|
101
|
+
- `envelopeKey` (_string_): Set a custom envelope key. (**Default:** `'soap'`)
|
|
102
|
+
- `preserveWhitespace` (_boolean_): Preserve any leading and trailing whitespace characters in text and cdata.
|
|
103
|
+
- `escapeXML` (_boolean_): Escape special XML characters (e.g. `&`, `>`, `<` etc) in SOAP messages. (**Default:** `true`)
|
|
104
|
+
- `suppressStack` (_boolean_): Suppress the full stack trace for error messages.
|
|
105
|
+
- `returnFault` (_boolean_): Return an `Invalid XML` SOAP fault upon a bad request. (**Default:** `false`)
|
|
106
|
+
- `forceSoap12Headers` (_boolean_): Enable SOAP 1.2 compliance.
|
|
107
|
+
- `httpClient` (_Object_): Override the built-in HttpClient object with your own. Must implement `request(rurl, data, callback, exheaders, exoptions)`.
|
|
108
|
+
- `request` (_Object_): Override the default request module ([Axios](https://axios-http.com/) as of `v0.40.0`).
|
|
109
|
+
- `wsdl_headers` (_Object_): Set HTTP headers with values to be sent on WSDL requests.
|
|
110
|
+
- `wsdl_options` (_Object_): Set options for the request module on WSDL requests. If using the default request module, see [Request Config | Axios Docs](https://axios-http.com/docs/req_config).
|
|
111
|
+
- `disableCache` (_boolean_): Prevents caching WSDL files and option objects.
|
|
112
|
+
- `wsdlCache` (_IWSDLCache_): Custom cache implementation. If not provided, defaults to caching WSDLs indefinitely.
|
|
113
|
+
- `overridePromiseSuffix` (_string_): Override the default method name suffix of WSDL operations for Promise-based methods. If any WSDL operation name ends with `Async', you must use this option. (**Default:** `Async`)
|
|
114
|
+
- `normalizeNames` (_boolean_): Replace non-identifier characters (`[^a-z$_0-9]`) with `_` in WSDL operation names. Note: Clients using WSDLs with two operations like `soap:method` and `soap-method` will be overwritten. In this case, you must use bracket notation instead (`client['soap:method']()`).
|
|
115
|
+
- `namespaceArrayElements` (_boolean_): Support non-standard array semantics. JSON arrays of the form `{list: [{elem: 1}, {elem: 2}]}` will be marshalled into XML as `<list><elem>1</elem></list> <list><elem>2</elem></list>`. If `false`, it would be marshalled into `<list> <elem>1</elem> <elem>2</elem> </list>`. (**Default:** `true`)
|
|
116
|
+
- `stream` (_boolean_): Use streams to parse the XML SOAP responses. (**Default:** `false`)
|
|
117
|
+
- `returnSaxStream` (_boolean_): Return the SAX stream, transferring responsibility of parsing XML to the end user. Only valid when the _stream_ option is set to `true`. (**Default:** `false`)
|
|
118
|
+
- `parseReponseAttachments` (_boolean_): Treat response as multipart/related response with MTOM attachment. Reach attachments on the `lastResponseAttachments` property of SoapClient. (**Default:** `false`)
|
|
119
|
+
- `encoding` (_string_): Response data enconding, used with `parseReponseAttachments`. (**Default:** `utf8`)
|
|
120
|
+
- `forceUseSchemaXmlns` (_boolean_): Force to use schema xmlns when schema prefix not found, this is needed when schema prefix is different for the same namespace in different files, for example wsdl and in imported xsd file fir complex types (**Default** `false`)
|
|
121
|
+
- `callback` (_Function_):
|
|
122
|
+
- `err` (_Error_ | _\<AggregateError\>_)
|
|
123
|
+
- `result` (_Any_)
|
|
125
124
|
- Returns: `Client`
|
|
126
125
|
|
|
127
126
|
#### Example
|
|
128
127
|
|
|
129
128
|
HTTP/HTTPS:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
var soap = require('soap');
|
|
132
|
+
var url = 'http://example.com/wsdl?wsdl';
|
|
133
|
+
var args = { name: 'value' };
|
|
134
|
+
|
|
135
|
+
soap.createClient(url, {}, function (err, client) {
|
|
136
|
+
client.MyFunction(args, function (err, result) {
|
|
137
|
+
console.log(result);
|
|
139
138
|
});
|
|
139
|
+
});
|
|
140
140
|
```
|
|
141
141
|
|
|
142
142
|
XML string format:
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
var soap = require('soap');
|
|
146
|
+
var xml = `
|
|
146
147
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
147
148
|
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|
148
149
|
<message name="MyFunctionRequest"/>
|
|
@@ -171,169 +172,179 @@ XML string format:
|
|
|
171
172
|
</service>
|
|
172
173
|
</definitions>
|
|
173
174
|
`;
|
|
174
|
-
|
|
175
|
+
var args = { name: 'value' };
|
|
175
176
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
});
|
|
177
|
+
soap.createClient(xml, {}, function (err, client) {
|
|
178
|
+
client.MyFunction(args, function (err, result) {
|
|
179
|
+
console.log(result);
|
|
180
180
|
});
|
|
181
|
+
});
|
|
181
182
|
```
|
|
182
183
|
|
|
183
|
-
|
|
184
184
|
Note: for versions of node >0.10.X, you may need to specify `{connection: 'keep-alive'}` in SOAP headers to avoid truncation of longer chunked responses.
|
|
185
185
|
|
|
186
186
|
### soap.createClientAsync(url[, options]) - create a new SOAP client from a WSDL url. Also supports a local filesystem path.
|
|
187
187
|
|
|
188
188
|
Construct a `Promise<Client>` with the given WSDL file.
|
|
189
189
|
|
|
190
|
-
- `url` (
|
|
191
|
-
- `options` (
|
|
190
|
+
- `url` (_string_): A HTTP/HTTPS URL, XML or a local filesystem path.
|
|
191
|
+
- `options` (_Object_): See [soap.createClient(url[, options], callback)](#soapcreateclienturl-options-callback---create-a-new-soap-client-from-a-wsdl-url-also-supports-a-local-filesystem-path) for a description.
|
|
192
192
|
- Returns: `Promise<Client>`
|
|
193
193
|
|
|
194
194
|
#### Example
|
|
195
195
|
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
196
|
+
```javascript
|
|
197
|
+
var soap = require('soap');
|
|
198
|
+
var url = 'http://example.com/wsdl?wsdl';
|
|
199
|
+
var args = { name: 'value' };
|
|
200
|
+
|
|
201
|
+
// then/catch
|
|
202
|
+
soap
|
|
203
|
+
.createClientAsync(url)
|
|
204
|
+
.then((client) => {
|
|
203
205
|
return client.MyFunctionAsync(args);
|
|
204
|
-
})
|
|
206
|
+
})
|
|
207
|
+
.then((result) => {
|
|
205
208
|
console.log(result);
|
|
206
209
|
});
|
|
207
210
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
211
|
+
// async/await
|
|
212
|
+
var client = await soap.createClientAsync(url);
|
|
213
|
+
var result = await client.MyFunctionAsync(args);
|
|
214
|
+
console.log(result[0]);
|
|
212
215
|
```
|
|
213
216
|
|
|
214
217
|
Note: for versions of node >0.10.X, you may need to specify `{connection: 'keep-alive'}` in SOAP headers to avoid truncation of longer chunked responses.
|
|
215
218
|
|
|
216
|
-
### soap.listen(
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
- `
|
|
221
|
-
- `
|
|
222
|
-
|
|
223
|
-
- `
|
|
224
|
-
- `
|
|
225
|
-
- `
|
|
226
|
-
- `
|
|
227
|
-
- `
|
|
228
|
-
- `
|
|
229
|
-
- `
|
|
230
|
-
- `
|
|
231
|
-
- `
|
|
232
|
-
- `
|
|
233
|
-
- `
|
|
234
|
-
- `
|
|
235
|
-
- `
|
|
236
|
-
- `
|
|
219
|
+
### soap.listen(_server_, _path_, _services_, _wsdl_, _callback_) - create a new SOAP server that listens on _path_ and provides _services_.
|
|
220
|
+
|
|
221
|
+
### soap.listen(_server_, _options_) - create a new SOAP server that listens on _path_ and provides _services_.
|
|
222
|
+
|
|
223
|
+
- `server` (_Object_): A [http](https://nodejs.org/api/http.html) server or [Express](http://expressjs.com/) framework based server.
|
|
224
|
+
- `path` (_string_)
|
|
225
|
+
- `options` (_Object_): An object containing _server options_ and [WSDL Options](#handling-xml-attributes-value-and-xml-wsdloptions)
|
|
226
|
+
- `path` (_string_)
|
|
227
|
+
- `services` (_Object_)
|
|
228
|
+
- `xml` (_string_)
|
|
229
|
+
- `uri` (_string_)
|
|
230
|
+
- `pfx` (_string_ | _Buffer_): The private key, certificate and CA certs of the server in PFX or PKCS12 format. (Mutually exclusive with the key, cert and ca options.)
|
|
231
|
+
- `key` (_string_ | _Buffer_): The private key of the server in PEM format. (Could be an array of keys). (Required)
|
|
232
|
+
- `passphrase` (_string_): The passphrase for the private key or pfx.
|
|
233
|
+
- `cert` (_string_ | _Buffer_): The certificate key of the server in PEM format. (Could be an array of certs). (Required)
|
|
234
|
+
- `ca` (_string[]_ | _Buffer[]_): Trusted certificates in PEM format. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections.
|
|
235
|
+
- `crl` (_string_ | _string[]_: PEM encoded CRLs (Certificate Revocation List)
|
|
236
|
+
- `ciphers` (_string_): A description of the ciphers to use or exclude, separated by `:`. The default cipher suite is:
|
|
237
|
+
- `enableChunkedEncoding` (_boolean_): Controls chunked transfer encoding in response. Some clients (such as Windows 10's MDM enrollment SOAP client) are sensitive to transfer-encoding mode and can't accept chunked response. This option lets users disable chunked transfer encoding for such clients. (**Default:** `true`)
|
|
238
|
+
- `services` (_Object_)
|
|
239
|
+
- `wsdl` (_string_): An XML string that defines the service.
|
|
240
|
+
- `callback` (_Function_): A function to run after the server has been initialized.
|
|
237
241
|
- Returns: `Server`
|
|
238
242
|
|
|
239
243
|
#### Example
|
|
240
244
|
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
// This is how to define an asynchronous function with a callback.
|
|
252
|
-
MyAsyncFunction: function(args, callback) {
|
|
253
|
-
// do some work
|
|
254
|
-
callback({
|
|
255
|
-
name: args.name
|
|
256
|
-
});
|
|
257
|
-
},
|
|
258
|
-
|
|
259
|
-
// This is how to define an asynchronous function with a Promise.
|
|
260
|
-
MyPromiseFunction: function(args) {
|
|
261
|
-
return new Promise((resolve) => {
|
|
262
|
-
// do some work
|
|
263
|
-
resolve({
|
|
264
|
-
name: args.name
|
|
265
|
-
});
|
|
266
|
-
});
|
|
267
|
-
},
|
|
268
|
-
|
|
269
|
-
// This is how to receive incoming headers
|
|
270
|
-
HeadersAwareFunction: function(args, cb, headers) {
|
|
271
|
-
return {
|
|
272
|
-
name: headers.Token
|
|
273
|
-
};
|
|
274
|
-
},
|
|
275
|
-
|
|
276
|
-
// You can also inspect the original `req`
|
|
277
|
-
reallyDetailedFunction: function(args, cb, headers, req) {
|
|
278
|
-
console.log('SOAP `reallyDetailedFunction` request from ' + req.connection.remoteAddress);
|
|
279
|
-
return {
|
|
280
|
-
name: headers.Token
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
};
|
|
245
|
+
```javascript
|
|
246
|
+
var myService = {
|
|
247
|
+
MyService: {
|
|
248
|
+
MyPort: {
|
|
249
|
+
MyFunction: function (args) {
|
|
250
|
+
return {
|
|
251
|
+
name: args.name,
|
|
252
|
+
};
|
|
253
|
+
},
|
|
286
254
|
|
|
287
|
-
|
|
255
|
+
// This is how to define an asynchronous function with a callback.
|
|
256
|
+
MyAsyncFunction: function (args, callback) {
|
|
257
|
+
// do some work
|
|
258
|
+
callback({
|
|
259
|
+
name: args.name,
|
|
260
|
+
});
|
|
261
|
+
},
|
|
288
262
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
263
|
+
// This is how to define an asynchronous function with a Promise.
|
|
264
|
+
MyPromiseFunction: function (args) {
|
|
265
|
+
return new Promise((resolve) => {
|
|
266
|
+
// do some work
|
|
267
|
+
resolve({
|
|
268
|
+
name: args.name,
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
},
|
|
293
272
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
273
|
+
// This is how to receive incoming headers
|
|
274
|
+
HeadersAwareFunction: function (args, cb, headers) {
|
|
275
|
+
return {
|
|
276
|
+
name: headers.Token,
|
|
277
|
+
};
|
|
278
|
+
},
|
|
298
279
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
280
|
+
// You can also inspect the original `req`
|
|
281
|
+
reallyDetailedFunction: function (args, cb, headers, req) {
|
|
282
|
+
console.log('SOAP `reallyDetailedFunction` request from ' + req.connection.remoteAddress);
|
|
283
|
+
return {
|
|
284
|
+
name: headers.Token,
|
|
285
|
+
};
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
var xml = require('fs').readFileSync('myservice.wsdl', 'utf8');
|
|
292
|
+
|
|
293
|
+
//http server example
|
|
294
|
+
var server = http.createServer(function (request, response) {
|
|
295
|
+
response.end('404: Not Found: ' + request.url);
|
|
296
|
+
});
|
|
310
297
|
|
|
298
|
+
server.listen(8000);
|
|
299
|
+
soap.listen(server, '/wsdl', myService, xml, function () {
|
|
300
|
+
console.log('server initialized');
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
//express server example
|
|
304
|
+
var app = express();
|
|
305
|
+
//body parser middleware are supported (optional)
|
|
306
|
+
app.use(
|
|
307
|
+
bodyParser.raw({
|
|
308
|
+
type: function () {
|
|
309
|
+
return true;
|
|
310
|
+
},
|
|
311
|
+
limit: '5mb',
|
|
312
|
+
}),
|
|
313
|
+
);
|
|
314
|
+
app.listen(8001, function () {
|
|
315
|
+
//Note: /wsdl route will be handled by soap module
|
|
316
|
+
//and all other routes & middleware will continue to work
|
|
317
|
+
soap.listen(app, '/wsdl', myService, xml, function () {
|
|
318
|
+
console.log('server initialized');
|
|
319
|
+
});
|
|
320
|
+
});
|
|
311
321
|
```
|
|
312
322
|
|
|
313
|
-
```
|
|
323
|
+
```javascript
|
|
314
324
|
var xml = require('fs').readFileSync('myservice.wsdl', 'utf8');
|
|
315
325
|
|
|
316
326
|
soap.listen(server, {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
327
|
+
// Server options.
|
|
328
|
+
path: '/wsdl',
|
|
329
|
+
services: myService,
|
|
330
|
+
xml: xml,
|
|
331
|
+
|
|
332
|
+
// WSDL options.
|
|
333
|
+
attributesKey: 'theAttrs',
|
|
334
|
+
valueKey: 'theVal',
|
|
335
|
+
xmlKey: 'theXml',
|
|
326
336
|
});
|
|
327
337
|
```
|
|
328
338
|
|
|
329
339
|
### Server Logging
|
|
330
340
|
|
|
331
341
|
If the `log` method is defined, it will be called with:
|
|
342
|
+
|
|
332
343
|
- `type`: 'received', 'replied', 'info' or 'error'.
|
|
333
344
|
- `data`: The data to be logged which will be an XML for 'received' and 'replied' or a message for the other types.
|
|
334
345
|
- `req`: The original request object
|
|
335
346
|
|
|
336
|
-
```
|
|
347
|
+
```javascript
|
|
337
348
|
server = soap.listen(...)
|
|
338
349
|
server.log = function(type, data, req) {
|
|
339
350
|
// type is 'received', 'replied', 'info' or 'error'
|
|
@@ -344,11 +355,11 @@ If the `log` method is defined, it will be called with:
|
|
|
344
355
|
|
|
345
356
|
Server instances emit the following events:
|
|
346
357
|
|
|
347
|
-
|
|
358
|
+
- request - Emitted for every received messages.
|
|
348
359
|
The signature of the callback is `function(request, methodName)`.
|
|
349
|
-
|
|
360
|
+
- response - Emitted before sending SOAP response.
|
|
350
361
|
The signature of the callback is `function(response, methodName)`.
|
|
351
|
-
|
|
362
|
+
- headers - Emitted when the SOAP Headers are not empty.
|
|
352
363
|
The signature of the callback is `function(headers, methodName)`.
|
|
353
364
|
|
|
354
365
|
The sequence order of the calls is `request`, `headers` and then the dedicated
|
|
@@ -369,31 +380,31 @@ Pass in `oneWay` object in server options. Use the following keys:
|
|
|
369
380
|
A service method can reply with a SOAP Fault to a client by `throw`ing an
|
|
370
381
|
object with a `Fault` property.
|
|
371
382
|
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
383
|
+
```javascript
|
|
384
|
+
throw {
|
|
385
|
+
Fault: {
|
|
386
|
+
Code: {
|
|
387
|
+
Value: 'soap:Sender',
|
|
388
|
+
Subcode: { value: 'rpc:BadArguments' },
|
|
389
|
+
},
|
|
390
|
+
Reason: { Text: 'Processing Error' },
|
|
391
|
+
},
|
|
392
|
+
};
|
|
382
393
|
```
|
|
383
394
|
|
|
384
|
-
To change the HTTP statusCode of the response include it on the fault.
|
|
395
|
+
To change the HTTP statusCode of the response include it on the fault. The statusCode property will not be put on the xml message.
|
|
385
396
|
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
+
```javascript
|
|
398
|
+
throw {
|
|
399
|
+
Fault: {
|
|
400
|
+
Code: {
|
|
401
|
+
Value: 'soap:Sender',
|
|
402
|
+
Subcode: { value: 'rpc:BadArguments' },
|
|
403
|
+
},
|
|
404
|
+
Reason: { Text: 'Processing Error' },
|
|
405
|
+
statusCode: 500,
|
|
406
|
+
},
|
|
407
|
+
};
|
|
397
408
|
```
|
|
398
409
|
|
|
399
410
|
### Server security example using PasswordDigest
|
|
@@ -401,7 +412,8 @@ To change the HTTP statusCode of the response include it on the fault. The stat
|
|
|
401
412
|
If `server.authenticate` is not defined then no authentication will take place.
|
|
402
413
|
|
|
403
414
|
Asynchronous authentication:
|
|
404
|
-
|
|
415
|
+
|
|
416
|
+
```javascript
|
|
405
417
|
server = soap.listen(...)
|
|
406
418
|
server.authenticate = function(security, callback) {
|
|
407
419
|
var created, nonce, password, user, token;
|
|
@@ -420,7 +432,8 @@ Asynchronous authentication:
|
|
|
420
432
|
```
|
|
421
433
|
|
|
422
434
|
Synchronous authentication:
|
|
423
|
-
|
|
435
|
+
|
|
436
|
+
```javascript
|
|
424
437
|
server = soap.listen(...)
|
|
425
438
|
server.authenticate = function(security) {
|
|
426
439
|
var created, nonce, password, user, token;
|
|
@@ -436,21 +449,20 @@ The `server.authorizeConnection` method is called prior to the soap service meth
|
|
|
436
449
|
If the method is defined and returns `false` then the incoming connection is
|
|
437
450
|
terminated.
|
|
438
451
|
|
|
439
|
-
```
|
|
452
|
+
```javascript
|
|
440
453
|
server = soap.listen(...)
|
|
441
454
|
server.authorizeConnection = function(req) {
|
|
442
455
|
return true; // or false
|
|
443
456
|
};
|
|
444
457
|
```
|
|
445
458
|
|
|
446
|
-
|
|
447
459
|
## SOAP Headers
|
|
448
460
|
|
|
449
461
|
### Received SOAP Headers
|
|
450
462
|
|
|
451
463
|
A service method can look at the SOAP headers by providing a 3rd arguments.
|
|
452
464
|
|
|
453
|
-
```
|
|
465
|
+
```javascript
|
|
454
466
|
{
|
|
455
467
|
HeadersAwareFunction: function(args, cb, headers) {
|
|
456
468
|
return {
|
|
@@ -464,7 +476,7 @@ It is also possible to subscribe to the 'headers' event.
|
|
|
464
476
|
The event is triggered before the service method is called, and only when the
|
|
465
477
|
SOAP Headers are not empty.
|
|
466
478
|
|
|
467
|
-
```
|
|
479
|
+
```javascript
|
|
468
480
|
server = soap.listen(...)
|
|
469
481
|
server.on('headers', function(headers, methodName) {
|
|
470
482
|
// It is possible to change the value of the headers
|
|
@@ -482,20 +494,21 @@ second parameter is the name of the SOAP method that will called
|
|
|
482
494
|
Both client & server can define SOAP headers that will be added to what they send.
|
|
483
495
|
They provide the following methods to manage the headers.
|
|
484
496
|
|
|
497
|
+
#### _addSoapHeader_(soapHeader[, name, namespace, xmlns]) - add soapHeader to soap:Header node
|
|
485
498
|
|
|
486
|
-
#### *addSoapHeader*(soapHeader[, name, namespace, xmlns]) - add soapHeader to soap:Header node
|
|
487
499
|
##### Parameters
|
|
488
|
-
|
|
489
|
-
|
|
500
|
+
|
|
501
|
+
- `soapHeader` Object({rootName: {name: 'value'}}), strict xml-string,
|
|
502
|
+
or function (server only)
|
|
490
503
|
|
|
491
504
|
For servers only, `soapHeader` can be a function, which allows headers to be
|
|
492
505
|
dynamically generated from information in the request. This function will be
|
|
493
506
|
called with the following arguments for each received request:
|
|
494
507
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
508
|
+
- `methodName` The name of the request method
|
|
509
|
+
- `args` The arguments of the request
|
|
510
|
+
- `headers` The headers in the request
|
|
511
|
+
- `req` The original request object
|
|
499
512
|
|
|
500
513
|
The return value of the function must be an Object({rootName: {name: 'value'}})
|
|
501
514
|
or strict xml-string, which will be inserted as an outgoing header of the
|
|
@@ -503,7 +516,7 @@ response to that request.
|
|
|
503
516
|
|
|
504
517
|
For example:
|
|
505
518
|
|
|
506
|
-
```
|
|
519
|
+
```javascript
|
|
507
520
|
server = soap.listen(...);
|
|
508
521
|
server.addSoapHeader(function(methodName, args, headers, req) {
|
|
509
522
|
console.log('Adding headers for method', methodName);
|
|
@@ -516,58 +529,62 @@ For example:
|
|
|
516
529
|
```
|
|
517
530
|
|
|
518
531
|
##### Returns
|
|
532
|
+
|
|
519
533
|
The index where the header is inserted.
|
|
520
534
|
|
|
521
535
|
##### Optional parameters when first arg is object :
|
|
522
|
-
- `name` Unknown parameter (it could just a empty string)
|
|
523
|
-
- `namespace` prefix of xml namespace
|
|
524
|
-
- `xmlns` URI
|
|
525
536
|
|
|
526
|
-
|
|
537
|
+
- `name` Unknown parameter (it could just a empty string)
|
|
538
|
+
- `namespace` prefix of xml namespace
|
|
539
|
+
- `xmlns` URI
|
|
540
|
+
|
|
541
|
+
#### _changeSoapHeader_(index, soapHeader[, name, namespace, xmlns]) - change an already existing soapHeader
|
|
542
|
+
|
|
527
543
|
##### Parameters
|
|
528
|
-
- `index` index of the header to replace with provided new value
|
|
529
|
-
- `soapHeader` Object({rootName: {name: 'value'}}), strict xml-string
|
|
530
|
-
or function (server only)
|
|
531
544
|
|
|
532
|
-
|
|
545
|
+
- `index` index of the header to replace with provided new value
|
|
546
|
+
- `soapHeader` Object({rootName: {name: 'value'}}), strict xml-string
|
|
547
|
+
or function (server only)
|
|
533
548
|
|
|
534
|
-
|
|
549
|
+
See `addSoapHeader` for how to pass a function into `soapHeader`.
|
|
535
550
|
|
|
536
|
-
####
|
|
551
|
+
#### _getSoapHeaders_() - return all defined headers
|
|
537
552
|
|
|
553
|
+
#### _clearSoapHeaders_() - remove all defined headers
|
|
538
554
|
|
|
539
555
|
## Client
|
|
540
556
|
|
|
541
|
-
An instance of `Client` is passed to the `soap.createClient` callback.
|
|
557
|
+
An instance of `Client` is passed to the `soap.createClient` callback. It is used to execute methods on the soap service.
|
|
542
558
|
|
|
543
559
|
### Client.describe() - description of services, ports and methods as a JavaScript object
|
|
544
560
|
|
|
545
|
-
```
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
}
|
|
554
|
-
}
|
|
561
|
+
```javascript
|
|
562
|
+
client.describe(); // returns
|
|
563
|
+
{
|
|
564
|
+
MyService: {
|
|
565
|
+
MyPort: {
|
|
566
|
+
MyFunction: {
|
|
567
|
+
input: {
|
|
568
|
+
name: 'string';
|
|
555
569
|
}
|
|
556
570
|
}
|
|
557
571
|
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
558
574
|
```
|
|
559
575
|
|
|
560
576
|
### Client.setSecurity(security) - use the specified security protocol
|
|
561
577
|
|
|
562
578
|
See [Security](#security) for example usage.
|
|
563
579
|
|
|
564
|
-
### Client
|
|
580
|
+
### Client._method_(args, callback, options) - call _method_ on the SOAP service.
|
|
581
|
+
|
|
582
|
+
- `args` (_Object_): Arguments that generate an XML document inside of the SOAP Body section.
|
|
583
|
+
- `callback` (_Function_)
|
|
584
|
+
- `options` (_Object_): Set options for the request module on WSDL requests. If using the default request module, see [Request Config | Axios Docs](https://axios-http.com/docs/req_config). Additional options supported by `node-soap` are documented below:
|
|
585
|
+
- `forever` (_boolean_): Enables keep-alive connections and pools them
|
|
586
|
+
- `attachments` (_Array_): array of attachment objects. This converts the request into MTOM: _headers['Content-Type']='multipart/related; type="application/xop+xml"; start= ... '_
|
|
565
587
|
|
|
566
|
-
- `args` (*Object*): Arguments that generate an XML document inside of the SOAP Body section.
|
|
567
|
-
- `callback` (*Function*)
|
|
568
|
-
- `options` (*Object*): Set options for the request module on WSDL requests. If using the default request module, see [Request Config | Axios Docs](https://axios-http.com/docs/req_config). Additional options supported by `node-soap` are documented below:
|
|
569
|
-
- `forever` (*boolean*): Enables keep-alive connections and pools them
|
|
570
|
-
- `attachments` (*Array*): array of attachment objects. This converts the request into MTOM: _headers['Content-Type']='multipart/related; type="application/xop+xml"; start= ... '_
|
|
571
588
|
```
|
|
572
589
|
[{
|
|
573
590
|
mimetype: content mimetype,
|
|
@@ -578,41 +595,43 @@ See [Security](#security) for example usage.
|
|
|
578
595
|
...
|
|
579
596
|
]
|
|
580
597
|
```
|
|
581
|
-
|
|
582
|
-
- `
|
|
598
|
+
|
|
599
|
+
- `forceMTOM` (_boolean_): Send the request as MTOM even if you don't have attachments.
|
|
600
|
+
- `forceGzip` (_boolean_): Force transfer-encoding in gzip. (**Default:** `false`)
|
|
583
601
|
|
|
584
602
|
#### Example
|
|
585
603
|
|
|
586
|
-
```
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
604
|
+
```javascript
|
|
605
|
+
client.MyFunction({ name: 'value' }, function (err, result, rawResponse, soapHeader, rawRequest) {
|
|
606
|
+
// result is a javascript object
|
|
607
|
+
// rawResponse is the raw xml response string
|
|
608
|
+
// soapHeader is the response soap header as a javascript object
|
|
609
|
+
// rawRequest is the raw xml request string
|
|
610
|
+
});
|
|
593
611
|
```
|
|
594
612
|
|
|
595
|
-
### Client.*method*Async(args, options) - call
|
|
613
|
+
### Client.*method*Async(args, options) - call _method_ on the SOAP service.
|
|
596
614
|
|
|
597
|
-
- `args` (
|
|
598
|
-
- `options` (
|
|
615
|
+
- `args` (_Object_): Arguments that generate an XML document inside of the SOAP Body section.
|
|
616
|
+
- `options` (_Object_): See [Client._method_(args, callback, options) - call _method_ on the SOAP service.](#clientmethodargs-callback-options---call-method-on-the-soap-service) for a description.
|
|
599
617
|
|
|
600
618
|
#### Example
|
|
601
619
|
|
|
602
|
-
```
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
620
|
+
```javascript
|
|
621
|
+
client.MyFunctionAsync({ name: 'value' }).then((result) => {
|
|
622
|
+
// result is a javascript array containing result, rawResponse, soapheader, and rawRequest
|
|
623
|
+
// result is a javascript object
|
|
624
|
+
// rawResponse is the raw xml response string
|
|
625
|
+
// soapHeader is the response soap header as a javascript object
|
|
626
|
+
// rawRequest is the raw xml request string
|
|
627
|
+
});
|
|
610
628
|
```
|
|
611
629
|
|
|
612
630
|
##### Example with JSON for the `args`
|
|
631
|
+
|
|
613
632
|
The example above uses `{name: 'value'}` as the args. This may generate a SOAP messages such as:
|
|
614
633
|
|
|
615
|
-
```
|
|
634
|
+
```javascript
|
|
616
635
|
<?xml version="1.0" encoding="utf-8"?>
|
|
617
636
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
618
637
|
<soapenv:Body>
|
|
@@ -623,12 +642,13 @@ The example above uses `{name: 'value'}` as the args. This may generate a SOAP m
|
|
|
623
642
|
</soapenv:Envelope>
|
|
624
643
|
```
|
|
625
644
|
|
|
626
|
-
Note that the "Request" element in the output above comes from the WSDL.
|
|
645
|
+
Note that the "Request" element in the output above comes from the WSDL. If an element in `args` contains no namespace prefix, the default namespace is assumed. Otherwise, you must add the namespace prefixes to the element names as necessary (e.g., `ns1:name`).
|
|
627
646
|
|
|
628
647
|
Currently, when supplying JSON args, elements may not contain both child elements and a text value, even though that is allowed in the XML specification.
|
|
629
648
|
|
|
630
649
|
##### Example with XML String for the `args`
|
|
631
|
-
|
|
650
|
+
|
|
651
|
+
You may pass in a fully-formed XML string instead the individual elements in JSON `args` and attributes that make up the XML. The XML string should not contain an XML declaration (e.g., `<?xml version="1.0" encoding="UTF-8"?>`) or a document type declaration (e.g., `<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">`).
|
|
632
652
|
|
|
633
653
|
```
|
|
634
654
|
var args = { _xml: "<ns1:MyRootElement xmlns:ns1="http://www.example.com/v1/ns1">
|
|
@@ -636,96 +656,95 @@ You may pass in a fully-formed XML string instead the individual elements in JSO
|
|
|
636
656
|
</ns1:MyRootElement>"
|
|
637
657
|
};
|
|
638
658
|
```
|
|
639
|
-
You must specify all of the namespaces and namespace prefixes yourself. The element(s) from the WSDL are not utilized as they were in the "Example with JSON as the `args`" example above, which automatically populated the "Request" element.
|
|
640
659
|
|
|
641
|
-
|
|
660
|
+
You must specify all of the namespaces and namespace prefixes yourself. The element(s) from the WSDL are not utilized as they were in the "Example with JSON as the `args`" example above, which automatically populated the "Request" element.
|
|
661
|
+
|
|
662
|
+
### Client._service_._port_._method_(args, callback[, options[, extraHeaders]]) - call a _method_ using a specific _service_ and _port_
|
|
642
663
|
|
|
643
|
-
- `args` (
|
|
644
|
-
- `callback` (
|
|
645
|
-
- `options` (
|
|
646
|
-
- `extraHeaders` (
|
|
664
|
+
- `args` (_Object_): Arguments that generate an XML document inside of the SOAP Body section.
|
|
665
|
+
- `callback` (_Function_)
|
|
666
|
+
- `options` (_Object_): See [Client._method_(args, callback, options) - call _method_ on the SOAP service.](#clientmethodargs-callback-options---call-method-on-the-soap-service) for a description.
|
|
667
|
+
- `extraHeaders` (_Object_): Sets HTTP headers for the WSDL request.
|
|
647
668
|
|
|
648
669
|
#### Example
|
|
649
670
|
|
|
650
|
-
```
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
671
|
+
```javascript
|
|
672
|
+
client.MyService.MyPort.MyFunction({ name: 'value' }, function (err, result) {
|
|
673
|
+
// result is a javascript object
|
|
674
|
+
});
|
|
654
675
|
```
|
|
655
676
|
|
|
656
677
|
#### Options (optional)
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
678
|
+
|
|
679
|
+
- Accepts any option that the request module accepts, see [here.](https://github.com/mikeal/request)
|
|
680
|
+
- For example, you could set a timeout of 5 seconds on the request like this:
|
|
681
|
+
|
|
682
|
+
```javascript
|
|
683
|
+
client.MyService.MyPort.MyFunction(
|
|
684
|
+
{ name: 'value' },
|
|
685
|
+
function (err, result) {
|
|
686
|
+
// result is a javascript object
|
|
687
|
+
},
|
|
688
|
+
{ timeout: 5000 },
|
|
689
|
+
);
|
|
663
690
|
```
|
|
664
691
|
|
|
665
692
|
- You can measure the elapsed time on the request by passing the time option:
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
693
|
+
|
|
694
|
+
```javascript
|
|
695
|
+
client.MyService.MyPort.MyFunction(
|
|
696
|
+
{ name: 'value' },
|
|
697
|
+
function (err, result) {
|
|
698
|
+
// client.lastElapsedTime - the elapsed time of the last request in milliseconds
|
|
699
|
+
},
|
|
700
|
+
{ time: true },
|
|
701
|
+
);
|
|
670
702
|
```
|
|
671
703
|
|
|
672
704
|
- Also, you could pass your soap request through a debugging proxy such as [Fiddler](http://www.telerik.com/fiddler) or [Betwixt](https://github.com/kdzwinel/betwixt).
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
},
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
705
|
+
|
|
706
|
+
```javascript
|
|
707
|
+
client.MyService.MyPort.MyFunction(
|
|
708
|
+
{ name: 'value' },
|
|
709
|
+
function (err, result) {
|
|
710
|
+
// client.lastElapsedTime - the elapsed time of the last request in milliseconds
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
proxy: {
|
|
714
|
+
protocol: 'https',
|
|
715
|
+
host: '127.0.0.1',
|
|
716
|
+
port: 9000,
|
|
717
|
+
auth: {
|
|
718
|
+
username: 'mikeymike',
|
|
719
|
+
password: 'rapunz3l',
|
|
720
|
+
},
|
|
721
|
+
},
|
|
722
|
+
},
|
|
723
|
+
);
|
|
687
724
|
```
|
|
688
725
|
|
|
689
726
|
- You can modify xml (string) before call:
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
const testString = "Jane"
|
|
705
|
-
xml = xml.replace("John", testString)
|
|
706
|
-
return xml;
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
// ...
|
|
710
|
-
```
|
|
711
|
-
- Asynchronous (resolves promise on async invoke of `postProcess`):
|
|
712
|
-
```javascript
|
|
713
|
-
// ...
|
|
714
|
-
client.registerUser(requestBody, {
|
|
715
|
-
postProcess: async (xml) => {
|
|
716
|
-
const testString = await new Promise(resolve => setTimeout(() => resolve("Jane"), 50));
|
|
717
|
-
xml = xml.replace("John", testString)
|
|
718
|
-
return xml;
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
// ...
|
|
722
|
-
```
|
|
727
|
+
|
|
728
|
+
```javascript
|
|
729
|
+
client.MyService.MyPort.MyFunction(
|
|
730
|
+
{ name: 'value' },
|
|
731
|
+
function (err, result) {
|
|
732
|
+
// client.lastElapsedTime - the elapsed time of the last request in milliseconds
|
|
733
|
+
},
|
|
734
|
+
{
|
|
735
|
+
postProcess: function (_xml) {
|
|
736
|
+
return _xml.replace('text', 'newtext');
|
|
737
|
+
},
|
|
738
|
+
},
|
|
739
|
+
);
|
|
740
|
+
```
|
|
723
741
|
|
|
724
742
|
#### Extra Headers (optional)
|
|
725
743
|
|
|
726
744
|
Object properties define extra HTTP headers to be sent on the request.
|
|
727
745
|
|
|
728
746
|
- Add custom User-Agent:
|
|
747
|
+
|
|
729
748
|
```javascript
|
|
730
749
|
client.addHttpHeader('User-Agent', `CustomUserAgent`);
|
|
731
750
|
```
|
|
@@ -735,57 +754,72 @@ client.addHttpHeader('User-Agent', `CustomUserAgent`);
|
|
|
735
754
|
To align method call signature with node' standard callback-last patter and event allow promisification of method calls, the following method signatures are also supported:
|
|
736
755
|
|
|
737
756
|
```javascript
|
|
738
|
-
client.MyService.MyPort.MyFunction({name: 'value'}, options, function (err, result) {
|
|
757
|
+
client.MyService.MyPort.MyFunction({ name: 'value' }, options, function (err, result) {
|
|
739
758
|
// result is a javascript object
|
|
740
|
-
})
|
|
759
|
+
});
|
|
741
760
|
|
|
742
|
-
client.MyService.MyPort.MyFunction({name: 'value'}, options, extraHeaders, function (err, result) {
|
|
761
|
+
client.MyService.MyPort.MyFunction({ name: 'value' }, options, extraHeaders, function (err, result) {
|
|
743
762
|
// result is a javascript object
|
|
744
|
-
})
|
|
763
|
+
});
|
|
745
764
|
```
|
|
746
765
|
|
|
747
766
|
### Overriding the namespace prefix
|
|
748
|
-
|
|
767
|
+
|
|
768
|
+
`node-soap` is still working out some kinks regarding namespaces. If you find that an element is given the wrong namespace prefix in the request body, you can add the prefix to it's name in the containing object. I.E.:
|
|
749
769
|
|
|
750
770
|
```javascript
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
771
|
+
client.MyService.MyPort.MyFunction(
|
|
772
|
+
{ 'ns1:name': 'value' },
|
|
773
|
+
function (err, result) {
|
|
774
|
+
// request body sent with `<ns1:name`, regardless of what the namespace should have been.
|
|
775
|
+
},
|
|
776
|
+
{ timeout: 5000 },
|
|
777
|
+
);
|
|
754
778
|
```
|
|
755
779
|
|
|
756
780
|
- Remove namespace prefix of param
|
|
757
781
|
|
|
758
782
|
```javascript
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
783
|
+
client.MyService.MyPort.MyFunction(
|
|
784
|
+
{ ':name': 'value' },
|
|
785
|
+
function (err, result) {
|
|
786
|
+
// request body sent with `<name`, regardless of what the namespace should have been.
|
|
787
|
+
},
|
|
788
|
+
{ timeout: 5000 },
|
|
789
|
+
);
|
|
762
790
|
```
|
|
763
791
|
|
|
764
|
-
### Client
|
|
792
|
+
### Client._lastRequest_ - the property that contains last full soap request for client logging
|
|
765
793
|
|
|
766
794
|
### Client.setEndpoint(url) - overwrite the SOAP service endpoint address
|
|
767
795
|
|
|
768
796
|
### Client Events
|
|
797
|
+
|
|
769
798
|
Client instances emit the following events:
|
|
770
799
|
|
|
771
800
|
### _request_
|
|
801
|
+
|
|
772
802
|
Emitted before a request is sent. The event handler has the signature `(xml, eid)`.
|
|
773
803
|
|
|
774
804
|
- _xml_ - The entire Soap request (Envelope) including headers.
|
|
775
805
|
- _eid_ - The exchange id.
|
|
776
806
|
|
|
777
807
|
### _message_
|
|
808
|
+
|
|
778
809
|
Emitted before a request is sent, but only the body is passed to the event handler. Useful if you don't want to log /store Soap headers. The event handler has the signature `(message, eid)`.
|
|
779
810
|
|
|
780
811
|
- _message_ - Soap body contents.
|
|
781
812
|
- _eid_ - The exchange id.
|
|
782
813
|
|
|
783
814
|
### _soapError_
|
|
815
|
+
|
|
784
816
|
Emitted when an erroneous response is received. Useful if you want to globally log errors. The event handler has the signature `(error, eid)`.
|
|
785
817
|
|
|
786
818
|
- _error_ - An error object which also contains the resoponse.
|
|
787
819
|
- _eid_ - The exchange id.
|
|
820
|
+
|
|
788
821
|
### _response_
|
|
822
|
+
|
|
789
823
|
Emitted after a response is received. This is emitted for all responses (both success and errors). The event handler has the signature `(body, response, eid)`
|
|
790
824
|
|
|
791
825
|
- _body_ - The SOAP response body.
|
|
@@ -802,9 +836,7 @@ By default exchange ids are generated by using node-uuid but you can use options
|
|
|
802
836
|
Example :
|
|
803
837
|
|
|
804
838
|
```javascript
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
}, {exchangeId: myExchangeId})
|
|
839
|
+
client.MyService.MyPort.MyFunction(args, function (err, result) {}, { exchangeId: myExchangeId });
|
|
808
840
|
```
|
|
809
841
|
|
|
810
842
|
## WSDL
|
|
@@ -817,18 +849,20 @@ services).
|
|
|
817
849
|
## WSDL.constructor(wsdl, baseURL, options):
|
|
818
850
|
|
|
819
851
|
Construct a WSDL instance from either the WSDL content or the URL to the WSDL.
|
|
852
|
+
|
|
820
853
|
#### Parameters
|
|
821
854
|
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
855
|
+
- wsdl: A string wSDL or an URL to the WSDL
|
|
856
|
+
- baseURL: base URL for the SOAP API
|
|
857
|
+
- options: options (see source for details), use `{}` as default.
|
|
825
858
|
|
|
826
859
|
### wsdl.xmlToObject(xml):
|
|
827
860
|
|
|
828
861
|
Unmarshal XML to object.
|
|
829
862
|
|
|
830
863
|
#### Parameters:
|
|
831
|
-
|
|
864
|
+
|
|
865
|
+
- xml: SOAP response (XML) to unmarshal
|
|
832
866
|
|
|
833
867
|
#### Returns:
|
|
834
868
|
|
|
@@ -839,16 +873,18 @@ Object containing the object types from the xml as keys.
|
|
|
839
873
|
Marshal an object to XML
|
|
840
874
|
|
|
841
875
|
#### Parameters:
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
876
|
+
|
|
877
|
+
- object: Object to marshal
|
|
878
|
+
- typeName: type (as per the wsdl) of the object
|
|
879
|
+
- namespacePrefix: namespace prefix
|
|
880
|
+
- namespaceURI: URI of the namespace
|
|
846
881
|
|
|
847
882
|
#### Returns:
|
|
848
883
|
|
|
849
884
|
XML representation of object.
|
|
850
885
|
|
|
851
886
|
#### Example:
|
|
887
|
+
|
|
852
888
|
```typescript
|
|
853
889
|
// Abstracted from a real use case
|
|
854
890
|
import { AxiosInstance } from 'axios';
|
|
@@ -888,154 +924,161 @@ async function samplePostCall(prospect: IProspectType) {
|
|
|
888
924
|
}
|
|
889
925
|
```
|
|
890
926
|
|
|
891
|
-
|
|
892
927
|
## Security
|
|
893
928
|
|
|
894
|
-
`node-soap` has several default security protocols.
|
|
895
|
-
as well.
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
929
|
+
`node-soap` has several default security protocols. You can easily add your own
|
|
930
|
+
as well. The interface is quite simple. Each protocol defines these optional methods:
|
|
931
|
+
|
|
932
|
+
- `addOptions(options)` - a method that accepts an options arg that is eventually passed directly to `request`.
|
|
933
|
+
- `addHeaders(headers)` - a method that accepts an argument with HTTP headers, to add new ones.
|
|
934
|
+
- `toXML()` - a method that returns a string of XML to be appended to the SOAP headers. Not executed if `postProcess` is also defined.
|
|
935
|
+
- `postProcess(xml, envelopeKey)` - a method that receives the the assembled request XML plus envelope key, and returns a processed string of XML. Executed before `options.postProcess`.
|
|
900
936
|
|
|
901
937
|
### BasicAuthSecurity
|
|
902
938
|
|
|
903
|
-
```
|
|
904
|
-
|
|
939
|
+
```javascript
|
|
940
|
+
client.setSecurity(new soap.BasicAuthSecurity('username', 'password'));
|
|
905
941
|
```
|
|
906
942
|
|
|
907
943
|
### BearerSecurity
|
|
908
944
|
|
|
909
|
-
```
|
|
910
|
-
|
|
945
|
+
```javascript
|
|
946
|
+
client.setSecurity(new soap.BearerSecurity('token'));
|
|
911
947
|
```
|
|
912
948
|
|
|
913
949
|
### ClientSSLSecurity
|
|
914
950
|
|
|
915
951
|
_Note_: If you run into issues using this protocol, consider passing these options
|
|
916
952
|
as default request options to the constructor:
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
953
|
+
|
|
954
|
+
- `rejectUnauthorized: false`
|
|
955
|
+
- `strictSSL: false`
|
|
956
|
+
- `secureOptions: constants.SSL_OP_NO_TLSv1_2` (this is likely needed for node >= 10.0)
|
|
920
957
|
|
|
921
958
|
If you want to reuse tls sessions, you can use the option `forever: true`.
|
|
922
959
|
|
|
923
|
-
```
|
|
924
|
-
client.setSecurity(
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
960
|
+
```javascript
|
|
961
|
+
client.setSecurity(
|
|
962
|
+
new soap.ClientSSLSecurity(
|
|
963
|
+
'/path/to/key',
|
|
964
|
+
'path/to/cert',
|
|
965
|
+
'/path/to/ca-cert' /*or an array of buffer: [fs.readFileSync('/path/to/ca-cert/1', 'utf8'),
|
|
966
|
+
'fs.readFileSync('/path/to/ca-cert/2', 'utf8')], */,
|
|
967
|
+
{
|
|
968
|
+
/*default request options like */
|
|
969
|
+
// strictSSL: true,
|
|
970
|
+
// rejectUnauthorized: false,
|
|
971
|
+
// hostname: 'some-hostname'
|
|
972
|
+
// secureOptions: constants.SSL_OP_NO_TLSv1_2,
|
|
973
|
+
// forever: true,
|
|
974
|
+
},
|
|
975
|
+
),
|
|
976
|
+
);
|
|
937
977
|
```
|
|
938
978
|
|
|
939
979
|
### ClientSSLSecurityPFX
|
|
940
980
|
|
|
941
981
|
_Note_: If you run into issues using this protocol, consider passing these options
|
|
942
982
|
as default request options to the constructor:
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
983
|
+
|
|
984
|
+
- `rejectUnauthorized: false`
|
|
985
|
+
- `strictSSL: false`
|
|
986
|
+
- `secureOptions: constants.SSL_OP_NO_TLSv1_2` (this is likely needed for node >= 10.0)
|
|
946
987
|
|
|
947
988
|
If you want to reuse tls sessions, you can use the option `forever: true`.
|
|
948
989
|
|
|
949
|
-
```
|
|
950
|
-
client.setSecurity(
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
990
|
+
```javascript
|
|
991
|
+
client.setSecurity(
|
|
992
|
+
new soap.ClientSSLSecurityPFX(
|
|
993
|
+
'/path/to/pfx/cert', // or a buffer: [fs.readFileSync('/path/to/pfx/cert', 'utf8'),
|
|
994
|
+
'path/to/optional/passphrase',
|
|
995
|
+
{
|
|
996
|
+
/*default request options like */
|
|
997
|
+
// strictSSL: true,
|
|
998
|
+
// rejectUnauthorized: false,
|
|
999
|
+
// hostname: 'some-hostname'
|
|
1000
|
+
// secureOptions: constants.SSL_OP_NO_TLSv1_2,
|
|
1001
|
+
// forever: true,
|
|
1002
|
+
},
|
|
1003
|
+
),
|
|
1004
|
+
);
|
|
961
1005
|
```
|
|
962
1006
|
|
|
963
1007
|
### WSSecurity
|
|
964
1008
|
|
|
965
1009
|
`WSSecurity` implements WS-Security. UsernameToken and PasswordText/PasswordDigest is supported.
|
|
966
1010
|
|
|
967
|
-
```
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1011
|
+
```javascript
|
|
1012
|
+
var options = {
|
|
1013
|
+
hasNonce: true,
|
|
1014
|
+
actor: 'actor',
|
|
1015
|
+
};
|
|
1016
|
+
var wsSecurity = new soap.WSSecurity('username', 'password', options);
|
|
1017
|
+
client.setSecurity(wsSecurity);
|
|
974
1018
|
```
|
|
1019
|
+
|
|
975
1020
|
the `options` object is optional and can contain the following properties:
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
1021
|
+
|
|
1022
|
+
- `passwordType`: 'PasswordDigest' or 'PasswordText' (default: `'PasswordText'`)
|
|
1023
|
+
- `hasTimeStamp`: adds Timestamp element (default: `true`)
|
|
1024
|
+
- `hasTokenCreated`: adds Created element (default: `true`)
|
|
1025
|
+
- `hasNonce`: adds Nonce element (default: `false`)
|
|
1026
|
+
- `mustUnderstand`: adds mustUnderstand=1 attribute to security tag (default: `false`)
|
|
1027
|
+
- `actor`: if set, adds Actor attribute with given value to security tag (default: `''`)
|
|
982
1028
|
|
|
983
1029
|
### WSSecurityCert
|
|
984
1030
|
|
|
985
1031
|
WS-Security X509 Certificate support.
|
|
986
1032
|
|
|
987
|
-
```
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
var wsSecurity = new soap.WSSecurityCert(privateKey, publicKey, password, options);
|
|
1007
|
-
client.setSecurity(wsSecurity);
|
|
1033
|
+
```javascript
|
|
1034
|
+
var privateKey = fs.readFileSync(privateKeyPath);
|
|
1035
|
+
var publicKey = fs.readFileSync(publicKeyPath);
|
|
1036
|
+
var password = ''; // optional password
|
|
1037
|
+
var options = {
|
|
1038
|
+
hasTimeStamp: true,
|
|
1039
|
+
additionalReferences: ['wsa:Action', 'wsa:ReplyTo', 'wsa:To'],
|
|
1040
|
+
signerOptions: {
|
|
1041
|
+
prefix: 'ds',
|
|
1042
|
+
attrs: { Id: 'Signature' },
|
|
1043
|
+
existingPrefixes: {
|
|
1044
|
+
wsse: 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd',
|
|
1045
|
+
},
|
|
1046
|
+
},
|
|
1047
|
+
};
|
|
1048
|
+
var wsSecurity = new soap.WSSecurityCert(privateKey, publicKey, password, options);
|
|
1049
|
+
client.setSecurity(wsSecurity);
|
|
1008
1050
|
```
|
|
1009
1051
|
|
|
1010
1052
|
The `options` object is optional and can contain the following properties:
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1053
|
+
|
|
1054
|
+
- `hasTimeStamp`: Includes Timestamp tags (default: `true`)
|
|
1055
|
+
- `signatureTransformations`: sets the Reference Transforms Algorithm (default ['http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#']). Type is a string array
|
|
1056
|
+
- `signatureAlgorithm`: set to `http://www.w3.org/2001/04/xmldsig-more#rsa-sha256` to use sha256
|
|
1057
|
+
- `digestAlgorithm`: set to `http://www.w3.org/2000/09/xmldsig#sha1` to use sha1 (default `http://www.w3.org/2001/04/xmlenc#sha256`)
|
|
1058
|
+
- `additionalReferences` : (optional) Array of Soap headers that need to be signed. This need to be added using `client.addSoapHeader('header')`
|
|
1059
|
+
- `excludeReferencesFromSigning`: (Optional) An array of SOAP element names to exclude from signing (e.g., `Body`, `Timestamp`, `To`, `Action`).
|
|
1060
|
+
- `signerOptions`: (optional) passes options to the XML Signer package - from (https://github.com/yaronn/xml-crypto)
|
|
1061
|
+
- `existingPrefixes`: (optional) A hash of prefixes and namespaces prefix: namespace that shouldn't be in the signature because they already exist in the xml (default: `{ 'wsse': 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' }`)
|
|
1062
|
+
- `prefix`: (optional) Adds this value as a prefix for the generated signature tags.
|
|
1063
|
+
- `attrs`: (optional) A hash of attributes and values attrName: value to add to the signature root node
|
|
1064
|
+
- `idMode`: (optional) either 'wssecurity' to generate wsse-scoped reference Id on <Body> or undefined for an unscoped reference Id
|
|
1022
1065
|
|
|
1023
1066
|
### WSSecurityPlusCert
|
|
1024
1067
|
|
|
1025
1068
|
Use WSSecurity and WSSecurityCert together.
|
|
1026
1069
|
|
|
1027
|
-
```
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1070
|
+
```javascript
|
|
1071
|
+
var wsSecurity = new soap.WSSecurity(/* see WSSecurity above */);
|
|
1072
|
+
var wsSecurityCert = new soap.WSSecurityCert(/* see WSSecurityCert above */);
|
|
1073
|
+
var wsSecurityPlusCert = new soap.WSSecurityPlusCert(wsSecurity, wsSecurityCert);
|
|
1074
|
+
client.setSecurity(wsSecurityPlusCert);
|
|
1032
1075
|
```
|
|
1033
1076
|
|
|
1034
1077
|
#### Option examples
|
|
1035
1078
|
|
|
1036
1079
|
`hasTimeStamp:true`
|
|
1037
1080
|
|
|
1038
|
-
```
|
|
1081
|
+
```xml
|
|
1039
1082
|
<soap:Header>
|
|
1040
1083
|
<wsse:Security soap:mustUnderstand="1">
|
|
1041
1084
|
<wsse:BinarySecurityToken>XXX</wsse:BinarySecurityToken>
|
|
@@ -1062,7 +1105,8 @@ Use WSSecurity and WSSecurityCert together.
|
|
|
1062
1105
|
```
|
|
1063
1106
|
|
|
1064
1107
|
`additionalReferences: ['To']`
|
|
1065
|
-
|
|
1108
|
+
|
|
1109
|
+
```XML
|
|
1066
1110
|
<soap:Header>
|
|
1067
1111
|
<To Id="To">localhost.com</To>
|
|
1068
1112
|
<wsse:Security soap:mustUnderstand="1">
|
|
@@ -1098,7 +1142,7 @@ Use WSSecurity and WSSecurityCert together.
|
|
|
1098
1142
|
|
|
1099
1143
|
`signerOptions.prefix:'ds'`
|
|
1100
1144
|
|
|
1101
|
-
```
|
|
1145
|
+
```XML
|
|
1102
1146
|
<soap:Header>
|
|
1103
1147
|
<To Id="To">localhost.com</To>
|
|
1104
1148
|
<wsse:Security soap:mustUnderstand="1">
|
|
@@ -1134,7 +1178,7 @@ Use WSSecurity and WSSecurityCert together.
|
|
|
1134
1178
|
|
|
1135
1179
|
`signerOptions.attrs:{ Id: 'signature-100', foo:'bar'}`
|
|
1136
1180
|
|
|
1137
|
-
```
|
|
1181
|
+
```xml
|
|
1138
1182
|
<soap:Header>
|
|
1139
1183
|
<wsse:Security soap:mustUnderstand="1">
|
|
1140
1184
|
<wsse:BinarySecurityToken>XXX</wsse:BinarySecurityToken>
|
|
@@ -1159,11 +1203,12 @@ Use WSSecurity and WSSecurityCert together.
|
|
|
1159
1203
|
</wsse:Security>
|
|
1160
1204
|
</soap:Header>
|
|
1161
1205
|
```
|
|
1206
|
+
|
|
1162
1207
|
### WSSecurityCertWithToken
|
|
1163
1208
|
|
|
1164
1209
|
WS-Security X509 Certificate support. Just like WSSecurityCert, except that it accepts the input properties as a single object, with two properties added `username` and `password`. Which if added, will add a UsernameToken Element to the xml security element.
|
|
1165
1210
|
|
|
1166
|
-
```
|
|
1211
|
+
```xml
|
|
1167
1212
|
<wsse:UsernameToken>
|
|
1168
1213
|
<wsse:Username>someusername</wsse:Username>
|
|
1169
1214
|
<wsse:Password>someusername's password</wsse:Password>
|
|
@@ -1173,36 +1218,44 @@ WS-Security X509 Certificate support. Just like WSSecurityCert, except that it a
|
|
|
1173
1218
|
### NTLMSecurity
|
|
1174
1219
|
|
|
1175
1220
|
Parameter invocation:
|
|
1176
|
-
|
|
1177
|
-
|
|
1221
|
+
|
|
1222
|
+
```javascript
|
|
1223
|
+
client.setSecurity(new soap.NTLMSecurity('username', 'password', 'domain', 'workstation'));
|
|
1178
1224
|
```
|
|
1225
|
+
|
|
1179
1226
|
This can also be set up with a JSON object, substituting values as appropriate, for example:
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1227
|
+
|
|
1228
|
+
```javascript
|
|
1229
|
+
var loginData = { username: 'username', password: 'password', domain: 'domain', workstation: 'workstation' };
|
|
1230
|
+
client.setSecurity(new soap.NTLMSecurity(loginData));
|
|
1183
1231
|
```
|
|
1184
1232
|
|
|
1185
1233
|
## Handling XML Attributes, Value and XML (wsdlOptions).
|
|
1234
|
+
|
|
1186
1235
|
Sometimes it is necessary to override the default behaviour of `node-soap` in order to deal with the special requirements
|
|
1187
1236
|
of your code base or a third library you use. Therefore you can use the `wsdlOptions` Object, which is passed in the
|
|
1188
1237
|
`#createClient()` method and could have any (or all) of the following contents:
|
|
1238
|
+
|
|
1189
1239
|
```javascript
|
|
1190
1240
|
var wsdlOptions = {
|
|
1191
1241
|
attributesKey: 'theAttrs',
|
|
1192
1242
|
valueKey: 'theVal',
|
|
1193
|
-
xmlKey: 'theXml'
|
|
1194
|
-
}
|
|
1243
|
+
xmlKey: 'theXml',
|
|
1244
|
+
};
|
|
1195
1245
|
```
|
|
1246
|
+
|
|
1196
1247
|
If nothing (or an empty Object `{}`) is passed to the `#createClient()` method, the `node-soap` defaults (`attributesKey: 'attributes'`, `valueKey: '$value'` and `xmlKey: '$xml'`) are used.
|
|
1197
1248
|
|
|
1198
1249
|
### Overriding the `value` key
|
|
1250
|
+
|
|
1199
1251
|
By default, `node-soap` uses `$value` as the key for any parsed XML value which may interfere with your other code as it
|
|
1200
1252
|
could be some reserved word, or the `$` in general cannot be used for a key to start with.
|
|
1201
1253
|
|
|
1202
1254
|
You can define your own `valueKey` by passing it in the `wsdl_options` to the createClient call:
|
|
1255
|
+
|
|
1203
1256
|
```javascript
|
|
1204
1257
|
var wsdlOptions = {
|
|
1205
|
-
valueKey: 'theVal'
|
|
1258
|
+
valueKey: 'theVal',
|
|
1206
1259
|
};
|
|
1207
1260
|
|
|
1208
1261
|
soap.createClient(__dirname + '/wsdl/default_namespace.wsdl', wsdlOptions, function (err, client) {
|
|
@@ -1211,9 +1264,11 @@ soap.createClient(__dirname + '/wsdl/default_namespace.wsdl', wsdlOptions, funct
|
|
|
1211
1264
|
```
|
|
1212
1265
|
|
|
1213
1266
|
### Overriding the `xml` key
|
|
1267
|
+
|
|
1214
1268
|
By default, `node-soap` uses `$xml` as the key to pass through an XML string as is; without parsing or namespacing it. It overrides all the other content that the node might have otherwise had.
|
|
1215
1269
|
|
|
1216
1270
|
For example :
|
|
1271
|
+
|
|
1217
1272
|
```javascript
|
|
1218
1273
|
{
|
|
1219
1274
|
dom: {
|
|
@@ -1232,7 +1287,9 @@ For example :
|
|
|
1232
1287
|
}
|
|
1233
1288
|
};
|
|
1234
1289
|
```
|
|
1290
|
+
|
|
1235
1291
|
could become
|
|
1292
|
+
|
|
1236
1293
|
```xml
|
|
1237
1294
|
<tns:dom>
|
|
1238
1295
|
<tns:nodeone>
|
|
@@ -1249,9 +1306,10 @@ could become
|
|
|
1249
1306
|
```
|
|
1250
1307
|
|
|
1251
1308
|
You can define your own `xmlKey` by passing it in the `wsdl_options` object to the createClient call:
|
|
1309
|
+
|
|
1252
1310
|
```javascript
|
|
1253
1311
|
var wsdlOptions = {
|
|
1254
|
-
xmlKey: 'theXml'
|
|
1312
|
+
xmlKey: 'theXml',
|
|
1255
1313
|
};
|
|
1256
1314
|
|
|
1257
1315
|
soap.createClient(__dirname + '/wsdl/default_namespace.wsdl', wsdlOptions, function (err, client) {
|
|
@@ -1260,9 +1318,10 @@ soap.createClient(__dirname + '/wsdl/default_namespace.wsdl', wsdlOptions, funct
|
|
|
1260
1318
|
```
|
|
1261
1319
|
|
|
1262
1320
|
### Overriding the `attributes` key
|
|
1321
|
+
|
|
1263
1322
|
By default, `node-soap` uses `attributes` as the key to define a nodes attributes.
|
|
1264
1323
|
|
|
1265
|
-
```
|
|
1324
|
+
```javascript
|
|
1266
1325
|
{
|
|
1267
1326
|
parentnode: {
|
|
1268
1327
|
childnode: {
|
|
@@ -1274,23 +1333,27 @@ By default, `node-soap` uses `attributes` as the key to define a nodes attribute
|
|
|
1274
1333
|
}
|
|
1275
1334
|
}
|
|
1276
1335
|
```
|
|
1336
|
+
|
|
1277
1337
|
could become
|
|
1278
|
-
|
|
1338
|
+
|
|
1339
|
+
```xml
|
|
1279
1340
|
<parentnode>
|
|
1280
1341
|
<childnode name="childsname">Value</childnode>
|
|
1281
1342
|
</parentnode>
|
|
1282
1343
|
```
|
|
1283
1344
|
|
|
1284
1345
|
However, `attributes` may be a reserved key for some systems that actually want a node called `attributes`
|
|
1346
|
+
|
|
1285
1347
|
```xml
|
|
1286
1348
|
<attributes>
|
|
1287
1349
|
</attributes>
|
|
1288
1350
|
```
|
|
1289
1351
|
|
|
1290
1352
|
You can define your own `attributesKey` by passing it in the `wsdl_options` object to the createClient call:
|
|
1353
|
+
|
|
1291
1354
|
```javascript
|
|
1292
1355
|
var wsdlOptions = {
|
|
1293
|
-
attributesKey: '$attributes'
|
|
1356
|
+
attributesKey: '$attributes',
|
|
1294
1357
|
};
|
|
1295
1358
|
|
|
1296
1359
|
soap.createClient(__dirname + '/wsdl/default_namespace.wsdl', wsdlOptions, function (err, client) {
|
|
@@ -1298,11 +1361,11 @@ soap.createClient(__dirname + '/wsdl/default_namespace.wsdl', wsdlOptions, funct
|
|
|
1298
1361
|
parentnode: {
|
|
1299
1362
|
childnode: {
|
|
1300
1363
|
$attributes: {
|
|
1301
|
-
name: 'childsname'
|
|
1364
|
+
name: 'childsname',
|
|
1302
1365
|
},
|
|
1303
|
-
$value: 'Value'
|
|
1304
|
-
}
|
|
1305
|
-
}
|
|
1366
|
+
$value: 'Value',
|
|
1367
|
+
},
|
|
1368
|
+
},
|
|
1306
1369
|
});
|
|
1307
1370
|
});
|
|
1308
1371
|
```
|
|
@@ -1341,25 +1404,30 @@ soap.createClient('https://127.0.0.1/service.wsdl', options, function(err, clien
|
|
|
1341
1404
|
```
|
|
1342
1405
|
|
|
1343
1406
|
### Specifying the exact namespace definition of the root element
|
|
1407
|
+
|
|
1344
1408
|
In rare cases, you may want to precisely control the namespace definition that is included in the root element.
|
|
1345
1409
|
|
|
1346
1410
|
You can specify the namespace definitions by setting the `overrideRootElement` key in the `wsdlOptions` like so:
|
|
1411
|
+
|
|
1347
1412
|
```javascript
|
|
1348
1413
|
var wsdlOptions = {
|
|
1349
1414
|
overrideRootElement: {
|
|
1350
1415
|
namespace: 'xmlns:tns',
|
|
1351
|
-
xmlnsAttributes: [
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1416
|
+
xmlnsAttributes: [
|
|
1417
|
+
{
|
|
1418
|
+
name: 'xmlns:ns2',
|
|
1419
|
+
value: 'http://tempuri.org/',
|
|
1420
|
+
},
|
|
1421
|
+
{
|
|
1422
|
+
name: 'xmlns:ns3',
|
|
1423
|
+
value: 'http://sillypets.com/xsd',
|
|
1424
|
+
},
|
|
1425
|
+
],
|
|
1426
|
+
},
|
|
1359
1427
|
};
|
|
1360
1428
|
```
|
|
1361
1429
|
|
|
1362
|
-
To see it in practice, have a look at the sample files in: [test/request-response-samples/
|
|
1430
|
+
To see it in practice, have a look at the sample files in: [test/request-response-samples/addPets\_\_force_namespaces](https://github.com/vpulim/node-soap/tree/master/test/request-response-samples/addPets__force_namespaces)
|
|
1363
1431
|
|
|
1364
1432
|
### Overriding element key specification in XML
|
|
1365
1433
|
|
|
@@ -1367,6 +1435,7 @@ In very rare cases ([external implementation isn't matching exactly the WSDL spe
|
|
|
1367
1435
|
you may want to override element XML keys in requests and/or responses.
|
|
1368
1436
|
|
|
1369
1437
|
You can specify the key definitions by setting the `overrideElementKey` key in the `wsdlOptions` like so:
|
|
1438
|
+
|
|
1370
1439
|
```javascript
|
|
1371
1440
|
var wsdlOptions = {
|
|
1372
1441
|
overrideElementKey: {
|
|
@@ -1377,7 +1446,7 @@ var wsdlOptions = {
|
|
|
1377
1446
|
};
|
|
1378
1447
|
```
|
|
1379
1448
|
|
|
1380
|
-
Test sample files covering this are in [test/request-response-samples/
|
|
1449
|
+
Test sample files covering this are in [test/request-response-samples/Dummy\_\_ref_element_should_have_correct_namespace_with_overrideElementKey](https://github.com/vpulim/node-soap/tree/master/test/request-response-samples/Dummy__ref_element_should_have_correct_namespace_with_overrideElementKey)
|
|
1381
1450
|
|
|
1382
1451
|
### Custom Deserializer
|
|
1383
1452
|
|
|
@@ -1387,6 +1456,7 @@ For example if the soap response contains dates that are not in a format recogni
|
|
|
1387
1456
|
To do so, you can pass a `customDeserializer` object in `options`. The properties of this object are the types that your deserializer handles itself.
|
|
1388
1457
|
|
|
1389
1458
|
Example :
|
|
1459
|
+
|
|
1390
1460
|
```javascript
|
|
1391
1461
|
|
|
1392
1462
|
var wsdlOptions = {
|
|
@@ -1417,134 +1487,89 @@ Example :
|
|
|
1417
1487
|
```
|
|
1418
1488
|
|
|
1419
1489
|
### Changing the tag formats to use self-closing (empty element) tags
|
|
1490
|
+
|
|
1420
1491
|
The XML specification specifies that there is no semantic difference between `<Tag></Tag>` and `<Tag />`, and node-soap defaults to using the `<Tag></Tag>` format. But if your web service is particular, or if there is a stylistic preference, the `useEmptyTag` option causes tags with no contents to use the `<Tag />` format instead.
|
|
1421
1492
|
|
|
1422
1493
|
```javascript
|
|
1423
1494
|
var wsdlOptions = {
|
|
1424
|
-
useEmptyTag: true
|
|
1495
|
+
useEmptyTag: true,
|
|
1425
1496
|
};
|
|
1426
1497
|
```
|
|
1427
1498
|
|
|
1428
1499
|
For example: `{ MyTag: { attributes: { MyAttr: 'value' } } }` is:
|
|
1429
1500
|
|
|
1430
|
-
|
|
1431
|
-
|
|
1501
|
+
- **Without useEmptyTag**: `<MyTag MyAttr="value"></MyTag>`
|
|
1502
|
+
- **With useEmptyTag set to true**: `<MyTag MyAttr="value" />`
|
|
1432
1503
|
|
|
1433
1504
|
## Handling "ignored" namespaces
|
|
1505
|
+
|
|
1434
1506
|
If an Element in a `schema` definition depends on an Element which is present in the same namespace, normally the `tns:`
|
|
1435
1507
|
namespace prefix is used to identify this Element. This is not much of a problem as long as you have just one `schema` defined
|
|
1436
1508
|
(inline or in a separate file). If there are more `schema` files, the `tns:` in the generated `soap` file resolved mostly to the parent `wsdl` file,
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
`node-soap` now handles namespace prefixes which shouldn't be resolved (because it's not necessary) as so called `ignoredNamespaces`
|
|
1440
|
-
which default to an Array of 3 Strings (`['tns', 'targetNamespace', 'typedNamespace']`).
|
|
1441
|
-
|
|
1442
|
-
If this is not sufficient for your purpose you can easily add more namespace prefixes to this Array, or override it in its entirety
|
|
1443
|
-
by passing an `ignoredNamespaces` object within the `options` you pass in `soap.createClient()` method.
|
|
1444
|
-
|
|
1445
|
-
A simple `ignoredNamespaces` object, which only adds certain namespaces could look like this:
|
|
1446
|
-
```
|
|
1447
|
-
var options = {
|
|
1448
|
-
ignoredNamespaces: {
|
|
1449
|
-
namespaces: ['namespaceToIgnore', 'someOtherNamespace']
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
```
|
|
1453
|
-
This would extend the `ignoredNamespaces` of the `WSDL` processor to `['tns', 'targetNamespace', 'typedNamespace', 'namespaceToIgnore', 'someOtherNamespace']`.
|
|
1454
|
-
|
|
1455
|
-
If you want to override the default ignored namespaces you would simply pass the following `ignoredNamespaces` object within the `options`:
|
|
1456
|
-
```
|
|
1457
|
-
var options = {
|
|
1458
|
-
ignoredNamespaces: {
|
|
1459
|
-
namespaces: ['namespaceToIgnore', 'someOtherNamespace'],
|
|
1460
|
-
override: true
|
|
1461
|
-
}
|
|
1462
|
-
}
|
|
1463
|
-
```
|
|
1464
|
-
This would override the default `ignoredNamespaces` of the `WSDL` processor to `['namespaceToIgnore', 'someOtherNamespace']`. (This shouldn't be necessary, anyways).
|
|
1509
|
+
which was obviously wrong.
|
|
1465
1510
|
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
but the request need only: <sendJob> set in the tree structure, you need to set the ignoreBaseNameSpaces to true. This is set because in a lot of workaround the wsdl structure is not correctly
|
|
1469
|
-
set or the webservice bring errors.
|
|
1511
|
+
`node-soap` now handles namespace prefixes which shouldn't be resolved (because it's not necessary) as so called `ignoredNamespaces`
|
|
1512
|
+
which default to an Array of 3 Strings (`['tns', 'targetNamespace', 'typedNamespace']`).
|
|
1470
1513
|
|
|
1471
|
-
|
|
1472
|
-
|
|
1514
|
+
If this is not sufficient for your purpose you can easily add more namespace prefixes to this Array, or override it in its entirety
|
|
1515
|
+
by passing an `ignoredNamespaces` object within the `options` you pass in `soap.createClient()` method.
|
|
1473
1516
|
|
|
1474
1517
|
A simple `ignoredNamespaces` object, which only adds certain namespaces could look like this:
|
|
1518
|
+
|
|
1475
1519
|
```
|
|
1476
1520
|
var options = {
|
|
1477
|
-
ignoredNamespaces:
|
|
1521
|
+
ignoredNamespaces: {
|
|
1522
|
+
namespaces: ['namespaceToIgnore', 'someOtherNamespace']
|
|
1523
|
+
}
|
|
1478
1524
|
}
|
|
1479
1525
|
```
|
|
1480
1526
|
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
Unit testing services that use soap clients can be very cumbersome. In order to get
|
|
1484
|
-
around this you can use `soap-stub` in conjunction with `sinon` to stub soap with
|
|
1485
|
-
your clients.
|
|
1486
|
-
|
|
1487
|
-
### Example
|
|
1488
|
-
|
|
1489
|
-
```javascript
|
|
1490
|
-
// test-initialization-script.js
|
|
1491
|
-
var sinon = require('sinon');
|
|
1492
|
-
var soapStub = require('soap/soap-stub');
|
|
1527
|
+
This would extend the `ignoredNamespaces` of the `WSDL` processor to `['tns', 'targetNamespace', 'typedNamespace', 'namespaceToIgnore', 'someOtherNamespace']`.
|
|
1493
1528
|
|
|
1494
|
-
|
|
1495
|
-
var clientStub = {
|
|
1496
|
-
SomeOperation: sinon.stub()
|
|
1497
|
-
};
|
|
1529
|
+
If you want to override the default ignored namespaces you would simply pass the following `ignoredNamespaces` object within the `options`:
|
|
1498
1530
|
|
|
1499
|
-
|
|
1500
|
-
|
|
1531
|
+
```
|
|
1532
|
+
var options = {
|
|
1533
|
+
ignoredNamespaces: {
|
|
1534
|
+
namespaces: ['namespaceToIgnore', 'someOtherNamespace'],
|
|
1535
|
+
override: true
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
```
|
|
1501
1539
|
|
|
1502
|
-
|
|
1540
|
+
This would override the default `ignoredNamespaces` of the `WSDL` processor to `['namespaceToIgnore', 'someOtherNamespace']`. (This shouldn't be necessary, anyways).
|
|
1503
1541
|
|
|
1504
|
-
|
|
1505
|
-
var soapStub = require('soap/soap-stub');
|
|
1542
|
+
## Handling "ignoreBaseNameSpaces" attribute
|
|
1506
1543
|
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1544
|
+
If an Element in a `schema` definition depends has a basenamespace defined but the request does not need that value, for example you have a "sentJob" with basenamespace "v20"
|
|
1545
|
+
but the request need only: <sendJob> set in the tree structure, you need to set the ignoreBaseNameSpaces to true. This is set because in a lot of workaround the wsdl structure is not correctly
|
|
1546
|
+
set or the webservice bring errors.
|
|
1510
1547
|
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
soapStub.reset();
|
|
1514
|
-
myService.init(clientStub);
|
|
1515
|
-
});
|
|
1548
|
+
By default the attribute is set to true.
|
|
1549
|
+
An example to use:
|
|
1516
1550
|
|
|
1517
|
-
|
|
1518
|
-
beforeEach(function() {
|
|
1519
|
-
clientStub.SomeOperation.respondWithError();
|
|
1520
|
-
});
|
|
1551
|
+
A simple `ignoredNamespaces` object, which only adds certain namespaces could look like this:
|
|
1521
1552
|
|
|
1522
|
-
it('should handle error responses', function() {
|
|
1523
|
-
myService.somethingThatCallsSomeOperation(function(err, response) {
|
|
1524
|
-
// handle the error response.
|
|
1525
|
-
});
|
|
1526
|
-
});
|
|
1527
|
-
});
|
|
1528
|
-
});
|
|
1529
1553
|
```
|
|
1530
|
-
|
|
1554
|
+
var options = {
|
|
1555
|
+
ignoredNamespaces: true
|
|
1556
|
+
}
|
|
1557
|
+
```
|
|
1531
1558
|
|
|
1532
1559
|
## Contributors
|
|
1533
1560
|
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1561
|
+
- Author: [Vinay Pulim](https://github.com/vpulim)
|
|
1562
|
+
- Active maintainers:
|
|
1563
|
+
- [Vasily Martynov](https://github.com/w666)
|
|
1564
|
+
- Previous maintainers (not active for a long time):
|
|
1565
|
+
- [Joe Spencer](https://github.com/jsdevel)
|
|
1566
|
+
- [Heinz Romirer](https://github.com/herom)
|
|
1567
|
+
- [All Contributors](https://github.com/vpulim/node-soap/graphs/contributors)
|
|
1541
1568
|
|
|
1542
1569
|
[downloads-image]: http://img.shields.io/npm/dm/soap.svg
|
|
1543
1570
|
[npm-url]: https://npmjs.org/package/soap
|
|
1544
1571
|
[npm-image]: http://img.shields.io/npm/v/soap.svg
|
|
1545
|
-
|
|
1546
1572
|
[coveralls-url]: https://coveralls.io/r/vpulim/node-soap
|
|
1547
1573
|
[coveralls-image]: http://img.shields.io/coveralls/vpulim/node-soap/master.svg
|
|
1548
|
-
|
|
1549
1574
|
[buy-me-a-coffee-url]: https://coff.ee/vasily.m
|
|
1550
1575
|
[buy-me-a-coffee-image]: https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png
|