Skip to content

Commit 4d16702

Browse files
authored
fix: empty file tags cause upload error for some providers (#7300)
* fix: empty file tags cause upload error for some providers DigitalOcean and Linode object storage solutions do not accept `tags` option while uploading a file. Previously, tags option was set to default empty object. Now, we do not include it if it is empty. * chore: add tests for saving a file with/without tags * chore: update file tags handling to make tests pass * chore: refactor file tag tests * chore: update file tag tests * chore: update changelog * chore: update changelog entry * chore: remove duplicated changelog entry
1 parent 626352d commit 4d16702

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ ___
121121
- Excluding keys that have trailing edges.node when performing GraphQL resolver (Chris Bland) [#7273](https://github.com/parse-community/parse-server/pull/7273)
122122
- Added centralized feature deprecation with standardized warning logs (Manuel Trezza) [#7303](https://github.com/parse-community/parse-server/pull/7303)
123123
- Use Node.js 15.13.0 in CI (Olle Jonsson) [#7312](https://github.com/parse-community/parse-server/pull/7312)
124+
- Fix file upload issue for S3 compatible storage (Linode, DigitalOcean) by avoiding empty tags property when creating a file (Ali Oguzhan Yildiz) [#7300](https://github.com/parse-community/parse-server/pull/7300)
124125
___
125126
## 4.5.0
126127
[Full Changelog](https://github.com/parse-community/parse-server/compare/4.4.0...4.5.0)

spec/ParseFile.spec.js

+29
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
'use strict';
55

6+
const { FilesController } = require('../lib/Controllers/FilesController');
67
const request = require('../lib/request');
78

89
const str = 'Hello World!';
@@ -205,6 +206,34 @@ describe('Parse.File testing', () => {
205206
notEqual(file.name(), 'hello.txt');
206207
});
207208

209+
it('saves the file with tags', async () => {
210+
spyOn(FilesController.prototype, 'createFile').and.callThrough();
211+
const file = new Parse.File('hello.txt', data, 'text/plain');
212+
const tags = { hello: 'world' };
213+
file.setTags(tags);
214+
expect(file.url()).toBeUndefined();
215+
const result = await file.save();
216+
expect(file.name()).toBeDefined();
217+
expect(file.url()).toBeDefined();
218+
expect(result.tags()).toEqual(tags);
219+
expect(FilesController.prototype.createFile.calls.argsFor(0)[4]).toEqual({
220+
tags: tags,
221+
metadata: {},
222+
});
223+
});
224+
225+
it('does not pass empty file tags while saving', async () => {
226+
spyOn(FilesController.prototype, 'createFile').and.callThrough();
227+
const file = new Parse.File('hello.txt', data, 'text/plain');
228+
expect(file.url()).toBeUndefined();
229+
expect(file.name()).toBeDefined();
230+
await file.save();
231+
expect(file.url()).toBeDefined();
232+
expect(FilesController.prototype.createFile.calls.argsFor(0)[4]).toEqual({
233+
metadata: {},
234+
});
235+
});
236+
208237
it('save file in object', async done => {
209238
const file = new Parse.File('hello.txt', data, 'text/plain');
210239
ok(!file.url());

src/Routers/FilesRouter.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -166,16 +166,22 @@ export class FilesRouter {
166166
// update fileSize
167167
const bufferData = Buffer.from(fileObject.file._data, 'base64');
168168
fileObject.fileSize = Buffer.byteLength(bufferData);
169+
// prepare file options
170+
const fileOptions = {
171+
metadata: fileObject.file._metadata,
172+
};
173+
// some s3-compatible providers (DigitalOcean, Linode) do not accept tags
174+
// so we do not include the tags option if it is empty.
175+
const fileTags =
176+
Object.keys(fileObject.file._tags).length > 0 ? { tags: fileObject.file._tags } : {};
177+
Object.assign(fileOptions, fileTags);
169178
// save file
170179
const createFileResult = await filesController.createFile(
171180
config,
172181
fileObject.file._name,
173182
bufferData,
174183
fileObject.file._source.type,
175-
{
176-
tags: fileObject.file._tags,
177-
metadata: fileObject.file._metadata,
178-
}
184+
fileOptions
179185
);
180186
// update file with new data
181187
fileObject.file._name = createFileResult.name;

0 commit comments

Comments
 (0)