ws-js
Version:
WS-* implementation for node
110 lines (72 loc) • 3.01 kB
JavaScript
var select = require('../../../xpath').SelectNodes;
var Dom = require('xmldom').DOMParser;
var utils = require('../../../utils');
var writer = require('../../../../lib/handlers/client/mtom/mime-writer.js');
var reader = require('../../../../lib/handlers/client/mtom/mime-reader.js');
require('bufferjs');
exports.MtomClientHandler = MtomClientHandler;
function MtomClientHandler() {
}
MtomClientHandler.prototype.send = function(ctx, callback) {
var self = this;
boundary = "my_unique_boundary";
var parts = [{
id: "part0",
contentType: 'application/xop+xml;charset=utf-8;type="'+ctx.contentType+'"',
encoding: "8bit"}];
var doc = new Dom().parseFromString(ctx.request);
for (var i in ctx.base64Elements) {
var file = ctx.base64Elements[i];
var elem = select(doc, file.xpath)[0];
var binary = new Buffer(elem.firstChild.data, 'base64');
var id = "part" + (parseInt(i)+1);
parts.push({id: id, contentType: file.contentType, body: binary, encoding: "binary"});
//put an xml placeholder
elem.removeChild(elem.firstChild);
utils.addElement(doc, elem, "http://www.w3.org/2004/08/xop/include", "xop:Include");
elem.firstChild.setAttribute("xmlns:xop", "http://www.w3.org/2004/08/xop/include");
elem.firstChild.setAttribute("href", "cid:" + id);
}
parts[0].body = new Buffer(doc.toString());
ctx.contentType = 'multipart/related; type="application/xop+xml";start="<part0>";boundary="'+boundary+'";start-info="'
+ ctx.contentType +'"; action="'+ctx.action+'"';
ctx.request = writer.build_multipart_body(parts, boundary);
this.next.send(
ctx,
function(ctx) {
self.receive(ctx, callback);
});
}
MtomClientHandler.prototype.receive = function(ctx, callback) {
if (!ctx.resp_contentType) {
console.log("warning: no content type in response");
callback(ctx);
return;
}
var boundary = utils.parseBoundary(ctx.resp_contentType);
//console.log("boundary: " + boundary);
//console.log("CTX Response: " + ctx.response);
//slice since in http multipart response the first chars seems to be #13#10 which the parser does not expect
var parts = reader.parse_multipart(ctx.response.slice(2), boundary);
if (parts.length==0) {
console.log("warning: no mime parts in response");
callback(ctx);
return;
}
var doc = new Dom().parseFromString(parts[0].data.toString());
for (var i in parts) {
var p = parts[i];
var id = utils.extractContentId(p.headers["content-id"] );
var xpath = "//*[@href='cid:" + encodeURIComponent(id) + "']//parent::*";
console.log("xml: " + doc.toString());
console.log("xpath: " + xpath);
var elem = select(doc, xpath)[0];
console.log("elem: " + elem);
if (!elem)
continue;
elem.removeChild(elem.firstChild);
utils.setElementValue(doc, elem, p.data.toString("base64"));
}
ctx.response = doc.toString();
callback(ctx);
}