1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
11 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
12 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
13 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
14 | return c > 3 && r && Object.defineProperty(target, key, r), r;
|
15 | };
|
16 | var __metadata = (this && this.__metadata) || function (k, v) {
|
17 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
18 | };
|
19 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
20 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
21 | };
|
22 | Object.defineProperty(exports, "__esModule", { value: true });
|
23 | exports.BodyParserMiddleware = void 0;
|
24 |
|
25 | const os_1 = require("os");
|
26 | const co_body_1 = __importDefault(require("@poppinss/co-body"));
|
27 | const path_1 = require("path");
|
28 | const utils_1 = require("@poppinss/utils");
|
29 | const application_1 = require("@adonisjs/application");
|
30 | const helpers_1 = require("@poppinss/utils/build/helpers");
|
31 | const Multipart_1 = require("../Multipart");
|
32 | const streamFile_1 = require("../Multipart/streamFile");
|
33 |
|
34 |
|
35 |
|
36 |
|
37 | let BodyParserMiddleware = class BodyParserMiddleware {
|
38 | constructor(Config, drive) {
|
39 | this.drive = drive;
|
40 | this.config = Config.get('bodyparser', {});
|
41 | }
|
42 | |
43 |
|
44 |
|
45 | getConfigFor(type) {
|
46 | const config = this.config[type];
|
47 | config['returnRawBody'] = true;
|
48 | return config;
|
49 | }
|
50 | |
51 |
|
52 |
|
53 | ensureTypes(types) {
|
54 | return !!(types && types.length);
|
55 | }
|
56 | |
57 |
|
58 |
|
59 |
|
60 | isType(request, types) {
|
61 | return !!(this.ensureTypes(types) && request.is(types));
|
62 | }
|
63 | |
64 |
|
65 |
|
66 |
|
67 | getExceptionFor(error) {
|
68 | switch (error.type) {
|
69 | case 'encoding.unsupported':
|
70 | return new utils_1.Exception(error.message, error.status, 'E_ENCODING_UNSUPPORTED');
|
71 | case 'entity.too.large':
|
72 | return new utils_1.Exception(error.message, error.status, 'E_REQUEST_ENTITY_TOO_LARGE');
|
73 | case 'request.aborted':
|
74 | return new utils_1.Exception(error.message, error.status, 'E_REQUEST_ABORTED');
|
75 | default:
|
76 | return error;
|
77 | }
|
78 | }
|
79 | |
80 |
|
81 |
|
82 | getTmpPath(config) {
|
83 | if (typeof config.tmpFileName === 'function') {
|
84 | const tmpPath = config.tmpFileName();
|
85 | return (0, path_1.isAbsolute)(tmpPath) ? tmpPath : (0, path_1.join)((0, os_1.tmpdir)(), tmpPath);
|
86 | }
|
87 | return (0, path_1.join)((0, os_1.tmpdir)(), (0, helpers_1.cuid)());
|
88 | }
|
89 | |
90 |
|
91 |
|
92 |
|
93 | async handle(ctx, next) {
|
94 | |
95 |
|
96 |
|
97 | ctx.request['__raw_files'] = {};
|
98 | const requestMethod = ctx.request.method();
|
99 | |
100 |
|
101 |
|
102 | if (!this.config.whitelistedMethods.includes(requestMethod)) {
|
103 | ctx.logger.trace(`bodyparser skipping method ${requestMethod}`);
|
104 | return next();
|
105 | }
|
106 | |
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 | if (!ctx.request.hasBody()) {
|
114 | ctx.logger.trace('bodyparser skipping empty body');
|
115 | return next();
|
116 | }
|
117 | |
118 |
|
119 |
|
120 | const multipartConfig = this.getConfigFor('multipart');
|
121 | if (this.isType(ctx.request, multipartConfig.types)) {
|
122 | ctx.logger.trace('bodyparser parsing as multipart body');
|
123 | ctx.request.multipart = new Multipart_1.Multipart(ctx, {
|
124 | maxFields: multipartConfig.maxFields,
|
125 | limit: multipartConfig.limit,
|
126 | fieldsLimit: multipartConfig.fieldsLimit,
|
127 | convertEmptyStringsToNull: multipartConfig.convertEmptyStringsToNull,
|
128 | }, this.drive);
|
129 | |
130 |
|
131 |
|
132 |
|
133 | if (!multipartConfig.autoProcess ||
|
134 | multipartConfig.processManually.indexOf(ctx.route.pattern) > -1) {
|
135 | return next();
|
136 | }
|
137 | |
138 |
|
139 |
|
140 |
|
141 |
|
142 | ctx.request.multipart.onFile('*', { deferValidations: true }, async (part, reporter) => {
|
143 | |
144 |
|
145 |
|
146 |
|
147 |
|
148 | try {
|
149 | const tmpPath = this.getTmpPath(multipartConfig);
|
150 | await (0, streamFile_1.streamFile)(part, tmpPath, reporter);
|
151 | return { tmpPath };
|
152 | }
|
153 | catch (error) {
|
154 | ctx.request.multipart.abort(error);
|
155 | }
|
156 | });
|
157 | const action = ctx.profiler.profile('bodyparser:multipart');
|
158 | try {
|
159 | await ctx.request.multipart.process();
|
160 | action.end();
|
161 | return next();
|
162 | }
|
163 | catch (error) {
|
164 | action.end({ error });
|
165 | throw error;
|
166 | }
|
167 | }
|
168 | |
169 |
|
170 |
|
171 | const formConfig = this.getConfigFor('form');
|
172 | if (this.isType(ctx.request, formConfig.types)) {
|
173 | ctx.logger.trace('bodyparser parsing as form request');
|
174 | const action = ctx.profiler.profile('bodyparser:urlencoded');
|
175 | try {
|
176 | const { parsed, raw } = await co_body_1.default.form(ctx.request.request, formConfig);
|
177 | ctx.request.setInitialBody(parsed);
|
178 | ctx.request.updateRawBody(raw);
|
179 | action.end();
|
180 | return next();
|
181 | }
|
182 | catch (error) {
|
183 | action.end({ error });
|
184 | throw this.getExceptionFor(error);
|
185 | }
|
186 | }
|
187 | |
188 |
|
189 |
|
190 | const jsonConfig = this.getConfigFor('json');
|
191 | if (this.isType(ctx.request, jsonConfig.types)) {
|
192 | ctx.logger.trace('bodyparser parsing as json body');
|
193 | const action = ctx.profiler.profile('bodyparser:json');
|
194 | try {
|
195 | const { parsed, raw } = await co_body_1.default.json(ctx.request.request, jsonConfig);
|
196 | ctx.request.setInitialBody(parsed);
|
197 | ctx.request.updateRawBody(raw);
|
198 | action.end();
|
199 | return next();
|
200 | }
|
201 | catch (error) {
|
202 | action.end({ error });
|
203 | throw this.getExceptionFor(error);
|
204 | }
|
205 | }
|
206 | |
207 |
|
208 |
|
209 | const rawConfig = this.getConfigFor('raw');
|
210 | if (this.isType(ctx.request, rawConfig.types)) {
|
211 | ctx.logger.trace('bodyparser parsing as raw body');
|
212 | const action = ctx.profiler.profile('bodyparser:raw');
|
213 | try {
|
214 | const { raw } = await co_body_1.default.text(ctx.request.request, rawConfig);
|
215 | ctx.request.setInitialBody({});
|
216 | ctx.request.updateRawBody(raw);
|
217 | action.end();
|
218 | return next();
|
219 | }
|
220 | catch (error) {
|
221 | action.end({ error });
|
222 | throw this.getExceptionFor(error);
|
223 | }
|
224 | }
|
225 | await next();
|
226 | }
|
227 | };
|
228 | BodyParserMiddleware = __decorate([
|
229 | (0, application_1.inject)(['Adonis/Core/Config', 'Adonis/Core/Drive']),
|
230 | __metadata("design:paramtypes", [Object, Object])
|
231 | ], BodyParserMiddleware);
|
232 | exports.BodyParserMiddleware = BodyParserMiddleware;
|