зеркало из https://github.com/mozilla/makedrive.git
Issue #312 - enforce filesystem limits
This commit is contained in:
Родитель
ae0e2572a8
Коммит
58281d1997
|
@ -6,4 +6,4 @@ before_install:
|
|||
before_script:
|
||||
- grunt init
|
||||
env:
|
||||
- "PORT=9090 ALLOWED_CORS_DOMAINS=\"http://localhost:7777\" NODE_ENV=\"development\" ENABLE_GELF_LOGS=false SESSION_SECRET=\"secret value\" FORCE_SSL=false LOGIN_SERVER_URL_WITH_AUTH=\"http://localhost:3000\" ENABLE_PATH_ROUTE=true ENABLE_JSON_ROUTE=true ENABLE_ZIP_ROUTE=true"
|
||||
- "PORT=9090 ALLOWED_CORS_DOMAINS=\"http://localhost:7777\" NODE_ENV=\"development\" ENABLE_GELF_LOGS=false SESSION_SECRET=\"secret value\" FORCE_SSL=false LOGIN_SERVER_URL_WITH_AUTH=\"http://localhost:3000\" ENABLE_PATH_ROUTE=true ENABLE_JSON_ROUTE=true ENABLE_ZIP_ROUTE=true MAX_SYNC_SIZE_BYTES=2000000"
|
||||
|
|
|
@ -192,7 +192,7 @@ module.exports = function(grunt) {
|
|||
},
|
||||
makeDriveClient: {
|
||||
files: ['client/src/*.js'],
|
||||
tasks: ["build"],
|
||||
tasks: ["makedriveClient"],
|
||||
options: {
|
||||
spawn: false
|
||||
}
|
||||
|
@ -228,6 +228,7 @@ module.exports = function(grunt) {
|
|||
grunt.registerTask( "default", [ "test" ] );
|
||||
grunt.registerTask( "init", [ "exec:grunt_bower" ] );
|
||||
grunt.registerTask( "build", [ "clean", "browserify:makedriveClient", "uglify" ] );
|
||||
grunt.registerTask( "makedriveClient", [ "clean", "browserify:makedriveClient", "uglify:develop" ] );
|
||||
grunt.registerTask( "install", [ "less", "uglify:dependencies", "uglify:angular_app" ] );
|
||||
grunt.registerTask( "dev", [ "less", "uglify:angular_app", "build", "express:dev", "watch" ] );
|
||||
|
||||
|
|
|
@ -223,6 +223,9 @@ function handleError(syncManager, data) {
|
|||
var message = SyncMessage.request.reset;
|
||||
syncManager.send(message.stringify());
|
||||
onError(syncManager, new Error('Could not sync filesystem from server... trying again'));
|
||||
} else if(data.is.maxsizeExceeded) {
|
||||
// We are only emitting the error since this is can be sync again from the client
|
||||
syncManager.sync.emit('error', new Error('Maximum file size exceeded'));
|
||||
} else {
|
||||
onError(syncManager, new Error('Failed to sync with the server. Current step is: ' +
|
||||
session.step + '. Current state is: ' + session.state));
|
||||
|
|
4
env.dist
4
env.dist
|
@ -87,3 +87,7 @@ export MAKEDRIVE_UPSTREAM_NAME="upstream"
|
|||
# Upstream branch to ovewrite on a grunt release command
|
||||
# (Default to "master")
|
||||
export MAKEDRIVE_UPSTREAM_BRANCH="master"
|
||||
|
||||
# Maximum file size allow to sync.
|
||||
# (Default to unlimited if not set)
|
||||
export MAX_SYNC_SIZE_BYTES=
|
||||
|
|
|
@ -61,6 +61,9 @@ function SyncMessage(type, name, content) {
|
|||
},
|
||||
get downstreamLocked() {
|
||||
return that.name === SyncMessage.DOWNSTREAM_LOCKED;
|
||||
},
|
||||
get fileSizeError() {
|
||||
return that.type === SyncMessage.ERROR && that.name === SyncMessage.MAXSIZE;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -101,6 +104,7 @@ SyncMessage.AUTHZ = "AUTHORIZED";
|
|||
SyncMessage.IMPL = "IMPLEMENTATION";
|
||||
SyncMessage.SERVER_RESET = "SERVER_RESET";
|
||||
SyncMessage.DOWNSTREAM_LOCKED = "DOWNSTREAM_LOCKED";
|
||||
SyncMessage.MAXSIZE = "MAXSIZE";
|
||||
|
||||
// SyncMessage Error constants
|
||||
SyncMessage.INFRMT = "INVALID FORMAT";
|
||||
|
@ -120,7 +124,8 @@ function isValidName(name) {
|
|||
name === SyncMessage.INFRMT ||
|
||||
name === SyncMessage.INCONT ||
|
||||
name === SyncMessage.SERVER_RESET ||
|
||||
name === SyncMessage.DOWNSTREAM_LOCKED;
|
||||
name === SyncMessage.DOWNSTREAM_LOCKED ||
|
||||
name === SyncMessage.MAXSIZE;
|
||||
}
|
||||
|
||||
function isValidType(type) {
|
||||
|
@ -189,6 +194,9 @@ SyncMessage.error = {
|
|||
get downstreamLocked() {
|
||||
return new SyncMessage(SyncMessage.ERROR, SyncMessage.DOWNSTREAM_LOCKED, 'Downstream syncs are locked!');
|
||||
},
|
||||
get maxsizeExceeded() {
|
||||
return new SyncMessage(SyncMessage.ERROR, SyncMessage.MAXSIZE, 'Maximum file size exceeded');
|
||||
},
|
||||
get verification() {
|
||||
return new SyncMessage(SyncMessage.ERROR,
|
||||
SyncMessage.VERIFICATION,
|
||||
|
|
|
@ -21,6 +21,7 @@ var ActiveSyncManager = require('../../server/lib/active-sync-manager');
|
|||
var connectedClients = {};
|
||||
|
||||
var CLIENT_TIMEOUT_MS = env.get('CLIENT_TIMEOUT_MS') || 5000;
|
||||
var MAX_SYNC_SIZE_BYTES = env.get('MAX_SYNC_SIZE_BYTES', Math.Infinity);
|
||||
|
||||
function Sync(username, id, ws) {
|
||||
EventEmitter.call(this);
|
||||
|
@ -410,6 +411,20 @@ function handleRequest(sync, data) {
|
|||
|
||||
var srcList = data.content.srcList;
|
||||
|
||||
// Check file size limit
|
||||
for (var key in srcList) {
|
||||
var obj = srcList[key];
|
||||
for (var prop in obj) {
|
||||
if(obj.hasOwnProperty(prop) && prop === 'size') {
|
||||
if(obj.size > MAX_SYNC_SIZE_BYTES) {
|
||||
sync.state = Sync.LISTENING;
|
||||
ActiveSyncManager.remove(sync.username);
|
||||
return sync.sendMessage(SyncMessage.error.maxsizeExceeded, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rsync.checksums(sync.fs, sync.path, srcList, rsyncOptions, function(err, checksums) {
|
||||
if(err) {
|
||||
sync.state = Sync.LISTENING;
|
||||
|
|
|
@ -18,6 +18,8 @@ var MakeDrive = require('../../client/src/index.js');
|
|||
// Ensure the client timeout restricts tests to a reasonable length
|
||||
var env = require('../../server/lib/environment');
|
||||
env.set('CLIENT_TIMEOUT_MS', 1000);
|
||||
// Set maximum file size limit to 2000000 bytes
|
||||
env.set('MAX_SYNC_SIZE_BYTES', 2000000);
|
||||
|
||||
// Enable a username:password for BASIC_AUTH_USERS to enable /api/get route
|
||||
env.set('BASIC_AUTH_USERS', 'testusername:testpassword');
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
var env = require('../../../server/lib/environment');
|
||||
var expect = require('chai').expect;
|
||||
var util = require('../../lib/util.js');
|
||||
var MakeDrive = require('../../../client/src');
|
||||
var Filer = require('../../../lib/filer.js');
|
||||
var MAX_SIZE_BYTES = 2000000;
|
||||
|
||||
describe('Syncing file larger than size limit', function(){
|
||||
var provider;
|
||||
|
||||
beforeEach(function() {
|
||||
var username = util.username();
|
||||
provider = new Filer.FileSystem.providers.Memory(username);
|
||||
});
|
||||
afterEach(function() {
|
||||
provider = null;
|
||||
});
|
||||
|
||||
it('should return an error if file exceeded the size limit', function(done) {
|
||||
util.authenticatedConnection(function(err, result) {
|
||||
expect(err).not.to.exist;
|
||||
|
||||
var fs = MakeDrive.fs({provider: provider, manual: true, forceCreate: true});
|
||||
var sync = fs.sync;
|
||||
var layout = {'/hello.txt': new Filer.Buffer(MAX_SIZE_BYTES+1) };
|
||||
|
||||
sync.once('connected', function onClientConnected() {
|
||||
|
||||
util.createFilesystemLayout(fs, layout, function(err) {
|
||||
expect(err).not.to.exist;
|
||||
|
||||
sync.request();
|
||||
});
|
||||
|
||||
});
|
||||
sync.once('error', function onClientError(error) {
|
||||
expect(error).to.eql(new Error('Maximum file size exceeded'));
|
||||
done();
|
||||
});
|
||||
|
||||
sync.connect(util.socketURL, result.token);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not return an error if file did not exceed the size limit', function(done) {
|
||||
var everError = false;
|
||||
|
||||
util.authenticatedConnection(function(err, result) {
|
||||
expect(err).not.to.exist;
|
||||
|
||||
var fs = MakeDrive.fs({provider: provider, manual: true, forceCreate: true});
|
||||
var sync = fs.sync;
|
||||
var layout = {'/hello.txt': new Filer.Buffer(MAX_SIZE_BYTES) };
|
||||
|
||||
sync.once('connected', function onClientConnected() {
|
||||
|
||||
util.createFilesystemLayout(fs, layout, function(err) {
|
||||
expect(err).not.to.exist;
|
||||
|
||||
sync.request();
|
||||
});
|
||||
|
||||
});
|
||||
sync.once('completed', function() {
|
||||
expect(everError).to.be.false;
|
||||
done();
|
||||
});
|
||||
sync.once('error', function onClientError(error) {
|
||||
everError = true;
|
||||
});
|
||||
|
||||
sync.connect(util.socketURL, result.token);
|
||||
});
|
||||
});
|
||||
});
|
Загрузка…
Ссылка в новой задаче