Permalink
Browse files

first

  • Loading branch information...
Raynos committed Jul 15, 2012
0 parents commit 08de18343bf93373723b7c2b1060cdcc2af25244
Showing with 340 additions and 0 deletions.
  1. +3 −0 .gitignore
  2. +3 −0 .npmignore
  3. +4 −0 .travis.yml
  4. +19 −0 LICENCE
  5. +10 −0 Makefile
  6. +69 −0 README.md
  7. +83 −0 index.js
  8. +39 −0 package.json
  9. +96 −0 test/integration.js
  10. +14 −0 testem.json
@@ -0,0 +1,3 @@
+node_modules
+*.log
+*.err
@@ -0,0 +1,3 @@
+node_modules
+*.log
+*.err
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+ - 0.6
+ - 0.8
19 LICENCE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 Raynos.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
@@ -0,0 +1,10 @@
+node-test:
+ ./node_modules/.bin/tap --stderr ./test
+
+test:
+ ./node_modules/.bin/testem \
+ --file testem.json \
+ --debuglog testem.log \
+ --debug 2> testem.err
+
+.PHONY: test
@@ -0,0 +1,69 @@
+# routil-body [![build status][1]][2]
+
+Body parsing
+
+## Example
+
+`body` simply parses the request body and returns it in the callback. `jsonBody` and `formBody` call JSON.parse and querystring.parse respectively on the body.
+
+anyBody will detect the content-type of the request and use the appropiate body method.
+
+ var Body = require("routil-body")
+ , bodyParser = Body()
+ , body = bodyParser.body
+ , formBody = bodyParser.formBody
+ , jsonBody = bodyParser.jsonBody
+ , anyBody = bodyParser.anyBody
+ , http = require("http")
+
+ http.createServer(function (req, res) {
+ if (req.url === '/json') {
+ jsonBody(req, function (body) {
+ res.end(JSON.stringify(body))
+ })
+ } else if (req.url === '/form') {
+ formbody(req, function (body) {
+ res.end(JSON.stringify(body))
+ })
+ } else if (req.url === '/any') {
+ anyBody(req, function (body) {
+ res.end(JSON.stringify(body))
+ })
+ } else {
+ body(req, function (body) {
+ res.end(body.toString())
+ })
+ }
+ }).listen(8080)
+
+## Example with custom error handling
+
+ var body = require("routil-body")({
+ errorPage: function (req, res, errorData) {
+ // errorData is either a single value or an array of values
+ // the values are either a number for the HTTP response code
+ // or an object error object
+ }
+ }).body
+ , http = require('http')
+
+ http.createServer(function (req, res) {
+ body(req, function (body) { res.end(body) })
+ }).listen(8080)
+
+## Installation
+
+`npm install routil-body`
+
+## Tests
+
+`make test`
+
+## Contributors
+
+ - Raynos
+
+## MIT Licenced
+
+ [1]: https://secure.travis-ci.org/Raynos/routil-body.png
+ [2]: http://travis-ci.org/Raynos/routil-body
@@ -0,0 +1,83 @@
+var StringDecoder = require("string_decoder").StringDecoder
+ , querystring = require("querystring")
+ , routil = require("routil")
+ , routilErrorPage = routil.errorPage
+ , contentTypes = routil.contentTypes
+ , isJSON = /\/(x-)?json$/
+ , isForm = /application\/x\-www\-form\-urlencoded/
+
+module.exports = Body
+
+function Body(options) {
+ var errorPage = routilErrorPage || options.errorPage
+
+ return {
+ body: body,
+ formBody: formBody,
+ jsonBody: jsonBody,
+ anyBody: anyBody
+ }
+
+ function formBody(req, res, callback) {
+ if (!req.headers['content-type'].match(isForm)) {
+ // XXX Add support for formidable uploading, as well
+ return errorPage(req, res, 415)
+ }
+ body(req, parseBody)
+
+ function parseBody(body) {
+ callback(querystring.parse(body))
+ }
+ }
+
+ function jsonBody(req, res, callback) {
+ if (!req.headers["content-type"].match(isJSON)) {
+ return errorPage(req, res, 415)
+ }
+ body(req, extractJSON)
+
+ function extractJSON(body) {
+ var json
+ try {
+ json = JSON.parse(body)
+ } catch (error) {
+ return errorPage(req, res, [400, error])
+ }
+ callback(json)
+ }
+ }
+
+ function anyBody(req, res, callback) {
+ contentTypes(req, {
+ "application/json": jsonBody,
+ "application/x-www-form-urlencoded": formBody,
+ "default": defaultAnyBodyHandler
+ })(req, res, callback)
+ }
+}
+
+function body(req, callback) {
+ if (req.__routil_body__) {
+ callback(req.__routil_body__)
+ }
+
+ var requestBody = "",
+ stringDecoder = new StringDecoder
+
+ req.on("data", addToBody)
+
+ req.on("end", returnBody)
+
+ function addToBody(buffer) {
+ requestBody += stringDecoder.write(buffer)
+ }
+
+ function returnBody() {
+ req.__routil_body__ = requestBody
+ callback(requestBody)
+ }
+}
+
+function defaultAnyBodyHandler(req, res, callback) {
+ body(req, callback)
+}
@@ -0,0 +1,39 @@
+{
+ "name": "routil-body",
+ "version": "0.0.1",
+ "description": "Body parsing",
+ "keywords": [],
+ "author": "Raynos <raynos2@gmail.com>",
+ "repository": "git://github.com/Raynos/routil-body.git",
+ "main": "index",
+ "homepage": "https://github.com/Raynos/routil-body",
+ "contributors": [
+ {
+ "name": "Jake Verbaten"
+ }
+ ],
+ "bugs": {
+ "url": "https://github.com/Raynos/routil-body/issues",
+ "email": "raynos2@gmail.com"
+ },
+ "dependencies": {
+ "routil": "0.0.14"
+ },
+ "devDependencies": {
+ "testling": "git://github.com/Raynos/testling#master",
+ "testem": "git://github.com/Raynos/testem#master",
+ "sinon": "1.4.2",
+ "tap": "0.2.5",
+ "after": "~0.6.0",
+ "test-server": "0.0.1"
+ },
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "http://github.com/Raynos/routil-body/raw/master/LICENSE"
+ }
+ ],
+ "scripts": {
+ "test": "make node-test"
+ }
+}
@@ -0,0 +1,96 @@
+var testServer = require("test-server")
+ , test = require("testling")
+ , routilBody = require("..")()
+ , body = routilBody.body
+ , formBody = routilBody.formBody
+ , jsonBody = routilBody.jsonBody
+ , anyBody = routilBody.anyBody
+ , sendJson = require("routil").sendJson
+ , after = require("after")
+
+testServer(handleRequest, runTests)
+
+function handleRequest(req, res) {
+ if (req.url === "/body") {
+ body(req, function (body) {
+ sendJson(res, body)
+ })
+ } else if (req.url === "/form") {
+ formBody(req, res, function (body) {
+ sendJson(res, body)
+ })
+ } else if (req.url === "/json") {
+ jsonBody(req, res, function (body) {
+ sendJson(res, body)
+ })
+ } else if (req.url === "/any") {
+ anyBody(req, res, function (body) {
+ sendJson(res, body)
+ })
+ }
+}
+
+function runTests(request, done) {
+ test("body works", function (t) {
+ t.end = after(2, t.end.bind(t))
+ testBody("/body", request, t)
+ testBody("/any", request, t)
+ })
+
+ test("form works", function (t) {
+ t.end = after(2, t.end.bind(t))
+ testFormBody("/form", request, t)
+ testFormBody("/any", request, t)
+ })
+
+ test("json works", function (t) {
+ t.end = after(2, t.end.bind(t))
+ testJsonBody("/json", request, t)
+ testJsonBody("/any", request, t)
+ })
+
+ .on("end", done)
+}
+
+function testBody(uri, request, t) {
+ request({
+ uri: uri
+ , body: "foo"
+ }, function (err, res, body) {
+ t.equal(err, null, "error is not null")
+
+ t.equal(JSON.parse(body), "foo", "body is incorrect")
+
+ t.end()
+ })
+}
+
+function testFormBody(uri, request, t) {
+ request({
+ uri: uri
+ , form: {
+ foo: "bar"
+ }
+ }, function (err, res, body) {
+ t.equal(err, null, "error is not null")
+
+ t.equal(JSON.parse(body).foo, "bar", "body is incorrect")
+
+ t.end()
+ })
+}
+
+function testJsonBody(uri, request, t) {
+ request({
+ uri: uri
+ , json: {
+ foo: "bar"
+ }
+ }, function (err, res, body) {
+ t.equal(err, null, "error is not null")
+
+ t.equal(body.foo, "bar", "body is incorrect")
+
+ t.end()
+ })
+}
@@ -0,0 +1,14 @@
+{
+ "framework": "custom"
+ , "browserify": true
+ , "src_files": [
+ "test/**/*.js"
+ , "node_modules/testem/adapters/testling.js"
+ ]
+ , "watch_files": [
+ "test/**/*.js"
+ , "./index.js"
+ ]
+ , "node": "node_modules/.bin/tap"
+ , "node-args": ["--tap", "test"]
+}

0 comments on commit 08de183

Please sign in to comment.