Skip to content

Commit

Permalink
export and update http middlewares
Browse files Browse the repository at this point in the history
  • Loading branch information
hnry committed Aug 10, 2016
1 parent 3c1b57d commit 9e88847
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 12 deletions.
8 changes: 8 additions & 0 deletions index.js
Expand Up @@ -16,6 +16,14 @@ node.utils = require("./lib/http/utils")
node.utils.resolve_response = p_utils.resolve_response
node.utils.resolveResponse = p_utils.resolve_response

// node http middleware
node.middleware = {
proxy: require("./lib/http/middleware/proxy"),
head: require("./lib/http/middleware/head"),
ifmod: require("./lib/http/middleware/if-modified"),
log: require("./lib/http/middleware/log")
}

module.exports = {
compose: core.compose,
callp: p_utils.callp,
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "spirit",
"version": "0.0.12",
"version": "0.1.0",
"description": "extensible web library for building applications & frameworks",
"main": "index.js",
"scripts": {
Expand Down
52 changes: 52 additions & 0 deletions spec/http/middleware/head-spec.js
@@ -0,0 +1,52 @@
const head = require("../../../index").node.middleware.head
const Promise = require("bluebird")

describe("Middleware: head", () => {

it("modifies any HEAD request to be a GET, stripping response body, and changing back to GET when done", (done) => {
const handler = (request) => {
expect(request.method).toBe("GET")
return Promise.resolve({
status: 200,
headers: { a: 123 },
body: "Hi"
})
}
const req = { method: "HEAD" }
head(handler)(req).then((response) => {
expect(req.method).toBe("HEAD")
expect(response.status).toBe(200)
expect(response.headers).toEqual({
a: 123
})
expect(response.body).toBe(undefined)
done()
})
})

it("when stripping, it closes a stream body", () => {
pending()
})

it("doesn't touch other requests", (done) => {
const handler = (request) => {
return {
status: 200,
headers: { a: 123 },
body: "ok"
}
}

let result = head(handler)({ method: "GET" })
expect(result).toEqual({ status: 200, headers: { a: 123 }, body: "ok" })

result = head(handler)({ method: "hEad" })
expect(result).toEqual({ status: 200, headers: { a: 123 }, body: "ok" })

result = head(handler)({ method: "POST" })
expect(result).toEqual({ status: 200, headers: { a: 123 }, body: "ok" })

done()
})

})
4 changes: 2 additions & 2 deletions spec/http/middleware/if-modified-spec.js
@@ -1,7 +1,7 @@
const if_mod = require("../../../lib/http/middleware/if-modified")
const if_mod = require("../../../index").node.middleware.ifmod
const Promise = require("bluebird")

describe("middleware - if-modified", () => {
describe("Middleware: if-modified", () => {

const req = {
method: "GET",
Expand Down
93 changes: 93 additions & 0 deletions spec/http/middleware/log-spec.js
@@ -0,0 +1,93 @@
const log = require("../../../index").node.middleware.log
const Promise = require("bluebird")

describe("Middleware: log", () => {
const orig_log = console.log

afterEach(() => {
console.log = orig_log
})

it("outputs a request", (done) => {
let called = 0
console.log = (prefix, method, url, status, time) => {
expect(method).toBe("TEST")
expect(url).toBe("/test/path")

if (!called) {
called = 1
expect(status).toBe(undefined)
expect(time).toBe(undefined)
return
}

const ms = parseInt(time.substr(0, time.length))
expect(ms).not.toBe(NaN)
// the time it took to run the test should
// at least be 3ms but probably not greater than 7ms
if (ms < 3 && ms > 7) {
throw new Error("time in milliseconds seems unlikely")
}
called = 2
}

const handler = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ status: 123, headers: {}, body: "hi" })
}, 3)
})
}

log(handler)({ method: "TEST", url: "/test/path" }).then((response) => {
expect(response).toEqual({
status: 123,
headers: {},
body: "hi"
})
expect(called).toBe(2)
done()
})
})

it("visual test", (done) => {
console.log("\nvisual test for log middleware (4 lines will be outputted):")
let called = false

const handler = () => {
return new Promise((resolve, reject) => {
if (called) {
return reject("simulating error")
}

called = true
setTimeout(() => {
resolve({ status: 123, headers: {}, body: "hi" })
}, 3)
})
}

log(handler)({ method: "TEST", url: "/test/path" }).then(() => {
log(handler)({ method: "TEST", url: "/test/path" }).catch(done)
})
})

it("does not do anything if production env set", (done) => {
process.env.NODE_ENV = "production"
console.log = () => {
throw new Error("should not be called")
}
const handler = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(123)
}, 3)
})
}
log(handler)({ method: "TEST", url: "/test/path" }).then((resp) => {
expect(resp).toBe(123)
process.env.NODE_ENV = ""
done()
})
})
})
2 changes: 1 addition & 1 deletion spec/http/middleware/proxy-spec.js
@@ -1,4 +1,4 @@
const proxy = require("../../../lib/http/middleware/proxy")
const proxy = require("../../../index").node.middleware.proxy
const Promise = require("bluebird")

describe("Middleware: X-Forwarded-For proxy", () => {
Expand Down
6 changes: 5 additions & 1 deletion src/core/core.js
Expand Up @@ -6,7 +6,11 @@ const p_utils = require("./promise_utils")


/**
* Returns a function that wraps `reduce_mw`
* A reducer function, for reducing over a handler
* and middlewares
*
* All functions are expected to return a Promise
* It is wrapped to ensure a Promise is returned
*
* @param {function} handler - a handler function
* @param {array} middleware - an array of middleware function
Expand Down
31 changes: 25 additions & 6 deletions src/http/middleware/log.js
@@ -1,21 +1,40 @@
/*
* A simple logger for reporting the time in milliseconds
* the amount of time elapsed in responding to a request
*
* It is meant purely for development
*/

//const arrow_in = "\u001b[33m=\u001b[93m>\u001b[39m"
//const arrow_out = "\u001b[92m<\u001b[32m=\u001b[39m"

const prefix_in = "⇢ "
const prefix_out = "↩︎ "
const prefix_err = "⚠︎ "

module.exports = (handler) => {
if (typeof process !== "undefined" && typeof process.env !== "undefined" && process.env.NODE_ENV === "production") {
if (typeof process !== "undefined"
&& typeof process.env !== "undefined"
&& process.env.NODE_ENV === "production") {
return (request) => {
return handler(request)
}
}

return (request) => {
const t = new Date()
return handler(request).then((response) => {
const diff = new Date - t
console.log(request.method, request.url, diff + "ms")
return response
})
console.log(prefix_in, request.method, request.url)

return handler(request)
.then((response) => {
const diff = new Date - t
console.log(prefix_out, request.method, request.url, response.status, diff + "ms")
return response
})
.catch((err) => {
const diff = new Date - t
console.log(prefix_err, request.method, request.url, "ERR", diff + "ms")
throw err
})
}
}
2 changes: 1 addition & 1 deletion src/http/node_adapter.js
Expand Up @@ -50,7 +50,7 @@ const send = (res, resp) => {
}

const adapter = (handler, middleware) => {
if (typeof middleware === "undefined") middleware = []
if (middleware === undefined) middleware = []

return (req, res) => {
const request_map = request.create(req)
Expand Down

0 comments on commit 9e88847

Please sign in to comment.