Skip to content

Commit

Permalink
Fixes response.stream(); adds response.binary()
Browse files Browse the repository at this point in the history
Fixes issue #340
  • Loading branch information
botic committed Jul 12, 2016
1 parent 8569f4e commit 573ce29
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 5 deletions.
31 changes: 28 additions & 3 deletions modules/ringo/jsgi/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

var {merge} = require("ringo/utils/objects");
var {mimeType} = require("ringo/mime");
var {MemoryStream, Stream} = require("io");

/**
* A wrapper around a JSGI response object. `JsgiResponse` is chainable.
Expand Down Expand Up @@ -130,8 +131,8 @@ Object.defineProperty(JsgiResponse.prototype, "xml", {
*/
Object.defineProperty(JsgiResponse.prototype, "stream", {
value: function (stream, contentType) {
if (!(stream instanceof Stream)) {
throw Error("Wrong argument for stream response: " + typeof(resource));
if (typeof stream.readable !== "function" || typeof stream.forEach !== "function") {
throw Error("Wrong argument for stream response!");
}

if (!stream.readable()) {
Expand All @@ -145,6 +146,30 @@ Object.defineProperty(JsgiResponse.prototype, "stream", {
}
});

/**
* Create a JSGI response with a <code>Binary</code> object as response body.
* @param {ByteString|ByteArray} binary the binary object to write
* @param {String} contentType optional MIME type. If not defined,
* the MIME type is <code>application/octet-stream</code>.
* @returns {JsgiResponse} JSGI response
*/
Object.defineProperty(JsgiResponse.prototype, "binary", {
value: function (binary, contentType) {
if (!(binary instanceof Binary)) {
throw Error("Wrong argument for binary response!");
}

this.headers["content-type"] = contentType || "application/octet-stream";
this.body = {
forEach: function(fn) {
fn(binary);
}
};

return this;
}
});

/**
* Set the character encoding used for text responses.
* @param {String} charsetName the encoding to use.
Expand Down Expand Up @@ -473,7 +498,7 @@ Object.defineProperty(JsgiResponse.prototype, "notModified", {

// Define helper functions
/** @ignore */
["setStatus", "text", "html", "json", "jsonp", "xml", "stream", "setCharset", "addHeaders",
["setStatus", "text", "html", "json", "jsonp", "xml", "stream", "binary", "setCharset", "addHeaders",
"ok", "created", "bad", "unauthorized", "forbidden", "notFound", "gone", "error",
"unavailable", "redirect", "notModified"].forEach(function(functionName) {
exports[functionName] = function() {
Expand Down
31 changes: 30 additions & 1 deletion test/ringo/httpclient_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ var {parseParameters, parseFileUpload, setCookie, Headers} = require("ringo/util
var {MemoryStream, TextStream} = require("io");
var fs = require("fs");
var base64 = require("ringo/base64");
var {ByteArray} = require("binary");
var {ByteArray, ByteString} = require("binary");

var server;
var host = "127.0.0.1";
Expand Down Expand Up @@ -569,6 +569,35 @@ exports.testMultipleHeaders_Issue225 = function() {
});
};

exports.testStreamResponse = function() {
getResponse = function(req) {
var bs = new MemoryStream(3);
bs.write(new ByteString("\t\r\n", "ASCII"));
bs.position = 0;
return response.stream(bs);
};

var exchange = request({
url: baseUri
});

assert.strictEqual(exchange.content, "\t\r\n");
};

exports.testBinaryResponse = function() {
getResponse = function(req) {
return response.binary(new ByteArray([35, 114, 105, 110, 103, 111, 106, 115]));
};

var exchange = request({
url: baseUri,
binary: true
});

assert.strictEqual(exchange.contentBytes.toArray().join(""), [35, 114, 105, 110, 103, 111, 106, 115].join(""));
};


// start the test runner if we're called directly from command line
if (require.main === module) {
var {run} = require("test");
Expand Down
41 changes: 40 additions & 1 deletion test/ringo/jsgi/response_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,45 @@ exports.testStream = function () {
assert.deepEqual(ba.toArray(), [0, 1, 2, 3, 4, 5, 6, 7]);
};

exports.testBinary = function () {
var res = new JsgiResponse().binary(new binary.ByteArray([0, 1, 2, 3, 4, 5, 6, 7]));
assert.equal(res.status, 200);
assert.deepEqual(res.headers, { "content-type": "application/octet-stream" });
assert.strictEqual(typeof res.body.forEach, "function");
var arr = [];
res.body.forEach(function (ba) {
arr = arr.concat(ba.toArray());
});
assert.deepEqual(arr, [0, 1, 2, 3, 4, 5, 6, 7]);

res = new JsgiResponse().binary(new binary.ByteArray([0, 1, 2, 3, 4, 5, 6, 7]), "application/pdf");
assert.equal(res.status, 200);
assert.deepEqual(res.headers, { "content-type": "application/pdf" });
assert.strictEqual(typeof res.body.forEach, "function");
arr = [];
res.body.forEach(function (ba) {
arr = arr.concat(ba.toArray());
});
assert.deepEqual(arr, [0, 1, 2, 3, 4, 5, 6, 7]);

res.setStatus(400);
assert.equal(res.status, 400);

res = new JsgiResponse().binary(new binary.ByteString("\r\n", "ASCII"), "application/asciistuff");
assert.equal(res.status, 200);
assert.deepEqual(res.headers, { "content-type": "application/asciistuff" });
assert.strictEqual(typeof res.body.forEach, "function");
arr = [];
res.body.forEach(function (ba) {
arr = arr.concat(ba.toArray());
});
assert.deepEqual(arr, [13,10]);

assert.throws(function() {
new JsgiResponse().binary("i am not a binary object");
}, Error);
};

exports.testSetCharset = function () {
var res = new JsgiResponse();

Expand Down Expand Up @@ -197,7 +236,7 @@ exports.testAddHeaders = function () {
assert.isTrue(res.headers.foo.indexOf("12345") >= 0);
assert.isTrue(res.headers.foo.every(function(val) {
return typeof val === "string";
}))
}));

// multiple headers as array
res = new JsgiResponse();
Expand Down

0 comments on commit 573ce29

Please sign in to comment.