diff --git a/README.md b/README.md index 4bfa9b8..6c95940 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,263 @@ fuse-wsfs combines libwebsockets and libfuse. It allows ot attach a remote files **Status**: Proof of concept ***Latest Build on travis***: [https://travis-ci.com/falk-werner/fuse-wsfs](https://travis-ci.com/falk-werner/fuse-wsfs) +# Workflow an API + + +---------------------+ +-------------+ +------+ + | Filesystem Provider | | wsfs daemon | | user | + | (e.g. Webbrowser) | | | | | + +----------+----------+ +------+------+ +---+--+ + | | | + | +-+-+ | + | | +--+ | + | | | | fuse_mount | + | | +<-+ | + | | | | + | | +--+ | + | | | | start ws | + | | +<-+ | + | +-+-+ | + | | | + +-+-+ connect +-+-+ | + | |--------------->| | | + +-+-+ +-+-+ | + | | | + | +-+-+ ls +-+-+ + +-+-+ readdir | |<------------+ | + | |<---------------+ | | | + | | | | | | + | | readdir_resp | | | | + | +--------------->| | [., ..] | | + +-+-+ | +------------>| | + | +-+-+ +-+-+ + | | | + +With fuse-wsfs it is possible to implement remote filesystems based on websockets. +A reference implementation of such a daemon is provided within the examples. The picture above describes the workflow: + +- The websocket filesystem daemon (*wsfs daemon*) mounts a filesystem on startup. + It starts the websocket server and waits for incoming connections. +- A remote filesystem provider connects to wsfs daemon via websocket protocol. + The example includes such a provider implemented in HTML and JavaScript. +- Whenever the user makes filesystem requests, such as *ls*, the request is redirected via wsfs daemon to the connected filesystem provider + +Currently all requests are initiated by wsfs daemon and responded by filesystem provider. This may change in future, e.g. when authentication is supported. + +## Requests, responses and notifications + +There are three types of messages, used for communication between wsfs daemon and filesystem provider. All message types are encoded in [JSON](https://www.json.org/) and strongly inspired by [JSON-RPC](https://www.jsonrpc.org/). + +### Request + +A request is used by a sender to invoke a method on the receiver. The sender awaits a response from the receiver. Since requests and responses can be sendet or answered in any order, an id is provided in each request to identify it. + + { + "method": , + "params": , + "id" : + } + +| Item | Data type | Description | +| ----------- |:---------:| --------------------------------- | +| method_name | string | name of the method to invoke | +| params | array | method specific parameters | +| id | integer | id, which is repeated in response | + +### Response + +A response is used to answer a prior request. There are two kinds of responses: + +#### Successful Results + + { + "result": , + "id": + } + +| Item | Data type | Description | +| ----------- |:---------:| ----------------------- | +| result | any | request specific result | +| id | integer | id, same as request | + +#### Error notifications + + { + "error": { + "code": + }, + "id": + } + +| Item | Data type | Description | +| ----------- |:---------:| ------------------- | +| code | integer | error code | +| id | integer | id, same as request | + +#### Error codes + +| Symbolic name | Code | Description | +| ------------------ | ---------:| ---------------------- | +| GOOD | 0 | no error | +| BAD | 1 | generic error | +| BAD_NOTIMPLEMENTED | 2 | method not implemented | +| BAD_TIMEOUT | 3 | timeout occured | +| BAD_BUSY | 4 | resource busy | +| BAD_FORMAT | 5 | invalid formt | +| BAD_NOENTRY | 101 | invalid entry | +| BAD_NOACCESS | 102 | access not allowed | + +### Notification + +Notfications are used to inform a receiver about something. Unlike requests, notifications are not answered. Therefore, an id is not supplied. + + { + "method": , + "params": + } + +| Item | Data type | Description | +| ----------- |:---------:| --------------------------------- | +| method_name | string | name of the method to invoke | +| params | array | method specific parameters | + +## Requests + +### lookup + +Retrieve information about a filesystem entry by name. + + wsfs daemon: {"method": "lookup", "params": [, ], "id": } + fs provider: {"result": { + "inode": , + "mode" : , + "type" : , + "size" : , + "atime": , + "mtime": , + "ctime": + }, "id": } + +| Item | Data type | Description | +| ----------- | --------------- | ------------------------------------------- | +| parent | integer | inode of parent directory (1 = root) | +| name | string | name of the filesystem object to look up | +| inode | integer | inode of the filesystem object | +| mode | integer | unix file mode | +| type | "file" or "dir" | type of filesystem object | +| size | integer | required for files; file size in bytes | +| atime | integer | optional; unix time of last access | +| mtime | integer | optional; unix time of last modification | +| ctime | intefer | optional; unix time of last metadata change | + +### getattr + +Get file attributes. + + wsfs daemon: {"method": "getattr", "params": [], "id": } + fs provider: {"result": { + "mode" : , + "type" : , + "size" : , + "atime": , + "mtime": , + "ctime": + }, "id": } + +| Item | Data type | Description | +| ----------- | --------------- | ------------------------------------------- | +| inode | integer | inode of the filesystem object | +| mode | integer | unix file mode | +| type | "file" or "dir" | type of filesystem object | +| size | integer | required for files; file size in bytes | +| atime | integer | optional; unix time of last access | +| mtime | integer | optional; unix time of last modification | +| ctime | intefer | optional; unix time of last metadata change | + +### readdir + +Read directory contents. +Result is an array of name-inode pairs for each entry. The generic entries +"." and ".." should also be provided. + + wsfs daemon: {"method": "readdir", "params": [], "id": } + fs provider: {"result": [ + {"name": , "inode": }, + ... + ], "id": } + +| Item | Data type | Description | +| ----------- | --------------- | ------------------------------ | +| dir_inode | integer | inode of the directory to read | +| name | integer | name of the entry | +| inode | integer | inode of the entry | + +### open + +Open a file. + + wsfs daemon: {"method": "readdir", "params": [, ], "id": } + fs provider: {"result": {"handle": }, "id": } + +| Item | Data type | Description | +| ----------- | ----------| ----------------------------- | +| inode | integer | inode of the file | +| flags | integer | access mode flags (see below) | +| handle | integer | handle of the file | + +#### Flags + +| Symbolic name | Code | Description | +| --------------| ---------:| --------------------------- | +| O_ACCMODE | 0x003 | access mode mask | +| O_RDONLY | 0x000 | open for reading only | +| O_WRONLY | 0x001 | open for writing only | +| O_RDWR | 0x002 | open for reading an writing | +| O_CREAT | 0x040 | create (a new) file | +| O_EXCL | 0x080 | open file exclusivly | +| O_TRUNK | 0x200 | open file to trunkate | +| O_APPEND | 0x400 | open file to append | + + +### close + +Informs filesystem provider, that a file is closed. +Since `close` is a notification, it cannot fail. + + wsfs daemon: {"method": "close", "params": [, , ], "id": } + +| Item | Data type | Description | +| ----------- | ----------| ---------------------------- | +| inode | integer | inode of the file | +| handle | integer | handle of the file | +| flags | integer | access mode flags (see open) | + +### read + +Read from an open file. + + wsfs daemon: {"method": "close", "params": [, , , ], "id": } + fs provider: {"result": { + "data": , + "format": , + "count": + }, "id": } + +| Item | Data type | Description | +| ----------- | ----------| ----------------------------- | +| inode | integer | inode of the file | +| handle | integer | handle of the file | +| offset | integer | Offet to start read operation | +| length | integer | Max. number of bytes to read | +| data | integer | handle of the file | +| format | string | Encoding of data (see below) | +| count | integer | Actual number of bytes read | + +#### Format + +| Format | Description | +| ---------- | ----------------------------------------------- | +| "identiy" | Use data as is; note that json is UTF-8 encoded | + # Build and run To install dependencies, see below.