Skip to content

Allow uploading files without Content-Type. #579

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 42 additions & 18 deletions spec/ParseFile.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,49 @@ for (var i = 0; i < str.length; i++) {
}

describe('Parse.File testing', () => {
it('works with REST API', done => {
var headers = {
'Content-Type': 'application/octet-stream',
'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) => {
describe('creating files', () => {
it('works with Content-Type', done => {
var headers = {
'Content-Type': 'application/octet-stream',
'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);
expect(body).toEqual('argle bargle');
done();
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();
});
});
});

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();
});
});
});
});
Expand Down
6 changes: 3 additions & 3 deletions src/Controllers/FilesController.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class FilesController extends AdaptableController {
name: filename
});
});
}
}

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

expectedAdapterType() {
return FilesAdapter;
}
Expand Down
38 changes: 19 additions & 19 deletions src/Routers/FilesRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import mime from 'mime';
import Config from '../Config';

export class FilesRouter {

getExpressRouter() {
var router = express.Router();
router.get('/files/:appId/:filename', this.getHandler);
Expand All @@ -19,7 +19,7 @@ export class FilesRouter {

router.post('/files/:filename',
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,
this.createHandler
);
Expand All @@ -32,23 +32,23 @@ export class FilesRouter {
);
return router;
}
getHandler(req, res, next) {

getHandler(req, res) {
const config = new Config(req.params.appId);
const filesController = config.filesController;
const filename = req.params.filename;
filesController.getFileData(config, filename).then((data) => {
res.status(200);
var contentType = mime.lookup(filename);
res.set('Content-type', contentType);
res.end(data);
}).catch((error) => {
res.status(404);
res.set('Content-type', 'text/plain');
res.end('File not found.');
});
res.status(200);
var contentType = mime.lookup(filename);
res.set('Content-Type', contentType);
res.end(data);
}).catch(() => {
res.status(404);
res.set('Content-Type', 'text/plain');
res.end('File not found.');
});
}

createHandler(req, res, next) {
if (!req.body || !req.body.length) {
next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR,
Expand All @@ -68,7 +68,7 @@ export class FilesRouter {
return;
}
let extension = '';

// Not very safe there.
const hasExtension = req.params.filename.indexOf('.') > 0;
const contentType = req.get('Content-type');
Expand All @@ -81,15 +81,15 @@ export class FilesRouter {
const filesController = config.filesController;

filesController.createFile(config, filename, req.body).then((result) => {
res.status(201);
res.status(201);
res.set('Location', result.url);
res.json(result);
}).catch((err) => {
next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR,
'Could not store file.'));
next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR,
'Could not store file.'));
});
}

deleteHandler(req, res, next) {
const filesController = req.config.filesController;
filesController.deleteFile(req.config, req.params.filename).then(() => {
Expand Down