Allow uploading files without content-type.

This commit is contained in:
Nikita Lutsenko
2016-02-22 13:59:24 -08:00
parent bbc3d36d51
commit 966d10ca43
3 changed files with 64 additions and 40 deletions

View File

@@ -10,25 +10,49 @@ for (var i = 0; i < str.length; i++) {
} }
describe('Parse.File testing', () => { describe('Parse.File testing', () => {
it('works with REST API', done => { describe('creating files', () => {
var headers = { it('works with Content-Type', done => {
'Content-Type': 'application/octet-stream', var headers = {
'X-Parse-Application-Id': 'test', 'Content-Type': 'application/octet-stream',
'X-Parse-REST-API-Key': 'rest' 'X-Parse-Application-Id': 'test',
}; 'X-Parse-REST-API-Key': 'rest'
request.post({ };
headers: headers, request.post({
url: 'http://localhost:8378/1/files/file.txt', headers: headers,
body: 'argle bargle', url: 'http://localhost:8378/1/files/file.txt',
}, (error, response, body) => { body: 'argle bargle',
expect(error).toBe(null); }, (error, response, body) => {
var b = JSON.parse(body);
expect(b.name).toMatch(/_file.txt$/);
expect(b.url).toMatch(/^http:\/\/localhost:8378\/1\/files\/test\/.*file.txt$/);
request.get(b.url, (error, response, body) => {
expect(error).toBe(null); expect(error).toBe(null);
expect(body).toEqual('argle bargle'); var b = JSON.parse(body);
done(); expect(b.name).toMatch(/_file.txt$/);
expect(b.url).toMatch(/^http:\/\/localhost:8378\/1\/files\/test\/.*file.txt$/);
request.get(b.url, (error, response, body) => {
expect(error).toBe(null);
expect(body).toEqual('argle bargle');
done();
});
});
});
it('works without Content-Type', done => {
var headers = {
'X-Parse-Application-Id': 'test',
'X-Parse-REST-API-Key': 'rest'
};
request.post({
headers: headers,
url: 'http://localhost:8378/1/files/file.txt',
body: 'argle bargle',
}, (error, response, body) => {
expect(error).toBe(null);
var b = JSON.parse(body);
expect(b.name).toMatch(/_file.txt$/);
expect(b.url).toMatch(/^http:\/\/localhost:8378\/1\/files\/test\/.*file.txt$/);
request.get(b.url, (error, response, body) => {
expect(error).toBe(null);
expect(body).toEqual('argle bargle');
done();
});
}); });
}); });
}); });

View File

@@ -19,7 +19,7 @@ export class FilesController extends AdaptableController {
name: filename name: filename
}); });
}); });
} }
deleteFile(config, filename) { deleteFile(config, filename) {
return this.adapter.deleteFile(config, filename); return this.adapter.deleteFile(config, filename);
@@ -30,7 +30,7 @@ export class FilesController extends AdaptableController {
* with the current mount point and app id. * with the current mount point and app id.
* Object may be a single object or list of REST-format objects. * Object may be a single object or list of REST-format objects.
*/ */
expandFilesInObject(config, object) { expandFilesInObject(config, object) {
if (object instanceof Array) { if (object instanceof Array) {
object.map((obj) => this.expandFilesInObject(config, obj)); object.map((obj) => this.expandFilesInObject(config, obj));
return; return;
@@ -53,7 +53,7 @@ export class FilesController extends AdaptableController {
} }
} }
} }
expectedAdapterType() { expectedAdapterType() {
return FilesAdapter; return FilesAdapter;
} }

View File

@@ -7,7 +7,7 @@ import mime from 'mime';
import Config from '../Config'; import Config from '../Config';
export class FilesRouter { export class FilesRouter {
getExpressRouter() { getExpressRouter() {
var router = express.Router(); var router = express.Router();
router.get('/files/:appId/:filename', this.getHandler); router.get('/files/:appId/:filename', this.getHandler);
@@ -19,7 +19,7 @@ export class FilesRouter {
router.post('/files/:filename', router.post('/files/:filename',
Middlewares.allowCrossDomain, Middlewares.allowCrossDomain,
BodyParser.raw({type: '*/*', limit: '20mb'}), BodyParser.raw({type: () => { return true; }, limit: '20mb'}), // Allow uploads without Content-Type, or with any Content-Type.
Middlewares.handleParseHeaders, Middlewares.handleParseHeaders,
this.createHandler this.createHandler
); );
@@ -32,23 +32,23 @@ export class FilesRouter {
); );
return router; return router;
} }
getHandler(req, res, next) { getHandler(req, res) {
const config = new Config(req.params.appId); const config = new Config(req.params.appId);
const filesController = config.filesController; const filesController = config.filesController;
const filename = req.params.filename; const filename = req.params.filename;
filesController.getFileData(config, filename).then((data) => { filesController.getFileData(config, filename).then((data) => {
res.status(200); res.status(200);
var contentType = mime.lookup(filename); var contentType = mime.lookup(filename);
res.set('Content-type', contentType); res.set('Content-Type', contentType);
res.end(data); res.end(data);
}).catch((error) => { }).catch(() => {
res.status(404); res.status(404);
res.set('Content-type', 'text/plain'); res.set('Content-Type', 'text/plain');
res.end('File not found.'); res.end('File not found.');
}); });
} }
createHandler(req, res, next) { createHandler(req, res, next) {
if (!req.body || !req.body.length) { if (!req.body || !req.body.length) {
next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR, next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR,
@@ -68,7 +68,7 @@ export class FilesRouter {
return; return;
} }
let extension = ''; let extension = '';
// Not very safe there. // Not very safe there.
const hasExtension = req.params.filename.indexOf('.') > 0; const hasExtension = req.params.filename.indexOf('.') > 0;
const contentType = req.get('Content-type'); const contentType = req.get('Content-type');
@@ -81,15 +81,15 @@ export class FilesRouter {
const filesController = config.filesController; const filesController = config.filesController;
filesController.createFile(config, filename, req.body).then((result) => { filesController.createFile(config, filename, req.body).then((result) => {
res.status(201); res.status(201);
res.set('Location', result.url); res.set('Location', result.url);
res.json(result); res.json(result);
}).catch((err) => { }).catch((err) => {
next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR, next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR,
'Could not store file.')); 'Could not store file.'));
}); });
} }
deleteHandler(req, res, next) { deleteHandler(req, res, next) {
const filesController = req.config.filesController; const filesController = req.config.filesController;
filesController.deleteFile(req.config, req.params.filename).then(() => { filesController.deleteFile(req.config, req.params.filename).then(() => {