From bf84c775d247cc1e3951d3c12238a4452203d5dc Mon Sep 17 00:00:00 2001 From: Tobias Kellner Date: Fri, 14 Jun 2024 09:47:23 +0200 Subject: [PATCH 1/2] Support binary data in MTOM --- src/http.ts | 16 ++++++++++------ test/client-test.js | 4 ++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/http.ts b/src/http.ts index d9c2b94e..3eb517a7 100644 --- a/src/http.ts +++ b/src/http.ts @@ -118,21 +118,25 @@ export class HttpClient implements IHttpClient { 'body': attachment.body, }); }); - options.data = `--${boundary}\r\n`; + options.data = [Buffer.from(`--${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.push(Buffer.from(`${key}: ${part[key]}\r\n`)); } }); - options.data += '\r\n'; - options.data += `${part.body}\r\n--${boundary}${ - multipartCount === multipart.length - 1 ? '--' : '' - }\r\n`; + options.data.push( + Buffer.from('\r\n'), + Buffer.from(part.body), + Buffer.from(`\r\n--${boundary}${ + multipartCount === multipart.length - 1 ? '--' : '' + }\r\n`), + ); multipartCount++; }); + options.data = Buffer.concat(options.data); } else { options.data = data; } diff --git a/test/client-test.js b/test/client-test.js index 5dd3c67c..071191ca 100644 --- a/test/client-test.js +++ b/test/client-test.js @@ -158,7 +158,7 @@ var fs = require('fs'), mimetype: 'image/png', contentId: 'file_0', name: 'nodejs.png', - body: fs.createReadStream(__dirname + '/static/nodejs.png') + body: fs.readFileSync(__dirname + '/static/nodejs.png') }; function parsePartHeaders(part) { @@ -239,7 +239,7 @@ var fs = require('fs'), mimetype: 'image/png', contentId: 'file_0', name: 'nodejs.png', - body: fs.createReadStream(__dirname + '/static/nodejs.png') + body: fs.readFileSync(__dirname + '/static/nodejs.png') }; function parsePartHeaders(part) { From acc83c7bff074467e179b48e825fd8ac608b8948 Mon Sep 17 00:00:00 2001 From: Vasily Martynov Date: Fri, 19 Jul 2024 22:56:25 +1200 Subject: [PATCH 2/2] Add assert that request contain binary data Uncomment test code that was disabled when migrated from Request to Axios. --- test/client-test.js | 47 +++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/test/client-test.js b/test/client-test.js index 071191ca..193a62ce 100644 --- a/test/client-test.js +++ b/test/client-test.js @@ -184,6 +184,9 @@ var fs = require('fs'), const body = Buffer.concat(bufs).toString().trim(); const headers = req.headers; const boundary = headers['content-type'].match(/boundary="?([^"]*"?)/)[1]; + + assert.ok(body.includes(`PNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR`), `Body does not contain part of binary data`); + const parts = body.split(new RegExp('--' + boundary + '-{0,2}')) .filter(part => part) .map(parsePartHeaders); @@ -208,18 +211,17 @@ var fs = require('fs'), }); assert.equal(contentType.rootType, 'multipart/related'); - /* does not handle attachements */ - // assert.equal(body.parts.length, 2); + assert.equal(body.parts.length, 2); - // const dataHeaders = body.parts[0]; - // assert(dataHeaders['Content-Type'].indexOf('application/xop+xml') > -1); - // assert.equal(dataHeaders['Content-ID'], contentType.start); + const dataHeaders = body.parts[0]; + assert(dataHeaders['Content-Type'].indexOf('application/xop+xml') > -1); + assert.equal(dataHeaders['Content-ID'], contentType.start); - // const attachmentHeaders = body.parts[1]; - // assert.equal(attachmentHeaders['Content-Type'], attachment.mimetype); - // assert.equal(attachmentHeaders['Content-Transfer-Encoding'], 'binary'); - // assert.equal(attachmentHeaders['Content-ID'], '<' + attachment.contentId + '>'); - // assert(attachmentHeaders['Content-Disposition'].indexOf(attachment.name) > -1); + const attachmentHeaders = body.parts[1]; + assert.equal(attachmentHeaders['Content-Type'], attachment.mimetype); + assert.equal(attachmentHeaders['Content-Transfer-Encoding'], 'binary'); + assert.equal(attachmentHeaders['Content-ID'], '<' + attachment.contentId + '>'); + assert(attachmentHeaders['Content-Disposition'].indexOf(attachment.name) > -1); server.close(); done(); @@ -308,12 +310,11 @@ var fs = require('fs'), } }); assert.equal(contentType.rootType, 'multipart/related'); - /** does not handle attachements */ - // assert.equal(body.parts.length, 1); + assert.equal(body.parts.length, 1); - // const dataHeaders = body.parts[0]; - // assert(dataHeaders['Content-Type'].indexOf('application/xop+xml') > -1); - // assert.equal(dataHeaders['Content-ID'], contentType.start); + const dataHeaders = body.parts[0]; + assert(dataHeaders['Content-Type'].indexOf('application/xop+xml') > -1); + assert.equal(dataHeaders['Content-ID'], contentType.start); done(); }, { forceMTOM: true }) }, baseUrl) @@ -628,9 +629,9 @@ var fs = require('fs'), assert.ifError(error); const contentTypeSplit = client.lastRequestHeaders['Content-Type'].split(';'); - + assert.equal(contentTypeSplit[0], 'multipart/related'); - assert.ok(contentTypeSplit.filter(function(e) { return e.trim().startsWith('type=') }).length === 1); + assert.ok(contentTypeSplit.filter(function (e) { return e.trim().startsWith('type=') }).length === 1); done(); }, { forceMTOM: true }) @@ -1474,7 +1475,7 @@ var fs = require('fs'), soap.createClient(__dirname + '/wsdl/default_namespace.wsdl', Object.assign({ envelopeSoapUrl: 'http://example.com/v1' }, meta.options), function (err, client) { assert.ok(client); assert.ifError(err); - + client.MyOperation({}, function (err, result) { assert.notEqual(client.lastRequest.indexOf('xmlns:soap=\"http://example.com/v1\"'), -1); done(); @@ -1684,10 +1685,10 @@ xit('should add namespace to array of objects', function (done) { done(); }); }) - .catch(function (err) { + .catch(function (err) { assert.equal(err.message, 'Root element of WSDL was . This is likely an authentication issue.'); done(); - }); + }); }); @@ -1767,7 +1768,7 @@ describe('Client posting complex body', () => { return void done(err); } assert.ok(client); - + var requestBody = { id: 'ID00000000000000000000000000000000', lastName: 'Doe', @@ -1786,7 +1787,7 @@ describe('Client posting complex body', () => { companyName: 'ACME' } } - + client.registerUser(requestBody, function (err, result) { assert.ok(client.lastRequest); assert.ok(client.lastMessage); @@ -1795,7 +1796,7 @@ describe('Client posting complex body', () => { console.log(client.lastMessage); const expectedBody = 'ID00000000000000000000000000000000DoeJohn1970-01-01ENGjdoe@doe.comALLOWEDStreetCodeCityUSACME'; assert.strictEqual(client.lastMessage, expectedBody); - + done(); }); }, baseUrl);