UNPKG

@adonisjs/bodyparser

Version:

BodyParser middleware for AdonisJS http server to read and parse request body

136 lines (135 loc) 5.13 kB
import "../file-CexcC_98.js"; import { a as prepareJSONParserOptions, c as streamFile, i as parseJSON, l as Multipart, n as parseForm, o as parseText, r as prepareFormParserOptions, s as prepareTextParserOptions, t as prepareMultipartConfig, u as debug_default } from "../multipart-C3ADW2mk.js"; import { isAbsolute, join } from "node:path"; import string from "@poppinss/utils/string"; import { Exception } from "@poppinss/utils/exception"; import { tmpdir } from "node:os"; var BodyParserMiddleware = class { #config; #parsersConfig; constructor(config, _featureFlags) { this.#config = config; this.#parsersConfig = { raw: prepareTextParserOptions(this.#config.raw), form: prepareFormParserOptions(this.#config.form), json: prepareJSONParserOptions(this.#config.json), multipart: prepareMultipartConfig(this.#config.multipart) }; debug_default("using config %O", this.#config); } #isType(request, types) { return !!(types && types.length && request.is(types)); } #getExceptionFor(error) { switch (error.type) { case "encoding.unsupported": return new Exception(error.message, { status: error.status, code: "E_ENCODING_UNSUPPORTED" }); case "entity.too.large": return new Exception(error.message, { status: error.status, code: "E_REQUEST_ENTITY_TOO_LARGE" }); case "request.aborted": return new Exception(error.message, { status: error.status, code: "E_REQUEST_ABORTED" }); default: return error; } } #getTmpPath(config) { if (typeof config.tmpFileName === "function") { const tmpPath = config.tmpFileName(); return isAbsolute(tmpPath) ? tmpPath : join(tmpdir(), tmpPath); } return join(tmpdir(), string.uuid()); } async handle(ctx, next) { ctx.request["__raw_files"] = {}; const requestUrl = ctx.request.url(); const requestMethod = ctx.request.method(); if (!this.#config.allowedMethods.includes(requestMethod)) { debug_default("skipping HTTP request \"%s:%s\"", requestMethod, requestUrl); return next(); } if (!ctx.request.hasBody()) { debug_default("skipping as request has no body \"%s:%s\"", requestMethod, requestUrl); return next(); } const multipartConfig = this.#config["multipart"]; if (this.#isType(ctx.request, multipartConfig.types)) { debug_default("detected multipart request \"%s:%s\"", requestMethod, requestUrl); ctx.request.multipart = new Multipart(ctx, this.#parsersConfig.multipart, {}); ctx.request.bodyType = "multipart"; if (multipartConfig.autoProcess === false) { debug_default("skipping auto processing of multipart request \"%s:%s\"", requestMethod, requestUrl); return next(); } if (ctx.route && multipartConfig.processManually.includes(ctx.route.pattern)) { debug_default("skipping auto processing of multipart request \"%s:%s\"", requestMethod, requestUrl); return next(); } if (ctx.route && Array.isArray(multipartConfig.autoProcess) && !multipartConfig.autoProcess.includes(ctx.route.pattern)) { debug_default("skipping auto processing of multipart request \"%s:%s\"", requestMethod, requestUrl); return next(); } debug_default("auto processing multipart request \"%s:%s\"", requestMethod, requestUrl); ctx.request.multipart.onFile("*", { deferValidations: true }, async (part, reporter) => { try { const tmpPath = this.#getTmpPath(multipartConfig); await streamFile(part, tmpPath, reporter); return { tmpPath }; } catch (error) { ctx.request.multipart.abort(error); } }); try { await ctx.request.multipart.process(); return next(); } catch (error) { throw error; } } const formConfig = this.#config["form"]; if (this.#isType(ctx.request, formConfig.types)) { debug_default("detected urlencoded request \"%s:%s\"", requestMethod, requestUrl); try { const { parsed, raw } = await parseForm(ctx.request.request, this.#parsersConfig.form); ctx.request.setInitialBody(parsed); ctx.request.updateRawBody(raw); ctx.request.bodyType = "urlencoded"; return next(); } catch (error) { throw this.#getExceptionFor(error); } } const jsonConfig = this.#config["json"]; if (this.#isType(ctx.request, jsonConfig.types)) { debug_default("detected JSON request \"%s:%s\"", requestMethod, requestUrl); try { const { parsed, raw } = await parseJSON(ctx.request.request, this.#parsersConfig.json); ctx.request.setInitialBody(parsed); ctx.request.updateRawBody(raw); ctx.request.bodyType = "json"; return next(); } catch (error) { throw this.#getExceptionFor(error); } } const rawConfig = this.#config["raw"]; if (this.#isType(ctx.request, rawConfig.types)) { debug_default("parsing raw body \"%s:%s\"", requestMethod, requestUrl); try { ctx.request.setInitialBody({}); ctx.request.updateRawBody(await parseText(ctx.request.request, this.#parsersConfig.raw)); ctx.request.bodyType = "raw"; return next(); } catch (error) { throw this.#getExceptionFor(error); } } ctx.request.bodyType = "unknown"; await next(); } }; export { BodyParserMiddleware };