UNPKG

stick

Version:

JSGI based webapp framework

109 lines (101 loc) 4.68 kB
/** * @fileoverview This module provides middleware for parsing * HTTP parameters from the query string and request body. * * It does not parse multipart MIME data such as file uploads which are handled * by the [upload] module. */ var http = require("../utils/http"); var isFileUpload = http.isFileUpload, isUrlEncoded = http.isUrlEncoded, parseFileUpload = http.parseFileUpload, parseParameters = http.parseParameters, mergeParameter = http.mergeParameter, BufferFactory = http.BufferFactory, Headers = http.Headers; var objects = require("common-utils/objects"); var strings = require("common-utils/strings"); /** * Middleware for parsing HTTP parameters. * This module handles URL-endcoded form data transmitted in the query string * and request body as well as JSON encoded data in the request body. * * @param {Function} next the wrapped middleware chain * @param {Object} app the Stick Application object * @returns {Function} a JSGI middleware function */ exports.middleware = function params(next, app) { return function(req) { var params, queryParams, postParams; var desc = Object.getOwnPropertyDescriptor(req, "postParams"); var servletRequest = req.env.servletRequest || { getCharacterEncoding: function() {} }; /** * An object containing the parsed HTTP parameters sent with this request. * @name request.params */ Object.defineProperty(req, "params", { get: function() { if (!params) { params = objects.merge(this.postParams, this.queryParams); } return params; }, configurable: true }); /** * An object containing the parsed HTTP query string parameters sent with this request. * @name request.queryParams */ Object.defineProperty(req, "queryParams", { get: function() { if (!queryParams) { queryParams = {}; var encoding = servletRequest.getCharacterEncoding() || "utf8"; parseParameters(this.queryString, queryParams, encoding); } return queryParams; }, configurable: true }); /** * An object containing the parsed HTTP POST parameters sent with this request. * @name request.postParams */ Object.defineProperty(req, "postParams", { get: function() { if (!postParams) { Headers(req.headers); var contentType = req.headers.get("content-type"); if (req.method === "POST" || req.method === "PUT") { var input; var encoding = servletRequest.getCharacterEncoding() || "utf8"; if (isUrlEncoded(contentType)) { postParams = {}; input = req.input.read(); var contentLength = parseInt(req.headers.get("content-length")); if (!input.length && contentLength > 0) { // Entity body already consumed, ask servlet API for params // See ringo issues #70 and #130 var map = servletRequest.getParameterMap(); for (var entry in Iterator(map.entrySet())) { var key = entry.key, value = entry.value; // value is a java string array for (var val in value) { mergeParameter(postParams, key, value[val]); } } } else { parseParameters(input, postParams, encoding); } } else if (strings.startsWith(contentType, "application/json")) { input = req.input.read(); postParams = JSON.parse(input.decodeToString(encoding)); } } // query previous postParams property descriptor in case // this is a file upload if (!postParams && desc) { postParams = desc.get ? desc.get.apply(req) : desc.value; } } return postParams; }, configurable: true }); return next(req); }; };