rest-file-io is a node.js application to securely read and write files in the file system via a REST API.
$ git clone https://github.com/peterthoeny/rest-file-io.git # or clone your own fork
$ cd rest-file-io
$ sudo cp -p rest-file-io.conf /etc # modify as desired
$ npm install
$ node rest-file-io
Visit http://localhost:8070/ to access the REST File I/O API.
The REST File I/O API is RESTful wrapper to securely read and write files in the file system. It is mainly intended to be used in an Intranet to automate processes, such as to read and write .csv files from Google sheets.
For security, only registered directories are available via the REST File I/O API. Directories are exposed via an ID (symbolic name), which point to the actual directory in the file system. Define the list of directory IDs with the directories setting in rest-file-io.conf. See Configration below for details.
Modify rest-file-io.conf located in /etc or the rest-file-io application directory. The referenced directories must be readable/writable by the rest-file-io application user.
- Endpoint:
GET /api/1/file/read/<directoryID>/<fileName><directoryID>: Directory ID<fileName>: File name with optional subdirectory path; allowed characters:/, alphanumeric,_,-,.- Example: http://localhost:8070/api/1/file/read/tmp/test.csv
- Return:
- If ok:
{ "data": "<content>", "error": "" } - If error:
{ "error": "File <fileName> not found in ID <directoryID>" }
- If ok:
- Optionally add a content-type:
- Endpoint:
GET /api/1/file/read/tmp/test.txt?contentType=text/plain - Example: http://localhost:8070/api/1/file/read/tmp/test.csv?contentType=text/plain
- Return: File content, delivered verbatimly with specified content-type
- Endpoint:
- Endpoint:
POST /api/1/file/write/<directoryID>/<fileName>- Message body is file content, such as CSV data of a spreadsheet file
- Example:
curl -X POST -H 'Content-Type: text/plain' --data-binary @test.csv http://localhost:8070/api/1/file/write/tmp/test.csv - Directory must be writable by the application user
- Return:
- If ok:
{ "data": "", "error": "" } - If error:
{ "data": "", "error": "Could not write file <fileName> to directory with ID <directoryID>" }
- If ok:
- Lock file endpoint:
GET /api/1/file/lock/<directoryID>/<fileName>?action=lock- Example: http://localhost:8070/api/1/file/lock/tmp/test.csv?action=lock
- return if ok:
{ "data": 1, "error": "" } - return if error:
{ "data": 0, "error": "Lock already exists for <fileName>" } - In case there is an existing stale lock: Break the lock if it is older than defined in the
lockBreaksetting, default 60 sec - In case there is an existing valid lock: Wait up to the time defined in the
lockWaitsetting, default 2.5 sec; an error is returned if not able to acquire a lock within that time
- Unlock file endpoint:
GET /api/1/file/lock/<directoryID>/<fileName>?action=unlock- Example: http://localhost:8070/api/1/file/lock/tmp/test.csv?action=unlock
- return if ok:
{ "data": 0, "error": "" } - return if error:
{ "data": 0, "error": "No lock exists for <fileName>" }
- Get lock status endpoint:
GET /api/1/file/lock/<directoryID>/<fileName>?action=status- Example: http://localhost:8070/api/1/file/lock/tmp/test.csv?action=status
- return if locked:
{ "data": 1, "error": "" } - return if unlocked:
{ "data": 0, "error": "" }
- Endpoint:
GET /api/1/file/directories- Return:
{ "data": [ "<id1>", "<id2>" ], "error": "" } - Example: http://localhost:8070/api/1/file/directories
- Available only if enabled with the
allowDirListsetting
- Return:
- Endpoint:
GET /api/1/file/list/<directoryID>/<subdirs><subdirs>: Optional subirectory path, available only if enabled with thesubdirsdirectory setting- return:
{ "data": [ "<file1>", "<file2>]" ], "error": "" } - Example: http://localhost:8070/api/1/file/list/tmp/files
- Available only if enabled with the
allowFileListsetting and thelistingdirectory setting
The rest-file-io.conf has the following format:
conf = {
directories: { // registry of directory IDs
example: { // directory ID
path: '/file/path/to/example',
listing: 0,
subdirs: 0,
comment: 'anything'
},
tmp: { // directory ID
path: './public/tmp', // path in the local file system
listing: 1, // 1: allow file listing, 0: disallow
subdirs: 1, // 1: allow subdirectories, 0: disallow
comment: 'sandbox for testing' // optional comment, such as directory owner
}
},
allowDirList: 1, // 1: allow directory ID listing, /api/1/directories
allowFileList: 1, // 1: default allow file listing, /api/1/file/list/<directoryID>
lockWait: 2.5, // wait time in sec in case someone else has a lock
lockBreak: 60, // time in sec to hijack a stale lock
port: 8070 // port used by the rest-file-io API
};
The tmp directory is a local rest-file-io directory that can be used for testing.
Note: The port number can be overloaded with a --port argument:
$ node rest-file-io --port 8088
LICENSE- MIT license fileREADME.md- documentationpackage.json- package definitionpackage-lock.json- node_modules dependenciespublic/favicon.ico- favicon, in case the API is used from a browserpublic/tmp/test.csv- test CSV file to read & writepublic/tmp/test.txt- test text file to read & writerest-file-io.conf- REST File I/O configuration template, copy to /etc and modifyrest-file-io.js- REST File I/O application
// EOF