Skip to content

Commit

Permalink
correctly serialize MTOM into axios data and add Content-Encoding: gz…
Browse files Browse the repository at this point in the history
…ip support in soap request (#1173)

* correctly serialize MTOM into axios data

* Add support to enforce gzip compression

* add forceGzip in readme for sync and async calls

* correct typo in Readme.md

* fix lint issues

* sort imports

Co-authored-by: Johannes Tödling <johannes.toedling@fluffysoft.at>
  • Loading branch information
ischisan and ischisan committed Nov 16, 2021
1 parent a69b357 commit edfe923
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
4 changes: 3 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ The `options` argument allows you to customize the client with the following pro
- returnSaxStream: enables the library to return the sax stream, transferring to the end user the responsibility of parsing the XML. It can be used only in combination with *stream* argument set to `true`. Default: `false`
- parseReponseAttachments: Treat response as multipart/related response with MTOM attachment. Reach attachments on the `lastResponseAttachments` property of SoapClient. Default: `false`

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.
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.

### soap.listen(*server*, *path*, *services*, *wsdl*, *callback*) - create a new SOAP server that listens on *path* and provides *services*.
*server* can be a [http](https://nodejs.org/api/http.html) Server or [express](http://expressjs.com/) framework based server
Expand Down Expand Up @@ -522,6 +522,7 @@ Interesting properties might be:
]
```
* `forceMTOM`: set to True if you want to send the request as MTOM even if you don't have attachments
* `forceGzip`: set to True if you want to force transfer-encoding in gzip (default: ```false```)


### Client.*method*Async(args, options) - call *method* on the SOAP service.
Expand Down Expand Up @@ -554,6 +555,7 @@ Interesting properties might be:
]
```
* `forceMTOM`: set to True if you want to send the request as MTOM even if you don't have attachments
* `forceGzip`: set to True if you want to force transfer-encoding in gzip (default: ```false```)

##### Example with JSON for the `args`
The example above uses `{name: 'value'}` as the args. This may generate a SOAP messages such as:
Expand Down
27 changes: 25 additions & 2 deletions src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ReadStream } from 'fs';
import * as url from 'url';

import { v4 as uuidv4 } from 'uuid';
import { gzipSync } from 'zlib';
import { IExOptions, IHeaders, IHttpClient, IMTOMAttachments, IOptions } from './types';
import { parseMTOMResp } from './utils';

Expand Down Expand Up @@ -100,7 +101,8 @@ export class HttpClient implements IHttpClient {
}
}
}
headers['Content-Type'] = 'multipart/related; type="application/xop+xml"; start="<' + start + '>"; start-info="text/xml"; boundary=' + uuidv4();
const boundary = uuidv4();
headers['Content-Type'] = 'multipart/related; type="application/xop+xml"; start="<' + start + '>"; type="text/xml"; boundary=' + boundary;
if (action) {
headers['Content-Type'] = headers['Content-Type'] + '; ' + action;
}
Expand All @@ -119,11 +121,32 @@ export class HttpClient implements IHttpClient {
'body': attachment.body,
});
});
// options.multipart = multipart;
options.data = `--${boundary}\r\n`;

let multipartCount = 0;
multipart.forEach((part) => {
Object.keys(part).forEach((key) => {
if (key !== 'body') {
options.data += `${key}: ${part[key]}\r\n`;
}
});
options.data += '\r\n';
options.data += `${part.body}\r\n--${boundary}${
multipartCount === multipart.length - 1 ? '--' : ''
}\r\n`;
multipartCount++;
});
} else {
options.data = data;
}

if (exoptions.forceGzip) {
options.decompress = true;
options.data = gzipSync(options.data);
options.headers['Accept-Encoding'] = 'gzip,deflate';
options.headers['Content-Encoding'] = 'gzip';
}

for (const attr in newExoptions) {
if (mergeOptions.indexOf(attr) !== -1) {
for (const header in exoptions[attr]) {
Expand Down

0 comments on commit edfe923

Please sign in to comment.