mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-44: Use Guacamole.FileWriter within ManagedFileUpload (rather than load entire file into memory).
This commit is contained in:
@@ -29,16 +29,6 @@ angular.module('client').factory('ManagedFileUpload', ['$rootScope', '$injector'
|
|||||||
// Required services
|
// Required services
|
||||||
var $window = $injector.get('$window');
|
var $window = $injector.get('$window');
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum number of bytes to include in each blob for the Guacamole
|
|
||||||
* file stream. Note that this, along with instruction opcode and protocol-
|
|
||||||
* related overhead, must not exceed the 8192 byte maximum imposed by the
|
|
||||||
* Guacamole protocol.
|
|
||||||
*
|
|
||||||
* @type Number
|
|
||||||
*/
|
|
||||||
var STREAM_BLOB_SIZE = 4096;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object which serves as a surrogate interface, encapsulating a Guacamole
|
* Object which serves as a surrogate interface, encapsulating a Guacamole
|
||||||
* file upload while it is active, allowing it to be detached and
|
* file upload while it is active, allowing it to be detached and
|
||||||
@@ -136,93 +126,91 @@ angular.module('client').factory('ManagedFileUpload', ['$rootScope', '$injector'
|
|||||||
ManagedFileUpload.getInstance = function getInstance(client, file, object, streamName) {
|
ManagedFileUpload.getInstance = function getInstance(client, file, object, streamName) {
|
||||||
|
|
||||||
var managedFileUpload = new ManagedFileUpload();
|
var managedFileUpload = new ManagedFileUpload();
|
||||||
|
var streamAcknowledged = false;
|
||||||
|
|
||||||
// Construct reader for file
|
// Open file for writing
|
||||||
var reader = new FileReader();
|
var stream;
|
||||||
reader.onloadend = function fileContentsLoaded() {
|
if (!object)
|
||||||
|
stream = client.createFileStream(file.type, file.name);
|
||||||
|
|
||||||
// Open file for writing
|
// If object/streamName specified, upload to that instead of a file
|
||||||
var stream;
|
// stream
|
||||||
if (!object)
|
else
|
||||||
stream = client.createFileStream(file.type, file.name);
|
stream = object.createOutputStream(file.type, streamName);
|
||||||
|
|
||||||
// If object/streamName specified, upload to that instead of a file
|
// Notify that the file transfer is pending
|
||||||
// stream
|
$rootScope.$apply(function uploadStreamOpen() {
|
||||||
else
|
|
||||||
stream = object.createOutputStream(file.type, streamName);
|
|
||||||
|
|
||||||
var valid = true;
|
// Init managed upload
|
||||||
var bytes = new Uint8Array(reader.result);
|
managedFileUpload.filename = file.name;
|
||||||
var offset = 0;
|
managedFileUpload.mimetype = file.type;
|
||||||
|
managedFileUpload.progress = 0;
|
||||||
|
managedFileUpload.length = file.size;
|
||||||
|
|
||||||
$rootScope.$apply(function uploadStreamOpen() {
|
// Notify that stream is open
|
||||||
|
ManagedFileTransferState.setStreamState(managedFileUpload.transferState,
|
||||||
|
ManagedFileTransferState.StreamState.OPEN);
|
||||||
|
|
||||||
// Init managed upload
|
});
|
||||||
managedFileUpload.filename = file.name;
|
|
||||||
managedFileUpload.mimetype = file.type;
|
|
||||||
managedFileUpload.progress = 0;
|
|
||||||
managedFileUpload.length = bytes.length;
|
|
||||||
|
|
||||||
// Notify that stream is open
|
var writer = new Guacamole.FileWriter(stream);
|
||||||
ManagedFileTransferState.setStreamState(managedFileUpload.transferState,
|
|
||||||
ManagedFileTransferState.StreamState.OPEN);
|
|
||||||
|
|
||||||
});
|
// Begin upload when stream is acknowledged, notify of any errors
|
||||||
|
writer.onack = function ackReceived(status) {
|
||||||
// Invalidate stream on all errors
|
|
||||||
// Continue upload when acknowledged
|
|
||||||
stream.onack = function ackReceived(status) {
|
|
||||||
|
|
||||||
// Handle errors
|
|
||||||
if (status.isError()) {
|
|
||||||
valid = false;
|
|
||||||
$rootScope.$apply(function uploadStreamError() {
|
|
||||||
ManagedFileTransferState.setStreamState(managedFileUpload.transferState,
|
|
||||||
ManagedFileTransferState.StreamState.ERROR,
|
|
||||||
status.code);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Abort upload if stream is invalid
|
|
||||||
if (!valid)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Encode packet as base64
|
|
||||||
var slice = bytes.subarray(offset, offset + STREAM_BLOB_SIZE);
|
|
||||||
var base64 = getBase64(slice);
|
|
||||||
|
|
||||||
// Write packet
|
|
||||||
stream.sendBlob(base64);
|
|
||||||
|
|
||||||
// Advance to next packet
|
|
||||||
offset += STREAM_BLOB_SIZE;
|
|
||||||
|
|
||||||
$rootScope.$apply(function uploadStreamProgress() {
|
|
||||||
|
|
||||||
// If at end, stop upload
|
|
||||||
if (offset >= bytes.length) {
|
|
||||||
stream.sendEnd();
|
|
||||||
managedFileUpload.progress = bytes.length;
|
|
||||||
|
|
||||||
// Upload complete
|
|
||||||
ManagedFileTransferState.setStreamState(managedFileUpload.transferState,
|
|
||||||
ManagedFileTransferState.StreamState.CLOSED);
|
|
||||||
|
|
||||||
// Notify of upload completion
|
|
||||||
$rootScope.$broadcast('guacUploadComplete', file.name);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, update progress
|
|
||||||
else
|
|
||||||
managedFileUpload.progress = offset;
|
|
||||||
|
|
||||||
|
// Notify of any errors from the Guacamole server
|
||||||
|
if (status.isError()) {
|
||||||
|
$rootScope.$apply(function uploadStreamError() {
|
||||||
|
ManagedFileTransferState.setStreamState(managedFileUpload.transferState,
|
||||||
|
ManagedFileTransferState.StreamState.ERROR,
|
||||||
|
status.code);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}; // end ack handler
|
// Begin sending the requested file once stream is acknowledged
|
||||||
|
else if (!streamAcknowledged) {
|
||||||
|
writer.sendFile(file);
|
||||||
|
streamAcknowledged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Abort and notify if the file cannot be read
|
||||||
|
writer.onerror = function fileReadError(file, offset, error) {
|
||||||
|
|
||||||
|
// Abort transfer
|
||||||
|
writer.sendEnd();
|
||||||
|
|
||||||
|
// Upload failed
|
||||||
|
ManagedFileTransferState.setStreamState(managedFileUpload.transferState,
|
||||||
|
ManagedFileTransferState.StreamState.ERROR);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Notify of upload progress
|
||||||
|
writer.onprogress = function uploadProgressing(file, length) {
|
||||||
|
|
||||||
|
$rootScope.$apply(function uploadStreamProgress() {
|
||||||
|
managedFileUpload.progress = length;
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Clean up and notify when upload completes
|
||||||
|
writer.oncomplete = function uploadComplete(file) {
|
||||||
|
|
||||||
|
// If at end, stop upload
|
||||||
|
writer.sendEnd();
|
||||||
|
managedFileUpload.progress = file.size;
|
||||||
|
|
||||||
|
// Upload complete
|
||||||
|
ManagedFileTransferState.setStreamState(managedFileUpload.transferState,
|
||||||
|
ManagedFileTransferState.StreamState.CLOSED);
|
||||||
|
|
||||||
|
// Notify of upload completion
|
||||||
|
$rootScope.$broadcast('guacUploadComplete', file.name);
|
||||||
|
|
||||||
};
|
};
|
||||||
reader.readAsArrayBuffer(file);
|
|
||||||
|
|
||||||
return managedFileUpload;
|
return managedFileUpload;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user