1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Server: Fixes #4402: Fixed uploading empty file to the API

This commit is contained in:
Laurent Cozic 2021-01-25 12:04:18 +00:00
parent dbbbd22aef
commit e828c8e6eb
2 changed files with 15 additions and 5 deletions

View File

@ -1,4 +1,4 @@
import { ErrorNotFound, ErrorBadRequest } from '../../utils/errors'; import { ErrorNotFound } from '../../utils/errors';
import { File } from '../../db'; import { File } from '../../db';
import { bodyFields, formParse } from '../../utils/requestUtils'; import { bodyFields, formParse } from '../../utils/requestUtils';
import { SubPath, respondWithFileContent } from '../../utils/routeUtils'; import { SubPath, respondWithFileContent } from '../../utils/routeUtils';
@ -57,8 +57,12 @@ router.put('api/files/:id/content', async (path: SubPath, ctx: AppContext) => {
const fileModel = ctx.models.file({ userId: ctx.owner.id }); const fileModel = ctx.models.file({ userId: ctx.owner.id });
const fileId = path.id; const fileId = path.id;
const result = await formParse(ctx.req); const result = await formParse(ctx.req);
if (!result?.files?.file) throw new ErrorBadRequest('File data is missing');
const buffer = await fs.readFile(result.files.file.path); // When an app PUTs an empty file, `result.files` will be an emtpy object
// (could be the way Formidable parses the data?), but we still need to
// process the file so we set its content to an empty buffer.
// https://github.com/laurent22/joplin/issues/4402
const buffer = result?.files?.file ? await fs.readFile(result.files.file.path) : Buffer.alloc(0);
const file: File = await fileModel.entityFromItemId(fileId, { mustExist: false }); const file: File = await fileModel.entityFromItemId(fileId, { mustExist: false });
file.content = buffer; file.content = buffer;

View File

@ -1,4 +1,4 @@
import { ErrorBadRequest, ErrorForbidden } from './errors'; import { ErrorForbidden } from './errors';
import { AppContext } from './types'; import { AppContext } from './types';
const formidable = require('formidable'); const formidable = require('formidable');
@ -36,11 +36,17 @@ export async function formParse(req: any): Promise<FormParseResult> {
} }
export async function bodyFields(req: any): Promise<BodyFields> { export async function bodyFields(req: any): Promise<BodyFields> {
// Formidable needs the content-type to be 'application/json' so on our side
// we explicitely set it to that. However save the previous value so that it
// can be restored.
let previousContentType = null;
if (req.headers['content-type'] !== 'application/json') { if (req.headers['content-type'] !== 'application/json') {
throw new ErrorBadRequest(`Unsupported Content-Type: "${req.headers['content-type']}". Expected: "application/json"`); previousContentType = req.headers['content-type'];
req.headers['content-type'] = 'application/json';
} }
const form = await formParse(req); const form = await formParse(req);
if (previousContentType) req.headers['content-type'] = previousContentType;
return form.fields; return form.fields;
} }