Skip to content
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
20 changes: 14 additions & 6 deletions lib/http-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -433,19 +433,26 @@ function toJSON(input) {
}
}

function toXML(input) {
function toXML(input, options) {
var xml;
var xmlDefaultOptions = { declaration : true };

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT, this is adding another feature, which is to allow the developer to specify whether XML declaration is included in the response. I can live with the fact that it's introduced together with other changes, but please add a unit-test to verify.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit-test added.

var xmlOptions = util._extend(xmlDefaultOptions, options);
if (input && typeof input.toXML === 'function') {
xml = input.toXML();
} else {
if (input) {
if (typeof input == 'string') {
// this is a hack to handle js2xmlparser throws syntax error on string
// wraps string from "a string" to "\"a string\""
input = JSON.stringify(input);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be

input = '"' + input + '"';

couldn't it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ritch we could, but we will also need to handle escaping the double quotes in the string itself, not sure any other stuff JSON.stringify escapes, I feel JSON.stringify might be easier to maintain, any thoughts?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a unit-test to verify this case.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit-test added.

} else if (typeof input == 'object') {
// Trigger toJSON() conversions
input = toJSON(input);
}
if (Array.isArray(input)) {
input = { result: input };
}
xml = js2xmlparser('response', input, {
xml = js2xmlparser(xmlOptions.wrapperElement || 'response', input, {
declaration : { include : xmlOptions.declaration },
prettyPrinting: {
indentString: ' '
},
Expand Down Expand Up @@ -501,13 +508,14 @@ function sendBodyJsonp(res, data) {
res.jsonp(data);
}

function sendBodyXml(res, data) {
function sendBodyXml(res, data, method) {
if (data === null) {
res.header('Content-Length', '7');
res.send('<null/>');
} else if (data) {
try {
var xml = toXML(data);
var xmlOptions = method.returns[0].xml || {};
var xml = toXML(data, xmlOptions);
res.send(xml);
} catch (e) {
res.status(500).send(e + '\n' + data);
Expand Down Expand Up @@ -629,7 +637,7 @@ HttpContext.prototype.done = function(cb) {
res.header('Content-Type', operationResults.contentType);
}
if (dataExists) {
operationResults.sendBody(res, data);
operationResults.sendBody(res, data, method);
} else {
if (res.statusCode === undefined || res.statusCode === 200) {
res.statusCode = 204;
Expand Down
115 changes: 115 additions & 0 deletions test/rest.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1359,6 +1359,121 @@ describe('strong-remoting-rest', function() {
});
});

it('should allow customized xml root element', function(done) {
var method = givenSharedStaticMethod(
function bar(cb) {
cb(null, {a: 1, b: 2});
},
{
returns: {
arg: 'data', type: 'object', root: true,
xml: { wrapperElement: 'foo'}
},
http: { path: '/' }
}
);
request(app).get(method.classUrl)
.set('Accept', 'application/xml')
.set('Content-Type', 'application/json')
.send()
.expect('Content-Type', /xml/)
.expect(200, function(err, res) {
expect(res.text).to.equal(
'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n' +
'<foo>\n ' +
'<a>1</a>\n ' +
'<b>2</b>\n' +
'</foo>');
done(err, res);
});
});

it('should allow xml declaration to be disabled', function(done) {
var method = givenSharedStaticMethod(
function bar(cb) {
cb(null, {a: 1, b: 2});
},
{
returns: {
arg: 'data', type: 'object', root: true,
xml: { declaration : false }
},
http: { path: '/' }
}
);
request(app).get(method.classUrl)
.set('Accept', 'application/xml')
.set('Content-Type', 'application/json')
.send()
.expect('Content-Type', /xml/)
.expect(200, function(err, res) {
expect(res.text).to.equal(
'<response>\n ' +
'<a>1</a>\n ' +
'<b>2</b>\n' +
'</response>');
done(err, res);
});
});

it('should allow string results to output as xml', function(done) {
var method = givenSharedStaticMethod(
function bar(cb) {
var stringResult = 'a quick brown fox jumps over the lazy dog';
cb(null, stringResult);
},
{
returns: {
root: true,
xml: { wrapperElement : 'text' }
},
http: { path: '/' }
}
);
request(app).get(method.classUrl)
.set('Accept', 'application/xml')
.set('Content-Type', 'application/json')
.send()
.expect('Content-Type', /xml/)
.expect(200, function(err, res) {
expect(res.text).to.equal(
'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n' +
'<text>a quick brown fox jumps over the lazy dog' +
'</text>');
done(err, res);
});
});

it('should handle UTF-8 & special & reserved characters', function(done) {
var method = givenSharedStaticMethod(
function bar(cb) {
var stringA = 'foo\xC1\xE1\u0102\u03A9asd><=$~!@#$%^&*()-_=+/.,;\'"[]{}?';
cb(null, {a: stringA});
},
{
returns: {
arg: 'data', type: 'object', root: true,
xml: { wrapperElement: false }
},
http: { path: '/' }
}
);
request(app).get(method.classUrl)
.set('Accept', 'application/xml')
.set('Content-Type', 'application/json')
.send()
.expect('Content-Type', /xml/)
.expect(200, function(err, res) {
expect(res).to.be.utf8;
expect(res.text).to.equal(
'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n' +
'<response>\n ' +
'<a>fooÁáĂΩasd&gt;&lt;=$~!@#$%^&amp;*()-_=+/.,;&apos;&quot;[]{}?</a>\n' +
'</response>');
done();
});
});

it('should produce xml from json objects with toXML()', function(done) {
var method = givenSharedStaticMethod(
function bar(a, cb) {
Expand Down