Allow uploading files without content-type.
This commit is contained in:
@@ -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();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user