Skip to content

Commit 3072782

Browse files
committed
Merge pull request #330 from ParsePlatform/nlutsenko.es6.adapters
Refactor files.js into FilesController.
2 parents 3c1311f + 53b2d4e commit 3072782

File tree

4 files changed

+105
-102
lines changed

4 files changed

+105
-102
lines changed

src/Controllers/FilesController.js

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// FilesController.js
2+
3+
import express from 'express';
4+
import mime from 'mime';
5+
import { Parse } from 'parse/node';
6+
import BodyParser from 'body-parser';
7+
import hat from 'hat';
8+
import * as Middlewares from '../middlewares';
9+
import Config from '../Config';
10+
11+
const rack = hat.rack();
12+
13+
export class FilesController {
14+
constructor(filesAdapter) {
15+
this._filesAdapter = filesAdapter;
16+
}
17+
18+
getHandler() {
19+
return (req, res) => {
20+
let config = new Config(req.params.appId);
21+
this._filesAdapter.getFileDataAsync(config, req.params.filename).then((data) => {
22+
res.status(200);
23+
var contentType = mime.lookup(req.params.filename);
24+
res.set('Content-type', contentType);
25+
res.end(data);
26+
}).catch((error) => {
27+
res.status(404);
28+
res.set('Content-type', 'text/plain');
29+
res.end('File not found.');
30+
});
31+
};
32+
}
33+
34+
createHandler() {
35+
return (req, res, next) => {
36+
if (!req.body || !req.body.length) {
37+
next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR,
38+
'Invalid file upload.'));
39+
return;
40+
}
41+
42+
if (req.params.filename.length > 128) {
43+
next(new Parse.Error(Parse.Error.INVALID_FILE_NAME,
44+
'Filename too long.'));
45+
return;
46+
}
47+
48+
if (!req.params.filename.match(/^[_a-zA-Z0-9][a-zA-Z0-9@\.\ ~_-]*$/)) {
49+
next(new Parse.Error(Parse.Error.INVALID_FILE_NAME,
50+
'Filename contains invalid characters.'));
51+
return;
52+
}
53+
54+
// If a content-type is included, we'll add an extension so we can
55+
// return the same content-type.
56+
let extension = '';
57+
let hasExtension = req.params.filename.indexOf('.') > 0;
58+
let contentType = req.get('Content-type');
59+
if (!hasExtension && contentType && mime.extension(contentType)) {
60+
extension = '.' + mime.extension(contentType);
61+
}
62+
63+
let filename = rack() + '_' + req.params.filename + extension;
64+
this._filesAdapter.createFileAsync(req.config, filename, req.body).then(() => {
65+
res.status(201);
66+
var location = this._filesAdapter.getFileLocation(req.config, req, filename);
67+
res.set('Location', location);
68+
res.json({ url: location, name: filename });
69+
}).catch((error) => {
70+
console.log(error);
71+
next(new Parse.Error(Parse.Error.FILE_SAVE_ERROR,
72+
'Could not store file.'));
73+
});
74+
};
75+
}
76+
77+
getExpressRouter() {
78+
let router = express.Router();
79+
router.get('/files/:appId/:filename', this.getHandler());
80+
81+
router.post('/files', function(req, res, next) {
82+
next(new Parse.Error(Parse.Error.INVALID_FILE_NAME,
83+
'Filename not provided.'));
84+
});
85+
86+
router.post('/files/:filename',
87+
Middlewares.allowCrossDomain,
88+
BodyParser.raw({type: '*/*', limit: '20mb'}),
89+
Middlewares.handleParseHeaders,
90+
this.createHandler()
91+
);
92+
93+
return router;
94+
}
95+
}
96+
97+
export default FilesController;

src/FilesAdapter.js

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,12 @@
1111
// and for the API server to be using the ExportAdapter
1212
// database adapter.
1313

14-
let adapter = null;
15-
16-
export function setAdapter(filesAdapter) {
17-
adapter = filesAdapter;
18-
}
19-
20-
export function getAdapter() {
21-
return adapter;
22-
}
23-
2414
export class FilesAdapter {
2515
createFileAsync(config, filename, data) { }
2616

2717
getFileDataAsync(config, filename) { }
2818

2919
getFileLocation(config, request, filename) { }
3020
}
21+
22+
export default FilesAdapter;

src/files.js

Lines changed: 0 additions & 85 deletions
This file was deleted.

src/index.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ var batch = require('./batch'),
1212
PromiseRouter = require('./PromiseRouter'),
1313
httpRequest = require('./httpRequest');
1414

15-
import { setAdapter as setFilesAdapter } from './FilesAdapter';
1615
import { default as GridStoreAdapter } from './GridStoreAdapter';
16+
import { default as FilesController } from './Controllers/FilesController';
1717

1818
// Mutate the Parse object to add the Cloud Code handlers
1919
addParseCloud();
@@ -48,11 +48,9 @@ function ParseServer(args) {
4848
if (args.databaseAdapter) {
4949
DatabaseAdapter.setAdapter(args.databaseAdapter);
5050
}
51-
if (args.filesAdapter) {
52-
setFilesAdapter(args.filesAdapter);
53-
} else {
54-
setFilesAdapter(new GridStoreAdapter());
55-
}
51+
52+
let filesAdapter = args.filesAdapter || new GridStoreAdapter();
53+
5654
if (args.databaseURI) {
5755
DatabaseAdapter.setAppDatabaseURI(args.appId, args.databaseURI);
5856
}
@@ -95,7 +93,8 @@ function ParseServer(args) {
9593
var api = express();
9694

9795
// File handling needs to be before default middlewares are applied
98-
api.use('/', require('./files').router);
96+
let filesController = new FilesController(filesAdapter);
97+
api.use('/', filesController.getExpressRouter());
9998

10099
// TODO: separate this from the regular ParseServer object
101100
if (process.env.TESTING == 1) {

0 commit comments

Comments
 (0)