Comparing version 0.0.0 to 1.0.0
171
lib/index.js
@@ -5,2 +5,3 @@ // Load modules | ||
var Fs = require('fs'); | ||
var Os = require('os'); | ||
var Path = require('path'); | ||
@@ -10,2 +11,3 @@ var Stream = require('stream'); | ||
var Boom = require('boom'); | ||
var Content = require('content'); | ||
var Hoek = require('hoek'); | ||
@@ -22,40 +24,43 @@ var Pez = require('pez'); | ||
// Read and parse body | ||
exports.parse = function (req, tap, options, next) { | ||
exports.read = function (request, next) { | ||
Hoek.assert(options, 'Missing options'); | ||
Hoek.assert(options.parse !== undefined, 'Missing parse option setting'); | ||
Hoek.assert(options.output !== undefined, 'Missing output option setting'); | ||
if (request.method === 'get' || request.method === 'head') { // When route.method is '*' | ||
return next(); | ||
} | ||
var parser = new internals.Parser(req, tap, options, next); | ||
return parser.read(); | ||
}; | ||
// Fail action | ||
var failActionNext = function (err) { | ||
internals.Parser = function (req, tap, options, next) { | ||
if (!err) { | ||
return next(); | ||
} | ||
var self = this; | ||
// failAction: 'error', 'log', 'ignore' | ||
this.req = req; | ||
this.settings = options; | ||
this.tap = tap; | ||
var failAction = request.route.payload.failAction; | ||
if (failAction !== 'ignore') { | ||
request.log(['hapi', 'payload', 'error'], err); | ||
} | ||
this.result = {}; | ||
if (failAction === 'error') { | ||
return next(err); | ||
} | ||
this.next = function (err) { | ||
return next(); | ||
return next(err, self.result); | ||
}; | ||
}; | ||
internals.Parser.prototype.read = function () { | ||
var next = this.next; | ||
// Content size | ||
var req = request.raw.req; | ||
var req = this.req; | ||
var contentLength = req.headers['content-length']; | ||
if (contentLength && | ||
parseInt(contentLength, 10) > request.route.payload.maxBytes) { | ||
if (this.settings.maxBytes !== undefined && | ||
contentLength && | ||
parseInt(contentLength, 10) > this.settings.maxBytes) { | ||
return next(Boom.badRequest('Payload content length greater than maximum allowed: ' + request.route.payload.maxBytes)); | ||
return next(Boom.badRequest('Payload content length greater than maximum allowed: ' + this.settings.maxBytes)); | ||
} | ||
@@ -65,3 +70,3 @@ | ||
var contentType = Pez.contentType(request.route.payload.override || req.headers['content-type'] || 'application/json'); // Defaults to 'application/json' | ||
var contentType = Content.type(this.settings.override || req.headers['content-type'] || 'application/json'); // Defaults to 'application/json' | ||
if (contentType.isBoom) { | ||
@@ -71,9 +76,9 @@ return next(contentType); | ||
var mime = contentType.mime; | ||
request.mime = mime; | ||
this.result.contentType = contentType; | ||
this.result.mime = contentType.mime; | ||
if (request.route.payload.allow && | ||
request.route.payload.allow.indexOf(mime) === -1) { | ||
if (this.settings.allow && | ||
this.settings.allow.indexOf(contentType.mime) === -1) { | ||
return failActionNext(Boom.unsupportedMediaType()); | ||
return next(Boom.unsupportedMediaType()); | ||
} | ||
@@ -83,4 +88,4 @@ | ||
if (request.route.payload.parse === true) { | ||
return internals.parse(request, contentType, failActionNext); | ||
if (this.settings.parse === true) { | ||
return this.parse(contentType); | ||
} | ||
@@ -90,11 +95,15 @@ | ||
return internals.raw(request, next); | ||
return this.raw(); | ||
}; | ||
internals.parse = function (request, contentType, next) { | ||
internals.Parser.prototype.parse = function (contentType) { | ||
var output = request.route.payload.output; // Output: 'data', 'stream', 'file' | ||
var source = request.raw.req; | ||
var self = this; | ||
var next = this.next; | ||
var output = this.settings.output; // Output: 'data', 'stream', 'file' | ||
var source = this.req; | ||
// Content-encoding | ||
@@ -106,2 +115,3 @@ | ||
next = Hoek.once(next); // Modify next() for async events | ||
this.next = next; | ||
decoder.once('error', function (err) { | ||
@@ -117,5 +127,4 @@ | ||
var tap = request._tap(); | ||
if (tap) { | ||
source = source.pipe(tap); | ||
if (this.tap) { | ||
source = source.pipe(this.tap); | ||
} | ||
@@ -125,4 +134,4 @@ | ||
if (request.mime === 'multipart/form-data') { | ||
return internals.multipart(request, source, contentType, next); | ||
if (this.result.contentType.mime === 'multipart/form-data') { | ||
return this.multipart(source, contentType); | ||
} | ||
@@ -133,3 +142,3 @@ | ||
if (output === 'stream') { | ||
request.payload = source; | ||
this.result.payload = source; | ||
return next(); | ||
@@ -141,3 +150,3 @@ } | ||
if (output === 'file') { | ||
internals.writeFile(source, request.route.payload.uploads, function (err, path, bytes) { | ||
this.writeFile(source, function (err, path, bytes) { | ||
@@ -148,3 +157,3 @@ if (err) { | ||
request.payload = { path: path, bytes: bytes }; | ||
self.result.payload = { path: path, bytes: bytes }; | ||
return next(); | ||
@@ -158,3 +167,3 @@ }); | ||
return internals.buffer(request, source, function (err, payload) { | ||
return Wreck.read(source, { timeout: this.settings.timeout, maxBytes: this.settings.maxBytes }, function (err, payload) { | ||
@@ -165,3 +174,3 @@ if (err) { | ||
request.payload = {}; | ||
self.result.payload = {}; | ||
@@ -172,3 +181,3 @@ if (!payload.length) { | ||
internals.object(payload, request.mime, function (err, result) { | ||
internals.object(payload, self.result.contentType.mime, function (err, result) { | ||
@@ -179,3 +188,3 @@ if (err) { | ||
request.payload = result; | ||
self.result.payload = result; | ||
return next(); | ||
@@ -187,10 +196,14 @@ }); | ||
internals.raw = function (request, next) { | ||
internals.Parser.prototype.raw = function () { | ||
var output = request.route.payload.output; // Output: 'data', 'stream', 'file' | ||
var source = request.raw.req; | ||
var self = this; | ||
var next = this.next; | ||
var output = this.settings.output; // Output: 'data', 'stream', 'file' | ||
var source = this.req; | ||
// Content-encoding | ||
if (request.route.payload.parse === 'gunzip') { | ||
if (this.settings.parse === 'gunzip') { | ||
var contentEncoding = source.headers['content-encoding']; | ||
@@ -200,2 +213,3 @@ if (contentEncoding === 'gzip' || contentEncoding === 'deflate') { | ||
next = Hoek.once(next); // Modify next() for async events | ||
decoder.once('error', function (err) { | ||
@@ -212,5 +226,4 @@ | ||
var tap = request._tap(); | ||
if (tap) { | ||
source = source.pipe(tap); | ||
if (this.tap) { | ||
source = source.pipe(this.tap); | ||
} | ||
@@ -221,3 +234,3 @@ | ||
if (output === 'stream') { | ||
request.payload = source; | ||
this.result.payload = source; | ||
return next(); | ||
@@ -229,3 +242,3 @@ } | ||
if (output === 'file') { | ||
internals.writeFile(source, request.route.payload.uploads, function (err, path, bytes) { | ||
this.writeFile(source, function (err, path, bytes) { | ||
@@ -236,3 +249,3 @@ if (err) { | ||
request.payload = { path: path, bytes: bytes }; | ||
self.result.payload = { path: path, bytes: bytes }; | ||
return next(); | ||
@@ -246,3 +259,3 @@ }); | ||
return internals.buffer(request, source, function (err, payload) { | ||
return Wreck.read(source, { timeout: this.settings.timeout, maxBytes: this.settings.maxBytes }, function (err, payload) { | ||
@@ -253,3 +266,3 @@ if (err) { | ||
request.payload = payload; | ||
self.result.payload = payload; | ||
return next(); | ||
@@ -260,13 +273,2 @@ }); | ||
internals.buffer = function (request, source, next) { | ||
var parseOptions = { | ||
timeout: request.server.settings.timeout.client, | ||
maxBytes: request.route.payload.maxBytes | ||
}; | ||
Wreck.read(source, parseOptions, next); | ||
}; | ||
internals.object = function (payload, mime, next) { | ||
@@ -313,6 +315,9 @@ | ||
internals.multipart = function (request, source, contentType, next) { | ||
internals.Parser.prototype.multipart = function (source, contentType) { | ||
var options = request.route.payload; | ||
var self = this; | ||
var next = this.next; | ||
next = Hoek.once(next); // Modify next() for async events | ||
this.next = next; | ||
@@ -340,3 +345,3 @@ var dispenser = new Pez.Dispenser(contentType); | ||
request.payload = data; | ||
self.result.payload = data; | ||
return next(); | ||
@@ -367,6 +372,6 @@ }; | ||
if (options.output === 'file') { // Output: 'file' | ||
if (self.settings.output === 'file') { // Output: 'file' | ||
var id = nextId++; | ||
pendingFiles[id] = true; | ||
internals.writeFile(part, options.uploads, function (err, path, bytes) { | ||
self.writeFile(part, function (err, path, bytes) { | ||
@@ -395,3 +400,3 @@ delete pendingFiles[id]; | ||
} | ||
else { // Output: 'data' | ||
else { // Output: 'data' | ||
Wreck.read(part, {}, function (err, payload) { | ||
@@ -401,3 +406,3 @@ | ||
if (options.output === 'stream') { // Output: 'stream' | ||
if (self.settings.output === 'stream') { // Output: 'stream' | ||
var item = Wreck.toReadableStream(payload); | ||
@@ -453,3 +458,2 @@ | ||
source.headers = source.headers || request.headers; | ||
source.pipe(dispenser); | ||
@@ -459,5 +463,5 @@ }; | ||
internals.writeFile = function (stream, dest, callback) { | ||
internals.Parser.prototype.writeFile = function (stream, callback) { | ||
var path = internals.uniqueFilename(dest); | ||
var path = Hoek.uniqueFilename(this.settings.uploads || Os.tmpDir()); | ||
var file = Fs.createWriteStream(path, { flags: 'wx' }); | ||
@@ -503,8 +507,1 @@ var counter = new internals.Counter(); | ||
}; | ||
internals.uniqueFilename = function (path) { | ||
var name = [Date.now(), process.pid, Crypto.randomBytes(8).toString('hex')].join('-'); | ||
return Path.join(path, name); | ||
}; |
{ | ||
"name": "subtext", | ||
"description": "HTTP payload parsing", | ||
"version": "0.0.0", | ||
"version": "1.0.0", | ||
"repository": "git://github.com/hapijs/payload", | ||
@@ -19,2 +19,3 @@ "main": "index", | ||
"boom": "2.x.x", | ||
"content": "1.x.x.", | ||
"hoek": "2.x.x", | ||
@@ -26,2 +27,3 @@ "qs": "2.x.x", | ||
"devDependencies": { | ||
"form-data": "0.1.x", | ||
"lab": "4.x.x" | ||
@@ -28,0 +30,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
232704
11
1139
1
6
2
3
2
+ Addedcontent@1.x.x.