Skip to content

Commit

Permalink
Creating res.json() for interop with express
Browse files Browse the repository at this point in the history
  • Loading branch information
avoidwork committed Nov 30, 2017
1 parent edf0f1f commit 69b6fca
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 8 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ http2.createSecureServer({
##### res.error (status[, body, headers])
Sends an error response.

##### res.json (body, [status = 200, headers])
Sends a JSON response.

##### res.redirect (uri[, perm = false])
Sends a redirection response.

Expand Down
3 changes: 2 additions & 1 deletion lib/regex.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ module.exports = {
isParam: /^:/,
isOptions: /^OPTIONS$/,
slashEnd: /\/$/,
slashStart: /^\//
slashStart: /^\//,
wrappedQuotes: /^".*"$/
};
33 changes: 28 additions & 5 deletions lib/woodland.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class Woodland {

if (this.http2) {
res._headers = {};
res.statusCode = 200;
res.hasHeader = key => key in res._headers;
res.getHeader = key => res.hasHeader(key) ? clone(res._headers[key]) : void 0;
res.getHeaders = () => clone(res._headers);
Expand All @@ -93,15 +94,34 @@ class Woodland {
res.send = (...args) => this.http2Send(req, res, ...args);
} else {
res.send = (body, status = 200, headers) => {
res.statusCode = status;
res.writeHead(status, headers);
if (res.statusCode < status) {
res.statusCode = status;
}

res.writeHead(res.statusCode, headers);
res.end(body);
};
}

res.error = (status, body, headers) => res.send(body, status, headers);
res.redirect = (uri, perm = true) => res.send("", perm ? 301 : 302, {"location:": uri});

res.json = arg => {
let x = arg;

try {
if (typeof x === "string") {
x = regex.wrappedQuotes.test(x) ? x : JSON.stringify(x);
} else {
x = JSON.stringify(x);
}
} catch (e) {
void 0;
}

res.send(x, void 0, {"content-type": "application/json"});
};

// Express interop
res.header = res.setHeader;
res.locals = {};
Expand Down Expand Up @@ -144,8 +164,9 @@ class Woodland {
return mmh3(arg, this.seed);
}

http2Send (req, res, body, status = 200, headers = null) {
const output = {":status": status},
http2Send (req, res, body, nstatus = 200, headers = null) {
const status = res.statusCode < nstatus ? nstatus : res.statusCode,
output = {":status": status},
empty = regex.isHead.test(req.method) || status === 204 || status === 304;

each(Object.keys(res._headers).filter(i => invalidHttp2Headers.test(i) === false), i => {
Expand All @@ -160,7 +181,9 @@ class Woodland {
});
}

res.statusCode = status;
if (res.statusCode < status) {
res.statusCode = status;
}

if (req.file === void 0 || empty) {
res.respond(output);
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "woodland",
"version": "4.0.6",
"version": "4.1.0",
"description": "Lightweight HTTP/HTTPS/HTTP2 router with automatic `Allow` & `CORS` headers",
"main": "index.js",
"scripts": {
Expand Down
22 changes: 22 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const http = require("http"),

router.onconnect = (req, res) => res.header("x-onconnect", "true");
router.use("/", (req, res) => res.send(req.method !== "OPTIONS" ? "Hello World!" : ""));
router.use("/json1", (req, res) => res.json({text: "Hello World!"}));
router.use("/json2", (req, res) => res.json("Hello World!"));
router.use("/echo/:echo", (req, res) => res.send(req.params.echo));
router.use("/echo/:echo", (req, res) => res.send("The entity will be echoed back to you"), "OPTIONS");

Expand Down Expand Up @@ -51,6 +53,26 @@ describe("Valid Requests", function () {
.end();
});

it("GET /json1 (200 / 'Success')", function () {
return tinyhttptest({url: "http://localhost:8001/json1"})
.expectStatus(200)
.expectHeader("allow", "GET, HEAD, OPTIONS")
.expectHeader("cache-control", "no-cache")
.expectHeader("content-type", "application/json")
.expectBody(arg => JSON.stringify(arg) !== void 0)
.end();
});

it("GET /json2 (200 / 'Success')", function () {
return tinyhttptest({url: "http://localhost:8001/json2"})
.expectStatus(200)
.expectHeader("allow", "GET, HEAD, OPTIONS")
.expectHeader("cache-control", "no-cache")
.expectHeader("content-type", "application/json")
.expectBody(arg => JSON.stringify(arg) !== void 0)
.end();
});

it("GET / CORS Pre-flight (200 / 'Success')", function () {
return tinyhttptest({url: "http://localhost:8001/", method: "OPTIONS"})
.cors("http://not.localhost:8001")
Expand Down
22 changes: 22 additions & 0 deletions test/test2.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const http2 = require("http2"),

router.onconnect = (req, res) => res.header("x-onconnect", "true");
router.use("/", (req, res) => res.send(req.method !== "OPTIONS" ? "Hello World!" : ""));
router.use("/json1", (req, res) => res.json({text: "Hello World!"}));
router.use("/json2", (req, res) => res.json("Hello World!"));
router.use("/echo/:echo", (req, res) => res.send(req.params.echo));
router.use("/echo/:echo", (req, res) => res.send("The entity will be echoed back to you"), "OPTIONS");

Expand Down Expand Up @@ -56,6 +58,26 @@ describe("Valid Requests (HTTP2)", function () {
.end();
});

it("GET /json1 (200 / 'Success')", function () {
return tinyhttptest({http2: true, url: "https://localhost:8002/json1"})
.expectStatus(200)
.expectHeader("allow", "GET, HEAD, OPTIONS")
.expectHeader("cache-control", "no-cache")
.expectHeader("content-type", "application/json")
.expectBody(arg => JSON.stringify(arg) !== void 0)
.end();
});

it("GET /json2 (200 / 'Success')", function () {
return tinyhttptest({http2: true, url: "https://localhost:8002/json2"})
.expectStatus(200)
.expectHeader("allow", "GET, HEAD, OPTIONS")
.expectHeader("cache-control", "no-cache")
.expectHeader("content-type", "application/json")
.expectBody(arg => JSON.stringify(arg) !== void 0)
.end();
});

it("GET / CORS Pre-flight (200 / 'Success')", function () {
return tinyhttptest({http2: true, url: "https://localhost:8002/", method: "OPTIONS"})
.cors("https://not.localhost:8002")
Expand Down

0 comments on commit 69b6fca

Please sign in to comment.