|
FileSystemAPI
Secure client file access
IntroductionThe purpose of this module is to provide secure access to files on the client machine. The FileSystem module has now been merged with the Desktop module. Therefore this document describes the FileSystem functionality in the Desktop module. NOTEWe should do something API wise that fits as close as possible with <input type="file"> and the webforms file picker extensions. See also: http://www.whatwg.org/specs/web-forms/current-work/#upload http://groups.google.com/group/google-gears-eng/browse_thread/thread/f73cb640a1c845/8026291efe8fc8a5 The one remaining issue preventing us from designing this is that we also have some desire to implement file writing. It's unclear how this relates and what the API would look like. FeaturesMultiple files can be provided by the user.
SecurityAccess to the user's file system can only be granted by the user.
Trade-offsSelecting directories
Use casesName: input files Description: a user provides details of files to make available for further processing Author: Chris De Vries Date: 11/01/2008 Steps:
JavaScript Interfaces
interface Desktop {
//
// ... other apis ...
//
// Displays a file chooser to the user, from which they can select files on the local
// disk. The callback is invoked with an array of the files which were selected.
void openFiles(OpenFilesCallback callback, optional OpenFilesOptions options);
}
void OpenFilesCallback(File[] files);
interface File {
// The name of the file, excluding the path.
readonly attribute string name;
// The contents of the file.
readonly attribute Blob blob;
}
interface OpenFileOptions {
// By default, the user may select multiple files. If true, the user is limited to
// selecting only one file.
bool singleFile;
// By default, all files on the local disk are shown as selectable. If a filter is
// provided, only files matching the filter are shown. The user can turn the filter
// off, so be aware that selected files may not match the filter. The filter is an
// array of Internet content types and file extensions.
// Example: ['text/html', '.txt', 'image/jpeg']
string[] filter;
}
C++ Internal Interfaces// Constructs a file dialog according to mode.
// Caller is responsible for freeing the returned memory.
// Returns: null pointer on failure
// Parameters:
// mode - in - the type of dialog to construct
FileDialog* NewFileDialog(const FileDialog::Mode mode,
const ModuleImplBaseClass& module);
// This interface will be implemented for every supported operating system.
class FileDialog {
// Used for constructing dialogs.
// This is intended to allow for different types of file pickers in future.
// For example, FILES_AND_DIRECTORIES, for a custom dialog that allows the
// user to select files and directories at the same time.
enum Mode {
MULTIPLE_FILES // one or more files
};
struct Filter {
// The text the user sees. For example "Images".
std::string16 description;
// A semi-colon separated list of filters. For example "*.jpg;*.gif;*.png".
std::string16 filter;
};
// Displays a file dialog.
// Returns: false on invalid input or failure
// Parameters:
// filter - in, optional - An array consisting of pairs of strings.
// Every first string is a description of a filter.
// Every second string is a semi-colon separated list of filters.
// Example "Images" and "*.jpg;*.gif;*.png".
//
// files - out - An array of files selected by the user.
// If the user canceled the dialog this will be an empty array.
// A new array is constructed and placed here.
// Caller is responsible for freeing returned memory.
//
// error - out - The error message if the function returned false.
//
virtual bool OpenDialog(const std::vector<Filter>& filters,
std::vector<std::string16>* selected_files,
std::string16* error) = 0;
}Code Examplevar desktop = google.gears.factory.create('beta.desktop');
var files = desktop.getLocalFiles(['Images (*.jpg, *.gif)', '*.jpg;*.gif', 'All files', '*']);
for (var i = 0; i < files.length; ++i) {
var img = document.createElement("img");
img.src = files[i];
document.body.appendChild(img);
}
|
Sign in to add a comment
It's a real shame that greater access hasn't been given to the file system, especially entire folders. The use case where local file access is most compelling is where the client requires heavy resources which would be too slow over the internet such as high res images which may be numerous and too much of a pain to select one by one with the current API.
Imagine you wanted to take an app 'like' Google Maps off line and wanted have the map tiles pre-cached locally, there is no feasible way to achieve this with Gears, what are you going to do? Add twenty thousand tiles to the manifest? Ask the user to select them all with a file picker?
It would have been interesting if Gears has something like the POW Firefox add-on which creates a web server right within Firefox. As client server communication over http is a security model most people are far more familiar with, just in this case the web server is always local. I'm sure it would have granted you all more freedom to experiment.
Security model presented here is great however I am surprised with the lack of attention that should have been given when browser is running in a local mode i.e. using file:/// protocol. In which case, without breaking security policies, there should be functions available to execute local commands within context. Think of a situation when the browser is running from a DVD/CD to run a trusted HTML and JavaScript? based application that could require access to some executable files.
We have a use case where we need to have to user select a single XML file and then locally on the client side process the XML, discover other imported XML documents, and then process those as well. Currently we're stuck with an Applet to do this, but would like to move away from it because of the multitude of problems getting the applet to load in different browsers and different versions. The limitations on the Gears file api eliminates Gears as an alternative for us.
I second the comment by evan.leonard. We would love to be able to explore a user selected directory tree to find files specified, for example, by columns in a spreadsheet. I think this could be made reasonably secure by sticking to a single volume, ignoring symlinks, etc.
As it stands, we'll just have to resort to using something like Adobe AIR to do this.
I third opening the API to allow script access to the contents of USER selected files. This is not a security risk as such because nothing is stopping the script from uploading that content to the server and downloading it right back! In fact this is exactly how we are getting around this issue now. It makes much more sense (and is more secure) to just allow it to be done in-browser.
I fourth the comments by evan.leonard, cjmason & pauldorn. The limitation of the Gears file api eliminates Gears as a solution for our Web app.