I am developping a tool which enables the user to upload large files (and by large i mean "size doesn't matter" large). I have pasted bellow the part of the code that actually handles the "upload" in JavaScript. The code itself works great, absolutely no problem. I have uploaded a 500 MB file in aprox. 15 minutes That is, on a crappy computer which also serves as a server. I expect it to work a lot better on an actual server.
What i'm asking for is suggestions for security that won't have to big an impact on performance and, also, performance upgrades. The way i see it, any attempt to encode/pack the data sent to the server will have a BIG impact on the performance.
Another issue is the chunkSize. I let the programmer choose how big a "slice" of file should be. However the limit is the server's max_post_size. By default it is set to 1024 * 512 bytes.
I have noticed(by countless test) that if I increase the chunk size the entire proccess of uploading works faster. The reason is obvious : The progress event and the communication with the server triggers less often. However, in case of a progress bar, the accuracy will be very low and it might cause the user to believe the application has crashed and close the page.
So basically i have these 2 questions :
1: how to encode/pack the data without affecting (too much) the performance
2: How could i increase the overall performance of the tool
Meanwhile, i will do some research myself.
Here is code that handles the upload :
Uploader.UploadFile = function (file, instance) {
var fr = new FileReader;
chunkSize = instance.settings.chunkSize > window.maxPost ? window.maxPost : instance.settings.chunkSize;
var chunks = Math.ceil(file.size / chunkSize);
var chunk = 0;
var startTime = (new Date()).getTime();
function SendSlice() {
var start, end;
start = chunk * chunkSize;
if (start > file.size) {
start = end + 1;
}
end = start + (chunkSize) >= file.size ? file.size : start + (chunkSize);
status = chunk == 0 ? "start" : (chunk == chunks ? "end" : "progress");
if (status == 'start') {
if(instance.settings.onStartUpload && instance.settings.onStartUpload.call) {
var event = new Uploader.Event.StartUpload({
time : (new Date()).getTime(),
file : file,
target : instance.element
});
instance.settings.onStartUpload(event);
}
}
fr.onload = function(e) {
var sliceData = e.target.result;
$.ajax({
type : "POST",
url : "uploader.php",
data : {
filename : file.name,
path : instance.settings.path,
status : status,
slice : sliceData
}
}).success(function(data) {
if (++chunk <= chunks) {
if(instance.settings.onProgress && instance.settings.onProgress.call) {
var event = new Uploader.Event.Progress({
time : (new Date()).getTime(),
file : file,
target : instance.element,
pieces: chunks,
currentPiece : chunk,
percent : (chunk / chunks) * 100,
bytesUploaded : end,
bytesRemaining : file.size - end
});
instance.settings.onProgress(event);
}
SendSlice();
} else {
if(instance.settings.onCompleteFile && instance.settings.onCompleteFile.call) {
var time = (new Date()).getTime();
var duration = time - startTime;
var event = new Uploader.Event.FileComplete({
time : time,
file : file,
target : instance.element,
duration : duration
});
instance.settings.onCompleteFile(event);
}
}
});
};
fr.readAsDataURL(file.slice(start, end));
}
SendSlice();
}