Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

correctly serialize MTOM into axios data and add Content-Encoding: gzip support in soap request #1173

Merged
merged 6 commits into from
Nov 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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